소스 검색

增加模块,以便在编辑器中可调试

nn 8 년 전
부모
커밋
e79c88f529
45개의 변경된 파일1864개의 추가작업 그리고 775개의 파일을 삭제
  1. 0 3
      resources/app/node_modules/debug/.eslintrc
  2. 4 10
      resources/app/node_modules/debug/.travis.yml
  3. 1 34
      resources/app/node_modules/debug/CHANGELOG.md
  4. 18 26
      resources/app/node_modules/debug/Makefile
  5. 62 118
      resources/app/node_modules/debug/README.md
  6. 20 17
      resources/app/node_modules/debug/package.json
  7. 6 16
      resources/app/node_modules/debug/src/browser.js
  8. 7 30
      resources/app/node_modules/debug/src/debug.js
  9. 1 1
      resources/app/node_modules/debug/src/index.js
  10. 93 31
      resources/app/node_modules/debug/src/node.js
  11. 1 0
      resources/app/node_modules/electron-storage/.eslintignore
  12. 6 0
      resources/app/node_modules/electron-storage/.eslintrc
  13. 3 0
      resources/app/node_modules/electron-storage/.npmignore
  14. 47 0
      resources/app/node_modules/electron-storage/CHANGELOG.md
  15. 21 0
      resources/app/node_modules/electron-storage/LICENSE
  16. 147 0
      resources/app/node_modules/electron-storage/README.md
  17. 199 0
      resources/app/node_modules/electron-storage/dist/index.js
  18. 69 0
      resources/app/node_modules/electron-storage/dist/utils.js
  19. 10 0
      resources/app/node_modules/electron-storage/gulpfile.js
  20. 73 0
      resources/app/node_modules/electron-storage/package.json
  21. 189 0
      resources/app/node_modules/electron-storage/src/index.js
  22. 67 0
      resources/app/node_modules/electron-storage/src/utils.js
  23. 132 0
      resources/app/node_modules/electron-storage/tests/src/index.spec.js
  24. 31 0
      resources/app/node_modules/electron-storage/tests/src/utils.spec.js
  25. 9 0
      resources/app/node_modules/glob/README.md
  26. 67 0
      resources/app/node_modules/glob/changelog.md
  27. 17 3
      resources/app/node_modules/glob/common.js
  28. 45 20
      resources/app/node_modules/glob/glob.js
  29. 18 21
      resources/app/node_modules/glob/package.json
  30. 39 13
      resources/app/node_modules/glob/sync.js
  31. 1 1
      resources/app/node_modules/readable-stream/README.md
  32. 204 173
      resources/app/node_modules/readable-stream/lib/_stream_readable.js
  33. 6 5
      resources/app/node_modules/readable-stream/lib/_stream_transform.js
  34. 45 136
      resources/app/node_modules/readable-stream/lib/_stream_writable.js
  35. 13 15
      resources/app/node_modules/readable-stream/package.json
  36. 2 1
      resources/app/node_modules/readable-stream/readable.js
  37. 3 1
      resources/app/node_modules/through2/.npmignore
  38. 43 18
      resources/app/node_modules/through2/README.md
  39. 20 20
      resources/app/node_modules/through2/package.json
  40. 73 19
      resources/app/node_modules/through2/through2.js
  41. 2 2
      resources/app/node_modules/xtend/LICENCE
  42. 7 2
      resources/app/node_modules/xtend/README.md
  43. 8 16
      resources/app/node_modules/xtend/mutable.js
  44. 15 23
      resources/app/node_modules/xtend/package.json
  45. 20 0
      resources/app/node_modules/xtend/test.js

+ 0 - 3
resources/app/node_modules/debug/.eslintrc

@@ -3,9 +3,6 @@
     "browser": true,
     "node": true
   },
