text: /////////////////////////////////////////////////////////////////////////////////////
  //
  // module 'cc.io.local-storage.0.2.0/'
  //
  /////////////////////////////////////////////////////////////////////////////////////
  (function(using, require) {
      define.parameters = {};
      define.parameters.wrapped = true;
      define.parameters.system = "pkx";
      define.parameters.id = "cc.io.local-storage.0.2.0/";
      define.parameters.pkx = {
          "name": "cc.io.local-storage",
          "version": "0.2.0",
          "title": "IO Local Storage Module",
          "description": "IO module that implements local storage protocol support.",
          "license": "Apache-2.0",
          "pkx": {
              "main": "local-storage.js",
              "dependencies": [
                  "cc.event.0.2",
                  "cc.type.0.2",
                  "cc.io.0.2"
              ]
          }
      };
      define.parameters.dependencies = [ "pkx", "module", "configuration", "requirer" ];
      define.parameters.dependencies[0] = define.parameters.pkx;
      define.parameters.dependencies.push(define.cache.get("cc.event.0.2/"));
      define.parameters.dependencies.push(define.cache.get("cc.type.0.2/"));
      define.parameters.dependencies.push(define.cache.get("cc.io.0.2/"));
      using = define.getUsing(define.parameters.id);
      require = define.getRequire(define.parameters.id, require);
      /////////////////////////////////////////////////////////////////////////////////////////////
      //
      // cc.io.filesystem
      //
      //    Library for working with primitives.
      //
      // License
      //    Apache License Version 2.0
      //
      // Copyright Nick Verlinden (info@createconform.com)
      //
      /////////////////////////////////////////////////////////////////////////////////////////////
      
      (function() {
          function LocalStorage(pkx, module) {
              var self = this;
      
              //
              // get dependencies
              //
              var type, event, io, crypt;
              if (typeof require === "function") {
                  type = require("./cc.type");
                  event = require("./cc.event");
                  io = require("./cc.io");
              }
      
              if (typeof localStorage === "undefined") {
                  return "The runtime does not support local storage.";
              }
      
              //
              // constants
              //
              this.PROTOCOL_LOCAL_STORAGE = "ls";
              this.MAX_SIZE = "5242880"; //5MB max for local storage: https://demo.agektmr.com/storage/
      
              //
              // private functions
              //
              function getItem(path) {
                  return localStorage.getItem(self.PROTOCOL_LOCAL_STORAGE + ":///" + (path.indexOf("/") == 0? path.substr(1) : path));
              }
              function setItem(path, value) {
                  return localStorage.setItem(self.PROTOCOL_LOCAL_STORAGE + ":///" + (path.indexOf("/") == 0? path.substr(1) : path), value);
              }
              function removeItem(path) {
                  return localStorage.removeItem(self.PROTOCOL_LOCAL_STORAGE + ":///" + (path.indexOf("/") == 0? path.substr(1) : path));
              }
      
              //
              // public functions
              //
              this.LocalStorageStream = function(buffer, key, access)
              {
                  var own = this;
      
                  var seek_origin = io.SEEKORIGIN_BEGIN;
                  var written = false;
                  var closed = false;
      
                  this.getName = function() {
                      if (key && key.lastIndexOf("/") >= 0) {
                          return key.substr(key.lastIndexOf("/"));
                      }
                      else {
                          return key;
                      }
                  };
                  this.getLength = function()
                  {
                      return new Promise(function(resolve, refuse) {
                          if (closed) {
                              refuse(new Error(io.ERROR_STREAM_CLOSED, ""));
                              return;
                          }
                          resolve(buffer.length);
                      });
                  };
                  this.read = function (len, position)
                  {
                      if (!position) {
                          position = 0;
                      }
      
                      return new Promise(function(resolve, refuse) {
                          if (closed) {
                              refuse(new Error(io.ERROR_STREAM_CLOSED, ""));
                              return;
                          }
      
                          if (len == null) {
                              own.getLength().then(function (length) {
                                  doRead(length - position);
                              }, function(err) {
                                  refuse(err);
                              });
                          }
                          else {
                              doRead(len);
                          }
      
                          function doRead(len) {
                              if (len == buffer.length) {
                                  resolve(buffer);
                              }
                              else {
                                  var nBuf = buffer.subarray(position, position + len);
                                  position += len;
                                  resolve(nBuf);
                              }
                          }
                      });
                  };
                  this.write = function(data, position) {
                      if (!position) {
                          position = 0;
                      }
                      
                      return new Promise(function(resolve, refuse) {
                          if (closed) {
                              refuse(new Error(io.ERROR_STREAM_CLOSED, ""));
                              return;
                          }
      
                          try {
                              if (data == null) {
                                  resolve();
                                  return;
                              }
                              if (!((typeof Buffer != "undefined" && data instanceof Buffer) || (typeof Uint8Array != "undefined" && data instanceof Uint8Array) || type.isString(data))) {
                                  refuse("Invalid parameter 'data'. The parameter should be of type 'Buffer', 'Uint8Array' or 'String'.");
                                  return;
                              }
                              if (!type.isFunction(data.toString)) {
                                  refuse("Invalid parameter 'data'. The parameter should have the toString() function.");
                                  return;
                              }
                              var newData;
                              var newB;
                              var newLength;
                          /* if (typeof Buffer != "undefined") {
                                  newData = data instanceof Buffer? data : data.toBuffer();
                                  newLength = position + newData.length;
                                  if (access == io.ACCESS_MODIFY && newLength < buffer.length) {
                                      newLength = buffer.length;
                                  }
                                  newB = Buffer.alloc(newLength);
                                  //only write previous contents if not access is modify and data is not text, or has been written once (overwrite)
                                  if (access == io.ACCESS_MODIFY || written) {
                                      for (var b = 0; b < buffer.length && b < position; b++) {
                                          newB.writeUInt8(buffer[b], b);
                                      }
                                  }
                                  else if (!written && type.isString(data)) {
                                      for (var b = 0; b < position; b++) {
                                          newB.write(" ", b);
                                      }
                                  }
                                  for (b=0;b<data.length;b++) {
                                      newB.writeUInt8(newData[b], position + b);
                                  }
                              }
                              else {*/
                                  newData = data instanceof Uint8Array? data : data.toUint8Array();
                                  newLength = position + newData.length;
                                  if (access == io.ACCESS_MODIFY && newLength < buffer.length) {
                                      newLength = buffer.length;
                                  }
                                  newB = new Uint8Array(newLength);
                                  //only write previous contents if not access is modify and data is not text, or has been written once (overwrite)
                                  if (access == io.ACCESS_MODIFY || written) {
                                      newB.set(buffer, 0);
                                  }
                                  else if (!written && type.isString(data)) {
                                      newB.set(" ".repeat(position).toUint8Array(), 0);
                                  }
                                  newB.set(newData, position);
                              //}
                              buffer = newB;
                              var bfrStr = buffer.toString();
                              setItem(key, bfrStr);
                              written = true;
                              resolve();
                          } catch(e) {
                              refuse(e);
                          }
                      });
                  };
                  this.close = function (remove)
                  {
                      return new Promise(function(resolve, refuse) {
                          if (closed) {
                              refuse(new Error(io.ERROR_STREAM_CLOSED, ""));
                              return;
                          }
      
                          buffer = null;
                          closed = true;
      
                          if (remove) {
                              removeItem(key);
                          }
      
                          resolve();
                      });
                  };
              };
              this.LocalStorageStream.open = function(uri, opt_access, opt_create) {
                  return new Promise(function(resolve, reject) {
                      var buffer;
                      var data = getItem(uri.toString());
      
                      if (data) {
                          buffer = new Uint8Array(data.length);
                          Array.prototype.forEach.call(data, function (ch, i) {
                              buffer[i] = ch.charCodeAt(0);
                          });
      
                          resolve(new self.LocalStorageStream(buffer, uri.toString(), opt_access));
                          return;
                      }
                      else if (opt_access && opt_access != io.ACCESS_READ) {
                          setItem(uri.toString(), "");
                          resolve(new self.LocalStorageStream(new Uint8Array(0), uri.toString(), opt_access));
                          return;
                      }
      
                      reject(new Error(io.ERROR_FILE_NOT_FOUND, ""));
                  });
              };
              this.LocalStorageStream.prototype = io.Stream;
      
              this.LocalStorageVolume = function(path) {
                  this.err = [];
                  this.name = "Browser Storage (Small)";
                  this.protocol = self.PROTOCOL_LOCAL_STORAGE;
                  this.description = "Browser Storage (Small)";
                  this.size = self.MAX_SIZE;
                  this.state = io.VOLUME_STATE_READY;
                  this.type = io.VOLUME_TYPE_FIXED;
                  this.scope = io.VOLUME_SCOPE_LOCAL;
                  this.class = io.VOLUME_CLASS_PERSISTENT;
                  this.readOnly = false;
                  var deviceId = "NOT IMPLEMENTED";
                  this.localId = ""; //crypt.guid(crypt.md5(this.name + "/" + this.description + "/" + deviceId)); //TODO - deviceId from host library, but that would cause circular dependency
                  
                  this.query = function(uri) {  
                      return new Promise(function(resolve, refuse) { 
                          if (uri && type.isString(uri)) {
                              uri = self.uri.parse(uri);
                          }
                          else if (uri && (typeof uri.scheme == "undefined" || typeof uri.path == "undefined")) {
                              uri = null;
                          }
      
                          if (!uri || uri.scheme != self.PROTOCOL_LOCAL_STORAGE) {
                              reject("Invalid scheme.");
                              return;
                          }
                          var dir = uri.toString();
                          var lastIdx = dir.lastIndexOf("/");
                          if (lastIdx != dir.length - 1) {
                              dir = dir.substr(0, lastIdx + 1);
                          }
      
                          var items = [];
                          for (var key in localStorage) {
                              if (key.indexOf(dir) == 0 && key.substr(dir.length).indexOf("/") == -1) {
                                  items.push(io.URI.parse(key));
                              }
                          }
                          resolve(items);
                      });
                  };
      
                  this.open = function(path, opt_access, opt_create) {
                      return self.uri.open(path, opt_access, opt_create);
                  };
      
                  this.events = new event.Emitter(this);
              };
              this.LocalStorageVolume.prototype = io.Volume;
      
              this.uri = {};
              this.uri.parse = function(uri) {
                  if(uri && type.isString(uri)) {
                      if (uri.length >= 5 && uri.substr(0,5) == self.PROTOCOL_LOCAL_STORAGE + "://") {
                          return new io.URI(uri, self);
                      }
                  }
              };
              this.uri.open = function(uri, opt_access, opt_create) {
                  if (uri && type.isString(uri)) {
                      uri = self.uri.parse(uri);
                  }
                  else if (uri && (typeof uri.scheme == "undefined" || typeof uri.path == "undefined")) {
                      uri = null;
                  }
                  if (!uri) {
                      throw new Error(io.ERROR_URI_PARSE, "");
                  }
                  return self.LocalStorageStream.open(uri.path, opt_access, opt_create);
              };
              this.uri.exists = function(uri) {
                  return new Promise(function(resolve, refuse) {
                      if (uri && type.isString(uri)) {
                          uri = self.uri.parse(uri);
                      }
                      else if (uri && (typeof uri.scheme == "undefined" || typeof uri.path == "undefined")) {
                          uri = null;
                      }
                      var val = getItem(uri.path);
                      if (val == null) {
                          resolve();
                          return;
                      }
                      resolve(io.FILE);
                  });
      
              };
              this.uri.delete = function(uri) {
                  return new Promise(function(resolve, refuse) {
                      if (uri && type.isString(uri)) {
                          uri = self.uri.parse(uri);
                      }
                      else if (uri && (typeof uri.scheme == "undefined" || typeof uri.path == "undefined")) {
                          uri = null;
                      }
                      if (!uri) {
                          reject(new Error(io.ERROR_URI_PARSE, ""));
                          return;
                      }
                      var val = null;
                      if (uri) {
                          val = getItem(uri.path);
                      }
                      if (val == null) {
                          refuse(new Error(io.ERROR_FILE_NOT_FOUND, ""), "The file or directory does not exist local storage.");
                          return;
                      }
                      removeItem(uri.path);
                      resolve();
                  });
      
              };
              this.uri.query = function(uri) {
                  return volume.query(uri);
              };
              this.uri.toString = function(uri, opt_format) {
                  if (uri && type.isString(uri)) {
                      uri = self.uri.parse(uri);
                  }
                  else if (uri && (typeof uri.scheme == "undefined" || typeof uri.path == "undefined")) {
                      uri = null;
                  }
                  if (!uri) {
                      return "";
                  }
                  switch (opt_format) {
                      default:
                          return uri.toString();
                  }
              };
              this.uri.getTemp = function() {
                  return self.uri.parse(self.PROTOCOL_LOCAL_STORAGE + ":///tmp/");
              };
      
              // register protocol handler
              io.protocols.register({
                  "protocol": this.PROTOCOL_LOCAL_STORAGE,
                  "module": self
              });
      
              // register root
              var volume = new self.LocalStorageVolume("/");
              io.volumes.register(volume);
          }
      
          var singleton;
          (function (obj, factory) {
              var supported = false;
              if (typeof define === "function" && (define.amd || define.using)) {
                  define(factory);
      
                  if (define.using) {
                      // create instance on define
                      define.cache.get().factory();
                  }
      
                  supported = true;
              }
              if (typeof module === "object" && module.exports && typeof require != "undefined" && typeof require.main != "undefined" && require.main !== module) {
                  module.exports = factory();
                  supported = true;
              }
              if (!supported) {
                  obj.returnExports = factory();
              }
          }(this, function() {
              if (singleton) {
                  return singleton;
              }
              singleton = new (Function.prototype.bind.apply(LocalStorage, arguments));
              return singleton;
          }));
      })();
  })(typeof using != "undefined"? using : null, typeof require != "undefined"? require : null);
  