-  "globals": {
-    "chrome": true
-  },
   "rules": {
     "no-console": 0,
     "no-empty": [1, { "allowEmptyCatch": true }]

+ 4 - 10
resources/app/node_modules/debug/.travis.yml

@@ -1,20 +1,14 @@
-sudo: false
 
 language: node_js
-
 node_js:
-  - "4"
   - "6"
-  - "8"
+  - "5"
+  - "4"
 
 install:
-  - make install
+  - make node_modules
 
 script:
   - make lint
   - make test
-
-matrix:
-  include:
-  - node_js: '8'
-    env: BROWSER=1
+  - make coveralls

+ 1 - 34
resources/app/node_modules/debug/CHANGELOG.md

@@ -1,37 +1,4 @@
 
-3.1.0 / 2017-09-26
-==================
-
-  * Add `DEBUG_HIDE_DATE` env var (#486)
-  * Remove ReDoS regexp in %o formatter (#504)
-  * Remove "component" from package.json
-  * Remove `component.json`
-  * Ignore package-lock.json
-  * Examples: fix colors printout
-  * Fix: browser detection
-  * Fix: spelling mistake (#496, @EdwardBetts)
-
-3.0.1 / 2017-08-24
-==================
-
-  * Fix: Disable colors in Edge and Internet Explorer (#489)
-
-3.0.0 / 2017-08-08
-==================
-
-  * Breaking: Remove DEBUG_FD (#406)
-  * Breaking: Use `Date#toISOString()` instead to `Date#toUTCString()` when output is not a TTY (#418)
-  * Breaking: Make millisecond timer namespace specific and allow 'always enabled' output (#408)
-  * Addition: document `enabled` flag (#465)
-  * Addition: add 256 colors mode (#481)
-  * Addition: `enabled()` updates existing debug instances, add `destroy()` function (#440)
-  * Update: component: update "ms" to v2.0.0
-  * Update: separate the Node and Browser tests in Travis-CI
-  * Update: refactor Readme, fixed documentation, added "Namespace Colors" section, redid screenshots
-  * Update: separate Node.js and web browser examples for organization
-  * Update: update "browserify" to v14.4.0
-  * Fix: fix Readme typo (#473)
-
 2.6.9 / 2017-09-22
 ==================
 
@@ -60,7 +27,7 @@
 2.6.4 / 2017-04-20
 ==================
 
-  * Fix: bug that would occur if process.env.DEBUG is a non-string value. (#444, @LucianBuzzo)
+  * Fix: bug that would occure if process.env.DEBUG is a non-string value. (#444, @LucianBuzzo)
   * Chore: ignore bower.json in npm installations. (#437, @joaovieira)
   * Misc: update "ms" to v0.7.3 (@tootallnate)
 

+ 18 - 26
resources/app/node_modules/debug/Makefile

@@ -15,44 +15,36 @@ YARN ?= $(shell which yarn)
 PKG ?= $(if $(YARN),$(YARN),$(NODE) $(shell which npm))
 BROWSERIFY ?= $(NODE) $(BIN)/browserify
 
-install: node_modules
+.FORCE:
 
-browser: dist/debug.js
+install: node_modules
 
 node_modules: package.json
 	@NODE_ENV= $(PKG) install
 	@touch node_modules
 
-dist/debug.js: src/*.js node_modules
-	@mkdir -p dist
+lint: .FORCE
+	eslint browser.js debug.js index.js node.js
+
+test-node: .FORCE
+	istanbul cover node_modules/mocha/bin/_mocha -- test/**.js
+
+test-browser: .FORCE
+	mkdir -p dist
+
 	@$(BROWSERIFY) \
 		--standalone debug \
 		. > dist/debug.js
 
-lint:
-	@eslint *.js src/*.js
-
-test-node:
-	@istanbul cover node_modules/mocha/bin/_mocha -- test/**.js
-	@cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js
+	karma start --single-run
+	rimraf dist
 
-test-browser:
-	@$(MAKE) browser
-	@karma start --single-run
-
-test-all:
-	@concurrently \
+test: .FORCE
+	concurrently \
 		"make test-node" \
 		"make test-browser"
 
-test:
-	@if [ "x$(BROWSER)" = "x" ]; then \
-		$(MAKE) test-node; \
-		else \
-		$(MAKE) test-browser; \
-	fi
-
-clean:
-	rimraf dist coverage
+coveralls:
+	cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js
 
-.PHONY: browser install clean lint test test-all test-node test-browser
+.PHONY: all install clean distclean

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 62 - 118
resources/app/node_modules/debug/README.md


+ 20 - 17
resources/app/node_modules/debug/package.json

@@ -1,35 +1,32 @@
 {
   "_args": [
     [
-      "debug@3.1.0",
-      "E:\\vscode\\UseStudio.Desktop\\resources\\app"
+      "debug@2.6.9",
+      "E:\\CampusInfo-borwers\\resources\\app"
     ]
   ],
-  "_development": true,
-  "_from": "debug@3.1.0",
-  "_id": "debug@3.1.0",
+  "_from": "debug@2.6.9",
+  "_id": "debug@2.6.9",
   "_inBundle": false,
-  "_integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
+  "_integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
   "_location": "/debug",
   "_phantomChildren": {},
   "_requested": {
     "type": "version",
     "registry": true,
-    "raw": "debug@3.1.0",
+    "raw": "debug@2.6.9",
     "name": "debug",
     "escapedName": "debug",
-    "rawSpec": "3.1.0",
+    "rawSpec": "2.6.9",
     "saveSpec": null,
-    "fetchSpec": "3.1.0"
+    "fetchSpec": "2.6.9"
   },
   "_requiredBy": [
-    "/electron-packager",
-    "/flora-colossus",
-    "/galactus"
+    "/regedit"
   ],
-  "_resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
-  "_spec": "3.1.0",
-  "_where": "E:\\vscode\\UseStudio.Desktop\\resources\\app",
+  "_resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+  "_spec": "2.6.9",
+  "_where": "E:\\CampusInfo-borwers\\resources\\app",
   "author": {
     "name": "TJ Holowaychuk",
     "email": "tj@vision-media.ca"
@@ -38,6 +35,12 @@
   "bugs": {
     "url": "https://github.com/visionmedia/debug/issues"
   },
+  "component": {
+    "scripts": {
+      "debug/index.js": "browser.js",
+      "debug/debug.js": "debug.js"
+    }
+  },
   "contributors": [
     {
       "name": "Nathan Rajlich",
@@ -54,7 +57,7 @@
   },
   "description": "small debugging utility",
   "devDependencies": {
-    "browserify": "14.4.0",
+    "browserify": "9.0.3",
     "chai": "^3.5.0",
     "concurrently": "^3.1.0",
     "coveralls": "^2.11.15",
@@ -84,5 +87,5 @@
     "type": "git",
     "url": "git://github.com/visionmedia/debug.git"
   },
-  "version": "3.1.0"
+  "version": "2.6.9"
 }

+ 6 - 16
resources/app/node_modules/debug/src/browser.js

@@ -20,17 +20,12 @@ exports.storage = 'undefined' != typeof chrome
  */
 
 exports.colors = [
-  '#0000CC', '#0000FF', '#0033CC', '#0033FF', '#0066CC', '#0066FF', '#0099CC',
-  '#0099FF', '#00CC00', '#00CC33', '#00CC66', '#00CC99', '#00CCCC', '#00CCFF',
-  '#3300CC', '#3300FF', '#3333CC', '#3333FF', '#3366CC', '#3366FF', '#3399CC',
-  '#3399FF', '#33CC00', '#33CC33', '#33CC66', '#33CC99', '#33CCCC', '#33CCFF',
-  '#6600CC', '#6600FF', '#6633CC', '#6633FF', '#66CC00', '#66CC33', '#9900CC',
-  '#9900FF', '#9933CC', '#9933FF', '#99CC00', '#99CC33', '#CC0000', '#CC0033',
-  '#CC0066', '#CC0099', '#CC00CC', '#CC00FF', '#CC3300', '#CC3333', '#CC3366',
-  '#CC3399', '#CC33CC', '#CC33FF', '#CC6600', '#CC6633', '#CC9900', '#CC9933',
-  '#CCCC00', '#CCCC33', '#FF0000', '#FF0033', '#FF0066', '#FF0099', '#FF00CC',
-  '#FF00FF', '#FF3300', '#FF3333', '#FF3366', '#FF3399', '#FF33CC', '#FF33FF',
-  '#FF6600', '#FF6633', '#FF9900', '#FF9933', '#FFCC00', '#FFCC33'
+  'lightseagreen',
+  'forestgreen',
+  'goldenrod',
+  'dodgerblue',
+  'darkorchid',
+  'crimson'
 ];
 
 /**
@@ -49,11 +44,6 @@ function useColors() {
     return true;
   }
 
-  // Internet Explorer and Edge do not support colors.
-  if (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/)) {
-    return false;
-  }
-
   // is webkit? http://stackoverflow.com/a/16459606/376773
   // document is undefined in react-native: https://github.com/facebook/react-native/pull/1632
   return (typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance) ||

+ 7 - 30
resources/app/node_modules/debug/src/debug.js

@@ -14,11 +14,6 @@ exports.enabled = enabled;
 exports.humanize = require('ms');
 
 /**
- * Active `debug` instances.
- */
-exports.instances = [];
-
-/**
  * The currently active debug mode names, and names to skip.
  */
 
@@ -34,6 +29,12 @@ exports.skips = [];
 exports.formatters = {};
 
 /**
+ * Previous log timestamp.
+ */
+
+var prevTime;
+
+/**
  * Select a color.
  * @param {String} namespace
  * @return {Number}
@@ -61,8 +62,6 @@ function selectColor(namespace) {
 
 function createDebug(namespace) {
 
-  var prevTime;
-
   function debug() {
     // disabled?
     if (!debug.enabled) return;
@@ -119,28 +118,15 @@ function createDebug(namespace) {
   debug.enabled = exports.enabled(namespace);
   debug.useColors = exports.useColors();
   debug.color = selectColor(namespace);
-  debug.destroy = destroy;
 
   // env-specific initialization logic for debug instances
   if ('function' === typeof exports.init) {
     exports.init(debug);
   }
 
-  exports.instances.push(debug);
-
   return debug;
 }
 
-function destroy () {
-  var index = exports.instances.indexOf(this);
-  if (index !== -1) {
-    exports.instances.splice(index, 1);
-    return true;
-  } else {
-    return false;
-  }
-}
-
 /**
  * Enables a debug mode by namespaces. This can include modes
  * separated by a colon and wildcards.
@@ -155,11 +141,10 @@ function enable(namespaces) {
   exports.names = [];
   exports.skips = [];
 
-  var i;
   var split = (typeof namespaces === 'string' ? namespaces : '').split(/[\s,]+/);
   var len = split.length;
 
-  for (i = 0; i < len; i++) {
+  for (var i = 0; i < len; i++) {
     if (!split[i]) continue; // ignore empty strings
     namespaces = split[i].replace(/\*/g, '.*?');
     if (namespaces[0] === '-') {
@@ -168,11 +153,6 @@ function enable(namespaces) {
       exports.names.push(new RegExp('^' + namespaces + '$'));
     }
   }
-
-  for (i = 0; i < exports.instances.length; i++) {
-    var instance = exports.instances[i];
-    instance.enabled = exports.enabled(instance.namespace);
-  }
 }
 
 /**
@@ -194,9 +174,6 @@ function disable() {
  */
 
 function enabled(name) {
-  if (name[name.length - 1] === '*') {
-    return true;
-  }
   var i, len;
   for (i = 0, len = exports.skips.length; i < len; i++) {
     if (exports.skips[i].test(name)) {

+ 1 - 1
resources/app/node_modules/debug/src/index.js

@@ -3,7 +3,7 @@
  * treat as a browser.
  */
 
-if (typeof process === 'undefined' || process.type === 'renderer') {
+if (typeof process !== 'undefined' && process.type === 'renderer') {
   module.exports = require('./browser.js');
 } else {
   module.exports = require('./node.js');

+ 93 - 31
resources/app/node_modules/debug/src/node.js

@@ -23,22 +23,7 @@ exports.useColors = useColors;
  * Colors.
  */
 
-exports.colors = [ 6, 2, 3, 4, 5, 1 ];
-
-try {
-  var supportsColor = require('supports-color');
-  if (supportsColor && supportsColor.level >= 2) {
-    exports.colors = [
-      20, 21, 26, 27, 32, 33, 38, 39, 40, 41, 42, 43, 44, 45, 56, 57, 62, 63, 68,
-      69, 74, 75, 76, 77, 78, 79, 80, 81, 92, 93, 98, 99, 112, 113, 128, 129, 134,
-      135, 148, 149, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171,
-      172, 173, 178, 179, 184, 185, 196, 197, 198, 199, 200, 201, 202, 203, 204,
-      205, 206, 207, 208, 209, 214, 215, 220, 221
-    ];
-  }
-} catch (err) {
-  // swallow - we only care if `supports-color` is available; it doesn't have to be.
-}
+exports.colors = [6, 2, 3, 4, 5, 1];
 
 /**
  * Build up the default `inspectOpts` object from the environment variables.
@@ -67,13 +52,30 @@ exports.inspectOpts = Object.keys(process.env).filter(function (key) {
 }, {});
 
 /**
+ * The file descriptor to write the `debug()` calls to.
+ * Set the `DEBUG_FD` env variable to override with another value. i.e.:
+ *
+ *   $ DEBUG_FD=3 node script.js 3>debug.log
+ */
+
+var fd = parseInt(process.env.DEBUG_FD, 10) || 2;
+
+if (1 !== fd && 2 !== fd) {
+  util.deprecate(function(){}, 'except for stderr(2) and stdout(1), any other usage of DEBUG_FD is deprecated. Override debug.log if you want to use a different log function (https://git.io/debug_fd)')()
+}
+
+var stream = 1 === fd ? process.stdout :
+             2 === fd ? process.stderr :
+             createWritableStdioStream(fd);
+
+/**
  * Is stdout a TTY? Colored output is enabled when `true`.
  */
 
 function useColors() {
   return 'colors' in exports.inspectOpts
     ? Boolean(exports.inspectOpts.colors)
-    : tty.isatty(process.stderr.fd);
+    : tty.isatty(fd);
 }
 
 /**
@@ -109,30 +111,22 @@ function formatArgs(args) {
 
   if (useColors) {
     var c = this.color;
-    var colorCode = '\u001b[3' + (c < 8 ? c : '8;5;' + c);
-    var prefix = '  ' + colorCode + ';1m' + name + ' ' + '\u001b[0m';
+    var prefix = '  \u001b[3' + c + ';1m' + name + ' ' + '\u001b[0m';
 
     args[0] = prefix + args[0].split('\n').join('\n' + prefix);
-    args.push(colorCode + 'm+' + exports.humanize(this.diff) + '\u001b[0m');
-  } else {
-    args[0] = getDate() + name + ' ' + args[0];
-  }
-}
-
-function getDate() {
-  if (exports.inspectOpts.hideDate) {
-    return '';
+    args.push('\u001b[3' + c + 'm+' + exports.humanize(this.diff) + '\u001b[0m');
   } else {
-    return new Date().toISOString() + ' ';
+    args[0] = new Date().toUTCString()
+      + ' ' + name + ' ' + args[0];
   }
 }
 
 /**
- * Invokes `util.format()` with the specified arguments and writes to stderr.
+ * Invokes `util.format()` with the specified arguments and writes to `stream`.
  */
 
 function log() {
-  return process.stderr.write(util.format.apply(util, arguments) + '\n');
+  return stream.write(util.format.apply(util, arguments) + '\n');
 }
 
 /**
@@ -164,6 +158,74 @@ function load() {
 }
 
 /**
+ * Copied from `node/src/node.js`.
+ *
+ * XXX: It's lame that node doesn't expose this API out-of-the-box. It also
+ * relies on the undocumented `tty_wrap.guessHandleType()` which is also lame.
+ */
+
+function createWritableStdioStream (fd) {
+  var stream;
+  var tty_wrap = process.binding('tty_wrap');
+
+  // Note stream._type is used for test-module-load-list.js
+
+  switch (tty_wrap.guessHandleType(fd)) {
+    case 'TTY':
+      stream = new tty.WriteStream(fd);
+      stream._type = 'tty';
+
+      // Hack to have stream not keep the event loop alive.
+      // See https://github.com/joyent/node/issues/1726
+      if (stream._handle && stream._handle.unref) {
+        stream._handle.unref();
+      }
+      break;
+
+    case 'FILE':
+      var fs = require('fs');
+      stream = new fs.SyncWriteStream(fd, { autoClose: false });
+      stream._type = 'fs';
+      break;
+
+    case 'PIPE':
+    case 'TCP':
+      var net = require('net');
+      stream = new net.Socket({
+        fd: fd,
+        readable: false,
+        writable: true
+      });
+
+      // FIXME Should probably have an option in net.Socket to create a
+      // stream from an existing fd which is writable only. But for now
+      // we'll just add this hack and set the `readable` member to false.
+      // Test: ./node test/fixtures/echo.js < /etc/passwd
+      stream.readable = false;
+      stream.read = null;
+      stream._type = 'pipe';
+
+      // FIXME Hack to have stream not keep the event loop alive.
+      // See https://github.com/joyent/node/issues/1726
+      if (stream._handle && stream._handle.unref) {
+        stream._handle.unref();
+      }
+      break;
+
+    default:
+      // Probably an error on in uv_guess_handle()
+      throw new Error('Implement me. Unknown stream file type!');
+  }
+
+  // For supporting legacy API we put the FD here.
+  stream.fd = fd;
+
+  stream._isStdio = true;
+
+  return stream;
+}
+
+/**
  * Init logic for `debug` instances.
  *
  * Create a new `inspectOpts` object in case `useColors` is set

+ 1 - 0
resources/app/node_modules/electron-storage/.eslintignore

@@ -0,0 +1 @@
+dist

+ 6 - 0
resources/app/node_modules/electron-storage/.eslintrc

@@ -0,0 +1,6 @@
+{
+  "extends": "airbnb-base",
+  "env": {
+        "mocha": "true"
+    }
+}

+ 3 - 0
resources/app/node_modules/electron-storage/.npmignore

@@ -0,0 +1,3 @@
+node_modules
+npm-debug.log
+fake-appData

+ 47 - 0
resources/app/node_modules/electron-storage/CHANGELOG.md

@@ -0,0 +1,47 @@
+# Change Log
+All notable changes to this project will be documented in this file.
+
+The format is based on [Keep a Changelog](http://keepachangelog.com/)
+and this project adheres to [Semantic Versioning](http://semver.org/).
+## [Unreleased]
+
+## [1.0.7]
+### Added
+- CHANGELOG.md
+
+### Changed
+- update dependencies (minor versions)
+- improve README.md
+
+## [1.0.6]
+### Changed
+- improve README.md and fix lint problems
+
+## [1.0.5]
+### Fixed
+- windows compatibility
+
+### Added
+- human readable message to existing ENOENT error
+
+## [1.0.4]
+### Changed
+- remove the .json automatic ending from ```remove``` and ```isPathExists``` methods because they also works on directories.
+- improve README.md file
+
+## [1.0.3]
+### Added
+- add .json ending on all methods
+
+## [1.0.2]
+### Added
+- ```storage.remove``` method
+
+## [1.0.1]
+### Added
+- tests
+- eslint
+- build
+
+## [1.0.0]
+- initial version

+ 21 - 0
resources/app/node_modules/electron-storage/LICENSE

@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2016 Ran
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.

+ 147 - 0
resources/app/node_modules/electron-storage/README.md

@@ -0,0 +1,147 @@
+# electron-storage
+
+> simple storage managing module for electron
+
+Electron saves data in app.getPath("userData") folder, which is different in every os.
+```electron-storage``` gives simple methods to get and set json files to this directory.
+
+* Creates subdirectories if needed - that means you can write ```movies/StarWars.json``` as path, a movies folder will be created and a StarWars.json file inside.
+* Supports callbacks and promises.
+* The data inserted can be a javascript object, or stringified json.
+* You don't have to write ```.json``` in the end of a file path, it will add it for you.
+
+[![NPM](https://nodei.co/npm/electron-storage.png?downloads=true&downloadRank=true)](https://nodei.co/npm/electron-storage/)
+[![Package Quality](http://npm.packagequality.com/badge/electron-storage.png)](http://packagequality.com/#?package=electron- storage)
+
+[![npm version](https://badge.fury.io/js/electron-storage.svg)](https://badge.fury.io/js/electron-storage)
+[![license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/Cocycles/electron-storage)
+[![issues](https://img.shields.io/github/issues/Cocycles/electron-storage.svg)](https://github.com/Cocycles/electron-storage)
+[![forks](https://img.shields.io/github/forks/Cocycles/electron-storage.svg)](https://github.com/Cocycles/electron-storage)
+[![stars](https://img.shields.io/github/stars/Cocycles/electron-storage.svg)](https://github.com/Cocycles/electron-storage)
+[![twitter](https://img.shields.io/twitter/url/http/shields.io.svg?style=social&maxAge=2592000)](https://twitter.com/intent/tweet?text=https://github.com/Cocycles/electron-storage&url=%5Bobject%20Object%5D)
+
+## Installation
+
+```
+$ npm install --save electron-storage
+```
+## usage
+```js
+
+const storage = require('electron-storage');
+```
+## API
+
+### get
+get a json file from storage.
+
+#### storage.get(filePath, cb)
+```js
+storage.get(filePath, (err, data) => {
+  if (err) {
+    console.error(err)
+  } else {
+    console.log(data);
+  }
+});
+```
+
+#### storage.get(filePath)
+```js
+storage.get(filePath)
+.then(data => {
+  console.log(data);
+})
+.catch(err => {
+  console.error(err);
+});
+```
+
+### set
+set a json file to storage.
+
+#### storage.set(filePath, data, cb)
+```js
+storage.set(filePath, data, (err) => {
+  if (err) {
+    console.error(err)
+  }
+});
+```
+
+#### storage.set(filePath, data)
+```js
+storage.set(filePath, data)
+.then(() => {
+  console.log('The file was successfully written to the storage');
+})
+.catch(err => {
+  console.error(err);
+});
+```
+
+### isPathExists
+check if a file or directory exists.
+
+```js
+// you have to write .json suffix for json files.
+// this method works on directories as well, if you don't write `.json` suffix it checks for a directory.
+```
+
+#### storage.isPathExists(path, cb)
+```js
+storage.isPathExists(path, (itDoes) => {
+  if (itDoes) {
+    console.log('pathDoesExists !')
+  }
+});
+```
+
+#### storage.isPathExists(path)
+```js
+storage.isPathExists(path)
+.then(itDoes => {
+  if (itDoes) {
+    console.log('pathDoesExists !')
+  }
+});
+```
+
+### remove
+remove a file or a directory from storage
+
+#### storage.remove(path, cb)
+```js
+storage.remove(path, err => {
+  if (err) {
+    console.log(err)
+  }
+});
+```
+
+#### storage.remove(path)
+```js
+storage.remove(path)
+.then(err => {
+  if (err) {
+    console.log(err)
+  }
+});
+```
+
+## Development
+``` npm run build ```
+for creating es5 files in dist folder
+
+## Contribute
+Contributions are welcome! please open issues and pull request :)
+
+## License
+The MIT License (MIT)
+Copyright (c) <year> <copyright holders>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

+ 199 - 0
resources/app/node_modules/electron-storage/dist/index.js

@@ -0,0 +1,199 @@
+'use strict';
+
+var _fs = require('fs');
+
+var _fs2 = _interopRequireDefault(_fs);
+
+var _mkdirp = require('mkdirp');
+
+var _mkdirp2 = _interopRequireDefault(_mkdirp);
+
+var _path = require('path');
+
+var _path2 = _interopRequireDefault(_path);
+
+var _rimraf = require('rimraf');
+
+var _rimraf2 = _interopRequireDefault(_rimraf);
+
+var _utils = require('./utils');
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+/**
+ * _get - function the gets filePath and a callback and returns a parse json
+ *        from the file in the specefied path
+ *
+ * @param  {string} filePath - path to the file relative to the `userData` folder
+ * @param  {function} cb - a callback function
+ */
+function _get(filePath, cb) {
+  var fullPath = (0, _utils.processPath)(filePath);
+  return _fs2.default.readFile(fullPath, { encoding: 'utf8' }, function (err, json) {
+    if (!err) {
+      var object = (0, _utils.tryParseJson)(json);
+
+      if (object instanceof Error) {
+        return cb(new Error('The file in path ' + fullPath + ' is not a valid json file'), null);
+      }
+
+      return cb(null, object);
+    }
+
+    if (err.code === 'ENOENT') {
+      err.message = 'The file in path ' + fullPath + ' doesn\'t exist'; /* eslint no-param-reassign: 0 */
+    }
+
+    return cb(err);
+  });
+}
+
+/**
+ * get - function the gets filePath and a callback and returns a parse json
+ *       from the file in the specefied path
+ *
+ * @param  {string} filePath - path to the file relative to the `userData` folder
+ * @param  {undefined | function} cb - an optional callback function
+ * @return {undefined | Promise} if there is only the first argument, the function
+ *                               will return a thenable Promise object
+ */
+/* eslint no-underscore-dangle: 0 */
+
+function get(filePath, cb) {
+  if (cb && (0, _utils.isFunction)(cb)) {
+    return _get(filePath, cb);
+  }
+
+  return new Promise(function (resolve, reject) {
+    return _get(filePath, function (err, data) {
+      if (err) return reject(err);
+      return resolve(data);
+    });
+  });
+}
+
+/**
+ * _set - sets a json file into the storage at a path (relative to the `userData` folder)
+ *        also stringify the json if needed and create any folder that is required in the path
+ *
+ * @param  {string} filePath - path to the file relative to the `userData` folder
+ * @param  {string | object} data - the data to save in the file path, can be parseJson or an object
+ * @param  {type} cb - a callback function
+ */
+function _set(filePath, data, cb) {
+  var fullPath = (0, _utils.processPath)(filePath);
+  var json = (0, _utils.tryStringifyJson)(data);
+
+  if (json instanceof Error) {
+    return cb(new Error('The file you trying to save at path ' + fullPath + ' is not valid json'));
+  }
+
+  var dir = _path2.default.dirname(fullPath);
+
+  return _fs2.default.access(dir, _fs2.default.F_OK, function (notExists) {
+    if (!notExists) return _fs2.default.writeFile(fullPath, json, cb);
+    return (0, _mkdirp2.default)(dir, function (err) {
+      if (err) return cb(err);
+      return _fs2.default.writeFile(fullPath, json, cb);
+    });
+  });
+}
+
+/**
+ * set - sets a json file into the storage at a path (relative to the `userData` folder)
+ *       also stringify the json if needed and create any folder that is required in the path
+ *
+ * @param  {string} filePath - path to the file relative to the `userData` folder
+ * @param  {string | object} data - the data to save in the file path, can be parseJson or an object
+ * @param  {undefined | function} cb - an optional callback function
+ * @return {undefined | Promise} if there are only two first arguments, the function
+ *                               will return a thenable Promise object
+ */
+
+function set(filePath, data, cb) {
+  if (cb && (0, _utils.isFunction)(cb)) {
+    return _set(filePath, data, cb);
+  }
+
+  return new Promise(function (resolve, reject) {
+    return _set(filePath, data, function (err) {
+      if (err) return reject(err);
+      return resolve();
+    });
+  });
+}
+
+/**
+ * _isPathExists - check whether the path inserted is exist in the userData directory
+ *
+ * @param  {string} fileOrDirPath - a path inside of the userData directory
+ * @param  {func} cb - a callback function
+ */
+function _isPathExists(fileOrDirPath, cb) {
+  var fullPath = (0, _utils.processPathNoJson)(fileOrDirPath);
+
+  return _fs2.default.exists(fullPath, function (exists) {
+    if (exists) return cb(true);
+    return cb(false);
+  });
+}
+
+/**
+ * isPathExists - check whether the path inserted is exist in the userData directory
+ *
+ * @param  {string} fileOrDirPath - a path inside of the userData directory
+ * @param  {undefined|func} cb - an optional callback function
+ * @return {undefined | Promise} if there are only two first arguments, the function
+ *                               will return a thenable Promise object
+ */
+function isPathExists(fileOrDirPath, cb) {
+  if (cb && (0, _utils.isFunction)(cb)) {
+    return _isPathExists(fileOrDirPath, cb);
+  }
+
+  return new Promise(function (resolve) {
+    return _isPathExists(fileOrDirPath, function (result) {
+      return resolve(result);
+    });
+  });
+}
+
+/**
+ * _remove - remove the file/folder from the path inserted
+ *
+ * @param  {string} fileOrDirPath - a path inside of the userData directory
+ * @param  {func} cb - a callback function
+ */
+function _remove(fileOrDirPath, cb) {
+  var fullPath = (0, _utils.processPathNoJson)(fileOrDirPath);
+
+  return (0, _rimraf2.default)(fullPath, cb);
+}
+
+/**
+ * remove - remove the file/folder from the path inserted
+ *
+ * @param  {string} fileOrDirPath - a path inside of the userData directory
+ * @param  {undefined|func} cb - an optional callback function
+ * @return {undefined | Promise} if there are only two first arguments, the function
+ *                               will return a thenable Promise object
+ */
+function remove(fileOrDirPath, cb) {
+  if (cb && (0, _utils.isFunction)(cb)) {
+    return _remove(fileOrDirPath, cb);
+  }
+
+  return new Promise(function (resolve, reject) {
+    return _remove(fileOrDirPath, function (error) {
+      if (error) return reject(error);
+      return resolve();
+    });
+  });
+}
+
+module.exports = {
+  get: get,
+  set: set,
+  isPathExists: isPathExists,
+  remove: remove
+};

+ 69 - 0
resources/app/node_modules/electron-storage/dist/utils.js

@@ -0,0 +1,69 @@
+'use strict';
+
+/* eslint object-shorthand: 0 */
+/* eslint no-param-reassign: 0 */
+/* eslint import/no-unresolved: 0 */
+
+var electron = require('electron');
+var app = electron.app || electron.remote.app;
+var userData = app.getPath('userData');
+var path = require('path');
+
+function isFunction(functionToCheck) {
+  var getType = {};
+  return functionToCheck && getType.toString.call(functionToCheck) === '[object Function]';
+}
+
+function tryParseJson(stringJson) {
+  var object = void 0;
+  try {
+    object = JSON.parse(stringJson);
+  } catch (e) {
+    return e;
+  }
+
+  return object;
+}
+
+function tryStringifyJson(objectJson) {
+  if (typeof objectJson === 'string') {
+    return objectJson;
+  }
+
+  var string = void 0;
+  try {
+    string = JSON.stringify(objectJson);
+  } catch (e) {
+    return e;
+  }
+
+  return string;
+}
+
+function getElectronFullPath(filePath) {
+  return path.join(userData, filePath);
+}
+
+function addDotJsonIfNeeded(filePath) {
+  if (filePath.substring(filePath.length - 5, filePath.length) === '.json') {
+    return filePath;
+  }
+
+  return filePath + '.json';
+}
+
+function processPath(filePath) {
+  return addDotJsonIfNeeded(getElectronFullPath(filePath));
+}
+
+function processPathNoJson(filePath) {
+  return getElectronFullPath(filePath);
+}
+
+module.exports = {
+  isFunction: isFunction,
+  tryParseJson: tryParseJson,
+  tryStringifyJson: tryStringifyJson,
+  processPath: processPath,
+  processPathNoJson: processPathNoJson
+};

+ 10 - 0
resources/app/node_modules/electron-storage/gulpfile.js

@@ -0,0 +1,10 @@
+const gulp = require('gulp');
+const babel = require('gulp-babel');
+
+gulp.task('default', () =>
+  gulp.src('./src/**/*.js')
+  .pipe(babel({
+    presets: ['es2015'],
+  }))
+	.pipe(gulp.dest('dist'))
+);

+ 73 - 0
resources/app/node_modules/electron-storage/package.json

@@ -0,0 +1,73 @@
+{
+  "_from": "electron-storage",
+  "_id": "electron-storage@1.0.7",
+  "_inBundle": false,
+  "_integrity": "sha1-8Ii2idqQQU5PlVUgg4lu7VP9518=",
+  "_location": "/electron-storage",
+  "_phantomChildren": {},
+  "_requested": {
+    "type": "tag",
+    "registry": true,
+    "raw": "electron-storage",
+    "name": "electron-storage",
+    "escapedName": "electron-storage",
+    "rawSpec": "",
+    "saveSpec": null,
+    "fetchSpec": "latest"
+  },
+  "_requiredBy": [
+    "#USER",
+    "/"
+  ],
+  "_resolved": "https://registry.npmjs.org/electron-storage/-/electron-storage-1.0.7.tgz",
+  "_shasum": "f088b689da90414e4f95552083896eed53fde75f",
+  "_spec": "electron-storage",
+  "_where": "E:\\CampusInfo-borwers\\resources\\app",
+  "author": {
+    "name": "Ran yitzhaki"
+  },
+  "bugs": {
+    "url": "https://github.com/ran-y/electron-storage/issues"
+  },
+  "bundleDependencies": false,
+  "dependencies": {
+    "mkdirp": "^0.5.1",
+    "rimraf": "^2.5.4"
+  },
+  "deprecated": false,
+  "description": "module for managing storage in electron applications",
+  "devDependencies": {
+    "babel-preset-es2015": "^6.9.0",
+    "chai": "^3.5.0",
+    "electron-mocha": "^2.3.1",
+    "electron-prebuilt": "^1.4.10",
+    "eslint": "^2.9.1",
+    "eslint-config-airbnb-base": "^3.0.1",
+    "eslint-plugin-import": "^1.10.2",
+    "gulp": "^3.9.1",
+    "gulp-babel": "^6.1.2",
+    "proxyquire": "^1.7.10"
+  },
+  "homepage": "https://github.com/ran-y/electron-storage",
+  "keywords": [
+    "electron",
+    "storage",
+    "json",
+    "get",
+    "set",
+    "isPathExists"
+  ],
+  "license": "MIT",
+  "main": "dist/index.js",
+  "name": "electron-storage",
+  "repository": {
+    "type": "git",
+    "url": "git+ssh://git@github.com/ran-y/electron-storage.git"
+  },
+  "scripts": {
+    "build": "gulp",
+    "lint": "eslint ./src/**/*.js; exit 0",
+    "test": "electron-mocha --recursive tests -R spec && electron-mocha --renderer --recursive tests -R spec"
+  },
+  "version": "1.0.7"
+}

+ 189 - 0
resources/app/node_modules/electron-storage/src/index.js

@@ -0,0 +1,189 @@
+/* eslint no-underscore-dangle: 0 */
+
+import fs from 'fs';
+import mkdirp from 'mkdirp';
+import path from 'path';
+import rimraf from 'rimraf';
+import {
+  isFunction,
+  tryParseJson,
+  tryStringifyJson,
+  processPath,
+  processPathNoJson,
+} from './utils';
+
+/**
+ * _get - function the gets filePath and a callback and returns a parse json
+ *        from the file in the specefied path
+ *
+ * @param  {string} filePath - path to the file relative to the `userData` folder
+ * @param  {function} cb - a callback function
+ */
+function _get(filePath, cb) {
+  const fullPath = processPath(filePath);
+  return fs.readFile(fullPath, { encoding: 'utf8' }, (err, json) => {
+    if (!err) {
+      const object = tryParseJson(json);
+
+      if (object instanceof Error) {
+        return cb(new Error(`The file in path ${fullPath} is not a valid json file`), null);
+      }
+
+      return cb(null, object);
+    }
+
+    if (err.code === 'ENOENT') {
+      err.message = `The file in path ${fullPath} doesn\'t exist`; /* eslint no-param-reassign: 0 */
+    }
+
+    return cb(err);
+  });
+}
+
+/**
+ * get - function the gets filePath and a callback and returns a parse json
+ *       from the file in the specefied path
+ *
+ * @param  {string} filePath - path to the file relative to the `userData` folder
+ * @param  {undefined | function} cb - an optional callback function
+ * @return {undefined | Promise} if there is only the first argument, the function
+ *                               will return a thenable Promise object
+ */
+function get(filePath, cb) {
+  if (cb && isFunction(cb)) {
+    return _get(filePath, cb);
+  }
+
+  return new Promise((resolve, reject) =>
+    _get(filePath, (err, data) => {
+      if (err) return reject(err);
+      return resolve(data);
+    })
+  );
+}
+
+/**
+ * _set - sets a json file into the storage at a path (relative to the `userData` folder)
+ *        also stringify the json if needed and create any folder that is required in the path
+ *
+ * @param  {string} filePath - path to the file relative to the `userData` folder
+ * @param  {string | object} data - the data to save in the file path, can be parseJson or an object
+ * @param  {type} cb - a callback function
+ */
+function _set(filePath, data, cb) {
+  const fullPath = processPath(filePath);
+  const json = tryStringifyJson(data);
+
+  if (json instanceof Error) {
+    return cb(new Error(`The file you trying to save at path ${fullPath} is not valid json`));
+  }
+
+  const dir = path.dirname(fullPath);
+
+  return fs.access(dir, fs.F_OK, (notExists) => {
+    if (!notExists) return fs.writeFile(fullPath, json, cb);
+    return mkdirp(dir, (err) => {
+      if (err) return cb(err);
+      return fs.writeFile(fullPath, json, cb);
+    });
+  });
+}
+
+/**
+ * set - sets a json file into the storage at a path (relative to the `userData` folder)
+ *       also stringify the json if needed and create any folder that is required in the path
+ *
+ * @param  {string} filePath - path to the file relative to the `userData` folder
+ * @param  {string | object} data - the data to save in the file path, can be parseJson or an object
+ * @param  {undefined | function} cb - an optional callback function
+ * @return {undefined | Promise} if there are only two first arguments, the function
+ *                               will return a thenable Promise object
+ */
+
+function set(filePath, data, cb) {
+  if (cb && isFunction(cb)) {
+    return _set(filePath, data, cb);
+  }
+
+  return new Promise((resolve, reject) =>
+    _set(filePath, data, (err) => {
+      if (err) return reject(err);
+      return resolve();
+    })
+  );
+}
+
+/**
+ * _isPathExists - check whether the path inserted is exist in the userData directory
+ *
+ * @param  {string} fileOrDirPath - a path inside of the userData directory
+ * @param  {func} cb - a callback function
+ */
+function _isPathExists(fileOrDirPath, cb) {
+  const fullPath = processPathNoJson(fileOrDirPath);
+
+  return fs.exists(fullPath, (exists) => {
+    if (exists) return cb(true);
+    return cb(false);
+  });
+}
+
+/**
+ * isPathExists - check whether the path inserted is exist in the userData directory
+ *
+ * @param  {string} fileOrDirPath - a path inside of the userData directory
+ * @param  {undefined|func} cb - an optional callback function
+ * @return {undefined | Promise} if there are only two first arguments, the function
+ *                               will return a thenable Promise object
+ */
+function isPathExists(fileOrDirPath, cb) {
+  if (cb && isFunction(cb)) {
+    return _isPathExists(fileOrDirPath, cb);
+  }
+
+  return new Promise(resolve =>
+    _isPathExists(fileOrDirPath, (result) =>
+      resolve(result)
+    )
+  );
+}
+
+/**
+ * _remove - remove the file/folder from the path inserted
+ *
+ * @param  {string} fileOrDirPath - a path inside of the userData directory
+ * @param  {func} cb - a callback function
+ */
+function _remove(fileOrDirPath, cb) {
+  const fullPath = processPathNoJson(fileOrDirPath);
+
+  return rimraf(fullPath, cb);
+}
+
+/**
+ * remove - remove the file/folder from the path inserted
+ *
+ * @param  {string} fileOrDirPath - a path inside of the userData directory
+ * @param  {undefined|func} cb - an optional callback function
+ * @return {undefined | Promise} if there are only two first arguments, the function
+ *                               will return a thenable Promise object
+ */
+function remove(fileOrDirPath, cb) {
+  if (cb && isFunction(cb)) {
+    return _remove(fileOrDirPath, cb);
+  }
+
+  return new Promise((resolve, reject) =>
+    _remove(fileOrDirPath, error => {
+      if (error) return reject(error);
+      return resolve();
+    })
+  );
+}
+
+module.exports = {
+  get,
+  set,
+  isPathExists,
+  remove,
+};

+ 67 - 0
resources/app/node_modules/electron-storage/src/utils.js

@@ -0,0 +1,67 @@
+/* eslint object-shorthand: 0 */
+/* eslint no-param-reassign: 0 */
+/* eslint import/no-unresolved: 0 */
+
+const electron = require('electron');
+const app = electron.app || electron.remote.app;
+const userData = app.getPath('userData');
+const path = require('path');
+
+function isFunction(functionToCheck) {
+  const getType = {};
+  return functionToCheck && getType.toString.call(functionToCheck) === '[object Function]';
+}
+
+function tryParseJson(stringJson) {
+  let object;
+  try {
+    object = JSON.parse(stringJson);
+  } catch (e) {
+    return e;
+  }
+
+  return object;
+}
+
+function tryStringifyJson(objectJson) {
+  if (typeof objectJson === 'string') {
+    return objectJson;
+  }
+
+  let string;
+  try {
+    string = JSON.stringify(objectJson);
+  } catch (e) {
+    return e;
+  }
+
+  return string;
+}
+
+function getElectronFullPath(filePath) {
+  return path.join(userData, filePath);
+}
+
+function addDotJsonIfNeeded(filePath) {
+  if (filePath.substring(filePath.length - 5, filePath.length) === '.json') {
+    return filePath;
+  }
+
+  return `${filePath}.json`;
+}
+
+function processPath(filePath) {
+  return addDotJsonIfNeeded(getElectronFullPath(filePath));
+}
+
+function processPathNoJson(filePath) {
+  return getElectronFullPath(filePath);
+}
+
+module.exports = {
+  isFunction,
+  tryParseJson,
+  tryStringifyJson,
+  processPath,
+  processPathNoJson,
+};

+ 132 - 0
resources/app/node_modules/electron-storage/tests/src/index.spec.js

@@ -0,0 +1,132 @@
+/* eslint consistent-return: 0 */
+
+const chai = require('chai');
+const fs = require('fs');
+const rimraf = require('rimraf');
+const path = require('path');
+const proxyquire = require('proxyquire');
+const fakeAppDataDir = path.join(process.cwd(), 'fake-appData');
+const mockGetElectronFullPath = (filePath) => path.join('fake-appData', filePath);
+const storage = proxyquire('../../dist/index', {
+  './utils': {
+    processPath: mockGetElectronFullPath,
+    processPathNoJson: mockGetElectronFullPath,
+  },
+});
+
+describe('Electron Storage', () => {
+  beforeEach('create the fake-appData folder', () => {
+    fs.mkdirSync(fakeAppDataDir);
+  });
+
+  afterEach('delete the fake-appData folder', () => {
+    rimraf.sync(fakeAppDataDir);
+  });
+
+  describe('storage.get()', () => {
+    it('receives the data from a json file', (done) => {
+      const json = JSON.stringify({ awesome: 'data' });
+      fs.writeFile(path.join(fakeAppDataDir, 'my-awesome-data.json'), json, (err) => {
+        if (err) {
+          throw err;
+        }
+
+        storage.get('my-awesome-data.json', (error, data) => {
+          chai.expect(error).to.equal(null);
+          chai.expect(data).to.deep.equal({ awesome: 'data' });
+          done();
+        });
+      });
+    });
+  });
+
+  describe('storage.get()', () => {
+    it('receives the data from a json file', (done) => {
+      const json = JSON.stringify({ awesome: 'data' });
+      fs.writeFile(path.join(fakeAppDataDir, 'my-awesome-data.json'), json, (err) => {
+        if (err) {
+          throw err;
+        }
+
+        storage.get('my-awesome-data.json').then(data => {
+          chai.expect(data).to.deep.equal({ awesome: 'data' });
+          done();
+        });
+      });
+    });
+  });
+
+  describe('storage.set()', () => {
+    it('sets a json file that you can later get', (done) => {
+      storage.set('data.json', { js: 'on' }, (err) => {
+        chai.expect(err).to.equal(null);
+        storage.get('data.json', (error, data) => {
+          chai.expect(data).to.deep.equal({ js: 'on' });
+          done();
+        });
+      });
+    });
+
+    it('creates folders if needed', (done) => {
+      storage.set(path.join('in', 'some', 'folders', 'data.json'), { js: 'on' }, (err) => {
+        chai.expect(err).to.equal(null);
+        storage.get(path.join('in', 'some', 'folders', 'data.json'), (error, data) => {
+          chai.expect(data).to.deep.equal({ js: 'on' });
+          done();
+        });
+      });
+    });
+  });
+
+  describe('storage.isPathExists()', () => {
+    it('return true if the path exists', (done) => {
+      storage.set(path.join('in', 'some', 'folders', 'data.json'), { js: 'on' }, (err) => {
+        chai.expect(err).to.equal(null);
+        storage.isPathExists(path.join('in', 'some', 'folders', 'data.json'), (data) => {
+          chai.expect(data).to.equal(true);
+          done();
+        });
+      });
+    });
+
+    it('return false if the path doesn\'t exists', (done) => {
+      storage.set(path.join('in', 'some', 'folders', 'data.json'), { js: 'on' }, (err) => {
+        chai.expect(err).to.equal(null);
+        storage.isPathExists(path.join('in', 'some', 'other', 'folders', 'data.json'), (data) => {
+          chai.expect(data).to.equal(false);
+          done();
+        });
+      });
+    });
+  });
+
+  describe('storage.remove() - file', () => {
+    it('removes the file in path', (done) => {
+      storage.set(path.join('in', 'some', 'folders', 'data.json'), { js: 'on' }, (err) => {
+        chai.expect(err).to.equal(null);
+        storage.remove(path.join('in', 'some', 'folders', 'data.json'), error => {
+          storage.isPathExists(path.join('in', 'some', 'other', 'folders', 'data.json'), (data) => {
+            chai.expect(data).to.equal(false);
+            chai.expect(error).to.equal(null);
+            done();
+          });
+        });
+      });
+    });
+  });
+
+  describe('storage.remove() - folder', () => {
+    it('removes the folder in path', (done) => {
+      storage.set(path.join('in', 'some', 'folders', 'data.json'), { js: 'on' }, (err) => {
+        chai.expect(err).to.equal(null);
+        storage.remove(path.join('in', 'some', 'folders'), error => {
+          storage.isPathExists(path.join('in', 'some', 'folders'), (data) => {
+            chai.expect(data).to.equal(false);
+            chai.expect(error).to.equal(null);
+            done();
+          });
+        });
+      });
+    });
+  });
+});

+ 31 - 0
resources/app/node_modules/electron-storage/tests/src/utils.spec.js

@@ -0,0 +1,31 @@
+const chai = require('chai');
+const { processPath } = require('../../dist/utils');
+const electron = require('electron');
+const app = electron.app || electron.remote.app;
+const userData = app.getPath('userData');
+const path = require('path');
+
+describe('Electron Storage utils', () => {
+  describe('utils.processPath', () => {
+    it('adds .json to the end of a file if needed', (done) => {
+      const filePath = path.join('a', 'filePath', 'without', 'json');
+      const fullPath = processPath(filePath);
+      chai.expect(fullPath).to.equal(path.join(userData, `${filePath}.json`));
+      done();
+    });
+
+    it('does not add .json to the end of a file if not needed', (done) => {
+      const filePath = path.join('a', 'filePath', 'without', 'json.json');
+      const fullPath = processPath(filePath);
+      chai.expect(fullPath).to.equal(path.join(userData, filePath));
+      done();
+    });
+
+    it('adds the electron appDataPath', (done) => {
+      const filePath = 'data.json';
+      const fullPath = processPath(filePath);
+      chai.expect(fullPath).to.equal(path.join(userData, filePath));
+      done();
+    });
+  });
+});

+ 9 - 0
resources/app/node_modules/glob/README.md

@@ -11,6 +11,12 @@ library to do its matching.
 
 ## Usage
 
+Install with npm
+
+```
+npm i glob
+```
+
 ```javascript
 var glob = require("glob")
 
@@ -267,6 +273,9 @@ the filesystem.
   In the case of a symlink that cannot be resolved, the full absolute
   path to the matched entry is returned (though it will usually be a
   broken symlink)
+* `absolute` Set to true to always receive absolute paths for matched
+  files.  Unlike `realpath`, this also affects the values returned in
+  the `match` event.
 
 ## Comparisons to other fnmatch/glob implementations
 

+ 67 - 0
resources/app/node_modules/glob/changelog.md

@@ -0,0 +1,67 @@
+## 7.0
+
+- Raise error if `options.cwd` is specified, and not a directory
+
+## 6.0
+
+- Remove comment and negation pattern support
+- Ignore patterns are always in `dot:true` mode
+
+## 5.0
+
+- Deprecate comment and negation patterns
+- Fix regression in `mark` and `nodir` options from making all cache
+  keys absolute path.
+- Abort if `fs.readdir` returns an error that's unexpected
+- Don't emit `match` events for ignored items
+- Treat ENOTSUP like ENOTDIR in readdir
+
+## 4.5
+
+- Add `options.follow` to always follow directory symlinks in globstar
+- Add `options.realpath` to call `fs.realpath` on all results
+- Always cache based on absolute path
+
+## 4.4
+
+- Add `options.ignore`
+- Fix handling of broken symlinks
+
+## 4.3
+
+- Bump minimatch to 2.x
+- Pass all tests on Windows
+
+## 4.2
+
+- Add `glob.hasMagic` function
+- Add `options.nodir` flag
+
+## 4.1
+
+- Refactor sync and async implementations for performance
+- Throw if callback provided to sync glob function
+- Treat symbolic links in globstar results the same as Bash 4.3
+
+## 4.0
+
+- Use `^` for dependency versions (bumped major because this breaks
+  older npm versions)
+- Ensure callbacks are only ever called once
+- switch to ISC license
+
+## 3.x
+
+- Rewrite in JavaScript
+- Add support for setting root, cwd, and windows support
+- Cache many fs calls
+- Add globstar support
+- emit match events
+
+## 2.x
+
+- Use `glob.h` and `fnmatch.h` from NetBSD
+
+## 1.x
+
+- `glob.h` static binding.

+ 17 - 3
resources/app/node_modules/glob/common.js

@@ -80,6 +80,7 @@ function setopts (self, pattern, options) {
   self.nocase = !!options.nocase
   self.stat = !!options.stat
   self.noprocess = !!options.noprocess
+  self.absolute = !!options.absolute
 
   self.maxLength = options.maxLength || Infinity
   self.cache = options.cache || Object.create(null)
@@ -93,8 +94,8 @@ function setopts (self, pattern, options) {
   if (!ownProp(options, "cwd"))
     self.cwd = cwd
   else {
-    self.cwd = options.cwd
-    self.changedCwd = path.resolve(options.cwd) !== cwd
+    self.cwd = path.resolve(options.cwd)
+    self.changedCwd = self.cwd !== cwd
   }
 
   self.root = options.root || path.resolve(self.cwd, "/")
@@ -102,6 +103,11 @@ function setopts (self, pattern, options) {
   if (process.platform === "win32")
     self.root = self.root.replace(/\\/g, "/")
 
+  // TODO: is an absolute `cwd` supposed to be resolved against `root`?
+  // e.g. { cwd: '/test', root: __dirname } === path.join(__dirname, '/test')
+  self.cwdAbs = isAbsolute(self.cwd) ? self.cwd : makeAbs(self, self.cwd)
+  if (process.platform === "win32")
+    self.cwdAbs = self.cwdAbs.replace(/\\/g, "/")
   self.nomount = !!options.nomount
 
   // disable comments and negation in Minimatch.
@@ -153,7 +159,11 @@ function finish (self) {
     }
     if (self.nodir) {
       all = all.filter(function (e) {
-        return !(/\/$/.test(e))
+        var notDir = !(/\/$/.test(e))
+        var c = self.cache[e] || self.cache[makeAbs(self, e)]
+        if (notDir && c)
+          notDir = c !== 'DIR' && !Array.isArray(c)
+        return notDir
       })
     }
   }
@@ -201,6 +211,10 @@ function makeAbs (self, f) {
   } else {
     abs = path.resolve(f)
   }
+
+  if (process.platform === 'win32')
+    abs = abs.replace(/\\/g, '/')
+
   return abs
 }
 

+ 45 - 20
resources/app/node_modules/glob/glob.js

@@ -41,6 +41,7 @@
 module.exports = glob
 
 var fs = require('fs')
+var rp = require('fs.realpath')
 var minimatch = require('minimatch')
 var Minimatch = minimatch.Minimatch
 var inherits = require('inherits')
@@ -99,6 +100,10 @@ glob.hasMagic = function (pattern, options_) {
 
   var g = new Glob(pattern, options)
   var set = g.minimatch.set
+
+  if (!pattern)
+    return false
+
   if (set.length > 1)
     return true
 
@@ -148,9 +153,7 @@ function Glob (pattern, options, cb) {
   }
 
   var self = this
-  var n = this.minimatch.set.length
   this._processing = 0
-  this.matches = new Array(n)
 
   this._emitQueue = []
   this._processQueue = []
@@ -162,14 +165,23 @@ function Glob (pattern, options, cb) {
   if (n === 0)
     return done()
 
+  var sync = true
   for (var i = 0; i < n; i ++) {
     this._process(this.minimatch.set[i], i, false, done)
   }
+  sync = false
 
   function done () {
     --self._processing
-    if (self._processing <= 0)
-      self._finish()
+    if (self._processing <= 0) {
+      if (sync) {
+        process.nextTick(function () {
+          self._finish()
+        })
+      } else {
+        self._finish()
+      }
+    }
   }
 }
 
@@ -223,7 +235,7 @@ Glob.prototype._realpathSet = function (index, cb) {
     // one or more of the links in the realpath couldn't be
     // resolved.  just return the abs value in that case.
     p = self._makeAbs(p)
-    fs.realpath(p, self.realpathCache, function (er, real) {
+    rp.realpath(p, self.realpathCache, function (er, real) {
       if (!er)
         set[real] = true
       else if (er.syscall === 'stat')
@@ -443,9 +455,6 @@ Glob.prototype._emitMatch = function (index, e) {
   if (this.aborted)
     return
 
-  if (this.matches[index][e])
-    return
-
   if (isIgnored(this, e))
     return
 
@@ -454,7 +463,16 @@ Glob.prototype._emitMatch = function (index, e) {
     return
   }
 
-  var abs = this._makeAbs(e)
+  var abs = isAbsolute(e) ? e : this._makeAbs(e)
+
+  if (this.mark)
+    e = this._mark(e)
+
+  if (this.absolute)
+    e = abs
+
+  if (this.matches[index][e])
+    return
 
   if (this.nodir) {
     var c = this.cache[abs]
@@ -462,9 +480,6 @@ Glob.prototype._emitMatch = function (index, e) {
       return
   }
 
-  if (this.mark)
-    e = this._mark(e)
-
   this.matches[index][e] = true
 
   var st = this.statCache[abs]
@@ -491,15 +506,15 @@ Glob.prototype._readdirInGlobStar = function (abs, cb) {
     fs.lstat(abs, lstatcb)
 
   function lstatcb_ (er, lstat) {
-    if (er)
+    if (er && er.code === 'ENOENT')
       return cb()
 
-    var isSym = lstat.isSymbolicLink()
+    var isSym = lstat && lstat.isSymbolicLink()
     self.symlinks[abs] = isSym
 
     // If it's not a symlink or a dir, then it's definitely a regular file.
     // don't bother doing a readdir in that case.
-    if (!isSym && !lstat.isDirectory()) {
+    if (!isSym && lstat && !lstat.isDirectory()) {
       self.cache[abs] = 'FILE'
       cb()
     } else
@@ -571,7 +586,15 @@ Glob.prototype._readdirError = function (f, er, cb) {
   switch (er.code) {
     case 'ENOTSUP': // https://github.com/isaacs/node-glob/issues/205
     case 'ENOTDIR': // totally normal. means it *does* exist.
-      this.cache[this._makeAbs(f)] = 'FILE'
+      var abs = this._makeAbs(f)
+      this.cache[abs] = 'FILE'
+      if (abs === this.cwdAbs) {
+        var error = new Error(er.code + ' invalid cwd ' + this.cwd)
+        error.path = this.cwd
+        error.code = er.code
+        this.emit('error', error)
+        this.abort()
+      }
       break
 
     case 'ENOENT': // not terribly unusual
@@ -744,7 +767,7 @@ Glob.prototype._stat = function (f, cb) {
 }
 
 Glob.prototype._stat2 = function (f, abs, er, stat, cb) {
-  if (er) {
+  if (er && (er.code === 'ENOENT' || er.code === 'ENOTDIR')) {
     this.statCache[abs] = false
     return cb()
   }
@@ -752,13 +775,15 @@ Glob.prototype._stat2 = function (f, abs, er, stat, cb) {
   var needDir = f.slice(-1) === '/'
   this.statCache[abs] = stat
 
-  if (abs.slice(-1) === '/' && !stat.isDirectory())
+  if (abs.slice(-1) === '/' && stat && !stat.isDirectory())
     return cb(null, false, stat)
 
-  var c = stat.isDirectory() ? 'DIR' : 'FILE'
+  var c = true
+  if (stat)
+    c = stat.isDirectory() ? 'DIR' : 'FILE'
   this.cache[abs] = this.cache[abs] || c
 
-  if (needDir && c !== 'DIR')
+  if (needDir && c === 'FILE')
     return cb()
 
   return cb(null, c, stat)

+ 18 - 21
resources/app/node_modules/glob/package.json

@@ -1,33 +1,27 @@
 {
-  "_args": [
-    [
-      "glob@6.0.4",
-      "E:\\vscode\\UseStudio.Desktop\\resources\\app"
-    ]
-  ],
-  "_development": true,
-  "_from": "glob@6.0.4",
-  "_id": "glob@6.0.4",
+  "_from": "glob@^7.0.5",
+  "_id": "glob@7.1.2",
   "_inBundle": false,
-  "_integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=",
+  "_integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
   "_location": "/glob",
   "_phantomChildren": {},
   "_requested": {
-    "type": "version",
+    "type": "range",
     "registry": true,
-    "raw": "glob@6.0.4",
+    "raw": "glob@^7.0.5",
     "name": "glob",
     "escapedName": "glob",
-    "rawSpec": "6.0.4",
+    "rawSpec": "^7.0.5",
     "saveSpec": null,
-    "fetchSpec": "6.0.4"
+    "fetchSpec": "^7.0.5"
   },
   "_requiredBy": [
-    "/asar"
+    "/rimraf"
   ],
-  "_resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz",
-  "_spec": "6.0.4",
-  "_where": "E:\\vscode\\UseStudio.Desktop\\resources\\app",
+  "_resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
+  "_shasum": "c19c9df9a028702d678612384a6552404c636d15",
+  "_spec": "glob@^7.0.5",
+  "_where": "E:\\CampusInfo-borwers\\resources\\app\\node_modules\\rimraf",
   "author": {
     "name": "Isaac Z. Schlueter",
     "email": "i@izs.me",
@@ -36,18 +30,21 @@
   "bugs": {
     "url": "https://github.com/isaacs/node-glob/issues"
   },
+  "bundleDependencies": false,
   "dependencies": {
+    "fs.realpath": "^1.0.0",
     "inflight": "^1.0.4",
     "inherits": "2",
-    "minimatch": "2 || 3",
+    "minimatch": "^3.0.4",
     "once": "^1.3.0",
     "path-is-absolute": "^1.0.0"
   },
+  "deprecated": false,
   "description": "a little globber",
   "devDependencies": {
     "mkdirp": "0",
     "rimraf": "^2.2.8",
-    "tap": "^5.0.0",
+    "tap": "^7.1.2",
     "tick": "0.0.6"
   },
   "engines": {
@@ -75,5 +72,5 @@
     "test": "tap test/*.js --cov",
     "test-regen": "npm run profclean && TEST_REGEN=1 node test/00-setup.js"
   },
-  "version": "6.0.4"
+  "version": "7.1.2"
 }

+ 39 - 13
resources/app/node_modules/glob/sync.js

@@ -2,6 +2,7 @@ module.exports = globSync
 globSync.GlobSync = GlobSync
 
 var fs = require('fs')
+var rp = require('fs.realpath')
 var minimatch = require('minimatch')
 var Minimatch = minimatch.Minimatch
 var Glob = require('./glob.js').Glob
@@ -15,6 +16,7 @@ var alphasorti = common.alphasorti
 var setopts = common.setopts
 var ownProp = common.ownProp
 var childrenIgnored = common.childrenIgnored
+var isIgnored = common.isIgnored
 
 function globSync (pattern, options) {
   if (typeof options === 'function' || arguments.length === 3)
@@ -57,7 +59,7 @@ GlobSync.prototype._finish = function () {
       for (var p in matchset) {
         try {
           p = self._makeAbs(p)
-          var real = fs.realpathSync(p, self.realpathCache)
+          var real = rp.realpathSync(p, self.realpathCache)
           set[real] = true
         } catch (er) {
           if (er.syscall === 'stat')
@@ -186,7 +188,7 @@ GlobSync.prototype._processReaddir = function (prefix, read, abs, remain, index,
       if (e.charAt(0) === '/' && !this.nomount) {
         e = path.join(this.root, e)
       }
-      this.matches[index][e] = true
+      this._emitMatch(index, e)
     }
     // This was the last one, and no stats were needed
     return
@@ -208,20 +210,29 @@ GlobSync.prototype._processReaddir = function (prefix, read, abs, remain, index,
 
 
 GlobSync.prototype._emitMatch = function (index, e) {
+  if (isIgnored(this, e))
+    return
+
   var abs = this._makeAbs(e)
+
   if (this.mark)
     e = this._mark(e)
 
+  if (this.absolute) {
+    e = abs
+  }
+
   if (this.matches[index][e])
     return
 
   if (this.nodir) {
-    var c = this.cache[this._makeAbs(e)]
+    var c = this.cache[abs]
     if (c === 'DIR' || Array.isArray(c))
       return
   }
 
   this.matches[index][e] = true
+
   if (this.stat)
     this._stat(e)
 }
@@ -239,16 +250,18 @@ GlobSync.prototype._readdirInGlobStar = function (abs) {
   try {
     lstat = fs.lstatSync(abs)
   } catch (er) {
-    // lstat failed, doesn't exist
-    return null
+    if (er.code === 'ENOENT') {
+      // lstat failed, doesn't exist
+      return null
+    }
   }
 
-  var isSym = lstat.isSymbolicLink()
+  var isSym = lstat && lstat.isSymbolicLink()
   this.symlinks[abs] = isSym
 
   // If it's not a symlink or a dir, then it's definitely a regular file.
   // don't bother doing a readdir in that case.
-  if (!isSym && !lstat.isDirectory())
+  if (!isSym && lstat && !lstat.isDirectory())
     this.cache[abs] = 'FILE'
   else
     entries = this._readdir(abs, false)
@@ -305,7 +318,14 @@ GlobSync.prototype._readdirError = function (f, er) {
   switch (er.code) {
     case 'ENOTSUP': // https://github.com/isaacs/node-glob/issues/205
     case 'ENOTDIR': // totally normal. means it *does* exist.
-      this.cache[this._makeAbs(f)] = 'FILE'
+      var abs = this._makeAbs(f)
+      this.cache[abs] = 'FILE'
+      if (abs === this.cwdAbs) {
+        var error = new Error(er.code + ' invalid cwd ' + this.cwd)
+        error.path = this.cwd
+        error.code = er.code
+        throw error
+      }
       break
 
     case 'ENOENT': // not terribly unusual
@@ -391,7 +411,7 @@ GlobSync.prototype._processSimple = function (prefix, index) {
     prefix = prefix.replace(/\\/g, '/')
 
   // Mark this as a match
-  this.matches[index][prefix] = true
+  this._emitMatch(index, prefix)
 }
 
 // Returns either 'DIR', 'FILE', or false
@@ -426,10 +446,13 @@ GlobSync.prototype._stat = function (f) {
     try {
       lstat = fs.lstatSync(abs)
     } catch (er) {
-      return false
+      if (er && (er.code === 'ENOENT' || er.code === 'ENOTDIR')) {
+        this.statCache[abs] = false
+        return false
+      }
     }
 
-    if (lstat.isSymbolicLink()) {
+    if (lstat && lstat.isSymbolicLink()) {
       try {
         stat = fs.statSync(abs)
       } catch (er) {
@@ -442,10 +465,13 @@ GlobSync.prototype._stat = function (f) {
 
   this.statCache[abs] = stat
 
-  var c = stat.isDirectory() ? 'DIR' : 'FILE'
+  var c = true
+  if (stat)
+    c = stat.isDirectory() ? 'DIR' : 'FILE'
+
   this.cache[abs] = this.cache[abs] || c
 
-  if (needDir && c !== 'DIR')
+  if (needDir && c === 'FILE')
     return false
 
   return c

+ 1 - 1
resources/app/node_modules/readable-stream/README.md

@@ -3,7 +3,7 @@
 ***Node-core streams for userland***
 
 [![NPM](https://nodei.co/npm/readable-stream.png?downloads=true&downloadRank=true)](https://nodei.co/npm/readable-stream/)
-[![NPM](https://nodei.co/npm-dl/readable-stream.png&months=6&height=3)](https://nodei.co/npm/readable-stream/)
+[![NPM](https://nodei.co/npm-dl/readable-stream.png?&months=6&height=3)](https://nodei.co/npm/readable-stream/)
 
 This package is a mirror of the Streams2 and Streams3 implementations in Node-core.
 

+ 204 - 173
resources/app/node_modules/readable-stream/lib/_stream_readable.js

@@ -49,29 +49,15 @@ util.inherits = require('inherits');
 
 var StringDecoder;
 
-
-/*<replacement>*/
-var debug = require('util');
-if (debug && debug.debuglog) {
-  debug = debug.debuglog('stream');
-} else {
-  debug = function () {};
-}
-/*</replacement>*/
-
-
 util.inherits(Readable, Stream);
 
 function ReadableState(options, stream) {
-  var Duplex = require('./_stream_duplex');
-
   options = options || {};
 
   // the point at which it stops calling _read() to fill the buffer
   // Note: 0 is a valid value, means "don't call _read preemptively ever"
   var hwm = options.highWaterMark;
-  var defaultHwm = options.objectMode ? 16 : 16 * 1024;
-  this.highWaterMark = (hwm || hwm === 0) ? hwm : defaultHwm;
+  this.highWaterMark = (hwm || hwm === 0) ? hwm : 16 * 1024;
 
   // cast to ints.
   this.highWaterMark = ~~this.highWaterMark;
@@ -80,13 +66,19 @@ function ReadableState(options, stream) {
   this.length = 0;
   this.pipes = null;
   this.pipesCount = 0;
-  this.flowing = null;
+  this.flowing = false;
   this.ended = false;
   this.endEmitted = false;
   this.reading = false;
 
+  // In streams that never have any data, and do push(null) right away,
+  // the consumer can miss the 'end' event if they do some I/O before
+  // consuming the stream.  So, we don't emit('end') until some reading
+  // happens.
+  this.calledRead = false;
+
   // a flag to be able to tell if the onwrite cb is called immediately,
-  // or on a later tick.  We set this to true at first, because any
+  // or on a later tick.  We set this to true at first, becuase any
   // actions that shouldn't happen until "later" should generally also
   // not happen before the first write call.
   this.sync = true;
@@ -102,9 +94,6 @@ function ReadableState(options, stream) {
   // make all the buffer merging and length checks go away
   this.objectMode = !!options.objectMode;
 
-  if (stream instanceof Duplex)
-    this.objectMode = this.objectMode || !!options.readableObjectMode;
-
   // Crypto is kind of old and crusty.  Historically, its default string
   // encoding is 'binary' so we have to make this configurable.
   // Everything else in the universe uses 'utf8', though.
@@ -131,8 +120,6 @@ function ReadableState(options, stream) {
 }
 
 function Readable(options) {
-  var Duplex = require('./_stream_duplex');
-
   if (!(this instanceof Readable))
     return new Readable(options);
 
@@ -151,7 +138,7 @@ function Readable(options) {
 Readable.prototype.push = function(chunk, encoding) {
   var state = this._readableState;
 
-  if (util.isString(chunk) && !state.objectMode) {
+  if (typeof chunk === 'string' && !state.objectMode) {
     encoding = encoding || state.defaultEncoding;
     if (encoding !== state.encoding) {
       chunk = new Buffer(chunk, encoding);
@@ -172,7 +159,7 @@ function readableAddChunk(stream, state, chunk, encoding, addToFront) {
   var er = chunkInvalid(state, chunk);
   if (er) {
     stream.emit('error', er);
-  } else if (util.isNullOrUndefined(chunk)) {
+  } else if (chunk === null || chunk === undefined) {
     state.reading = false;
     if (!state.ended)
       onEofChunk(stream, state);
@@ -187,25 +174,18 @@ function readableAddChunk(stream, state, chunk, encoding, addToFront) {
       if (state.decoder && !addToFront && !encoding)
         chunk = state.decoder.write(chunk);
 
-      if (!addToFront)
-        state.reading = false;
-
-      // if we want the data now, just emit it.
-      if (state.flowing && state.length === 0 && !state.sync) {
-        stream.emit('data', chunk);
-        stream.read(0);
+      // update the buffer info.
+      state.length += state.objectMode ? 1 : chunk.length;
+      if (addToFront) {
+        state.buffer.unshift(chunk);
       } else {
-        // update the buffer info.
-        state.length += state.objectMode ? 1 : chunk.length;
-        if (addToFront)
-          state.buffer.unshift(chunk);
-        else
-          state.buffer.push(chunk);
-
-        if (state.needReadable)
-          emitReadable(stream);
+        state.reading = false;
+        state.buffer.push(chunk);
       }
 
+      if (state.needReadable)
+        emitReadable(stream);
+
       maybeReadMore(stream, state);
     }
   } else if (!addToFront) {
@@ -237,7 +217,6 @@ Readable.prototype.setEncoding = function(enc) {
     StringDecoder = require('string_decoder/').StringDecoder;
   this._readableState.decoder = new StringDecoder(enc);
   this._readableState.encoding = enc;
-  return this;
 };
 
 // Don't raise the hwm > 128MB
@@ -261,7 +240,7 @@ function howMuchToRead(n, state) {
   if (state.objectMode)
     return n === 0 ? 0 : 1;
 
-  if (isNaN(n) || util.isNull(n)) {
+  if (n === null || isNaN(n)) {
     // only flow one buffer at a time
     if (state.flowing && state.buffer.length)
       return state.buffer[0].length;
@@ -293,11 +272,12 @@ function howMuchToRead(n, state) {
 
 // you can override either this method, or the async _read(n) below.
 Readable.prototype.read = function(n) {
-  debug('read', n);
   var state = this._readableState;
+  state.calledRead = true;
   var nOrig = n;
+  var ret;
 
-  if (!util.isNumber(n) || n > 0)
+  if (typeof n !== 'number' || n > 0)
     state.emittedReadable = false;
 
   // if we're doing read(0) to trigger a readable event, but we
@@ -306,11 +286,7 @@ Readable.prototype.read = function(n) {
   if (n === 0 &&
       state.needReadable &&
       (state.length >= state.highWaterMark || state.ended)) {
-    debug('read: emitReadable', state.length, state.ended);
-    if (state.length === 0 && state.ended)
-      endReadable(this);
-    else
-      emitReadable(this);
+    emitReadable(this);
     return null;
   }
 
@@ -318,9 +294,28 @@ Readable.prototype.read = function(n) {
 
   // if we've ended, and we're now clear, then finish it up.
   if (n === 0 && state.ended) {
+    ret = null;
+
+    // In cases where the decoder did not receive enough data
+    // to produce a full chunk, then immediately received an
+    // EOF, state.buffer will contain [<Buffer >, <Buffer 00 ...>].
+    // howMuchToRead will see this and coerce the amount to
+    // read to zero (because it's looking at the length of the
+    // first <Buffer > in state.buffer), and we'll end up here.
+    //
+    // This can only happen via state.decoder -- no other venue
+    // exists for pushing a zero-length chunk into state.buffer
+    // and triggering this behavior. In this case, we return our
+    // remaining data and end the stream, if appropriate.
+    if (state.length > 0 && state.decoder) {
+      ret = fromList(n, state);
+      state.length -= ret.length;
+    }
+
     if (state.length === 0)
       endReadable(this);
-    return null;
+
+    return ret;
   }
 
   // All the actual chunk generation logic needs to be
@@ -347,23 +342,17 @@ Readable.prototype.read = function(n) {
 
   // if we need a readable event, then we need to do some reading.
   var doRead = state.needReadable;
-  debug('need readable', doRead);
 
   // if we currently have less than the highWaterMark, then also read some
-  if (state.length === 0 || state.length - n < state.highWaterMark) {
+  if (state.length - n <= state.highWaterMark)
     doRead = true;
-    debug('length less than watermark', doRead);
-  }
 
   // however, if we've ended, then there's no point, and if we're already
   // reading, then it's unnecessary.
-  if (state.ended || state.reading) {
+  if (state.ended || state.reading)
     doRead = false;
-    debug('reading or ended', doRead);
-  }
 
   if (doRead) {
-    debug('do read');
     state.reading = true;
     state.sync = true;
     // if the length is currently zero, then we *need* a readable event.
@@ -374,18 +363,18 @@ Readable.prototype.read = function(n) {
     state.sync = false;
   }
 
-  // If _read pushed data synchronously, then `reading` will be false,
-  // and we need to re-evaluate how much data we can return to the user.
+  // If _read called its callback synchronously, then `reading`
+  // will be false, and we need to re-evaluate how much data we
+  // can return to the user.
   if (doRead && !state.reading)
     n = howMuchToRead(nOrig, state);
 
-  var ret;
   if (n > 0)
     ret = fromList(n, state);
   else
     ret = null;
 
-  if (util.isNull(ret)) {
+  if (ret === null) {
     state.needReadable = true;
     n = 0;
   }
@@ -397,21 +386,21 @@ Readable.prototype.read = function(n) {
   if (state.length === 0 && !state.ended)
     state.needReadable = true;
 
-  // If we tried to read() past the EOF, then emit end on the next tick.
-  if (nOrig !== n && state.ended && state.length === 0)
+  // If we happened to read() exactly the remaining amount in the
+  // buffer, and the EOF has been seen at this point, then make sure
+  // that we emit 'end' on the very next tick.
+  if (state.ended && !state.endEmitted && state.length === 0)
     endReadable(this);
 
-  if (!util.isNull(ret))
-    this.emit('data', ret);
-
   return ret;
 };
 
 function chunkInvalid(state, chunk) {
   var er = null;
-  if (!util.isBuffer(chunk) &&
-      !util.isString(chunk) &&
-      !util.isNullOrUndefined(chunk) &&
+  if (!Buffer.isBuffer(chunk) &&
+      'string' !== typeof chunk &&
+      chunk !== null &&
+      chunk !== undefined &&
       !state.objectMode) {
     er = new TypeError('Invalid non-string/buffer chunk');
   }
@@ -429,8 +418,12 @@ function onEofChunk(stream, state) {
   }
   state.ended = true;
 
-  // emit 'readable' now to make sure it gets picked up.
-  emitReadable(stream);
+  // if we've ended and we have some data left, then emit
+  // 'readable' now to make sure it gets picked up.
+  if (state.length > 0)
+    emitReadable(stream);
+  else
+    endReadable(stream);
 }
 
 // Don't emit readable right away in sync mode, because this can trigger
@@ -439,22 +432,20 @@ function onEofChunk(stream, state) {
 function emitReadable(stream) {
   var state = stream._readableState;
   state.needReadable = false;
-  if (!state.emittedReadable) {
-    debug('emitReadable', state.flowing);
-    state.emittedReadable = true;
-    if (state.sync)
-      process.nextTick(function() {
-        emitReadable_(stream);
-      });
-    else
+  if (state.emittedReadable)
+    return;
+
+  state.emittedReadable = true;
+  if (state.sync)
+    process.nextTick(function() {
       emitReadable_(stream);
-  }
+    });
+  else
+    emitReadable_(stream);
 }
 
 function emitReadable_(stream) {
-  debug('emit readable');
   stream.emit('readable');
-  flow(stream);
 }
 
 
@@ -477,7 +468,6 @@ function maybeReadMore_(stream, state) {
   var len = state.length;
   while (!state.reading && !state.flowing && !state.ended &&
          state.length < state.highWaterMark) {
-    debug('maybeReadMore read 0');
     stream.read(0);
     if (len === state.length)
       // didn't get any data, stop spinning.
@@ -512,7 +502,6 @@ Readable.prototype.pipe = function(dest, pipeOpts) {
       break;
   }
   state.pipesCount += 1;
-  debug('pipe count=%d opts=%j', state.pipesCount, pipeOpts);
 
   var doEnd = (!pipeOpts || pipeOpts.end !== false) &&
               dest !== process.stdout &&
@@ -526,14 +515,11 @@ Readable.prototype.pipe = function(dest, pipeOpts) {
 
   dest.on('unpipe', onunpipe);
   function onunpipe(readable) {
-    debug('onunpipe');
-    if (readable === src) {
-      cleanup();
-    }
+    if (readable !== src) return;
+    cleanup();
   }
 
   function onend() {
-    debug('onend');
     dest.end();
   }
 
@@ -545,7 +531,6 @@ Readable.prototype.pipe = function(dest, pipeOpts) {
   dest.on('drain', ondrain);
 
   function cleanup() {
-    debug('cleanup');
     // cleanup event handlers once the pipe is broken
     dest.removeListener('close', onclose);
     dest.removeListener('finish', onfinish);
@@ -554,34 +539,19 @@ Readable.prototype.pipe = function(dest, pipeOpts) {
     dest.removeListener('unpipe', onunpipe);
     src.removeListener('end', onend);
     src.removeListener('end', cleanup);
-    src.removeListener('data', ondata);
 
     // if the reader is waiting for a drain event from this
     // specific writer, then it would cause it to never start
     // flowing again.
     // So, if this is awaiting a drain, then we just call it now.
     // If we don't know, then assume that we are waiting for one.
-    if (state.awaitDrain &&
-        (!dest._writableState || dest._writableState.needDrain))
+    if (!dest._writableState || dest._writableState.needDrain)
       ondrain();
   }
 
-  src.on('data', ondata);
-  function ondata(chunk) {
-    debug('ondata');
-    var ret = dest.write(chunk);
-    if (false === ret) {
-      debug('false write response, pause',
-            src._readableState.awaitDrain);
-      src._readableState.awaitDrain++;
-      src.pause();
-    }
-  }
-
   // if the dest has an error, then stop piping into it.
   // however, don't suppress the throwing behavior for this.
   function onerror(er) {
-    debug('onerror', er);
     unpipe();
     dest.removeListener('error', onerror);
     if (EE.listenerCount(dest, 'error') === 0)
@@ -605,14 +575,12 @@ Readable.prototype.pipe = function(dest, pipeOpts) {
   }
   dest.once('close', onclose);
   function onfinish() {
-    debug('onfinish');
     dest.removeListener('close', onclose);
     unpipe();
   }
   dest.once('finish', onfinish);
 
   function unpipe() {
-    debug('unpipe');
     src.unpipe(dest);
   }
 
@@ -621,8 +589,16 @@ Readable.prototype.pipe = function(dest, pipeOpts) {
 
   // start the flow if it hasn't been started already.
   if (!state.flowing) {
-    debug('pipe resume');
-    src.resume();
+    // the handler that waits for readable events after all
+    // the data gets sucked out in flow.
+    // This would be easier to follow with a .once() handler
+    // in flow(), but that is too slow.
+    this.on('readable', pipeOnReadable);
+
+    state.flowing = true;
+    process.nextTick(function() {
+      flow(src);
+    });
   }
 
   return dest;
@@ -630,17 +606,65 @@ Readable.prototype.pipe = function(dest, pipeOpts) {
 
 function pipeOnDrain(src) {
   return function() {
+    var dest = this;
     var state = src._readableState;
-    debug('pipeOnDrain', state.awaitDrain);
-    if (state.awaitDrain)
-      state.awaitDrain--;
-    if (state.awaitDrain === 0 && EE.listenerCount(src, 'data')) {
-      state.flowing = true;
+    state.awaitDrain--;
+    if (state.awaitDrain === 0)
       flow(src);
-    }
   };
 }
 
+function flow(src) {
+  var state = src._readableState;
+  var chunk;
+  state.awaitDrain = 0;
+
+  function write(dest, i, list) {
+    var written = dest.write(chunk);
+    if (false === written) {
+      state.awaitDrain++;
+    }
+  }
+
+  while (state.pipesCount && null !== (chunk = src.read())) {
+
+    if (state.pipesCount === 1)
+      write(state.pipes, 0, null);
+    else
+      forEach(state.pipes, write);
+
+    src.emit('data', chunk);
+
+    // if anyone needs a drain, then we have to wait for that.
+    if (state.awaitDrain > 0)
+      return;
+  }
+
+  // if every destination was unpiped, either before entering this
+  // function, or in the while loop, then stop flowing.
+  //
+  // NB: This is a pretty rare edge case.
+  if (state.pipesCount === 0) {
+    state.flowing = false;
+
+    // if there were data event listeners added, then switch to old mode.
+    if (EE.listenerCount(src, 'data') > 0)
+      emitDataEvents(src);
+    return;
+  }
+
+  // at this point, no one needed a drain, so we just ran out of data
+  // on the next readable event, start it over again.
+  state.ranOut = true;
+}
+
+function pipeOnReadable() {
+  if (this._readableState.ranOut) {
+    this._readableState.ranOut = false;
+    flow(this);
+  }
+}
+
 
 Readable.prototype.unpipe = function(dest) {
   var state = this._readableState;
@@ -661,6 +685,7 @@ Readable.prototype.unpipe = function(dest) {
     // got a match.
     state.pipes = null;
     state.pipesCount = 0;
+    this.removeListener('readable', pipeOnReadable);
     state.flowing = false;
     if (dest)
       dest.emit('unpipe', this);
@@ -675,6 +700,7 @@ Readable.prototype.unpipe = function(dest) {
     var len = state.pipesCount;
     state.pipes = null;
     state.pipesCount = 0;
+    this.removeListener('readable', pipeOnReadable);
     state.flowing = false;
 
     for (var i = 0; i < len; i++)
@@ -702,11 +728,8 @@ Readable.prototype.unpipe = function(dest) {
 Readable.prototype.on = function(ev, fn) {
   var res = Stream.prototype.on.call(this, ev, fn);
 
-  // If listening to data, and it has not explicitly been paused,
-  // then call resume to start the flow of data on the next tick.
-  if (ev === 'data' && false !== this._readableState.flowing) {
-    this.resume();
-  }
+  if (ev === 'data' && !this._readableState.flowing)
+    emitDataEvents(this);
 
   if (ev === 'readable' && this.readable) {
     var state = this._readableState;
@@ -715,11 +738,7 @@ Readable.prototype.on = function(ev, fn) {
       state.emittedReadable = false;
       state.needReadable = true;
       if (!state.reading) {
-        var self = this;
-        process.nextTick(function() {
-          debug('readable nexttick read 0');
-          self.read(0);
-        });
+        this.read(0);
       } else if (state.length) {
         emitReadable(this, state);
       }
@@ -733,54 +752,63 @@ Readable.prototype.addListener = Readable.prototype.on;
 // pause() and resume() are remnants of the legacy readable stream API
 // If the user uses them, then switch into old mode.
 Readable.prototype.resume = function() {
-  var state = this._readableState;
-  if (!state.flowing) {
-    debug('resume');
-    state.flowing = true;
-    if (!state.reading) {
-      debug('resume read 0');
-      this.read(0);
-    }
-    resume(this, state);
-  }
-  return this;
+  emitDataEvents(this);
+  this.read(0);
+  this.emit('resume');
 };
 
-function resume(stream, state) {
-  if (!state.resumeScheduled) {
-    state.resumeScheduled = true;
-    process.nextTick(function() {
-      resume_(stream, state);
-    });
-  }
-}
-
-function resume_(stream, state) {
-  state.resumeScheduled = false;
-  stream.emit('resume');
-  flow(stream);
-  if (state.flowing && !state.reading)
-    stream.read(0);
-}
-
 Readable.prototype.pause = function() {
-  debug('call pause flowing=%j', this._readableState.flowing);
-  if (false !== this._readableState.flowing) {
-    debug('pause');
-    this._readableState.flowing = false;
-    this.emit('pause');
-  }
-  return this;
+  emitDataEvents(this, true);
+  this.emit('pause');
 };
 
-function flow(stream) {
+function emitDataEvents(stream, startPaused) {
   var state = stream._readableState;
-  debug('flow', state.flowing);
+
   if (state.flowing) {
-    do {
-      var chunk = stream.read();
-    } while (null !== chunk && state.flowing);
+    // https://github.com/isaacs/readable-stream/issues/16
+    throw new Error('Cannot switch to old mode now.');
   }
+
+  var paused = startPaused || false;
+  var readable = false;
+
+  // convert to an old-style stream.
+  stream.readable = true;
+  stream.pipe = Stream.prototype.pipe;
+  stream.on = stream.addListener = Stream.prototype.on;
+
+  stream.on('readable', function() {
+    readable = true;
+
+    var c;
+    while (!paused && (null !== (c = stream.read())))
+      stream.emit('data', c);
+
+    if (c === null) {
+      readable = false;
+      stream._readableState.needReadable = true;
+    }
+  });
+
+  stream.pause = function() {
+    paused = true;
+    this.emit('pause');
+  };
+
+  stream.resume = function() {
+    paused = false;
+    if (readable)
+      process.nextTick(function() {
+        stream.emit('readable');
+      });
+    else
+      this.read(0);
+    this.emit('resume');
+  };
+
+  // now make it start, just in case it hadn't already.
+  stream.emit('readable');
 }
 
 // wrap an old-style stream as the async data source.
@@ -792,7 +820,6 @@ Readable.prototype.wrap = function(stream) {
 
   var self = this;
   stream.on('end', function() {
-    debug('wrapped end');
     if (state.decoder && !state.ended) {
       var chunk = state.decoder.end();
       if (chunk && chunk.length)
@@ -803,10 +830,14 @@ Readable.prototype.wrap = function(stream) {
   });
 
   stream.on('data', function(chunk) {
-    debug('wrapped data');
     if (state.decoder)
       chunk = state.decoder.write(chunk);
-    if (!chunk || !state.objectMode && !chunk.length)
+
+    // don't skip over falsy values in objectMode
+    //if (state.objectMode && util.isNullOrUndefined(chunk))
+    if (state.objectMode && (chunk === null || chunk === undefined))
+      return;
+    else if (!state.objectMode && (!chunk || !chunk.length))
       return;
 
     var ret = self.push(chunk);
@@ -819,7 +850,8 @@ Readable.prototype.wrap = function(stream) {
   // proxy all the other methods.
   // important when wrapping filters and duplexes.
   for (var i in stream) {
-    if (util.isFunction(stream[i]) && util.isUndefined(this[i])) {
+    if (typeof stream[i] === 'function' &&
+        typeof this[i] === 'undefined') {
       this[i] = function(method) { return function() {
         return stream[method].apply(stream, arguments);
       }}(i);
@@ -835,7 +867,6 @@ Readable.prototype.wrap = function(stream) {
   // when we try to consume some more bytes, simply unpause the
   // underlying stream.
   self._read = function(n) {
-    debug('wrapped _read', n);
     if (paused) {
       paused = false;
       stream.resume();
@@ -924,7 +955,7 @@ function endReadable(stream) {
   if (state.length > 0)
     throw new Error('endReadable called on non-empty stream');
 
-  if (!state.endEmitted) {
+  if (!state.endEmitted && state.calledRead) {
     state.ended = true;
     process.nextTick(function() {
       // Check that we didn't get one last unshift.

+ 6 - 5
resources/app/node_modules/readable-stream/lib/_stream_transform.js

@@ -97,7 +97,7 @@ function afterTransform(stream, er, data) {
   ts.writechunk = null;
   ts.writecb = null;
 
-  if (!util.isNullOrUndefined(data))
+  if (data !== null && data !== undefined)
     stream.push(data);
 
   if (cb)
@@ -117,7 +117,7 @@ function Transform(options) {
 
   Duplex.call(this, options);
 
-  this._transformState = new TransformState(options, this);
+  var ts = this._transformState = new TransformState(options, this);
 
   // when the writable side finishes, then flush out anything remaining.
   var stream = this;
@@ -130,8 +130,8 @@ function Transform(options) {
   // sync guard flag.
   this._readableState.sync = false;
 
-  this.once('prefinish', function() {
-    if (util.isFunction(this._flush))
+  this.once('finish', function() {
+    if ('function' === typeof this._flush)
       this._flush(function(er) {
         done(stream, er);
       });
@@ -179,7 +179,7 @@ Transform.prototype._write = function(chunk, encoding, cb) {
 Transform.prototype._read = function(n) {
   var ts = this._transformState;
 
-  if (!util.isNull(ts.writechunk) && ts.writecb && !ts.transforming) {
+  if (ts.writechunk !== null && ts.writecb && !ts.transforming) {
     ts.transforming = true;
     this._transform(ts.writechunk, ts.writeencoding, ts.afterTransform);
   } else {
@@ -197,6 +197,7 @@ function done(stream, er) {
   // if there's nothing in the write buffer, then that means
   // that nothing more will ever be provided
   var ws = stream._writableState;
+  var rs = stream._readableState;
   var ts = stream._transformState;
 
   if (ws.length)

+ 45 - 136
resources/app/node_modules/readable-stream/lib/_stream_writable.js

@@ -48,24 +48,18 @@ function WriteReq(chunk, encoding, cb) {
 }
 
 function WritableState(options, stream) {
-  var Duplex = require('./_stream_duplex');
-
   options = options || {};
 
   // the point at which write() starts returning false
   // Note: 0 is a valid value, means that we always return false if
   // the entire buffer is not flushed immediately on write()
   var hwm = options.highWaterMark;
-  var defaultHwm = options.objectMode ? 16 : 16 * 1024;
-  this.highWaterMark = (hwm || hwm === 0) ? hwm : defaultHwm;
+  this.highWaterMark = (hwm || hwm === 0) ? hwm : 16 * 1024;
 
   // object stream flag to indicate whether or not this stream
   // contains buffers or objects.
   this.objectMode = !!options.objectMode;
 
-  if (stream instanceof Duplex)
-    this.objectMode = this.objectMode || !!options.writableObjectMode;
-
   // cast to ints.
   this.highWaterMark = ~~this.highWaterMark;
 
@@ -96,11 +90,8 @@ function WritableState(options, stream) {
   // a flag to see when we're in the middle of a write.
   this.writing = false;
 
-  // when true all writes will be buffered until .uncork() call
-  this.corked = 0;
-
   // a flag to be able to tell if the onwrite cb is called immediately,
-  // or on a later tick.  We set this to true at first, because any
+  // or on a later tick.  We set this to true at first, becuase any
   // actions that shouldn't happen until "later" should generally also
   // not happen before the first write call.
   this.sync = true;
@@ -123,14 +114,6 @@ function WritableState(options, stream) {
 
   this.buffer = [];
 
-  // number of pending user-supplied write callbacks
-  // this must be 0 before 'finish' can be emitted
-  this.pendingcb = 0;
-
-  // emit prefinish if the only thing we're waiting for is _write cbs
-  // This is relevant for synchronous Transform streams
-  this.prefinished = false;
-
   // True if the error was already emitted and should not be thrown again
   this.errorEmitted = false;
 }
@@ -173,9 +156,10 @@ function writeAfterEnd(stream, state, cb) {
 // how many bytes or characters.
 function validChunk(stream, state, chunk, cb) {
   var valid = true;
-  if (!util.isBuffer(chunk) &&
-      !util.isString(chunk) &&
-      !util.isNullOrUndefined(chunk) &&
+  if (!Buffer.isBuffer(chunk) &&
+      'string' !== typeof chunk &&
+      chunk !== null &&
+      chunk !== undefined &&
       !state.objectMode) {
     var er = new TypeError('Invalid non-string/buffer chunk');
     stream.emit('error', er);
@@ -191,54 +175,31 @@ Writable.prototype.write = function(chunk, encoding, cb) {
   var state = this._writableState;
   var ret = false;
 
-  if (util.isFunction(encoding)) {
+  if (typeof encoding === 'function') {
     cb = encoding;
     encoding = null;
   }
 
-  if (util.isBuffer(chunk))
+  if (Buffer.isBuffer(chunk))
     encoding = 'buffer';
   else if (!encoding)
     encoding = state.defaultEncoding;
 
-  if (!util.isFunction(cb))
+  if (typeof cb !== 'function')
     cb = function() {};
 
   if (state.ended)
     writeAfterEnd(this, state, cb);
-  else if (validChunk(this, state, chunk, cb)) {
-    state.pendingcb++;
+  else if (validChunk(this, state, chunk, cb))
     ret = writeOrBuffer(this, state, chunk, encoding, cb);
-  }
 
   return ret;
 };
 
-Writable.prototype.cork = function() {
-  var state = this._writableState;
-
-  state.corked++;
-};
-
-Writable.prototype.uncork = function() {
-  var state = this._writableState;
-
-  if (state.corked) {
-    state.corked--;
-
-    if (!state.writing &&
-        !state.corked &&
-        !state.finished &&
-        !state.bufferProcessing &&
-        state.buffer.length)
-      clearBuffer(this, state);
-  }
-};
-
 function decodeChunk(state, chunk, encoding) {
   if (!state.objectMode &&
       state.decodeStrings !== false &&
-      util.isString(chunk)) {
+      typeof chunk === 'string') {
     chunk = new Buffer(chunk, encoding);
   }
   return chunk;
@@ -249,7 +210,7 @@ function decodeChunk(state, chunk, encoding) {
 // If we return false, then we need a drain event, so set that flag.
 function writeOrBuffer(stream, state, chunk, encoding, cb) {
   chunk = decodeChunk(state, chunk, encoding);
-  if (util.isBuffer(chunk))
+  if (Buffer.isBuffer(chunk))
     encoding = 'buffer';
   var len = state.objectMode ? 1 : chunk.length;
 
@@ -260,36 +221,30 @@ function writeOrBuffer(stream, state, chunk, encoding, cb) {
   if (!ret)
     state.needDrain = true;
 
-  if (state.writing || state.corked)
+  if (state.writing)
     state.buffer.push(new WriteReq(chunk, encoding, cb));
   else
-    doWrite(stream, state, false, len, chunk, encoding, cb);
+    doWrite(stream, state, len, chunk, encoding, cb);
 
   return ret;
 }
 
-function doWrite(stream, state, writev, len, chunk, encoding, cb) {
+function doWrite(stream, state, len, chunk, encoding, cb) {
   state.writelen = len;
   state.writecb = cb;
   state.writing = true;
   state.sync = true;
-  if (writev)
-    stream._writev(chunk, state.onwrite);
-  else
-    stream._write(chunk, encoding, state.onwrite);
+  stream._write(chunk, encoding, state.onwrite);
   state.sync = false;
 }
 
 function onwriteError(stream, state, sync, er, cb) {
   if (sync)
     process.nextTick(function() {
-      state.pendingcb--;
       cb(er);
     });
-  else {
-    state.pendingcb--;
+  else
     cb(er);
-  }
 
   stream._writableState.errorEmitted = true;
   stream.emit('error', er);
@@ -315,12 +270,8 @@ function onwrite(stream, er) {
     // Check if we're actually ready to finish, but don't emit yet
     var finished = needFinish(stream, state);
 
-    if (!finished &&
-        !state.corked &&
-        !state.bufferProcessing &&
-        state.buffer.length) {
+    if (!finished && !state.bufferProcessing && state.buffer.length)
       clearBuffer(stream, state);
-    }
 
     if (sync) {
       process.nextTick(function() {
@@ -335,9 +286,9 @@ function onwrite(stream, er) {
 function afterWrite(stream, state, finished, cb) {
   if (!finished)
     onwriteDrain(stream, state);
-  state.pendingcb--;
   cb();
-  finishMaybe(stream, state);
+  if (finished)
+    finishMaybe(stream, state);
 }
 
 // Must force callback to be called on nextTick, so that we don't
@@ -355,82 +306,51 @@ function onwriteDrain(stream, state) {
 function clearBuffer(stream, state) {
   state.bufferProcessing = true;
 
-  if (stream._writev && state.buffer.length > 1) {
-    // Fast case, write everything using _writev()
-    var cbs = [];
-    for (var c = 0; c < state.buffer.length; c++)
-      cbs.push(state.buffer[c].callback);
-
-    // count the one we are adding, as well.
-    // TODO(isaacs) clean this up
-    state.pendingcb++;
-    doWrite(stream, state, true, state.length, state.buffer, '', function(err) {
-      for (var i = 0; i < cbs.length; i++) {
-        state.pendingcb--;
-        cbs[i](err);
-      }
-    });
-
-    // Clear buffer
-    state.buffer = [];
-  } else {
-    // Slow case, write chunks one-by-one
-    for (var c = 0; c < state.buffer.length; c++) {
-      var entry = state.buffer[c];
-      var chunk = entry.chunk;
-      var encoding = entry.encoding;
-      var cb = entry.callback;
-      var len = state.objectMode ? 1 : chunk.length;
-
-      doWrite(stream, state, false, len, chunk, encoding, cb);
-
-      // if we didn't call the onwrite immediately, then
-      // it means that we need to wait until it does.
-      // also, that means that the chunk and cb are currently
-      // being processed, so move the buffer counter past them.
-      if (state.writing) {
-        c++;
-        break;
-      }
+  for (var c = 0; c < state.buffer.length; c++) {
+    var entry = state.buffer[c];
+    var chunk = entry.chunk;
+    var encoding = entry.encoding;
+    var cb = entry.callback;
+    var len = state.objectMode ? 1 : chunk.length;
+
+    doWrite(stream, state, len, chunk, encoding, cb);
+
+    // if we didn't call the onwrite immediately, then
+    // it means that we need to wait until it does.
+    // also, that means that the chunk and cb are currently
+    // being processed, so move the buffer counter past them.
+    if (state.writing) {
+      c++;
+      break;
     }
-
-    if (c < state.buffer.length)
-      state.buffer = state.buffer.slice(c);
-    else
-      state.buffer.length = 0;
   }
 
   state.bufferProcessing = false;
+  if (c < state.buffer.length)
+    state.buffer = state.buffer.slice(c);
+  else
+    state.buffer.length = 0;
 }
 
 Writable.prototype._write = function(chunk, encoding, cb) {
   cb(new Error('not implemented'));
-
 };
 
-Writable.prototype._writev = null;
-
 Writable.prototype.end = function(chunk, encoding, cb) {
   var state = this._writableState;
 
-  if (util.isFunction(chunk)) {
+  if (typeof chunk === 'function') {
     cb = chunk;
     chunk = null;
     encoding = null;
-  } else if (util.isFunction(encoding)) {
+  } else if (typeof encoding === 'function') {
     cb = encoding;
     encoding = null;
   }
 
-  if (!util.isNullOrUndefined(chunk))
+  if (typeof chunk !== 'undefined' && chunk !== null)
     this.write(chunk, encoding);
 
-  // .end() fully uncorks
-  if (state.corked) {
-    state.corked = 1;
-    this.uncork();
-  }
-
   // ignore unnecessary end() calls.
   if (!state.ending && !state.finished)
     endWritable(this, state, cb);
@@ -444,22 +364,11 @@ function needFinish(stream, state) {
           !state.writing);
 }
 
-function prefinish(stream, state) {
-  if (!state.prefinished) {
-    state.prefinished = true;
-    stream.emit('prefinish');
-  }
-}
-
 function finishMaybe(stream, state) {
   var need = needFinish(stream, state);
   if (need) {
-    if (state.pendingcb === 0) {
-      prefinish(stream, state);
-      state.finished = true;
-      stream.emit('finish');
-    } else
-      prefinish(stream, state);
+    state.finished = true;
+    stream.emit('finish');
   }
   return need;
 }

+ 13 - 15
resources/app/node_modules/readable-stream/package.json

@@ -1,34 +1,32 @@
 {
   "_args": [
     [
-      "readable-stream@1.1.14",
-      "E:\\vscode\\UseStudio.Desktop\\resources\\app"
+      "readable-stream@1.0.34",
+      "E:\\CampusInfo-borwers\\resources\\app"
     ]
   ],
-  "_development": true,
-  "_from": "readable-stream@1.1.14",
-  "_id": "readable-stream@1.1.14",
+  "_from": "readable-stream@1.0.34",
+  "_id": "readable-stream@1.0.34",
   "_inBundle": false,
-  "_integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
+  "_integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=",
   "_location": "/readable-stream",
   "_phantomChildren": {},
   "_requested": {
     "type": "version",
     "registry": true,
-    "raw": "readable-stream@1.1.14",
+    "raw": "readable-stream@1.0.34",
     "name": "readable-stream",
     "escapedName": "readable-stream",
-    "rawSpec": "1.1.14",
+    "rawSpec": "1.0.34",
     "saveSpec": null,
-    "fetchSpec": "1.1.14"
+    "fetchSpec": "1.0.34"
   },
   "_requiredBy": [
-    "/decompress-zip",
     "/through2"
   ],
-  "_resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
-  "_spec": "1.1.14",
-  "_where": "E:\\vscode\\UseStudio.Desktop\\resources\\app",
+  "_resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
+  "_spec": "1.0.34",
+  "_where": "E:\\CampusInfo-borwers\\resources\\app",
   "author": {
     "name": "Isaac Z. Schlueter",
     "email": "i@izs.me",
@@ -46,7 +44,7 @@
     "isarray": "0.0.1",
     "string_decoder": "~0.10.x"
   },
-  "description": "Streams3, a user-land copy of the stream library from Node.js v0.11.x",
+  "description": "Streams2, a user-land copy of the stream library from Node.js v0.10.x",
   "devDependencies": {
     "tap": "~0.2.6"
   },
@@ -66,5 +64,5 @@
   "scripts": {
     "test": "tap test/simple/*.js"
   },
-  "version": "1.1.14"
+  "version": "1.0.34"
 }

+ 2 - 1
resources/app/node_modules/readable-stream/readable.js

@@ -1,5 +1,6 @@
+var Stream = require('stream'); // hack to fix a circular dependency issue when used with browserify
 exports = module.exports = require('./lib/_stream_readable.js');
-exports.Stream = require('stream');
+exports.Stream = Stream;
 exports.Readable = exports;
 exports.Writable = require('./lib/_stream_writable.js');
 exports.Duplex = require('./lib/_stream_duplex.js');

+ 3 - 1
resources/app/node_modules/through2/.npmignore

@@ -1 +1,3 @@
-node_modules
+test
+.jshintrc
+.travis.yml

+ 43 - 18
resources/app/node_modules/through2/README.md

@@ -1,25 +1,24 @@
 # through2
 
-[![Build Status](https://secure.travis-ci.org/rvagg/through2.png)](http://travis-ci.org/rvagg/through2)
-
-[![NPM](https://nodei.co/npm/through2.png?compact=true)](https://nodei.co/npm/through2/) 
-
-[![david-dm](https://david-dm.org/rvagg/through2.png)](https://david-dm.org/rvagg/through2/)
-[![david-dm](https://david-dm.org/rvagg/through2/dev-status.png)](https://david-dm.org/rvagg/through2#info=devDependencies/)
+[![NPM](https://nodei.co/npm/through2.png?downloads&downloadRank)](https://nodei.co/npm/through2/)
 
 **A tiny wrapper around Node streams.Transform (Streams2) to avoid explicit subclassing noise**
 
 Inspired by [Dominic Tarr](https://github.com/dominictarr)'s [through](https://github.com/dominictarr/through) in that it's so much easier to make a stream out of a function than it is to set up the prototype chain properly: `through(function (chunk) { ... })`.
 
+Note: A **Streams3** version of through2 is available in npm with the tag `"1.0"` rather than `"latest"` so an `npm install through2` will get you the current Streams2 version (version number is 0.x.x). To use a Streams3 version use `npm install through2@1` to fetch the latest version 1.x.x. More information about Streams2 vs Streams3 and recommendations see the article **[Why I don't use Node's core 'stream' module](http://r.va.gg/2014/06/why-i-dont-use-nodes-core-stream-module.html)**.
+
 ```js
 fs.createReadStream('ex.txt')
-    .pipe(through2(function (chunk, enc, callback) {
+  .pipe(through2(function (chunk, enc, callback) {
     for (var i = 0; i < chunk.length; i++)
       if (chunk[i] == 97)
         chunk[i] = 122 // swap 'a' for 'z'
+
     this.push(chunk)
+
     callback()
-  }))
+   }))
   .pipe(fs.createWriteStream('out.txt'))
 ```
 
@@ -27,15 +26,17 @@ Or object streams:
 
 ```js
 var all = []
+
 fs.createReadStream('data.csv')
   .pipe(csv2())
-  .pipe(through2({ objectMode: true }, function (chunk, enc, callback) {
-  	var data = {
+  .pipe(through2.obj(function (chunk, enc, callback) {
+    var data = {
         name    : chunk[0]
       , address : chunk[3]
       , phone   : chunk[10]
     }
     this.push(data)
+
     callback()
   }))
   .on('data', function (data) {
@@ -46,6 +47,8 @@ fs.createReadStream('data.csv')
   })
 ```
 
+Note that `through2.obj(fn)` is a convenience wrapper around `through2({ objectMode: true }, fn)`.
+
 ## API
 
 <b><code>through2([ options, ] [ transformFunction ] [, flushFunction ])</code></b>
@@ -54,16 +57,18 @@ Consult the **[stream.Transform](http://nodejs.org/docs/latest/api/stream.html#s
 
 ### options
 
-The options argument is optional and is passed straight through to `stream.Transform`. So you can use `objectMode:true` if you are processing non-binary streams.
+The options argument is optional and is passed straight through to `stream.Transform`. So you can use `objectMode:true` if you are processing non-binary streams (or just use `through2.obj()`).
 
 The `options` argument is first, unlike standard convention, because if I'm passing in an anonymous function then I'd prefer for the options argument to not get lost at the end of the call:
 
 ```js
 fs.createReadStream('/tmp/important.dat')
-	.pipe(through2({ objectMode: true, allowHalfOpen: false }, function (chunk, enc, cb) {
-		this.push(new Buffer('wut?'))
-  	cb()
-	})
+  .pipe(through2({ objectMode: true, allowHalfOpen: false },
+    function (chunk, enc, cb) {
+      cb(null, 'wut?') // note we can use the second argument on the callback
+                       // to provide data as an alternative to this.push('wut?')
+    }
+  )
   .pipe(fs.createWriteStream('/tmp/wut.txt'))
 ```
 
@@ -73,12 +78,26 @@ The `transformFunction` must have the following signature: `function (chunk, enc
 
 To queue a new chunk, call `this.push(chunk)`&mdash;this can be called as many times as required before the `callback()` if you have multiple pieces to send on.
 
-If you **do not provide a `transformFunction`** then you will get a simple simple pass-through stream.
+Alternatively, you may use `callback(err, chunk)` as shorthand for emitting a single chunk or an error.
+
+If you **do not provide a `transformFunction`** then you will get a simple pass-through stream.
 
 ### flushFunction
 
 The optional `flushFunction` is provided as the last argument (2nd or 3rd, depending on whether you've supplied options) is called just prior to the stream ending. Can be used to finish up any processing that may be in progress.
 
+```js
+fs.createReadStream('/tmp/important.dat')
+  .pipe(through2(
+    function (chunk, enc, cb) { cb(null, chunk) }, // transform is a noop
+    function (cb) { // flush function
+      this.push('tacking on an extra buffer to the end');
+      cb();
+    }
+  ))
+  .pipe(fs.createWriteStream('/tmp/wut.txt'));
+```
+
 <b><code>through2.ctor([ options, ] transformFunction[, flushFunction ])</code></b>
 
 Instead of returning a `stream.Transform` instance, `through2.ctor()` returns a **constructor** for a custom Transform. This is useful when you want to use the same transform logic in multiple instances.
@@ -99,9 +118,15 @@ var converter = new FToC()
 var converter = FToC()
 // Or specify/override options when you instantiate, if you prefer:
 var converter = FToC({objectMode: true})
-
 ```
 
+## See Also
+
+  - [through2-map](https://github.com/brycebaril/through2-map) - Array.prototype.map analog for streams.
+  - [through2-filter](https://github.com/brycebaril/through2-filter) - Array.prototype.filter analog for streams.
+  - [through2-reduce](https://github.com/brycebaril/through2-reduce) - Array.prototype.reduce analog for streams.
+  - [through2-spy](https://github.com/brycebaril/through2-spy) - Wrapper for simple stream.PassThrough spies.
+
 ## License
 
-**through2** is Copyright (c) 2013 Rod Vagg [@rvagg](https://twitter.com/rvagg) and licenced under the MIT licence. All rights not explicitly granted in the MIT license are reserved. See the included LICENSE file for more details.
+**through2** is Copyright (c) 2013 Rod Vagg [@rvagg](https://twitter.com/rvagg) and licenced under the MIT licence. All rights not explicitly granted in the MIT license are reserved. See the included LICENSE file for more details.

+ 20 - 20
resources/app/node_modules/through2/package.json

@@ -1,33 +1,32 @@
 {
   "_args": [
     [
-      "through2@0.2.3",
-      "E:\\vscode\\UseStudio.Desktop\\resources\\app"
+      "through2@0.6.5",
+      "E:\\CampusInfo-borwers\\resources\\app"
     ]
   ],
-  "_development": true,
-  "_from": "through2@0.2.3",
-  "_id": "through2@0.2.3",
+  "_from": "through2@0.6.5",
+  "_id": "through2@0.6.5",
   "_inBundle": false,
-  "_integrity": "sha1-6zKE2k6jEbbMis42U3SKUqvyWj8=",
+  "_integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=",
   "_location": "/through2",
   "_phantomChildren": {},
   "_requested": {
     "type": "version",
     "registry": true,
-    "raw": "through2@0.2.3",
+    "raw": "through2@0.6.5",
     "name": "through2",
     "escapedName": "through2",
-    "rawSpec": "0.2.3",
+    "rawSpec": "0.6.5",
     "saveSpec": null,
-    "fetchSpec": "0.2.3"
+    "fetchSpec": "0.6.5"
   },
   "_requiredBy": [
-    "/progress-stream"
+    "/regedit"
   ],
-  "_resolved": "https://registry.npmjs.org/through2/-/through2-0.2.3.tgz",
-  "_spec": "0.2.3",
-  "_where": "E:\\vscode\\UseStudio.Desktop\\resources\\app",
+  "_resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz",
+  "_spec": "0.6.5",
+  "_where": "E:\\CampusInfo-borwers\\resources\\app",
   "author": {
     "name": "Rod Vagg",
     "email": "r@va.gg",
@@ -37,14 +36,14 @@
     "url": "https://github.com/rvagg/through2/issues"
   },
   "dependencies": {
-    "readable-stream": "~1.1.9",
-    "xtend": "~2.1.1"
+    "readable-stream": ">=1.0.33-1 <1.1.0-0",
+    "xtend": ">=4.0.0 <4.1.0-0"
   },
   "description": "A tiny wrapper around Node streams2 Transform to avoid explicit subclassing noise",
   "devDependencies": {
-    "bl": "~0.4.1",
-    "stream-spigot": "~2.1.2",
-    "tape": "~1.1.1"
+    "bl": ">=0.9.0 <0.10.0-0",
+    "stream-spigot": ">=3.0.4 <3.1.0-0",
+    "tape": ">=2.14.0 <2.15.0-0"
   },
   "homepage": "https://github.com/rvagg/through2#readme",
   "keywords": [
@@ -61,7 +60,8 @@
     "url": "git+https://github.com/rvagg/through2.git"
   },
   "scripts": {
-    "test": "node test.js"
+    "test": "node test/test.js",
+    "test-local": "brtapsauce-local test/basic-test.js"
   },
-  "version": "0.2.3"
+  "version": "0.6.5"
 }

+ 73 - 19
resources/app/node_modules/through2/through2.js

@@ -1,42 +1,96 @@
-const Transform = require('stream').Transform || require('readable-stream/transform')
-    , inherits  = require('util').inherits
-    , xtend     = require('xtend')
+var Transform = require('readable-stream/transform')
+  , inherits  = require('util').inherits
+  , xtend     = require('xtend')
 
+function DestroyableTransform(opts) {
+  Transform.call(this, opts)
+  this._destroyed = false
+}
+
+inherits(DestroyableTransform, Transform)
+
+DestroyableTransform.prototype.destroy = function(err) {
+  if (this._destroyed) return
+  this._destroyed = true
+  
+  var self = this
+  process.nextTick(function() {
+    if (err)
+      self.emit('error', err)
+    self.emit('close')
+  })
+}
+
+// a noop _transform function
 function noop (chunk, enc, callback) {
   callback(null, chunk)
 }
 
-function ctor (options, transform, flush) {
-  if (typeof options == 'function') {
-    flush     = transform
-    transform = options
-    options   = {}
+
+// create a new export function, used by both the main export and
+// the .ctor export, contains common logic for dealing with arguments
+function through2 (construct) {
+  return function (options, transform, flush) {
+    if (typeof options == 'function') {
+      flush     = transform
+      transform = options
+      options   = {}
+    }
+
+    if (typeof transform != 'function')
+      transform = noop
+
+    if (typeof flush != 'function')
+      flush = null
+
+    return construct(options, transform, flush)
   }
+}
+
 
-  if (typeof transform != 'function')
-    transform = noop
+// main export, just make me a transform stream!
+module.exports = through2(function (options, transform, flush) {
+  var t2 = new DestroyableTransform(options)
 
+  t2._transform = transform
+
+  if (flush)
+    t2._flush = flush
+
+  return t2
+})
+
+
+// make me a reusable prototype that I can `new`, or implicitly `new`
+// with a constructor call
+module.exports.ctor = through2(function (options, transform, flush) {
   function Through2 (override) {
     if (!(this instanceof Through2))
       return new Through2(override)
 
     this.options = xtend(options, override)
-    Transform.call(this, this.options)
+
+    DestroyableTransform.call(this, this.options)
   }
 
-  inherits(Through2, Transform)
+  inherits(Through2, DestroyableTransform)
 
   Through2.prototype._transform = transform
 
-  if (typeof flush == 'function')
+  if (flush)
     Through2.prototype._flush = flush
 
   return Through2
-}
+})
 
-function make (options, transform, flush) {
-  return ctor(options, transform, flush)()
-}
 
-module.exports      = make
-module.exports.ctor = ctor
+module.exports.obj = through2(function (options, transform, flush) {
+  var t2 = new DestroyableTransform(xtend({ objectMode: true, highWaterMark: 16 }, options))
+
+  t2._transform = transform
+
+  if (flush)
+    t2._flush = flush
+
+  return t2
+})

+ 2 - 2
resources/app/node_modules/xtend/LICENCE

@@ -1,4 +1,4 @@
-Copyright (c) 2012 Raynos.
+Copyright (c) 2012-2014 Raynos.
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
@@ -16,4 +16,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
+THE SOFTWARE.

+ 7 - 2
resources/app/node_modules/xtend/README.md

@@ -2,23 +2,28 @@
 
 [![browser support][3]][4]
 
+[![locked](http://badges.github.io/stability-badges/dist/locked.svg)](http://github.com/badges/stability-badges)
+
 Extend like a boss
 
-xtend is a basic utility library which allows you to extend an object by appending all of the properties from each object in a list. When there are identical properties, the right-most property takes presedence.
+xtend is a basic utility library which allows you to extend an object by appending all of the properties from each object in a list. When there are identical properties, the right-most property takes precedence.
 
 ## Examples
 
 ```js
 var extend = require("xtend")
 
+// extend returns a new object. Does not mutate arguments
 var combination = extend({
-    a: "a"
+    a: "a",
+    b: 'c'
 }, {
     b: "b"
 })
 // { a: "a", b: "b" }
 ```
 
+## Stability status: Locked
 
 ## MIT Licenced
 

+ 8 - 16
resources/app/node_modules/xtend/mutable.js

@@ -1,23 +1,15 @@
-var Keys = require("object-keys")
-var hasKeys = require("./has-keys")
-
 module.exports = extend
 
-function extend(target) {
-    var sources = [].slice.call(arguments, 1)
-
-    for (var i = 0; i < sources.length; i++) {
-        var source = sources[i]
+var hasOwnProperty = Object.prototype.hasOwnProperty;
 
-        if (!hasKeys(source)) {
-            continue
-        }
-
-        var keys = Keys(source)
+function extend(target) {
+    for (var i = 1; i < arguments.length; i++) {
+        var source = arguments[i]
 
-        for (var j = 0; j < keys.length; j++) {
-            var name = keys[j]
-            target[name] = source[name]
+        for (var key in source) {
+            if (hasOwnProperty.call(source, key)) {
+                target[key] = source[key]
+            }
         }
     }
 

+ 15 - 23
resources/app/node_modules/xtend/package.json

@@ -1,33 +1,32 @@
 {
   "_args": [
     [
-      "xtend@2.1.2",
-      "E:\\vscode\\UseStudio.Desktop\\resources\\app"
+      "xtend@4.0.1",
+      "E:\\CampusInfo-borwers\\resources\\app"
     ]
   ],
-  "_development": true,
-  "_from": "xtend@2.1.2",
-  "_id": "xtend@2.1.2",
+  "_from": "xtend@4.0.1",
+  "_id": "xtend@4.0.1",
   "_inBundle": false,
-  "_integrity": "sha1-bv7MKk2tjmlixJAbM3znuoe10os=",
+  "_integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=",
   "_location": "/xtend",
   "_phantomChildren": {},
   "_requested": {
     "type": "version",
     "registry": true,
-    "raw": "xtend@2.1.2",
+    "raw": "xtend@4.0.1",
     "name": "xtend",
     "escapedName": "xtend",
-    "rawSpec": "2.1.2",
+    "rawSpec": "4.0.1",
     "saveSpec": null,
-    "fetchSpec": "2.1.2"
+    "fetchSpec": "4.0.1"
   },
   "_requiredBy": [
     "/through2"
   ],
-  "_resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz",
-  "_spec": "2.1.2",
-  "_where": "E:\\vscode\\UseStudio.Desktop\\resources\\app",
+  "_resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz",
+  "_spec": "4.0.1",
+  "_where": "E:\\CampusInfo-borwers\\resources\\app",
   "author": {
     "name": "Raynos",
     "email": "raynos2@gmail.com"
@@ -44,9 +43,7 @@
       "name": "Matt Esch"
     }
   ],
-  "dependencies": {
-    "object-keys": "~0.4.0"
-  },
+  "dependencies": {},
   "description": "extend like a boss",
   "devDependencies": {
     "tape": "~1.1.0"
@@ -63,13 +60,8 @@
     "object",
     "array"
   ],
-  "licenses": [
-    {
-      "type": "MIT",
-      "url": "http://github.com/raynos/xtend/raw/master/LICENSE"
-    }
-  ],
-  "main": "index",
+  "license": "MIT",
+  "main": "immutable",
   "name": "xtend",
   "repository": {
     "type": "git",
@@ -93,5 +85,5 @@
       "iphone/6.0..latest"
     ]
   },
-  "version": "2.1.2"
+  "version": "4.0.1"
 }

+ 20 - 0
resources/app/node_modules/xtend/test.js

@@ -61,3 +61,23 @@ test("mutable", function (assert) {
     assert.equal(a.bar, "baz")
     assert.end()
 })
+
+test("null prototype", function(assert) {
+    var a = { a: "foo" }
+    var b = Object.create(null)
+    b.b = "bar";
+
+    assert.deepEqual(extend(a, b), { a: "foo", b: "bar" })
+    assert.end()
+})
+
+test("null prototype mutable", function (assert) {
+    var a = { foo: "bar" }
+    var b = Object.create(null)
+    b.bar = "baz";
+
+    mutableExtend(a, b)
+
+    assert.equal(a.bar, "baz")
+    assert.end()
+})