Browse Source

Adding Jake + Jakefile (we include node binaries on Windows and Mac now and this removes core dependency on Ruby)

Josh Engebretson 10 years ago
parent
commit
b592a12a2c
100 changed files with 17241 additions and 0 deletions
  1. 48 0
      Build/node_modules/jake/Jakefile
  2. 44 0
      Build/node_modules/jake/Makefile
  3. 10 0
      Build/node_modules/jake/README.md
  4. 25 0
      Build/node_modules/jake/bin/cli.js
  5. 382 0
      Build/node_modules/jake/lib/api.js
  6. 329 0
      Build/node_modules/jake/lib/jake.js
  7. 106 0
      Build/node_modules/jake/lib/loader.js
  8. 74 0
      Build/node_modules/jake/lib/namespace.js
  9. 408 0
      Build/node_modules/jake/lib/package_task.js
  10. 134 0
      Build/node_modules/jake/lib/parseargs.js
  11. 257 0
      Build/node_modules/jake/lib/program.js
  12. 307 0
      Build/node_modules/jake/lib/publish_task.js
  13. 327 0
      Build/node_modules/jake/lib/rule.js
  14. 29 0
      Build/node_modules/jake/lib/task/directory_task.js
  15. 136 0
      Build/node_modules/jake/lib/task/file_task.js
  16. 9 0
      Build/node_modules/jake/lib/task/index.js
  17. 314 0
      Build/node_modules/jake/lib/task/task.js
  18. 277 0
      Build/node_modules/jake/lib/test_task.js
  19. 258 0
      Build/node_modules/jake/lib/utils/index.js
  20. 24 0
      Build/node_modules/jake/lib/utils/logger.js
  21. 99 0
      Build/node_modules/jake/lib/watch_task.js
  22. 5 0
      Build/node_modules/jake/node_modules/async/.travis.yml
  23. 19 0
      Build/node_modules/jake/node_modules/async/LICENSE
  24. 1647 0
      Build/node_modules/jake/node_modules/async/README.md
  25. 38 0
      Build/node_modules/jake/node_modules/async/bower.json
  26. 16 0
      Build/node_modules/jake/node_modules/async/component.json
  27. 1123 0
      Build/node_modules/jake/node_modules/async/lib/async.js
  28. 84 0
      Build/node_modules/jake/node_modules/async/package.json
  29. 53 0
      Build/node_modules/jake/node_modules/async/support/sync-package-managers.js
  30. 63 0
      Build/node_modules/jake/node_modules/chalk/index.js
  31. 1 0
      Build/node_modules/jake/node_modules/chalk/node_modules/.bin/strip-ansi
  32. 38 0
      Build/node_modules/jake/node_modules/chalk/node_modules/ansi-styles/ansi-styles.js
  33. 75 0
      Build/node_modules/jake/node_modules/chalk/node_modules/ansi-styles/package.json
  34. 65 0
      Build/node_modules/jake/node_modules/chalk/node_modules/ansi-styles/readme.md
  35. 32 0
      Build/node_modules/jake/node_modules/chalk/node_modules/has-color/index.js
  36. 71 0
      Build/node_modules/jake/node_modules/chalk/node_modules/has-color/package.json
  37. 30 0
      Build/node_modules/jake/node_modules/chalk/node_modules/has-color/readme.md
  38. 27 0
      Build/node_modules/jake/node_modules/chalk/node_modules/strip-ansi/cli.js
  39. 4 0
      Build/node_modules/jake/node_modules/chalk/node_modules/strip-ansi/index.js
  40. 81 0
      Build/node_modules/jake/node_modules/chalk/node_modules/strip-ansi/package.json
  41. 46 0
      Build/node_modules/jake/node_modules/chalk/node_modules/strip-ansi/readme.md
  42. 78 0
      Build/node_modules/jake/node_modules/chalk/package.json
  43. 158 0
      Build/node_modules/jake/node_modules/chalk/readme.md
  44. 14 0
      Build/node_modules/jake/node_modules/filelist/Jakefile
  45. 84 0
      Build/node_modules/jake/node_modules/filelist/README.md
  46. 319 0
      Build/node_modules/jake/node_modules/filelist/index.js
  47. 1 0
      Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/.npmignore
  48. 23 0
      Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/LICENSE
  49. 218 0
      Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/README.md
  50. 1061 0
      Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/minimatch.js
  51. 1 0
      Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/node_modules/lru-cache/.npmignore
  52. 8 0
      Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/node_modules/lru-cache/.travis.yml
  53. 14 0
      Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/node_modules/lru-cache/CONTRIBUTORS
  54. 15 0
      Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/node_modules/lru-cache/LICENSE
  55. 109 0
      Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/node_modules/lru-cache/README.md
  56. 274 0
      Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/node_modules/lru-cache/lib/lru-cache.js
  57. 58 0
      Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/node_modules/lru-cache/package.json
  58. 395 0
      Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/node_modules/lru-cache/test/basic.js
  59. 120 0
      Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/node_modules/lru-cache/test/foreach.js
  60. 51 0
      Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/node_modules/lru-cache/test/memory-leak.js
  61. 15 0
      Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/node_modules/sigmund/LICENSE
  62. 53 0
      Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/node_modules/sigmund/README.md
  63. 283 0
      Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/node_modules/sigmund/bench.js
  64. 60 0
      Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/node_modules/sigmund/package.json
  65. 39 0
      Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/node_modules/sigmund/sigmund.js
  66. 24 0
      Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/node_modules/sigmund/test/basic.js
  67. 31 0
      Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/package.json
  68. 399 0
      Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/test/basic.js
  69. 33 0
      Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/test/brace-expand.js
  70. 14 0
      Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/test/caching.js
  71. 274 0
      Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/test/defaults.js
  72. 8 0
      Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/test/extglob-ending-with-state-char.js
  73. 42 0
      Build/node_modules/jake/node_modules/filelist/node_modules/utilities/Jakefile
  74. 6 0
      Build/node_modules/jake/node_modules/filelist/node_modules/utilities/README.md
  75. 94 0
      Build/node_modules/jake/node_modules/filelist/node_modules/utilities/lib/array.js
  76. 298 0
      Build/node_modules/jake/node_modules/filelist/node_modules/utilities/lib/async.js
  77. 128 0
      Build/node_modules/jake/node_modules/filelist/node_modules/utilities/lib/core.js
  78. 928 0
      Build/node_modules/jake/node_modules/filelist/node_modules/utilities/lib/date.js
  79. 109 0
      Build/node_modules/jake/node_modules/filelist/node_modules/utilities/lib/event_buffer.js
  80. 557 0
      Build/node_modules/jake/node_modules/filelist/node_modules/utilities/lib/file.js
  81. 73 0
      Build/node_modules/jake/node_modules/filelist/node_modules/utilities/lib/i18n.js
  82. 59 0
      Build/node_modules/jake/node_modules/filelist/node_modules/utilities/lib/index.js
  83. 222 0
      Build/node_modules/jake/node_modules/filelist/node_modules/utilities/lib/inflection.js
  84. 69 0
      Build/node_modules/jake/node_modules/filelist/node_modules/utilities/lib/log.js
  85. 72 0
      Build/node_modules/jake/node_modules/filelist/node_modules/utilities/lib/network.js
  86. 108 0
      Build/node_modules/jake/node_modules/filelist/node_modules/utilities/lib/object.js
  87. 143 0
      Build/node_modules/jake/node_modules/filelist/node_modules/utilities/lib/request.js
  88. 558 0
      Build/node_modules/jake/node_modules/filelist/node_modules/utilities/lib/sorted_collection.js
  89. 810 0
      Build/node_modules/jake/node_modules/filelist/node_modules/utilities/lib/string.js
  90. 238 0
      Build/node_modules/jake/node_modules/filelist/node_modules/utilities/lib/uri.js
  91. 282 0
      Build/node_modules/jake/node_modules/filelist/node_modules/utilities/lib/xml.js
  92. 55 0
      Build/node_modules/jake/node_modules/filelist/node_modules/utilities/package.json
  93. 71 0
      Build/node_modules/jake/node_modules/filelist/node_modules/utilities/test/array.js
  94. 97 0
      Build/node_modules/jake/node_modules/filelist/node_modules/utilities/test/core.js
  95. 84 0
      Build/node_modules/jake/node_modules/filelist/node_modules/utilities/test/date.js
  96. 45 0
      Build/node_modules/jake/node_modules/filelist/node_modules/utilities/test/event_buffer.js
  97. 228 0
      Build/node_modules/jake/node_modules/filelist/node_modules/utilities/test/file.js
  98. 60 0
      Build/node_modules/jake/node_modules/filelist/node_modules/utilities/test/i18n.js
  99. 388 0
      Build/node_modules/jake/node_modules/filelist/node_modules/utilities/test/inflection.js
  100. 68 0
      Build/node_modules/jake/node_modules/filelist/node_modules/utilities/test/logging.js

+ 48 - 0
Build/node_modules/jake/Jakefile

@@ -0,0 +1,48 @@
+var fs = require('fs')
+  , path = require('path');
+
+testTask('Jake', function () {
+  this.testFiles.include('test/*.js');
+  this.testFiles.exclude('test/helpers.js');
+});
+
+namespace('doc', function () {
+  task('generate', ['doc:clobber'], function () {
+    var cmd = '../node-jsdoc-toolkit/app/run.js -n -r=100 ' +
+        '-t=../node-jsdoc-toolkit/templates/codeview -d=./doc/ ./lib';
+    jake.logger.log('Generating docs ...');
+    jake.exec([cmd], function () {
+      jake.logger.log('Done.');
+      complete();
+    });
+  }, {async: true});
+
+  task('clobber', function () {
+    var cmd = 'rm -fr ./doc/*';
+    jake.exec([cmd], function () {
+      jake.logger.log('Clobbered old docs.');
+      complete();
+    });
+  }, {async: true});
+
+});
+
+desc('Generate docs for Jake');
+task('doc', ['doc:generate']);
+
+npmPublishTask('jake', function () {
+  this.packageFiles.include([
+    'Makefile'
+  , 'Jakefile'
+  , 'README.md'
+  , 'package.json'
+  , 'lib/**'
+  , 'bin/**'
+  , 'test/**'
+    ]);
+  this.packageFiles.exclude([
+    'test/tmp'
+  ]);
+});
+
+

+ 44 - 0
Build/node_modules/jake/Makefile

@@ -0,0 +1,44 @@
+#
+# Jake JavaScript build tool
+# Copyright 2112 Matthew Eernisse ([email protected])
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+.PHONY: all build install clean uninstall
+
+PREFIX=/usr/local
+DESTDIR=
+
+all: build
+
+build:
+	@echo 'Jake built.'
+
+install:
+	@mkdir -p $(DESTDIR)$(PREFIX)/bin && \
+    mkdir -p $(DESTDIR)$(PREFIX)/lib/node_modules/jake && \
+    mkdir -p ./node_modules && \
+    npm install utilities minimatch && \
+		cp -R ./* $(DESTDIR)$(PREFIX)/lib/node_modules/jake/ && \
+		ln -snf ../lib/node_modules/jake/bin/cli.js $(DESTDIR)$(PREFIX)/bin/jake && \
+		chmod 755 $(DESTDIR)$(PREFIX)/lib/node_modules/jake/bin/cli.js && \
+		echo 'Jake installed.'
+
+clean:
+	@true
+
+uninstall:
+	@rm -f $(DESTDIR)$(PREFIX)/bin/jake && \
+		rm -fr $(DESTDIR)$(PREFIX)/lib/node_modules/jake/ && \
+		echo 'Jake uninstalled.'

+ 10 - 0
Build/node_modules/jake/README.md

@@ -0,0 +1,10 @@
+### Jake -- the JavaScript build tool for Node.js
+
+[![Build Status](https://api.travis-ci.org/jakejs/jake.png)](https://travis-ci.org/mde/jake)
+
+Documentation site at [http://jakejs.com](http://jakejs.com/)
+
+### License
+
+Licensed under the Apache License, Version 2.0
+(<http://www.apache.org/licenses/LICENSE-2.0>)

+ 25 - 0
Build/node_modules/jake/bin/cli.js

@@ -0,0 +1,25 @@
+#!/usr/bin/env node
+/*
+ * Jake JavaScript build tool
+ * Copyright 2112 Matthew Eernisse ([email protected])
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+
+// Load `jake` global
+require('../lib/jake');
+
+var args = process.argv.slice(2);
+
+jake.run.apply(jake, args);

+ 382 - 0
Build/node_modules/jake/lib/api.js

@@ -0,0 +1,382 @@
+/*
+ * Jake JavaScript build tool
+ * Copyright 2112 Matthew Eernisse ([email protected])
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+
+var api = new (function () {
+  /**
+    @name task
+    @static
+    @function
+    @description Creates a Jake Task
+    `
+    @param {String} name The name of the Task
+    @param {Array} [prereqs] Prerequisites to be run before this task
+    @param {Function} [action] The action to perform for this task
+    @param {Object} [opts]
+      @param {Boolean} [opts.asyc=false] Perform this task asynchronously.
+      If you flag a task with this option, you must call the global
+      `complete` method inside the task's action, for execution to proceed
+      to the next task.
+
+    @example
+    desc('This is the default task.');
+    task('default', function (params) {
+      console.log('This is the default task.');
+    });
+
+    desc('This task has prerequisites.');
+    task('hasPrereqs', ['foo', 'bar', 'baz'], function (params) {
+      console.log('Ran some prereqs first.');
+    });
+
+    desc('This is an asynchronous task.');
+    task('asyncTask', function () {
+      setTimeout(complete, 1000);
+    }, {async: true});
+   */
+  this.task = function (name, prereqs, action, opts) {
+    var args = Array.prototype.slice.call(arguments)
+      , type
+      , createdTask;
+    args.unshift('task');
+    createdTask = jake.createTask.apply(global, args);
+    jake.currentTaskDescription = null;
+    return createdTask;
+  };
+
+  /**
+    @name rule
+    @static
+    @function
+    @description Creates a Jake Suffix Rule
+    `
+    @param {String} pattern The suffix name of the objective
+    @param {String} source The suffix name of the objective
+    @param {Array} [prereqs] Prerequisites to be run before this task
+    @param {Function} [action] The action to perform for this task
+    @param {Object} [opts]
+      @param {Boolean} [opts.asyc=false] Perform this task asynchronously.
+      If you flag a task with this option, you must call the global
+      `complete` method inside the task's action, for execution to proceed
+      to the next task.
+    @example
+    desc('This is a rule, which does not support namespace or pattern.');
+    rule('.o', '.c', {async: true}, function () {
+      var cmd = util.format('gcc -o %s %s', this.name, this.source);
+      jake.exec([cmd], function () {
+        complete();
+      }, {printStdout: true});
+    });
+
+    desc('This rule has prerequisites.');
+    rule('.o', '.c', ['util.h'], {async: true}, function () {
+      var cmd = util.format('gcc -o %s %s', this.name, this.source);
+      jake.exec([cmd], function () {
+        complete();
+      }, {printStdout: true});
+    });
+
+    desc('This is a rule with patterns.');
+    rule('%.o', '%.c', {async: true}, function () {
+      var cmd = util.format('gcc -o %s %s', this.name, this.source);
+      jake.exec([cmd], function () {
+        complete();
+      }, {printStdout: true});
+    });
+
+    desc('This is another rule with patterns.');
+    rule('obj/%.o', 'src/%.c', {async: true}, function () {
+      var cmd = util.format('gcc -o %s %s', this.name, this.source);
+      jake.exec([cmd], function () {
+        complete();
+      }, {printStdout: true});
+    });
+
+    desc('This is an example with chain rules.');
+    rule('%.pdf', '%.dvi', {async: true}, function () {
+      var cmd = util.format('dvipdfm %s',this.source);
+      jake.exec([cmd], function () {
+        complete();
+      }, {printStdout: true});
+    });
+
+    rule('%.dvi', '%.tex', {async: true}, function () {
+      var cmd = util.format('latex %s',this.source);
+      jake.exec([cmd], function () {
+        complete();
+      }, {printStdout: true});
+    });
+
+    desc('This rule has a namespace.');
+    task('default', ['debug:obj/main.o]);
+
+    namespace('debug', {async: true}, function() {
+      rule('obj/%.o', 'src/%.c', function () {
+        // ...
+      });
+    }
+   */
+  this.rule = function () {
+    var args = Array.prototype.slice.call(arguments)
+      , arg
+      , pattern = args.shift()
+      , source = args.shift()
+      , prereqs = []
+      , action = function () {}
+      , opts = {}
+      , key = pattern.toString(); // May be a RegExp
+
+    while ((arg = args.shift())) {
+      if (typeof arg == 'function') {
+        action = arg;
+      }
+      else if (Array.isArray(arg)) {
+        prereqs = arg;
+      }
+      else {
+        opts = arg;
+      }
+    }
+
+    jake.currentNamespace.rules[key] = new jake.Rule({
+      pattern: pattern
+    , source: source
+    , prereqs: prereqs
+    , action: action
+    , opts: opts
+    , desc: jake.currentTaskDescription
+    , ns: jake.currentNamespace
+    });
+    jake.currentTaskDescription = null;
+  };
+
+  /**
+    @name directory
+    @static
+    @function
+    @description Creates a Jake DirectoryTask. Can be used as a prerequisite
+    for FileTasks, or for simply ensuring a directory exists for use with a
+    Task's action.
+    `
+    @param {String} name The name of the DiretoryTask
+
+    @example
+
+    // Creates the package directory for distribution
+    directory('pkg');
+   */
+  this.directory = function (name) {
+    var args = Array.prototype.slice.call(arguments)
+      , createdTask;
+    args.unshift('directory');
+    createdTask = jake.createTask.apply(global, args);
+    jake.currentTaskDescription = null;
+    return createdTask;
+  };
+
+  /**
+    @name file
+    @static
+    @function
+    @description Creates a Jake FileTask.
+    `
+    @param {String} name The name of the FileTask
+    @param {Array} [prereqs] Prerequisites to be run before this task
+    @param {Function} [action] The action to create this file, if it doesn't
+    exist already.
+    @param {Object} [opts]
+      @param {Array} [opts.asyc=false] Perform this task asynchronously.
+      If you flag a task with this option, you must call the global
+      `complete` method inside the task's action, for execution to proceed
+      to the next task.
+
+   */
+  this.file = function (name, prereqs, action, opts) {
+    var args = Array.prototype.slice.call(arguments)
+      , createdTask;
+    args.unshift('file');
+    createdTask = jake.createTask.apply(global, args);
+    jake.currentTaskDescription = null;
+    return createdTask;
+  };
+
+  /**
+    @name desc
+    @static
+    @function
+    @description Creates a description for a Jake Task (or FileTask,
+    DirectoryTask). When invoked, the description that iscreated will
+    be associated with whatever Task is created next.
+    `
+    @param {String} description The description for the Task
+   */
+  this.desc = function (description) {
+    jake.currentTaskDescription = description;
+  };
+
+  /**
+    @name namespace
+    @static
+    @function
+    @description Creates a namespace which allows logical grouping
+    of tasks, and prevents name-collisions with task-names. Namespaces
+    can be nested inside of other namespaces.
+    `
+    @param {String} name The name of the namespace
+    @param {Function} scope The enclosing scope for the namespaced tasks
+
+    @example
+    namespace('doc', function () {
+      task('generate', ['doc:clobber'], function () {
+        // Generate some docs
+      });
+
+      task('clobber', function () {
+        // Clobber the doc directory first
+      });
+    });
+   */
+  this.namespace = function (name, closure) {
+    var curr = jake.currentNamespace
+      , ns = curr.childNamespaces[name] || new jake.Namespace(name, curr);
+    curr.childNamespaces[name] = ns;
+    jake.currentNamespace = ns;
+    closure();
+    jake.currentNamespace = curr;
+    jake.currentTaskDescription = null;
+    return ns;
+  };
+
+  /**
+    @name complete
+    @static
+    @function
+    @description Completes an asynchronous task, allowing Jake's
+    execution to proceed to the next task. Calling complete globally or without
+    arguments completes the last task on the invocationChain. If you use parallel
+    execution of prereqs this will probably complete a wrong task. You should call this
+    function with this task as the first argument, before the optional return value.
+    Alternatively you can call task.complete()
+    `
+    @example
+    task('generate', ['doc:clobber'], function () {
+      exec('./generate_docs.sh', function (err, stdout, stderr) {
+        if (err || stderr) {
+          fail(err || stderr);
+        }
+        else {
+          console.log(stdout);
+          complete();
+        }
+      });
+    }, {async: true});
+   */
+  this.complete = function (task, val) {
+    //this should detect if the first arg is a task, but I guess it should be more thorough
+    if(task && task. _currentPrereqIndex >=0 ) {
+      task.complete(val);
+    } else {
+      val = task;
+      if(jake._invocationChain.length > 0) {
+        jake._invocationChain[jake._invocationChain.length-1].complete(val);
+      } else {
+      }
+    }
+  };
+
+  /**
+    @name fail
+    @static
+    @function
+    @description Causes Jake execution to abort with an error.
+    Allows passing an optional error code, which will be used to
+    set the exit-code of exiting process.
+    `
+    @param {Error|String} err The error to thow when aborting execution.
+    If this argument is an Error object, it will simply be thrown. If
+    a String, it will be used as the error-message. (If it is a multi-line
+    String, the first line will be used as the Error message, and the
+    remaining lines will be used as the error-stack.)
+
+    @example
+    task('createTests, function () {
+      if (!fs.existsSync('./tests')) {
+        fail('Test directory does not exist.');
+      }
+      else {
+        // Do some testing stuff ...
+      }
+    });
+   */
+  this.fail = function (err, code) {
+    var msg
+      , errObj;
+    if (code) {
+      jake.errorCode = code;
+    }
+    if (err) {
+      if (typeof err == 'string') {
+        // Use the initial or only line of the error as the error-message
+        // If there was a multi-line error, use the rest as the stack
+        msg = err.split('/n');
+        errObj = new Error(msg.shift());
+        if (msg.length) {
+          errObj.stack = msg.join('\n');
+        }
+        throw errObj;
+      }
+      else if (err instanceof Error) {
+        throw err;
+      }
+      else {
+        throw new Error(err.toString());
+      }
+    }
+    else {
+      throw new Error();
+    }
+  };
+
+  this.packageTask = function (name, version, definition) {
+    return new jake.PackageTask(name, version, definition);
+  };
+
+  this.publishTask = function (name, prereqs, opts, definition) {
+    return new jake.PublishTask(name, prereqs, opts, definition);
+  };
+
+  // Backward-compat
+  this.npmPublishTask = function (name, prereqs, opts, definition) {
+    return new jake.PublishTask(name, prereqs, opts, definition);
+  };
+
+  this.watchTask = function (name, taskNames, definition) {
+    return new jake.WatchTask(name, taskNames, definition);
+  };
+
+  this.testTask = function () {
+    var ctor = function () {}
+      , t;
+    ctor.prototype = jake.TestTask.prototype;
+    t = new ctor();
+    jake.TestTask.apply(t, arguments);
+    return t;
+  };
+
+})();
+
+module.exports = api;

+ 329 - 0
Build/node_modules/jake/lib/jake.js

@@ -0,0 +1,329 @@
+/*
+ * Jake JavaScript build tool
+ * Copyright 2112 Matthew Eernisse ([email protected])
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+
+var EventEmitter = require('events').EventEmitter;
+// And so it begins
+global.jake = new EventEmitter();
+
+var fs = require('fs')
+  , path = require('path')
+  , chalk = require('chalk')
+  , taskNs = require('./task')
+  , Task = taskNs.Task
+  , FileTask = taskNs.FileTask
+  , DirectoryTask = taskNs.DirectoryTask
+  , Rule = require('./rule').Rule
+  , Namespace = require('./namespace').Namespace
+  , api = require('./api')
+  , utils = require('./utils')
+  , Program = require('./program').Program
+  , Loader = require('./loader').Loader
+  , pkg = JSON.parse(fs.readFileSync(__dirname + '/../package.json').toString());
+
+var MAX_RULE_RECURSION_LEVEL = 16;
+
+var Invocation = function (taskName, args) {
+  this.taskName = taskName;
+  this.args = args;
+};
+
+// Globalize jake and top-level API methods (e.g., `task`, `desc`)
+utils.mixin(global, api);
+
+// Copy utils onto base jake
+utils.mixin(jake, utils);
+// File utils should be aliased directly on base jake as well
+utils.mixin(jake, utils.file);
+
+utils.mixin(jake, new (function () {
+
+  this._invocationChain = [];
+
+  // Private variables
+  // =================
+  // Local reference for scopage
+  var self = this;
+
+  // Public properties
+  // =================
+  this.version = pkg.version;
+  // Used when Jake exits with a specific error-code
+  this.errorCode = undefined;
+  // Loads Jakefiles/jakelibdirs
+  this.loader = new Loader();
+  // Name/value map of all the various tasks defined in a Jakefile.
+  // Non-namespaced tasks are placed into 'default.'
+  this.defaultNamespace = new Namespace('default', null);
+  // For namespaced tasks -- tasks with no namespace are put into the
+  // 'default' namespace so lookup code can work the same for both
+  // namespaced and non-namespaced.
+  this.currentNamespace = this.defaultNamespace;
+  // Saves the description created by a 'desc' call that prefaces a
+  // 'task' call that defines a task.
+  this.currentTaskDescription = null;
+  this.program = new Program();
+  this.FileList = require('filelist').FileList;
+  this.PackageTask = require('./package_task').PackageTask;
+  this.PublishTask = require('./publish_task').PublishTask;
+  this.WatchTask = require('./watch_task').WatchTask;
+  this.TestTask = require('./test_task').TestTask;
+  this.Task = Task;
+  this.FileTask = FileTask;
+  this.DirectoryTask = DirectoryTask;
+  this.Namespace = Namespace;
+  this.Rule = Rule;
+
+  this.parseAllTasks = function () {
+    var _parseNs = function (name, ns) {
+      var nsTasks = ns.tasks
+        , task
+        , nsNamespaces = ns.childNamespaces
+        , fullName;
+      // Iterate through the tasks in each namespace
+      for (var q in nsTasks) {
+        task = nsTasks[q];
+        // Prefix namespaced tasks
+        fullName = name == 'default' ? q : name + ':' + q;
+        // Save with 'taskname' or 'namespace:taskname' key
+        task.fullName = fullName;
+        jake.Task[fullName] = task;
+      }
+      for (var p in nsNamespaces) {
+        fullName = (name == 'default') ? p : name + ':' + p;
+        _parseNs(fullName, nsNamespaces[p]);
+      }
+    };
+
+    _parseNs('default', jake.defaultNamespace);
+  };
+
+  /**
+   * Displays the list of descriptions avaliable for tasks defined in
+   * a Jakefile
+   */
+  this.showAllTaskDescriptions = function (f) {
+    var p
+      , maxTaskNameLength = 0
+      , task
+      , str = ''
+      , padding
+      , name
+      , descr
+      , filter = typeof f == 'string' ? f : null;
+
+    for (p in jake.Task) {
+      task = jake.Task[p];
+      // Record the length of the longest task name -- used for
+      // pretty alignment of the task descriptions
+      maxTaskNameLength = p.length > maxTaskNameLength ?
+        p.length : maxTaskNameLength;
+    }
+    // Print out each entry with descriptions neatly aligned
+    for (p in jake.Task) {
+      if (filter && p.indexOf(filter) == -1) {
+        continue;
+      }
+      task = jake.Task[p];
+
+      //name = '\033[32m' + p + '\033[39m ';
+      name = chalk.green(p);
+
+      // Create padding-string with calculated length
+      padding = (new Array(maxTaskNameLength - p.length + 2)).join(' ');
+
+      descr = task.description;
+      if (descr) {
+        descr = chalk.gray(descr);
+        console.log('jake ' + name + padding + descr);
+      }
+    }
+  };
+
+  this.createTask = function () {
+    var args = Array.prototype.slice.call(arguments)
+      , arg
+      , obj
+      , task
+      , type
+      , name
+      , action
+      , opts = {}
+      , prereqs = [];
+
+      type = args.shift();
+
+    // name, [deps], [action]
+    // Name (string) + deps (array) format
+    if (typeof args[0] == 'string') {
+      name = args.shift();
+      if (Array.isArray(args[0])) {
+        prereqs = args.shift();
+      }
+    }
+    // name:deps, [action]
+    // Legacy object-literal syntax, e.g.: {'name': ['depA', 'depB']}
+    else {
+      obj = args.shift();
+      for (var p in obj) {
+        prereqs = prereqs.concat(obj[p]);
+        name = p;
+      }
+    }
+
+    // Optional opts/callback or callback/opts
+    while ((arg = args.shift())) {
+      if (typeof arg == 'function') {
+        action = arg;
+      }
+      else {
+        opts = arg;
+      }
+    }
+
+    task = jake.currentNamespace.resolveTask(name);
+    if (task && !action) {
+      // Task already exists and no action, just update prereqs, and return it.
+      task.prereqs = task.prereqs.concat(prereqs);
+      return task;
+    }
+
+    switch (type) {
+      case 'directory':
+        action = function () {
+          jake.mkdirP(name);
+        };
+        task = new DirectoryTask(name, prereqs, action, opts);
+        break;
+      case 'file':
+        task = new FileTask(name, prereqs, action, opts);
+        break;
+      default:
+        task = new Task(name, prereqs, action, opts);
+    }
+
+    if (jake.currentTaskDescription) {
+      task.description = jake.currentTaskDescription;
+      jake.currentTaskDescription = null;
+    }
+    jake.currentNamespace.tasks[name] = task;
+    task.namespace = jake.currentNamespace;
+
+    // FIXME: Should only need to add a new entry for the current
+    // task-definition, not reparse the entire structure
+    jake.parseAllTasks();
+
+    return task;
+  };
+
+  this.attemptRule = function (name, ns, level) {
+    var prereqRule
+      , prereq;
+    if (level > MAX_RULE_RECURSION_LEVEL) {
+      return null;
+    }
+    // Check Rule
+    prereqRule = ns.matchRule(name);
+    if (prereqRule) {
+      prereq = prereqRule.createTask(name, level);
+    }
+    return prereq || null;
+  };
+
+  this.createPlaceholderFileTask = function (name, namespace) {
+    var nsPath = ''
+      , filePath = name.split(':').pop() // Strip any namespace
+      , parts
+      , fileTaskName
+      , task
+      , stats;
+
+    if (namespace) {
+      if (typeof namespace == 'string') {
+        nsPath = namespace;
+      }
+      else {
+        nsPath = namespace.path;
+      }
+    }
+
+    parts = nsPath.length ? nsPath.split(':') : [];
+    parts.push(filePath);
+    fileTaskName = parts.join(':');
+
+    task = jake.Task[fileTaskName];
+
+    // If there's not already an existing dummy FileTask for it,
+    // create one
+    if (!task) {
+      // Create a dummy FileTask only if file actually exists
+      if (fs.existsSync(filePath)) {
+        stats = fs.statSync(filePath);
+        task = new jake.FileTask(filePath);
+        task.fullName = fileTaskName;
+        task.modTime = stats.mtime;
+        task.dummy = true;
+        // Put this dummy Task in the global Tasks list so
+        // modTime will be eval'd correctly
+        jake.Task[fileTaskName] = task;
+      }
+    }
+
+    return task || null;
+  };
+
+
+  this.init = function () {
+    var self = this;
+    process.addListener('uncaughtException', function (err) {
+      self.program.handleErr(err);
+    });
+
+  };
+
+  this.run = function () {
+    var args = Array.prototype.slice.call(arguments)
+      , program = this.program
+      , loader = this.loader
+      , preempt
+      , opts;
+
+    program.parseArgs(args);
+    program.init();
+
+    preempt = program.firstPreemptiveOption();
+    if (preempt) {
+      preempt();
+    }
+    else {
+      opts = program.opts;
+      // Load Jakefile and jakelibdir files
+      var jakefileLoaded = loader.loadFile(opts.jakefile);
+      var jakelibdirLoaded = loader.loadDirectory(opts.jakelibdir);
+
+      if(!jakefileLoaded && !jakelibdirLoaded) {
+        fail('No Jakefile. Specify a valid path with -f/--jakefile, ' +
+            'or place one in the current directory.');
+      }
+
+      program.run();
+    }
+  };
+
+})());
+
+module.exports = jake;

+ 106 - 0
Build/node_modules/jake/lib/loader.js

@@ -0,0 +1,106 @@
+/*
+ * Jake JavaScript build tool
+ * Copyright 2112 Matthew Eernisse ([email protected])
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+
+var path = require('path')
+  , fs = require('fs')
+  , existsSync = typeof fs.existsSync == 'function' ?
+      fs.existsSync : path.existsSync
+  , utils = require('utilities')
+  , CoffeeScript
+  , Loader;
+
+
+Loader = function () {
+
+  var JAKEFILE_PAT = /\.jake(\.js|\.coffee)?$/;
+
+  var _requireCoffee = function () {
+        try {
+          var cs = require('coffee-script');
+          // Ensure we support CoffeeScript versions older than 1.7.0
+          if (typeof cs.register == 'function') {
+            cs.register();
+          }
+        }
+        catch (e) {
+          fail('CoffeeScript is missing! Try `npm install coffee-script`');
+        }
+        return(cs);
+      };
+
+  this.loadFile = function (file) {
+    var jakefile = file ?
+            file.replace(/\.js$/, '').replace(/\.coffee$/, '') : 'Jakefile'
+      , fileSpecified = !!file
+      // Dear God, why?
+      , isCoffee = false
+      // Warning, recursive
+      , exists
+      , oldCwd = process.cwd();
+
+    exists = function () {
+      var cwd = process.cwd();
+      if (existsSync(jakefile) || existsSync(jakefile + '.js') ||
+        existsSync(jakefile + '.coffee')) {
+        return true;
+      }
+      if (!fileSpecified) {
+        process.chdir("..");
+        if (cwd === process.cwd()) {
+          // Restore the working directory on failure
+          process.chdir(oldCwd);
+          return false;
+        }
+        return exists();
+      }
+    };
+
+    if (!exists()) {
+      return false;
+    }
+
+    isCoffee = existsSync(jakefile + '.coffee');
+    if (isCoffee) {
+      CoffeeScript = _requireCoffee();
+    }
+    require(utils.file.absolutize(jakefile));
+    return true;
+  };
+
+  this.loadDirectory = function (d) {
+    var dirname = d || 'jakelib'
+      , dirlist;
+    dirname = utils.file.absolutize(dirname);
+    if (existsSync(dirname)) {
+      dirlist = fs.readdirSync(dirname);
+      dirlist.forEach(function (filePath) {
+        if (JAKEFILE_PAT.test(filePath)) {
+          if (/\.coffee$/.test(filePath)) {
+            CoffeeScript = _requireCoffee();
+          }
+          require(path.join(dirname, filePath));
+        }
+      });
+      return true;
+    }
+
+    return false;
+  };
+};
+
+module.exports.Loader = Loader;

+ 74 - 0
Build/node_modules/jake/lib/namespace.js

@@ -0,0 +1,74 @@
+
+var Namespace = function (name, parentNamespace) {
+  this.name = name;
+  this.parentNamespace = parentNamespace;
+  this.childNamespaces = {};
+  this.tasks = {};
+  this.rules = {};
+  this.path = this.getPath();
+};
+
+Namespace.prototype = new (function () {
+
+  this.resolveTask = function(relativeName) {
+    var parts = relativeName.split(':')
+      , name = parts.pop()
+      , ns = this.resolveNamespace(parts.join(':'));
+
+    return (ns && ns.tasks[name]) ||
+        (this.parentNamespace &&
+        this.parentNamespace.resolveTask(relativeName));
+  };
+
+  this.resolveNamespace = function(relativeName) {
+    var parts = relativeName.split(':')
+      , ns;
+
+    if (!relativeName) {
+      return this;
+    }
+
+    ns = this;
+    for (var i = 0, ii = parts.length; ns && i < ii; i++) {
+      ns = ns.childNamespaces[parts[i]];
+    }
+
+    return (ns || (this.parentNamespace &&
+        this.parentNamespace.resolveNamespace(relativeName)));
+  };
+
+  this.matchRule = function(relativeName) {
+    var parts = relativeName.split(':')
+      , name = parts.pop()
+      , ns = this.resolveNamespace(parts.join(':'))
+      , rules = ns ? ns.rules : []
+      , r
+      , match;
+
+    for (var p in rules) {
+      r = rules[p];
+      if (r.match(relativeName)) {
+        match = r;
+      }
+    }
+
+    return (ns && match) ||
+        (this.parentNamespace &&
+        this.parentNamespace.matchRule(relativeName));
+  };
+
+  this.getPath = function () {
+    var parts = []
+      , next = this;
+    while (!!next) {
+      parts.push(next.name);
+      next = next.parentNamespace;
+    }
+    parts.pop(); // Remove 'default'
+    return parts.reverse().join(':');
+  };
+
+})();
+
+module.exports.Namespace = Namespace;
+

+ 408 - 0
Build/node_modules/jake/lib/package_task.js

@@ -0,0 +1,408 @@
+/*
+ * Jake JavaScript build tool
+ * Copyright 2112 Matthew Eernisse ([email protected])
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+
+var path = require('path')
+  , fs = require('fs')
+  , exec = require('child_process').exec
+  , FileList = require('filelist').FileList;
+
+/**
+  @name jake
+  @namespace jake
+*/
+/**
+  @name jake.PackageTask
+  @constructor
+  @description Instantiating a PackageTask creates a number of Jake
+  Tasks that make packaging and distributing your software easy.
+
+  @param {String} name The name of the project
+  @param {String} version The current project version (will be
+  appended to the project-name in the package-archive
+  @param {Function} definition Defines the contents of the package,
+  and format of the package-archive. Will be executed on the instantiated
+  PackageTask (i.e., 'this', will be the PackageTask instance),
+  to set the various instance-propertiess.
+
+  @example
+  var t = new jake.PackageTask('rous', 'v' + version, function () {
+    var files = [
+      'Capfile'
+    , 'Jakefile'
+    , 'README.md'
+    , 'package.json'
+    , 'app/*'
+    , 'bin/*'
+    , 'config/*'
+    , 'lib/*'
+    , 'node_modules/*'
+    ];
+    this.packageFiles.include(files);
+    this.packageFiles.exclude('node_modules/foobar');
+    this.needTarGz = true;
+  });
+
+ */
+var PackageTask = function () {
+  var args = Array.prototype.slice.call(arguments)
+    , name = args.shift()
+    , version = args.shift()
+    , definition = args.pop()
+    , prereqs = args.pop() || []; // Optional
+
+    prereqs = [].concat(prereqs); // Accept string or list
+
+  /**
+    @name jake.PackageTask#name
+    @public
+    @type {String}
+    @description The name of the project
+   */
+  this.name = name;
+  /**
+    @name jake.PackageTask#version
+    @public
+    @type {String}
+    @description The project version-string
+   */
+  this.version = version;
+  /**
+    @name jake.PackageTask#prereqs
+    @public
+    @type {Array}
+    @description Tasks to run before packaging
+   */
+  this.prereqs = prereqs;
+  /**
+    @name jake.PackageTask#version
+    @public
+    @type {String='pkg'}
+    @description The directory-name to use for packaging the software
+   */
+  this.packageDir = 'pkg';
+  /**
+    @name jake.PackageTask#packageFiles
+    @public
+    @type {jake.FileList}
+    @description The list of files and directories to include in the
+    package-archive
+   */
+  this.packageFiles = new FileList();
+  /**
+    @name jake.PackageTask#needTar
+    @public
+    @type {Boolean=false}
+    @description If set to true, uses the `tar` utility to create
+    a gzip .tgz archive of the package
+   */
+  this.needTar = false;
+  /**
+    @name jake.PackageTask#needTar
+    @public
+    @type {Boolean=false}
+    @description If set to true, uses the `tar` utility to create
+    a gzip .tar.gz archive of the package
+   */
+  this.needTarGz = false;
+  /**
+    @name jake.PackageTask#needTarBz2
+    @public
+    @type {Boolean=false}
+    @description If set to true, uses the `tar` utility to create
+    a bzip2 .bz2 archive of the package
+   */
+  this.needTarBz2 = false;
+  /**
+    @name jake.PackageTask#needJar
+    @public
+    @type {Boolean=false}
+    @description If set to true, uses the `jar` utility to create
+    a .jar archive of the package
+   */
+  this.needJar = false;
+  /**
+    @name jake.PackageTask#needZip
+    @public
+    @type {Boolean=false}
+    @description If set to true, uses the `zip` utility to create
+    a .zip archive of the package
+   */
+  this.needZip = false;
+  /**
+    @name jake.PackageTask#manifestFile
+    @public
+    @type {String=null}
+    @description Can be set to point the `jar` utility at a manifest
+    file to use in a .jar archive. If unset, one will be automatically
+    created by the `jar` utility. This path should be relative to the
+    root of the package directory (this.packageDir above, likely 'pkg')
+   */
+  this.manifestFile = null;
+  /**
+    @name jake.PackageTask#tarCommand
+    @public
+    @type {String='tar'}
+    @description The shell-command to use for creating tar archives.
+   */
+  this.tarCommand = 'tar';
+  /**
+    @name jake.PackageTask#jarCommand
+    @public
+    @type {String='jar'}
+    @description The shell-command to use for creating jar archives.
+   */
+  this.jarCommand = 'jar';
+  /**
+    @name jake.PackageTask#zipCommand
+    @public
+    @type {String='zip'}
+    @description The shell-command to use for creating zip archives.
+   */
+  this.zipCommand = 'zip';
+  /**
+    @name jake.PackageTask#archiveNoBaseDir
+    @public
+    @type {Boolean=false}
+    @description Simple option for performing the archive on the
+    contents of the directory instead of the directory itself
+   */
+  this.archiveNoBaseDir = false;
+  /**
+    @name jake.PackageTask#archiveChangeDir
+    @public
+    @type {String=null}
+    @description Equivalent to the '-C' command for the `tar` and `jar`
+    commands. ("Change to this directory before adding files.")
+   */
+  this.archiveChangeDir = null;
+  /**
+    @name jake.PackageTask#archiveContentDir
+    @public
+    @type {String=null}
+    @description Specifies the files and directories to include in the
+    package-archive. If unset, this will default to the main package
+    directory -- i.e., name + version.
+   */
+  this.archiveContentDir = null;
+
+  if (typeof definition == 'function') {
+    definition.call(this);
+  }
+  this.define();
+};
+
+PackageTask.prototype = new (function () {
+
+  var _compressOpts = {
+        Tar: {
+          ext: '.tgz'
+        , flags: 'cvzf'
+        , cmd: 'tar'
+        }
+      , TarGz: {
+          ext: '.tar.gz'
+        , flags: 'cvzf'
+        , cmd: 'tar'
+        }
+      , TarBz2: {
+          ext: '.tar.bz2'
+        , flags: 'cvjf'
+        , cmd: 'tar'
+        }
+      , Jar: {
+          ext: '.jar'
+        , flags: 'cf'
+        , cmd: 'jar'
+        }
+      , Zip: {
+          ext: '.zip'
+        , flags: 'r'
+        , cmd: 'zip'
+        }
+      };
+
+  this.define = function () {
+    var self = this
+      , packageDirPath = this.packageDirPath()
+      , compressTaskArr = [];
+
+    desc('Build the package for distribution');
+    task('package', self.prereqs.concat(['clobberPackage', 'buildPackage']));
+    // Backward-compat alias
+    task('repackage', ['package']);
+
+    task('clobberPackage', function () {
+      jake.rmRf(self.packageDir, {silent: true});
+    });
+
+    desc('Remove the package');
+    task('clobber', ['clobberPackage']);
+
+    var doCommand = function (p) {
+      var filename = path.resolve(self.packageDir + '/' + self.packageName() +
+                                  _compressOpts[p].ext);
+      if (process.platform == 'win32') {
+          // Windows full path may have drive letter, which is going to cause
+          // namespace problems, so strip it.
+          if (filename.length > 2 && filename[1] == ':') {
+            filename = filename.substr(2);
+          }
+      }
+      compressTaskArr.push(filename);
+
+      file(filename, [packageDirPath], function () {
+        var cmd
+        , opts = _compressOpts[p]
+        // Directory to move to when doing the compression-task
+        // Changes in the case of zip for emulating -C option
+        , chdir = self.packageDir
+        // Save the current dir so it's possible to pop back up
+        // after compressing
+        , currDir = process.cwd()
+        , archiveChangeDir
+        , archiveContentDir;
+
+        if (self.archiveNoBaseDir) {
+          archiveChangeDir = self.packageName();
+          archiveContentDir = '.* -x "../*"';
+        }
+        else {
+          archiveChangeDir = self.archiveChangeDir;
+          archiveContentDir = self.archiveContentDir;
+        }
+
+        cmd = self[opts.cmd + 'Command'];
+        cmd += ' -' + opts.flags;
+        if (opts.cmd == 'jar' && self.manifestFile) {
+          cmd += 'm';
+        }
+
+        // The name of the archive to create -- use full path
+        // so compression can be performed from a different dir
+        // if needed
+        cmd += ' ' + filename;
+
+        if (opts.cmd == 'jar' && self.manifestFile) {
+          cmd += ' ' + self.manifestFile;
+        }
+
+        // Where to perform the compression -- -C option isn't
+        // supported in zip, so actually do process.chdir for this
+        if (archiveChangeDir) {
+          if (opts.cmd == 'zip') {
+            chdir = path.join(chdir, archiveChangeDir);
+          }
+          else {
+            cmd += ' -C ' + archiveChangeDir;
+          }
+        }
+
+        // Where to get the archive content
+        if (archiveContentDir) {
+          cmd += ' ' + archiveContentDir;
+        }
+        else {
+          cmd += ' ' + self.packageName();
+        }
+
+        // Move into the desired dir (usually packageDir) to compress
+        // Return back up to the current dir after the exec
+        process.chdir(chdir);
+
+        exec(cmd, function (err, stdout, stderr) {
+          if (err) { throw err; }
+
+          // Return back up to the starting directory (see above,
+          // before exec)
+          process.chdir(currDir);
+
+          complete();
+        });
+      }, {async: true});
+    };
+
+    for (var p in _compressOpts) {
+      if (this['need' + p]) {
+        doCommand(p);
+      }
+    }
+
+    task('buildPackage', compressTaskArr, function () {});
+
+    directory(this.packageDir);
+
+    file(packageDirPath, this.packageFiles, function () {
+      jake.mkdirP(packageDirPath);
+      var fileList = [];
+      self.packageFiles.forEach(function (name) {
+        var f = path.join(self.packageDirPath(), name)
+          , fDir = path.dirname(f)
+          , stats;
+        jake.mkdirP(fDir, {silent: true});
+
+        // Add both files and directories
+        fileList.push({
+          from: name
+        , to: f
+        });
+      });
+      var _copyFile = function () {
+        var cmd
+          , file = fileList.pop()
+          , stat;
+        if (file) {
+          stat = fs.statSync(file.from);
+          // Target is a directory, just create it
+          if (stat.isDirectory()) {
+            jake.mkdirP(file.to, {silent: true});
+            _copyFile();
+          }
+          // Otherwise copy the file
+          else {
+            jake.cpR(file.from, file.to, {silent: true});
+            _copyFile();
+          }
+        }
+        else {
+          complete();
+        }
+      };
+      _copyFile();
+    }, {async: true});
+
+
+  };
+
+  this.packageName = function () {
+    if (this.version) {
+      return this.name + '-' + this.version;
+    }
+    else {
+      return this.name;
+    }
+  };
+
+  this.packageDirPath = function () {
+    return this.packageDir + '/' + this.packageName();
+  };
+
+})();
+
+jake.PackageTask = PackageTask;
+exports.PackageTask = PackageTask;
+

+ 134 - 0
Build/node_modules/jake/lib/parseargs.js

@@ -0,0 +1,134 @@
+/*
+ * Jake JavaScript build tool
+ * Copyright 2112 Matthew Eernisse ([email protected])
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+
+var parseargs = {};
+
+/**
+ * @constructor
+ * Parses a list of command-line args into a key/value object of
+ * options and an array of positional commands.
+ * @ param {Array} opts A list of options in the following format:
+ * [{full: 'foo', abbr: 'f'}, {full: 'bar', abbr: 'b'}]]
+ */
+parseargs.Parser = function (opts) {
+  // A key/value object of matching options parsed out of the args
+  this.opts = {};
+  this.taskNames = null;
+  this.envVars = null;
+
+  // Data structures used for parsing
+  this.reg = [];
+  this.shortOpts = {};
+  this.longOpts = {};
+
+  var item;
+  for (var i = 0, ii = opts.length; i < ii; i++) {
+    item = opts[i];
+    this.shortOpts[item.abbr] = item;
+    this.longOpts[item.full] = item;
+  }
+  this.reg = opts;
+};
+
+parseargs.Parser.prototype = new function () {
+
+  var _trueOrNextVal = function (argParts, args) {
+        if (argParts[1]) {
+          return argParts[1];
+        }
+        else {
+          return (!args[0] || (args[0].indexOf('-') === 0)) ?
+              true : args.shift();
+        }
+      };
+
+  /**
+   * Parses an array of arguments into options and positional commands
+   * @param {Array} args The command-line args to parse
+   */
+  this.parse = function (args) {
+    var cmds = []
+      , cmd
+      , envVars = {}
+      , opts = {}
+      , arg
+      , argItem
+      , argParts
+      , cmdItems
+      , taskNames = []
+      , preempt;
+
+    while (args.length) {
+      arg = args.shift();
+
+      if (arg.indexOf('-') === 0) {
+        arg = arg.replace(/^--/, '').replace(/^-/, '');
+        argParts = arg.split('=');
+        argItem = this.longOpts[argParts[0]] || this.shortOpts[argParts[0]];
+        if (argItem) {
+          // First-encountered preemptive opt takes precedence -- no further opts
+          // or possibility of ambiguity, so just look for a value, or set to
+          // true and then bail
+          if (argItem.preempts) {
+            opts[argItem.full] = _trueOrNextVal(argParts, args);
+            preempt = true;
+            break;
+          }
+          // If the opt requires a value, see if we can get a value from the
+          // next arg, or infer true from no-arg -- if it's followed by another
+          // opt, throw an error
+          if (argItem.expectValue) {
+            opts[argItem.full] = _trueOrNextVal(argParts, args);
+            if (!opts[argItem.full]) {
+              throw new Error(argItem.full + ' option expects a value.');
+            }
+          }
+          else {
+            opts[argItem.full] = true;
+          }
+        }
+      }
+      else {
+        cmds.unshift(arg);
+      }
+    }
+
+    if (!preempt) {
+      // Parse out any env-vars and task-name
+      while (!!(cmd = cmds.pop())) {
+        cmdItems = cmd.split('=');
+        if (cmdItems.length > 1) {
+          envVars[cmdItems[0]] = cmdItems[1];
+        }
+        else {
+          taskNames.push(cmd);
+        }
+      }
+
+    }
+
+    return {
+      opts: opts
+    , envVars: envVars
+    , taskNames: taskNames
+    };
+  };
+
+};
+
+module.exports = parseargs;

+ 257 - 0
Build/node_modules/jake/lib/program.js

@@ -0,0 +1,257 @@
+/*
+ * Jake JavaScript build tool
+ * Copyright 2112 Matthew Eernisse ([email protected])
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+
+var fs = require('fs')
+  , parseargs = require('./parseargs')
+  , utils = require('./utils')
+  , Program
+  , optsReg
+  , preempts
+  , usage
+  , die;
+
+optsReg = [
+  { full: 'jakefile'
+  , abbr: 'f'
+  , preempts: false
+  , expectValue: true
+  }
+, { full: 'quiet'
+  , abbr: 'q'
+  , preempts: false
+  , expectValue: false
+  }
+, { full: 'directory'
+  , abbr: 'C'
+  , preempts: false
+  , expectValue: true
+  }
+, { full: 'always-make'
+  , abbr: 'B'
+  , preempts: false
+  , expectValue: false
+  }
+, { full: 'tasks'
+  , abbr: 'T'
+  , preempts: true
+  }
+// Alias ls
+, { full: 'tasks'
+  , abbr: 'ls'
+  , preempts: true
+  }
+, { full: 'trace'
+  , abbr: 't'
+  , preempts: false
+  , expectValue: false
+  }
+, { full: 'help'
+  , abbr: 'h'
+  , preempts: true
+  }
+, { full: 'version'
+  , abbr: 'V'
+  , preempts: true
+  }
+  // Alias lowercase v
+, { full: 'version'
+  , abbr: 'v'
+  , preempts: true
+  }
+, { full: 'jakelibdir'
+  , abbr: 'J'
+  , preempts: false
+  , expectValue: true
+  }
+];
+
+preempts = {
+  version: function () {
+    die(jake.version);
+  }
+, help: function () {
+    die(usage);
+  }
+};
+
+usage = ''
+    + 'Jake JavaScript build tool\n'
+    + '********************************************************************************\n'
+    + 'If no flags are given, Jake looks for a Jakefile or Jakefile.js in the current directory.\n'
+    + '********************************************************************************\n'
+    + '{Usage}: jake [options ...] [env variables ...] target\n'
+    + '\n'
+    + '{Options}:\n'
+    + '  -f,     --jakefile FILE            Use FILE as the Jakefile.\n'
+    + '  -C,     --directory DIRECTORY      Change to DIRECTORY before running tasks.\n'
+    + '  -q,     --quiet                    Do not log messages to standard output.\n'
+    + '  -B,     --always-make              Unconditionally make all targets.\n'
+    + '  -T/ls,  --tasks                 Display the tasks (matching optional PATTERN) with descriptions, then exit.\n'
+    + '  -J,     --jakelibdir JAKELIBDIR    Auto-import any .jake files in JAKELIBDIR. (default is \'jakelib\')\n'
+    + '  -t,     --trace                    Enable full backtrace.\n'
+    + '  -h,     --help                     Display this help message.\n'
+    + '  -V/v,   --version                  Display the Jake version.\n'
+    + '';
+
+Program = function () {
+  this.opts = {};
+  this.taskNames = null;
+  this.taskArgs = null;
+  this.envVars = null;
+};
+
+Program.prototype = new (function () {
+
+  this.handleErr = function (err) {
+    if(jake.listeners('error').length !== 0) {
+      jake.emit('error', err);
+      return;
+    }
+
+    var msg;
+
+    if (jake.listeners('error').length) {
+      jake.emit('error', err);
+      return;
+    }
+
+    utils.logger.error('jake aborted.');
+    if (this.opts.trace && err.stack) {
+      utils.logger.error(err.stack);
+    }
+    else {
+      if (err.stack) {
+        msg = err.stack.split('\n').slice(0, 3).join('\n');
+        utils.logger.error(msg);
+        utils.logger.error('(See full trace by running task with --trace)');
+      }
+      else {
+        utils.logger.error(err.message);
+      }
+    }
+    process.stdout.write('', function() {
+      process.stderr.write('', function() {
+        jake.errorCode = jake.errorCode || 1;
+        process.exit(jake.errorCode);
+      });
+    });
+  };
+
+  this.parseArgs = function (args) {
+    var result = (new parseargs.Parser(optsReg)).parse(args);
+    this.setOpts(result.opts);
+    this.setTaskNames(result.taskNames);
+    this.setEnvVars(result.envVars);
+  };
+
+  this.setOpts = function (options) {
+    var opts = options || {};
+    utils.mixin(this.opts, opts);
+  };
+
+  this.setTaskNames = function (names) {
+    if (names && !Array.isArray(names)) {
+      throw new Error('Task names must be an array');
+    }
+    this.taskNames = (names && names.length) ? names : ['default'];
+  };
+
+  this.setEnvVars = function (vars) {
+    this.envVars = vars || null;
+  };
+
+  this.firstPreemptiveOption = function () {
+    var opts = this.opts;
+    for (var p in opts) {
+      if (preempts[p]) {
+        return preempts[p];
+      }
+    }
+    return false;
+  };
+
+  this.init = function (configuration) {
+    var self = this
+      , config = configuration || {};
+    if (config.options) {
+      this.setOpts(config.options);
+    }
+    if (config.taskNames) {
+      this.setTaskNames(config.taskNames);
+    }
+    if (config.envVars) {
+      this.setEnvVars(config.envVars);
+    }
+    process.addListener('uncaughtException', function (err) {
+      self.handleErr(err);
+    });
+    if (this.envVars) {
+      utils.mixin(process.env, this.envVars);
+    }
+  };
+
+  this.run = function () {
+    var rootTask
+      , taskNames
+      , dirname
+      , opts = this.opts;
+
+    // Run with `jake -T`, just show descriptions
+    if (opts.tasks) {
+      return jake.showAllTaskDescriptions(opts.tasks);
+    }
+
+    taskNames = this.taskNames;
+    if (!(Array.isArray(taskNames) && taskNames.length)) {
+      throw new Error('Please pass jake.runTasks an array of task-names');
+    }
+
+    // Set working dir
+    dirname = opts.directory;
+    if (dirname) {
+      if (utils.file.existsSync(dirname) &&
+        fs.statSync(dirname).isDirectory()) {
+        process.chdir(dirname);
+      }
+      else {
+        throw new Error(dirname + ' is not a valid directory path');
+      }
+    }
+
+    task('__root__', taskNames, function () {});
+
+    rootTask = jake.Task.__root__;
+    rootTask.once('complete', function () {
+      jake.emit('complete');
+    });
+    jake.emit('start');
+    rootTask.invoke();
+  };
+
+})();
+
+die = function (msg) {
+  console.log(msg);
+  process.stdout.write('', function() {
+    process.stderr.write('', function() {
+      process.exit();
+	});
+  });
+};
+
+module.exports.Program = Program;

+ 307 - 0
Build/node_modules/jake/lib/publish_task.js

@@ -0,0 +1,307 @@
+/*
+ * Jake JavaScript build tool
+ * Copyright 2112 Matthew Eernisse ([email protected])
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+
+var fs = require('fs')
+  , path = require('path')
+  , exec = require('child_process').exec
+  , utils = require('utilities')
+  , FileList = require('filelist').FileList;
+
+var PublishTask = function () {
+  var args = Array.prototype.slice.call(arguments).filter(function (item) {
+        return typeof item != 'undefined';
+      })
+    , arg
+    , opts = {}
+    , definition
+    , prereqs = []
+    , createDef = function (arg) {
+        return function () {
+          this.packageFiles.include(arg);
+        };
+      };
+
+  this.name = args.shift();
+
+  // Old API, just name + list of files
+  if (args.length == 1 && (Array.isArray(args[0]) || typeof args[0] == 'string')) {
+    definition = createDef(args.pop());
+  }
+  // Current API, name + [prereqs] + [opts] + definition
+  else {
+    while ((arg = args.pop())) {
+      // Definition func
+      if (typeof arg == 'function') {
+        definition = arg;
+      }
+      // Prereqs
+      else if (Array.isArray(arg) || typeof arg == 'string') {
+        prereqs = arg;
+      }
+      // Opts
+      else {
+        opts = arg;
+      }
+    }
+  }
+
+  this.prereqs = prereqs;
+  this.packageFiles = new FileList();
+  this.publishCmd = opts.publishCmd || 'npm publish %filename';
+  this.gitCmd = opts.gitCmd || 'git';
+  this.versionFiles = opts.versionFiles || ['package.json'];
+  this.scheduleDelay = 5000;
+
+  // Override utility funcs for testing
+  this._ensureRepoClean = function (stdout) {
+    if (stdout.length) {
+      fail(new Error('Git repository is not clean.'));
+    }
+  };
+  this._getCurrentBranch = function (stdout) {
+    return utils.string.trim(stdout);
+  };
+
+  if (typeof definition == 'function') {
+    definition.call(this);
+  }
+  this.define();
+};
+
+
+PublishTask.prototype = new (function () {
+
+  var _currentBranch = null;
+
+  var getPackage = function () {
+        var pkg = JSON.parse(fs.readFileSync(path.join(process.cwd(),
+            '/package.json')).toString());
+        return pkg;
+      }
+    , getPackageVersionNumber = function () {
+        return getPackage().version;
+      };
+
+  this.define = function () {
+    var self = this;
+
+    namespace('publish', function () {
+      task('fetchTags', {async: true}, function () {
+        // Make sure local tags are up to date
+        var cmds = [
+          self.gitCmd + ' fetch --tags'
+        ];
+        jake.exec(cmds, function () {
+          console.log('Fetched remote tags.');
+          complete();
+        });
+      });
+
+      task('getCurrentBranch', {async: true}, function () {
+        // Figure out what branch to push to
+        exec(self.gitCmd + ' symbolic-ref --short HEAD',
+            function (err, stdout, stderr) {
+          if (err) {
+            fail(err);
+          }
+          if (stderr) {
+            fail(new Error(stderr));
+          }
+          if (!stdout) {
+            fail(new Error('No current Git branch found'));
+          }
+          _currentBranch = self._getCurrentBranch(stdout);
+          console.log('On branch ' + _currentBranch);
+          complete();
+        });
+      });
+
+      task('ensureClean', {async: true}, function () {
+        // Only bump, push, and tag if the Git repo is clean
+        exec(self.gitCmd + ' status --porcelain --untracked-files=no',
+            function (err, stdout, stderr) {
+          if (err) {
+            fail(err);
+          }
+          if (stderr) {
+            fail(new Error(stderr));
+          }
+
+          // Throw if there's output
+          self._ensureRepoClean(stdout);
+
+          complete();
+        });
+      });
+
+      task('updateVersionFiles', function () {
+        var pkg
+          , version
+          , arr
+          , patch;
+
+        // Grab the current version-string
+        pkg = getPackage();
+        version = pkg.version;
+        // Increment the patch-number for the version
+        arr = version.split('.');
+        patch = parseInt(arr.pop(), 10) + 1;
+        arr.push(patch);
+        version = arr.join('.');
+
+        // Update package.json or other files with the new version-info
+        self.versionFiles.forEach(function (file) {
+          var p = path.join(process.cwd(), file)
+            , data = JSON.parse(fs.readFileSync(p).toString());
+          data.version = version;
+          fs.writeFileSync(p, JSON.stringify(data, true, 2) + '\n');
+        });
+        // Return the version string so that listeners for the 'complete' event
+        // for this task can use it (e.g., to update other files before pushing
+        // to Git)
+        return version;
+      });
+
+      task('pushVersion', ['ensureClean', 'updateVersionFiles'], {async: true},
+          function () {
+        var version = getPackageVersionNumber()
+          , message = 'Version ' + version
+          , cmds = [
+              self.gitCmd + ' commit -a -m "' + message + '"'
+            , self.gitCmd + ' push origin ' + _currentBranch
+            , self.gitCmd + ' tag -a v' + version + ' -m "' + message + '"'
+            , self.gitCmd + ' push --tags'
+            ];
+
+        var execOpts = {};
+        if (process.platform == 'win32') {
+          // Windows won't like the quotes in our cmdline
+          execOpts.windowsVerbatimArguments = true;
+        }
+
+        jake.exec(cmds, function () {
+          var version = getPackageVersionNumber();
+          console.log('Bumped version number to v' + version + '.');
+          complete();
+        }, execOpts);
+
+      });
+
+      task('definePackage', function () {
+        var version = getPackageVersionNumber()
+          , t;
+        t = new jake.PackageTask(self.name, 'v' + version, self.prereqs, function () {
+          // Replace the PackageTask's FileList with the PublishTask's FileList
+          this.packageFiles = self.packageFiles;
+          this.needTarGz = true; // Default to tar.gz
+          // If any of the need<CompressionFormat> or archive opts are set
+          // proxy them to the PackageTask
+          for (var p in this) {
+            if (p.indexOf('need') === 0 || p.indexOf('archive') === 0) {
+              if (typeof self[p] != 'undefined') {
+                this[p] = self[p];
+              }
+            }
+          }
+        });
+      });
+
+      task('package', {async: true}, function () {
+        var definePack = jake.Task['publish:definePackage']
+          , pack = jake.Task.package
+          , version = getPackageVersionNumber();
+
+        // May have already been run
+        definePack.reenable(true);
+        definePack.addListener('complete', function () {
+          pack.addListener('complete', function () {
+            console.log('Created package for ' + self.name + ' v' + version);
+            complete();
+          });
+          pack.invoke();
+        });
+        definePack.invoke();
+      });
+
+      task('publish', {async: true}, function () {
+        var version = getPackageVersionNumber()
+          , filename
+          , cmd;
+
+        console.log('Publishing ' + self.name + ' v' + version);
+
+        if (typeof self.createPublishCommand == 'function') {
+          cmd = self.createPublishCommand(version);
+        }
+        else {
+          filename = 'pkg/' + self.name + '-v' + version + '.tar.gz';
+          cmd = self.publishCmd.replace(/%filename/gi, filename);
+        }
+
+        // Hackity hack -- NPM publish sometimes returns errror like:
+        // Error sending version data\nnpm ERR!
+        // Error: forbidden 0.2.4 is modified, should match modified time
+        setTimeout(function () {
+          jake.exec(cmd, function () {
+            console.log('BOOM! Published.');
+            complete();
+          }, {printStdout: true, printStderr: true});
+        }, self.scheduleDelay);
+      });
+
+      task('cleanup', {async: true}, function () {
+        var clobber = jake.Task.clobber;
+        clobber.reenable(true);
+        clobber.on('complete', function () {
+          console.log('Cleaned up package');
+          complete();
+        });
+        clobber.invoke();
+      });
+
+    });
+
+    var prefixNs = function (item) {
+      return 'publish:' + item;
+    };
+
+    // Create aliases in the default namespace
+    desc('Create a new version and release.');
+    task('publish', self.prereqs.concat(['version', 'release']
+        .map(prefixNs)));
+
+    desc('Release the existing version.');
+    task('publishExisting', self.prereqs.concat(['release']
+        .map(prefixNs)));
+
+    task('version', ['fetchTags', 'getCurrentBranch', 'pushVersion']
+        .map(prefixNs));
+
+    task('release', ['package', 'publish', 'cleanup']
+        .map(prefixNs));
+
+    // Invoke proactively so there will be a callable 'package' task
+    // which can be used apart from 'publish'
+    jake.Task['publish:definePackage'].invoke();
+  };
+
+})();
+
+jake.PublishTask = PublishTask;
+exports.PublishTask = PublishTask;
+

+ 327 - 0
Build/node_modules/jake/lib/rule.js

@@ -0,0 +1,327 @@
+var path = require('path')
+  , fs = require('fs')
+  , Task = require('./task/task').Task
+  , Matcher
+  , rule = {}
+  , Rule;
+
+// Define a helper object with some utility functions
+Matcher = new (function () {
+
+  // Split a task to two parts, name space and task name.
+  // For example, given 'foo:bin/a%.c', return an object with
+  // - 'ns'     : foo
+  // - 'name'   : bin/a%.c
+  this.split = function(task) {
+    var parts = task.split(':')
+    , name  = parts.pop()
+    , ns    = this.resolveNS( parts );
+    return {
+      'name' : name,
+      'ns'   : ns
+    };
+  };
+
+  // Return the namespace based on an array of names.
+  // For example, given ['foo', 'baz' ], return the namespace
+  //
+  //   default -> foo -> baz
+  //
+  // where default is the global root namespace
+  // and -> means child namespace.
+  this.resolveNS = function(parts) {
+    var  ns    = jake.defaultNamespace;
+    for(var i = 0, l = parts.length; ns && i < l; i++) {
+      ns = ns.childNamespaces[parts[i]];
+    }
+    return ns;
+  };
+
+  // Given a pattern p, say 'foo:bin/a%.c'
+  // Return an object with
+  // - 'ns'     : foo
+  // - 'dir'    : bin
+  // - 'prefix' : a
+  // - 'suffix' : .c
+  this.resolve = function(p) {
+    var task = this.split(p),
+        name  = task.name,
+        ns    = task.ns;
+    var split = path.basename(name).split('%');
+    return {
+      ns: ns
+    , dir: path.dirname(name)
+    , prefix: split[0]
+    , suffix: split[1]
+    };
+  };
+
+  // Test whether string a is a suffix of string b
+  this.stringEndWith = function (a,b) {
+    var l;
+    return (l = b.lastIndexOf(a)) == -1 ? false : l + a.length == b.length;
+  };
+
+  // Replace the suffix a of the string s with b.
+  // Note that, it is assumed a is a suffix of s.
+  this.stringReplaceSuffix = function (s, a, b) {
+    return s.slice(0,s.lastIndexOf(a)) + b;
+  };
+
+  // Test wether the a prerequisite matchs the pattern.
+  // The arg 'pattern' does not have namespace as prefix.
+  // For example, the following tests are true
+  //
+  //   pattern      |    name
+  //   bin/%.o      |    bin/main.o
+  //   bin/%.o      |    foo:bin/main.o
+  //
+  // The following tests are false (trivally)
+  //
+  //   pattern      |    name
+  //   bin/%.o      |    foobin/main.o
+  //   bin/%.o      |    bin/main.oo
+  this.match = function(pattern, name) {
+    var p
+      , task
+      , ns
+      , obj
+      , filename;
+
+    if (pattern instanceof RegExp) {
+      return pattern.test(name);
+    }
+    else if (pattern.indexOf('%') == -1) {
+      // No Pattern. No Folder. No Namespace.
+      // A Simple Suffix Rule. Just test suffix
+      return this.stringEndWith(pattern, name);
+    }
+    else {
+      // Resolve the dir, prefix and suffix of pattern
+      p = this.resolve(pattern);
+
+      // Resolve the namespace and task-name
+      task = this.split(name);
+      name = task.name;
+      ns = task.ns;
+
+      // Set the objective as the task-name
+      obj = name;
+
+      // Namespace is already matched.
+
+      // Check dir
+      if (path.dirname(obj) != p.dir) {
+        return false;
+      }
+
+      filename = path.basename(obj);
+
+      // Check file name length
+      if ((p.prefix.length + p.suffix.length + 1) > filename.length) {
+        // Length does not match.
+        return false;
+      }
+
+      // Check prefix
+      if (filename.indexOf(p.prefix) !== 0) {
+        return false;
+      }
+
+      // Check suffix
+      if (!this.stringEndWith(p.suffix, filename)) {
+        return false;
+      }
+
+      // OK. Find a match.
+      return true;
+    }
+  };
+
+  // Generate the source based on
+  //  - name    name for the synthesized task
+  //  - pattern    pattern for the objective
+  //  - source    pattern for the source
+  //
+  // Return the source with properties
+  //  - dep      the prerequisite of source
+  //             (with the namespace)
+  //
+  //  - file     the file name of source
+  //             (without the namespace)
+  //
+  // For example, given
+  //
+  //  - name   foo:bin/main.o
+  //  - pattern    bin/%.o
+  //  - source    src/%.c
+  //
+  //    return 'foo:src/main.c',
+  //
+  this.getSource = function(name, pattern, source) {
+    var dep
+      , pat
+      , match
+      , file
+      , src;
+
+    // Regex pattern -- use to look up the extension
+    if (pattern instanceof RegExp) {
+      match = pattern.exec(name);
+      if (match) {
+        if (typeof source == 'function') {
+          src = source(name);
+        }
+        else {
+          src = this.stringReplaceSuffix(name, match[0], source);
+        }
+      }
+    }
+    // Assume string
+    else {
+      // Simple string suffix replacement
+      if (pattern.indexOf('%') == -1) {
+        if (typeof source == 'function') {
+          src = source(name);
+        }
+        else {
+          src = this.stringReplaceSuffix(name, pattern, source);
+        }
+      }
+      // Percent-based substitution
+      else {
+        pat = pattern.replace('%', '(.*?)');
+        pat = new RegExp(pat);
+        match = pat.exec(name);
+        if (match) {
+          if (typeof source == 'function') {
+            src = source(name);
+          }
+          else {
+            file = match[1];
+            file = source.replace('%', file);
+            dep = match[0];
+            src = name.replace(dep, file);
+          }
+        }
+      }
+    }
+
+    return src;
+  };
+
+})();
+
+
+Rule = function (opts) {
+  this.pattern = opts.pattern;
+  this.source = opts.source;
+  this.prereqs = opts.prereqs;
+  this.action = opts.action;
+  this.opts = opts.opts;
+  this.desc =  opts.desc;
+  this.ns = opts.ns;
+};
+
+Rule.prototype = new (function () {
+  // Create a file task based on this rule for the specified
+  // task-name
+  // ======
+  // FIXME: Right now this just throws away any passed-in args
+  // for the synthsized task (taskArgs param)
+  // ======
+  this.createTask = function (fullName, level) {
+    var self = this
+      , pattern
+      , source
+      , action
+      , opts
+      , prereqs
+      , parts
+      , valid
+      , src
+      , tNs
+      , createdTask
+      , name = Task.getBaseTaskName(fullName)
+      , nsPath = Task.getBaseNamespacePath(fullName)
+      , ns = this.ns.resolveNamespace(nsPath);
+
+    pattern = this.pattern;
+    source = this.source;
+
+    if (typeof source == 'string') {
+      src = Matcher.getSource(name, pattern, source);
+    }
+    else {
+      src = source(name);
+    }
+
+    // TODO: Write a utility function that appends a
+    // taskname to a namespace path
+    src = nsPath.split(':').filter(function (item) {
+      return !!item;
+    }).concat(src).join(':');
+
+    // Generate the prerequisite for the matching task.
+    //    It is the original prerequisites plus the prerequisite
+    //    representing source file, i.e.,
+    //
+    //      rule( '%.o', '%.c', ['some.h'] ...
+    //
+    //    If the objective is main.o, then new task should be
+    //
+    //      file( 'main.o', ['main.c', 'some.h' ] ...
+    prereqs = this.prereqs.slice(); // Get a copy to work with
+    prereqs.unshift(src);
+
+    // Prereq should be:
+    // 1. an existing task
+    // 2. an existing file on disk
+    // 3. a valid rule (i.e., not at too deep a level)
+    valid = prereqs.some(function (p) {
+      var ns = self.ns;
+      return ns.resolveTask(p) ||
+        fs.existsSync(Task.getBaseTaskName(p)) ||
+        jake.attemptRule(p, ns, level + 1);
+    });
+
+    // If any of the prereqs aren't valid, the rule isn't valid
+    if (!valid) {
+      return null;
+    }
+    // Otherwise, hunky-dory, finish creating the task for the rule
+    else {
+      // Create the action for the task
+      action = function () {
+        var task = this;
+        self.action.apply(task);
+      };
+
+      opts = this.opts;
+
+      // Insert the file task into Jake
+      //
+      // Since createTask function stores the task as a child task
+      // of currentNamespace. Here we temporariliy switch the namespace.
+      // FIXME: Should allow optional ns passed in instead of this hack
+      tNs = jake.currentNamespace;
+      jake.currentNamespace = ns;
+      createdTask = jake.createTask('file', name, prereqs, action, opts);
+      createdTask.source = src.split(':').pop();
+      jake.currentNamespace = tNs;
+
+      return createdTask;
+    }
+
+  };
+
+  this.match = function (name) {
+    return Matcher.match(this.pattern, name);
+  };
+
+})();
+
+rule.Rule = Rule;
+rule.Matcher = Matcher;
+
+module.exports = rule;

+ 29 - 0
Build/node_modules/jake/lib/task/directory_task.js

@@ -0,0 +1,29 @@
+var DirectoryTask
+  , FileTask = require('./file_task').FileTask;
+
+/**
+  @name jake
+  @namespace jake
+*/
+/**
+  @name jake.DirectoryTask
+  @constructor
+  @augments EventEmitter
+  @augments jake.Task
+  @augments jake.FileTask
+  @description A Jake DirectoryTask
+
+  @param {String} name The name of the directory to create.
+ */
+DirectoryTask = function (name) {
+  this.modTime = null;
+  // Do constructor-work only on actual instances, not when used
+  // for inheritance
+  if (arguments.length) {
+    this.init.apply(this, arguments);
+  }
+};
+DirectoryTask.prototype = new FileTask();
+DirectoryTask.prototype.constructor = DirectoryTask;
+
+exports.DirectoryTask = DirectoryTask;

+ 136 - 0
Build/node_modules/jake/lib/task/file_task.js

@@ -0,0 +1,136 @@
+var fs = require('fs')
+  , Task = require('./task').Task
+  , FileTask
+  , FileBase
+  , DirectoryTask
+  , utils = require('../utils');
+
+FileBase = new (function () {
+  var isFileOrDirectory = function (t) {
+        return (t instanceof FileTask ||
+            t instanceof DirectoryTask);
+      }
+    , isFile = function (t) {
+        return (t instanceof FileTask && !(t instanceof DirectoryTask));
+      };
+
+  this.isNeeded = function () {
+    var runAction = false
+      , prereqs = this.prereqs
+      , prereqName
+      , prereqTask;
+
+    // No repeatsies
+    if (this.taskStatus === Task.runStatuses.DONE) {
+      return false;
+    }
+    // The always-make override
+    else if (jake.program.opts['always-make']) {
+      // Run if there actually is an action
+      if (typeof this.action == 'function') {
+        return true;
+      }
+      else {
+        return false;
+      }
+    }
+    // Default case
+    else {
+      // We need either an existing file, or an action to create one.
+      // First try grabbing the actual mod-time of the file
+      try {
+        this.updateModTime();
+      }
+      // Then fall back to looking for an action
+      catch(e) {
+        if (typeof this.action == 'function') {
+          return true;
+        }
+        else {
+          throw new Error('File-task ' + this.fullName + ' has no ' +
+            'existing file, and no action to create one.');
+        }
+      }
+
+      // Compare mod-time of all the prereqs with its mod-time
+      // If any prereqs are newer, need to run the action to update
+      if (prereqs && prereqs.length) {
+        for (var i = 0, ii = prereqs.length; i < ii; i++) {
+          prereqName = prereqs[i];
+          prereqTask = this.namespace.resolveTask(prereqName) ||
+            jake.createPlaceholderFileTask(prereqName, this.namespace);
+          // Run the action if:
+          // 1. The prereq is a normal task (not file/dir)
+          // 2. The prereq is a file-task with a mod-date more recent than
+          // the one for this file/dir
+          if (prereqTask) {
+            if (!isFileOrDirectory(prereqTask) ||
+                (isFile(prereqTask) && prereqTask.modTime > this.modTime)) {
+              return true;
+            }
+          }
+        }
+      }
+      // File/dir has no prereqs, and exists -- no need to run
+      else {
+        return false;
+      }
+    }
+  };
+
+  this.updateModTime = function () {
+    var stats = fs.statSync(this.name);
+    this.modTime = stats.mtime;
+  };
+
+  this.complete = function () {
+    jake._invocationChain.splice(jake._invocationChain.indexOf(this),1);
+    if (!this.dummy) {
+      this.updateModTime();
+    }
+    this._currentPrereqIndex = 0;
+    this.taskStatus = Task.runStatuses.DONE;
+    this.emit('complete');
+  };
+
+})();
+
+/**
+  @name jake
+  @namespace jake
+*/
+/**
+  @name jake.FileTask
+  @constructor
+  @augments EventEmitter
+  @augments jake.Task
+  @description A Jake FileTask
+
+  @param {String} name The name of the Task
+  @param {Array} [prereqs] Prerequisites to be run before this task
+  @param {Function} [action] The action to perform to create this file
+  @param {Object} [opts]
+    @param {Array} [opts.asyc=false] Perform this task asynchronously.
+    If you flag a task with this option, you must call the global
+    `complete` method inside the task's action, for execution to proceed
+    to the next task.
+ */
+FileTask = function (name, prereqs, action, opts) {
+  this.modTime = null;
+  this.dummy = false;
+  // Do constructor-work only on actual instances, not when used
+  // for inheritance
+  if (arguments.length) {
+    this.init.apply(this, arguments);
+  }
+};
+FileTask.prototype = new Task();
+FileTask.prototype.constructor = FileTask;
+utils.mixin(FileTask.prototype, FileBase);
+
+exports.FileTask = FileTask;
+
+// DirectoryTask is a subclass of FileTask, depends on it
+// being defined
+DirectoryTask = require('./directory_task').DirectoryTask;
+

+ 9 - 0
Build/node_modules/jake/lib/task/index.js

@@ -0,0 +1,9 @@
+
+var Task = require('./task').Task
+  , FileTask = require('./file_task').FileTask
+  , DirectoryTask = require('./directory_task').DirectoryTask;
+
+exports.Task = Task;
+exports.FileTask = FileTask;
+exports.DirectoryTask = DirectoryTask;
+

+ 314 - 0
Build/node_modules/jake/lib/task/task.js

@@ -0,0 +1,314 @@
+var util = require('util') // Native Node util module
+  , path = require('path')
+  , EventEmitter = require('events').EventEmitter
+  , Task
+  , TaskBase
+  , utils = require('../utils')
+  , async = require('async')
+  , rule; // Lazy-require this at the bottom
+
+var UNDEFINED_VALUE;
+
+/**
+  @name jake
+  @namespace jake
+*/
+/**
+  @name jake.Task
+  @constructor
+  @augments EventEmitter
+  @description A Jake Task
+
+  @param {String} name The name of the Task
+  @param {Array} [prereqs] Prerequisites to be run before this task
+  @param {Function} [action] The action to perform for this task
+  @param {Object} [opts]
+    @param {Array} [opts.asyc=false] Perform this task asynchronously.
+    If you flag a task with this option, you must call the global
+    `complete` method inside the task's action, for execution to proceed
+    to the next task.
+ */
+Task = function () {
+  // Do constructor-work only on actual instances, not when used
+  // for inheritance
+  if (arguments.length) {
+    this.init.apply(this, arguments);
+  }
+};
+
+util.inherits(Task, EventEmitter);
+
+TaskBase = new (function () {
+
+  // Parse any positional args attached to the task-name
+  var parsePrereqName = function (name) {
+        var taskArr = name.split('[')
+          , taskName = taskArr[0]
+          , taskArgs = [];
+        if (taskArr[1]) {
+          taskArgs = taskArr[1].replace(/\]$/, '');
+          taskArgs = taskArgs.split(',');
+        }
+        return {
+          name: taskName
+        , args: taskArgs
+        };
+      };
+
+  /**
+    @name jake.Task#event:complete
+    @event
+   */
+
+  this.init = function (name, prereqs, action, options) {
+    var opts = options || {};
+
+    this._currentPrereqIndex = 0;
+
+    this.name = name;
+    this.prereqs = prereqs;
+    this.action = action;
+    this.async = false;
+    this.taskStatus = Task.runStatuses.UNSTARTED;
+    this.fullName = null;
+    this.description = null;
+    this.args = [];
+    this.value = UNDEFINED_VALUE;
+    this.namespace = null;
+    this.parallelLimit = 1;
+
+    // Support legacy async-flag -- if not explicitly passed or falsy, will
+    // be set to empty-object
+    if (typeof opts == 'boolean' && opts === true) {
+      this.async = true;
+    }
+    else {
+      if (opts.async) {
+        this.async = true;
+      }
+      if (opts.parallelLimit) {
+        this.parallelLimit = opts.parallelLimit;
+      }
+    }
+  };
+
+  /**
+    @name jake.Task#invoke
+    @function
+    @description Runs prerequisites, then this task. If the task has already
+    been run, will not run the task again.
+   */
+  this.invoke = function () {
+    jake._invocationChain.push(this);
+    this.args = Array.prototype.slice.call(arguments);
+    this.runPrereqs();
+  };
+
+  /**
+    @name jake.Task#execute
+    @function
+    @description Runs prerequisites, then this task. If the task has already
+    been run, will not run the task again.
+   */
+  this.execute = function () {
+    jake._invocationChain.push(this);
+    this.args = Array.prototype.slice.call(arguments);
+    this.reenable();
+    this.run();
+  };
+
+  this.runPrereqs = function () {
+    if (this.prereqs && this.prereqs.length) {
+      if(this.parallelLimit > 1) {
+        var currenttask = this;
+        async.eachLimit(currenttask.prereqs,currenttask.parallelLimit,function(name, cb) {
+
+          var parsed = parsePrereqName(name);
+
+          var prereq = currenttask.namespace.resolveTask(parsed.name) ||
+          jake.attemptRule(name, currenttask.namespace, 0) ||
+          jake.createPlaceholderFileTask(name, currenttask.namespace);
+
+          if (!prereq) {
+            throw new Error('Unknown task "' + name + '"');
+          }
+
+          if (prereq.taskStatus === Task.runStatuses.DONE) {
+            //prereq already done, return
+            cb();
+          } else {
+            //wait for complete before calling cb
+            prereq.once('complete', function () {
+              cb();
+            });
+            //start te prereq if we are the first to encounter it
+            if(prereq.taskStatus === Task.runStatuses.UNSTARTED) {
+              prereq.taskStatus = Task.runStatuses.RUNNING;
+              prereq.invoke.apply(prereq, parsed.args);
+            }
+          }
+        }, function(err) {
+          //async callback is called after all prereqs have run.
+          currenttask.run();
+        });
+      } else {
+        this.nextPrereq();
+      }
+    }
+    else {
+      this.run();
+    }
+  };
+
+  this.nextPrereq = function () {
+    var self = this
+      , index = this._currentPrereqIndex
+      , name = this.prereqs[index]
+      , prereq
+      , parsed
+      , filePath
+      , stats;
+
+    if (name) {
+
+      parsed = parsePrereqName(name);
+
+      prereq = this.namespace.resolveTask(parsed.name) ||
+          jake.attemptRule(name, this.namespace, 0) ||
+          jake.createPlaceholderFileTask(name, this.namespace);
+
+      if (!prereq) {
+        throw new Error('Unknown task "' + name + '"');
+      }
+
+      // Do when done
+      if (prereq.taskStatus === Task.runStatuses.DONE) {
+        self.handlePrereqComplete(prereq);
+      } else {
+        prereq.once('complete', function () {
+          self.handlePrereqComplete(prereq);
+        });
+        if(prereq.taskStatus === Task.runStatuses.UNSTARTED) {
+           prereq.taskStatus = Task.runStatuses.RUNNING;
+           prereq.invoke.apply(prereq, parsed.args);
+        }
+      }
+    }
+  };
+
+  /**
+    @name jake.Task#reenable
+    @function
+    @description Reenables a task so that it can be run again.
+   */
+  this.reenable = function (deep) {
+    var prereqs
+      , prereq;
+    this.taskStatus = Task.runStatuses.UNSTARTED;
+    this.value = UNDEFINED_VALUE;
+    if (deep && this.prereqs) {
+      prereqs = this.prereqs;
+      for (var i = 0, ii = prereqs.length; i < ii; i++) {
+        prereq = jake.Task[prereqs[i]];
+        if (prereq) {
+          prereq.reenable(deep);
+        }
+      }
+    }
+  };
+
+  this.handlePrereqComplete = function (prereq) {
+    var self = this;
+    this._currentPrereqIndex++;
+    if (this._currentPrereqIndex < this.prereqs.length) {
+      setTimeout(function () {
+        self.nextPrereq();
+      }, 0);
+    }
+    else {
+      this.run();
+    }
+  };
+
+  this.isNeeded = function () {
+    if (this.taskStatus === Task.runStatuses.DONE || typeof this.action != 'function') {
+      return false;
+    }
+    return true;
+  };
+
+  this.run = function () {
+    var runAction = this.isNeeded()
+      , val;
+
+    if (runAction) {
+      this.emit('start');
+      try {
+        val = this.action.apply(this, this.args);
+
+        if (typeof val == 'object' && typeof val.then == 'function') {
+          this.async = true;
+
+          val.then(
+            function(result) {
+              setTimeout(function() {
+                  complete(result);
+                },
+                0);
+            },
+            function(err) {
+              setTimeout(function() {
+                  fail(err);
+                },
+                0);
+            });
+        }
+      }
+      catch (e) {
+        this.emit('error', e);
+        return; // Bail out, not complete
+      }
+    }
+    else {
+      this.emit('skip');
+    }
+
+    if (!(runAction && this.async)) {
+      this.complete(val);
+    }
+  };
+
+  this.complete = function (val) {
+    jake._invocationChain.splice(jake._invocationChain.indexOf(this),1);
+
+    this._currentPrereqIndex = 0;
+    this.taskStatus = Task.runStatuses.DONE;
+
+    // If 'complete' getting called because task has been
+    // run already, value will not be passed -- leave in place
+    if (typeof val != 'undefined') {
+      this.value = val;
+    }
+
+    this.emit('complete', this.value);
+  };
+
+})();
+utils.mixin(Task.prototype, TaskBase);
+
+Task.getBaseNamespacePath = function (fullName) {
+  return fullName.split(':').slice(0, -1).join(':');
+};
+
+Task.getBaseTaskName = function (fullName) {
+  return fullName.split(':').pop();
+};
+
+//The task is in one of three states
+Task.runStatuses = {UNSTARTED: 'unstarted', DONE: 'done', STARTED: 'started'};
+
+exports.Task = Task;
+
+// Lazy-require
+rule = require('../rule');
+

+ 277 - 0
Build/node_modules/jake/lib/test_task.js

@@ -0,0 +1,277 @@
+/*
+ * Jake JavaScript build tool
+ * Copyright 2112 Matthew Eernisse ([email protected])
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+
+var path = require('path')
+  , fs = require('fs')
+  , exec = require('child_process').exec
+  , currDir = process.cwd();
+
+/**
+  @name jake
+  @namespace jake
+*/
+/**
+  @name jake.TestTask
+  @constructor
+  @description Instantiating a TestTask creates a number of Jake
+  Tasks that make running tests for your software easy.
+
+  @param {String} name The name of the project
+  @param {Function} definition Defines the list of files containing the tests,
+  and the name of the namespace/task for running them. Will be executed on the
+  instantiated TestTask (i.e., 'this', will be the TestTask instance), to set
+  the various instance-propertiess.
+
+  @example
+  var t = new jake.TestTask('bij-js', function () {
+    this.testName = 'testSpecial';
+    this.testFiles.include('test/**');
+  });
+
+ */
+var TestTask = function () {
+  var self = this
+    , args = Array.prototype.slice.call(arguments)
+    , name = args.shift()
+    , definition = args.pop()
+    , prereqs = args.pop() || [];
+
+  /**
+    @name jake.TestTask#testNam
+    @public
+    @type {String}
+    @description The name of the namespace to place the tests in, and
+    the top-level task for running tests. Defaults to "test"
+   */
+  this.testName = 'test';
+
+  /**
+    @name jake.TestTask#testFiles
+    @public
+    @type {jake.FileList}
+    @description The list of files containing tests to load
+   */
+  this.testFiles = new jake.FileList();
+
+  /**
+    @name jake.TestTask#showDescription
+    @public
+    @type {Boolean}
+    @description Show the created task when doing Jake -T
+   */
+  this.showDescription = true;
+
+  /*
+    @name jake.TestTask#totalTests
+    @public
+    @type {Number}
+    @description The total number of tests to run
+  */
+  this.totalTests = 0;
+
+  /*
+    @name jake.TestTask#executedTests
+    @public
+    @type {Number}
+    @description The number of tests successfully run
+  */
+  this.executedTests = 0;
+
+  if (typeof definition == 'function') {
+    definition.call(this);
+  }
+
+  if (this.showDescription) {
+    desc('Run the tests for ' + name);
+  }
+
+  task(this.testName, prereqs, {async: true}, function () {
+    var t = jake.Task[self.testName + ':run'];
+    t.on('complete', function () {
+      complete();
+    });
+    // Pass args to the namespaced test
+    t.invoke.apply(t, arguments);
+  });
+
+  namespace(self.testName, function () {
+
+    task('run', {async: true}, function (pat) {
+      var p = pat || '.*'
+        , re
+        , testFiles;
+
+      // Don't nest; make a top-level namespace. Don't want
+      // re-calling from inside to nest infinitely
+     jake.currentNamespace = jake.defaultNamespace;
+
+      re = new RegExp(pat);
+      // Get test files that match the passed-in pattern
+      testFiles = self.testFiles.toArray()
+          .filter(function (f) {
+        return (re).test(f);
+      }) // Don't load the same file multiple times -- should this be in FileList?
+          .reduce(function(p, c) {
+        if (p.indexOf(c) < 0) {
+          p.push(c);
+        }
+        return p;
+      }, []);
+
+      // Create a namespace for all the testing tasks to live in
+      namespace(self.testName + 'Exec', function () {
+        // Each test will be a prereq for the dummy top-level task
+        var prereqs = []
+        // Continuation to pass to the async tests, wrapping `continune`
+          , next = function () {
+              complete();
+            }
+        // Create the task for this test-function
+          , createTask = function (name, action) {
+              // If the test-function is defined with a continuation
+              // param, flag the task as async
+              var t
+                , isAsync = !!action.length;
+
+              // Define the actual namespaced task with the name, the
+              // wrapped action, and the correc async-flag
+              t = task(name, createAction(name, action), {
+                async: isAsync
+              });
+              t.once('complete', function () {
+                self.executedTests++;
+              });
+            }
+        // Used as the action for the defined task for each test.
+          , createAction = function (n, a) {
+              // A wrapped function that passes in the `next` function
+              // for any tasks that run asynchronously
+              return function () {
+                var cb
+                  , msg;
+                if (a.length) {
+                  cb = next;
+                }
+                if (!(n == 'before' || n == 'after' ||
+                    /_beforeEach$/.test(n) || /_afterEach$/.test(n))) {
+                  if (n.toLowerCase().indexOf('test') === 0) {
+                    msg = n;
+                  }
+                  else {
+                    msg = 'test ' + n;
+                  }
+                  jake.logger.log(n);
+                }
+                // 'this' will be the task when action is run
+                return a.call(this, cb);
+              };
+            }
+          // Dummy top-level task for everything to be prereqs for
+          , topLevel;
+
+        // Pull in each test-file, and iterate over any exported
+        // test-functions. Register each test-function as a prereq task
+        testFiles.forEach(function (file) {
+          var exp = require(path.join(currDir, file))
+            , name
+            , action
+            , isAsync;
+
+          // Create a namespace for each filename, so test-name collisions
+          // won't be a problem
+          namespace(file, function () {
+            var testPrefix = self.testName + 'Exec:' + file + ':'
+              , testName;
+            // Dummy task for displaying file banner
+            testName = '*** Running ' + file + ' ***';
+            prereqs.push(testPrefix + testName);
+            createTask(testName, function () {});
+
+            // 'before' setup
+            if (typeof exp.before == 'function') {
+              prereqs.push(testPrefix + 'before');
+              // Create the task
+              createTask('before', exp.before);
+            }
+
+            // Walk each exported function, and create a task for each
+            for (var p in exp) {
+              if (p == 'before' || p == 'after' ||
+                  p == 'beforeEach' || p == 'afterEach') {
+                continue;
+              }
+
+              if (typeof exp.beforeEach == 'function') {
+                prereqs.push(testPrefix + p + '_beforeEach');
+                // Create the task
+                createTask(p + '_beforeEach', exp.beforeEach);
+              }
+
+              // Add the namespace:name of this test to the list of prereqs
+              // for the dummy top-level task
+              prereqs.push(testPrefix + p);
+              // Create the task
+              createTask(p, exp[p]);
+
+              if (typeof exp.afterEach == 'function') {
+                prereqs.push(testPrefix + p + '_afterEach');
+                // Create the task
+                createTask(p + '_afterEach', exp.afterEach);
+              }
+            }
+
+            // 'after' teardown
+            if (typeof exp.after == 'function') {
+              prereqs.push(testPrefix + 'after');
+              // Create the task
+              createTask('after', exp.after);
+            }
+
+          });
+        });
+
+        self.totalTests = prereqs.length;
+        process.on('exit', function () {
+          // Throw in the case where the process exits without
+          // finishing tests, but no error was thrown
+          if (!jake.errorCode && (self.totalTests > self.executedTests)) {
+            throw new Error('Process exited without all tests completing.');
+          }
+        });
+
+        // Create the dummy top-level task. When calling a task internally
+        // with `invoke` that is async (or has async prereqs), have to listen
+        // for the 'complete' event to know when it's done
+        topLevel = task('__top__', prereqs);
+        topLevel.addListener('complete', function () {
+          jake.logger.log('All tests ran successfully');
+          complete();
+        });
+
+        topLevel.invoke(); // Do the thing!
+      });
+
+    });
+  });
+
+
+};
+
+jake.TestTask = TestTask;
+exports.TestTask = TestTask;
+

+ 258 - 0
Build/node_modules/jake/lib/utils/index.js

@@ -0,0 +1,258 @@
+/*
+ * Jake JavaScript build tool
+ * Copyright 2112 Matthew Eernisse ([email protected])
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+
+
+var util = require('util') // Native Node util module
+  , exec = require('child_process').exec
+  , spawn = require('child_process').spawn
+  , EventEmitter = require('events').EventEmitter
+  , utils = require('utilities')
+  , logger = require('./logger')
+  , Exec;
+
+var parseArgs = function (argumentsObj) {
+    var args
+      , arg
+      , cmds
+      , callback
+      , opts = {
+          interactive: false
+        , printStdout: false
+        , printStderr: false
+        , breakOnError: true
+        };
+
+    args = Array.prototype.slice.call(argumentsObj);
+
+    cmds = args.shift();
+    // Arrayize if passed a single string command
+    if (typeof cmds == 'string') {
+      cmds = [cmds];
+    }
+    // Make a copy if it's an actual list
+    else {
+      cmds = cmds.slice();
+    }
+
+    // Get optional callback or opts
+    while((arg = args.shift())) {
+      if (typeof arg == 'function') {
+        callback = arg;
+      }
+      else if (typeof arg == 'object') {
+        utils.mixin(opts, arg);
+      }
+    }
+
+    // Backward-compat shim
+    if (typeof opts.stdout != 'undefined') {
+      opts.printStdout = opts.stdout;
+      delete opts.stdout;
+    }
+    if (typeof opts.stderr != 'undefined') {
+      opts.printStderr = opts.stderr;
+      delete opts.stderr;
+    }
+
+    return {
+      cmds: cmds
+    , opts: opts
+    , callback: callback
+    };
+};
+
+/**
+  @name jake
+  @namespace jake
+*/
+utils.mixin(utils, new (function () {
+  /**
+    @name jake.exec
+    @static
+    @function
+    @description Executes shell-commands asynchronously with an optional
+    final callback.
+    `
+    @param {String[]} cmds The list of shell-commands to execute
+    @param {Object} [opts]
+      @param {Boolean} [opts.printStdout=false] Print stdout from each command
+      @param {Boolean} [opts.printStderr=false] Print stderr from each command
+      @param {Boolean} [opts.breakOnError=true] Stop further execution on
+      the first error.
+      @param {Boolean} [opts.windowsVerbatimArguments=false] Don't translate
+      arguments on Windows.
+    @param {Function} [callback] Callback to run after executing  the
+    commands
+
+    @example
+    var cmds = [
+          'echo "showing directories"'
+        , 'ls -al | grep ^d'
+        , 'echo "moving up a directory"'
+        , 'cd ../'
+        ]
+      , callback = function () {
+          console.log('Finished running commands.');
+        }
+    jake.exec(cmds, {stdout: true}, callback);
+   */
+  this.exec = function (a, b, c) {
+    var parsed = parseArgs(arguments)
+      , cmds = parsed.cmds
+      , opts = parsed.opts
+      , callback = parsed.callback;
+
+    var ex = new Exec(cmds, opts, callback);
+
+    ex.addListener('error', function (msg, code) {
+      if (opts.breakOnError) {
+        fail(msg, code);
+      }
+    });
+    ex.run();
+
+    return ex;
+  };
+
+  this.createExec = function (a, b, c) {
+    return new Exec(a, b, c);
+  };
+
+})());
+
+Exec = function () {
+  var parsed = parseArgs(arguments)
+    , cmds = parsed.cmds
+    , opts = parsed.opts
+    , callback = parsed.callback;
+
+  this._cmds = cmds;
+  this._callback = callback;
+  this._config = opts;
+};
+
+util.inherits(Exec, EventEmitter);
+
+utils.mixin(Exec.prototype, new (function () {
+
+  var _run = function () {
+        var self = this
+          , sh
+          , cmd
+          , args
+          , next = this._cmds.shift()
+          , config = this._config
+          , errData = ''
+          , shStdio
+          , handleStdoutData = function (data) {
+              self.emit('stdout', data);
+            }
+          , handleStderrData = function (data) {
+              var d = data.toString();
+              self.emit('stderr', data);
+              // Accumulate the error-data so we can use it as the
+              // stack if the process exits with an error
+              errData += d;
+            };
+
+        // Keep running as long as there are commands in the array
+        if (next) {
+          var spawnOpts = {};
+          this.emit('cmdStart', next);
+
+          // Ganking part of Node's child_process.exec to get cmdline args parsed
+          if (process.platform == 'win32') {
+            cmd = 'cmd';
+            args = ['/c', next];
+            if (config.windowsVerbatimArguments) {
+              spawnOpts.windowsVerbatimArguments = true;
+            }
+          }
+          else {
+            cmd = '/bin/sh';
+            args = ['-c', next];
+          }
+
+          if (config.interactive) {
+            spawnOpts.stdio = 'inherit';
+            sh = spawn(cmd, args, spawnOpts);
+          }
+          else {
+            shStdio = [
+              process.stdin
+            ];
+            if (config.printStdout) {
+              shStdio.push(process.stdout);
+            }
+            else {
+              shStdio.push('pipe');
+            }
+            if (config.printStderr) {
+              shStdio.push(process.stderr);
+            }
+            else {
+              shStdio.push('pipe');
+            }
+            spawnOpts.stdio = shStdio;
+            sh = spawn(cmd, args, spawnOpts);
+            if (!config.printStdout) {
+              sh.stdout.addListener('data', handleStdoutData);
+            }
+            if (!config.printStderr) {
+              sh.stderr.addListener('data', handleStderrData);
+            }
+          }
+
+          // Exit, handle err or run next
+          sh.on('exit', function (code) {
+            var msg;
+            if (code !== 0) {
+              msg = errData || 'Process exited with error.';
+              msg = utils.string.trim(msg);
+              self.emit('error', msg, code);
+            }
+            if (code === 0 || !config.breakOnError) {
+              self.emit('cmdEnd', next);
+              setTimeout(function () { _run.call(self); }, 0);
+            }
+          });
+
+        }
+        else {
+          self.emit('end');
+          if (typeof self._callback == 'function') {
+            self._callback();
+          }
+        }
+      };
+
+  this.append = function (cmd) {
+    this._cmds.push(cmd);
+  };
+
+  this.run = function () {
+    _run.call(this);
+  };
+
+})());
+
+utils.Exec = Exec;
+utils.logger = logger;
+
+module.exports = utils;
+

+ 24 - 0
Build/node_modules/jake/lib/utils/logger.js

@@ -0,0 +1,24 @@
+var util = require('util');
+
+var logger = new (function () {
+  var _output = function (type, out) {
+    var quiet = typeof jake != 'undefined' && jake.program &&
+        jake.program.opts && jake.program.opts.quiet
+      , msg;
+    if (!quiet) {
+      msg = typeof out == 'string' ? out : util.inspect(out);
+      console[type](msg);
+    }
+  };
+
+  this.log = function (out) {
+    _output('log', out);
+  };
+
+  this.error = function (out) {
+    _output('error', out);
+  };
+
+})();
+
+module.exports = logger;

+ 99 - 0
Build/node_modules/jake/lib/watch_task.js

@@ -0,0 +1,99 @@
+var fs = require('fs')
+  , FileList = require('filelist').FileList;
+
+var THROTTLE = 5000;
+
+/**
+  @name WatchTask
+  @constructor
+  @description  Watches specified files for changes, and runs a
+      set of tasks each time there's a change
+  @param {String} [name] Name of the WatchTask -- defaults to 'watch'
+      if not specified
+  @param {Array} taskNames The list of tasks to run with each change
+  @param {Function} definition Function to set up the WatchTask --
+      invoked on `this` after the initial construction
+*/
+var WatchTask = function () {
+  var self = this
+    , args = Array.prototype.slice.call(arguments)
+    , arg
+    , definition
+    , taskNames
+    , name
+    , last = (new Date()).getTime() - THROTTLE;
+
+  args = args.filter(function (a) {
+    return !!a;
+  });
+
+  while ((arg = args.shift())) {
+    if (typeof arg == 'string') {
+      name = arg;
+    }
+    else if (typeof arg == 'object' && Array.isArray(arg)) {
+      taskNames = arg;
+    }
+    else if (typeof arg == 'function') {
+      definition = arg;
+    }
+  }
+
+  if (!(taskNames && taskNames.length)) {
+    throw new Error('Watch task needs some tasks to run');
+  }
+
+  name = name || 'watch';
+  definition = definition || function () {};
+
+  if (jake.Task[name]) {
+    throw new Error('WatchTask named "' + name + '" already exists. ' +
+      'Please use a different name.');
+  }
+
+  this.watchTasks = Array.isArray(taskNames) ? taskNames : [taskNames];
+  this.watchFiles = new FileList();
+  this.rootTask = task('watchTasks', this.watchTasks);
+  this.throttle = THROTTLE;
+
+  this.watchFiles.include(WatchTask.DEFAULT_INCLUDE_FILES);
+  this.watchFiles.exclude(WatchTask.DEFAULT_EXCLUDE_FILES);
+
+  if (typeof definition == 'function') {
+    definition.call(this);
+  }
+
+  desc('Runs these tasks: ' + this.watchTasks.join(', '));
+  task(name, function () {
+    console.log('WatchTask started for: ' + self.watchTasks.join(', '));
+    jake.watch('.', {includePattern: /.+/}, function (filePath) {
+      var fileMatch = self.watchFiles.toArray().some(function (item) {
+        return item == filePath;
+      });
+      if (fileMatch && ((new Date()).getTime() - last) > self.throttle) {
+        last = (new Date()).getTime();
+        self.rootTask.reenable(true);
+        self.rootTask.invoke();
+      }
+    });
+  });
+};
+
+WatchTask.DEFAULT_INCLUDE_FILES = [
+  './**/*.js'
+, './**/*.coffee'
+, './**/*.css'
+, './**/*.less'
+, './**/*.scss'
+];
+
+WatchTask.DEFAULT_EXCLUDE_FILES = [];
+if (fs.existsSync('node_modules')) {
+  WatchTask.DEFAULT_EXCLUDE_FILES.push('node_modules/**');
+}
+if (fs.existsSync('.git')) {
+  WatchTask.DEFAULT_EXCLUDE_FILES.push('.git/**');
+}
+
+exports.WatchTask = WatchTask;
+

+ 5 - 0
Build/node_modules/jake/node_modules/async/.travis.yml

@@ -0,0 +1,5 @@
+language: node_js
+node_js:
+  - "0.10"
+  - "0.12"
+  - "iojs"

+ 19 - 0
Build/node_modules/jake/node_modules/async/LICENSE

@@ -0,0 +1,19 @@
+Copyright (c) 2010-2014 Caolan McMahon
+
+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.

+ 1647 - 0
Build/node_modules/jake/node_modules/async/README.md

@@ -0,0 +1,1647 @@
+# Async.js
+
+[![Build Status via Travis CI](https://travis-ci.org/caolan/async.svg?branch=master)](https://travis-ci.org/caolan/async)
+
+
+Async is a utility module which provides straight-forward, powerful functions
+for working with asynchronous JavaScript. Although originally designed for
+use with [Node.js](http://nodejs.org) and installable via `npm install async`,
+it can also be used directly in the browser.
+
+Async is also installable via:
+
+- [bower](http://bower.io/): `bower install async`
+- [component](https://github.com/component/component): `component install
+  caolan/async`
+- [jam](http://jamjs.org/): `jam install async`
+- [spm](http://spmjs.io/): `spm install async`
+
+Async provides around 20 functions that include the usual 'functional'
+suspects (`map`, `reduce`, `filter`, `each`…) as well as some common patterns
+for asynchronous control flow (`parallel`, `series`, `waterfall`…). All these
+functions assume you follow the Node.js convention of providing a single
+callback as the last argument of your `async` function.
+
+
+## Quick Examples
+
+```javascript
+async.map(['file1','file2','file3'], fs.stat, function(err, results){
+    // results is now an array of stats for each file
+});
+
+async.filter(['file1','file2','file3'], fs.exists, function(results){
+    // results now equals an array of the existing files
+});
+
+async.parallel([
+    function(){ ... },
+    function(){ ... }
+], callback);
+
+async.series([
+    function(){ ... },
+    function(){ ... }
+]);
+```
+
+There are many more functions available so take a look at the docs below for a
+full list. This module aims to be comprehensive, so if you feel anything is
+missing please create a GitHub issue for it.
+
+## Common Pitfalls
+
+### Binding a context to an iterator
+
+This section is really about `bind`, not about `async`. If you are wondering how to
+make `async` execute your iterators in a given context, or are confused as to why
+a method of another library isn't working as an iterator, study this example:
+
+```js
+// Here is a simple object with an (unnecessarily roundabout) squaring method
+var AsyncSquaringLibrary = {
+  squareExponent: 2,
+  square: function(number, callback){ 
+    var result = Math.pow(number, this.squareExponent);
+    setTimeout(function(){
+      callback(null, result);
+    }, 200);
+  }
+};
+
+async.map([1, 2, 3], AsyncSquaringLibrary.square, function(err, result){
+  // result is [NaN, NaN, NaN]
+  // This fails because the `this.squareExponent` expression in the square
+  // function is not evaluated in the context of AsyncSquaringLibrary, and is
+  // therefore undefined.
+});
+
+async.map([1, 2, 3], AsyncSquaringLibrary.square.bind(AsyncSquaringLibrary), function(err, result){
+  // result is [1, 4, 9]
+  // With the help of bind we can attach a context to the iterator before
+  // passing it to async. Now the square function will be executed in its 
+  // 'home' AsyncSquaringLibrary context and the value of `this.squareExponent`
+  // will be as expected.
+});
+```
+
+## Download
+
+The source is available for download from
+[GitHub](http://github.com/caolan/async).
+Alternatively, you can install using Node Package Manager (`npm`):
+
+    npm install async
+
+__Development:__ [async.js](https://github.com/caolan/async/raw/master/lib/async.js) - 29.6kb Uncompressed
+
+## In the Browser
+
+So far it's been tested in IE6, IE7, IE8, FF3.6 and Chrome 5. 
+
+Usage:
+
+```html
+<script type="text/javascript" src="async.js"></script>
+<script type="text/javascript">
+
+    async.map(data, asyncProcess, function(err, results){
+        alert(results);
+    });
+
+</script>
+```
+
+## Documentation
+
+### Collections
+
+* [`each`](#each)
+* [`eachSeries`](#eachSeries)
+* [`eachLimit`](#eachLimit)
+* [`map`](#map)
+* [`mapSeries`](#mapSeries)
+* [`mapLimit`](#mapLimit)
+* [`filter`](#filter)
+* [`filterSeries`](#filterSeries)
+* [`reject`](#reject)
+* [`rejectSeries`](#rejectSeries)
+* [`reduce`](#reduce)
+* [`reduceRight`](#reduceRight)
+* [`detect`](#detect)
+* [`detectSeries`](#detectSeries)
+* [`sortBy`](#sortBy)
+* [`some`](#some)
+* [`every`](#every)
+* [`concat`](#concat)
+* [`concatSeries`](#concatSeries)
+
+### Control Flow
+
+* [`series`](#seriestasks-callback)
+* [`parallel`](#parallel)
+* [`parallelLimit`](#parallellimittasks-limit-callback)
+* [`whilst`](#whilst)
+* [`doWhilst`](#doWhilst)
+* [`until`](#until)
+* [`doUntil`](#doUntil)
+* [`forever`](#forever)
+* [`waterfall`](#waterfall)
+* [`compose`](#compose)
+* [`seq`](#seq)
+* [`applyEach`](#applyEach)
+* [`applyEachSeries`](#applyEachSeries)
+* [`queue`](#queue)
+* [`priorityQueue`](#priorityQueue)
+* [`cargo`](#cargo)
+* [`auto`](#auto)
+* [`retry`](#retry)
+* [`iterator`](#iterator)
+* [`apply`](#apply)
+* [`nextTick`](#nextTick)
+* [`times`](#times)
+* [`timesSeries`](#timesSeries)
+
+### Utils
+
+* [`memoize`](#memoize)
+* [`unmemoize`](#unmemoize)
+* [`log`](#log)
+* [`dir`](#dir)
+* [`noConflict`](#noConflict)
+
+
+## Collections
+
+<a name="forEach" />
+<a name="each" />
+### each(arr, iterator, callback)
+
+Applies the function `iterator` to each item in `arr`, in parallel.
+The `iterator` is called with an item from the list, and a callback for when it
+has finished. If the `iterator` passes an error to its `callback`, the main
+`callback` (for the `each` function) is immediately called with the error.
+
+Note, that since this function applies `iterator` to each item in parallel,
+there is no guarantee that the iterator functions will complete in order.
+
+__Arguments__
+
+* `arr` - An array to iterate over.
+* `iterator(item, callback)` - A function to apply to each item in `arr`.
+  The iterator is passed a `callback(err)` which must be called once it has 
+  completed. If no error has occurred, the `callback` should be run without 
+  arguments or with an explicit `null` argument.
+* `callback(err)` - A callback which is called when all `iterator` functions
+  have finished, or an error occurs.
+
+__Examples__
+
+
+```js
+// assuming openFiles is an array of file names and saveFile is a function
+// to save the modified contents of that file:
+
+async.each(openFiles, saveFile, function(err){
+    // if any of the saves produced an error, err would equal that error
+});
+```
+
+```js
+// assuming openFiles is an array of file names 
+
+async.each(openFiles, function(file, callback) {
+  
+  // Perform operation on file here.
+  console.log('Processing file ' + file);
+  
+  if( file.length > 32 ) {
+    console.log('This file name is too long');
+    callback('File name too long');
+  } else {
+    // Do work to process file here
+    console.log('File processed');
+    callback();
+  }
+}, function(err){
+    // if any of the file processing produced an error, err would equal that error
+    if( err ) {
+      // One of the iterations produced an error.
+      // All processing will now stop.
+      console.log('A file failed to process');
+    } else {
+      console.log('All files have been processed successfully');
+    }
+});
+```
+
+---------------------------------------
+
+<a name="forEachSeries" />
+<a name="eachSeries" />
+### eachSeries(arr, iterator, callback)
+
+The same as [`each`](#each), only `iterator` is applied to each item in `arr` in
+series. The next `iterator` is only called once the current one has completed. 
+This means the `iterator` functions will complete in order.
+
+
+---------------------------------------
+
+<a name="forEachLimit" />
+<a name="eachLimit" />
+### eachLimit(arr, limit, iterator, callback)
+
+The same as [`each`](#each), only no more than `limit` `iterator`s will be simultaneously 
+running at any time.
+
+Note that the items in `arr` are not processed in batches, so there is no guarantee that 
+the first `limit` `iterator` functions will complete before any others are started.
+
+__Arguments__
+
+* `arr` - An array to iterate over.
+* `limit` - The maximum number of `iterator`s to run at any time.
+* `iterator(item, callback)` - A function to apply to each item in `arr`.
+  The iterator is passed a `callback(err)` which must be called once it has 
+  completed. If no error has occurred, the callback should be run without 
+  arguments or with an explicit `null` argument.
+* `callback(err)` - A callback which is called when all `iterator` functions
+  have finished, or an error occurs.
+
+__Example__
+
+```js
+// Assume documents is an array of JSON objects and requestApi is a
+// function that interacts with a rate-limited REST api.
+
+async.eachLimit(documents, 20, requestApi, function(err){
+    // if any of the saves produced an error, err would equal that error
+});
+```
+
+---------------------------------------
+
+<a name="map" />
+### map(arr, iterator, callback)
+
+Produces a new array of values by mapping each value in `arr` through
+the `iterator` function. The `iterator` is called with an item from `arr` and a
+callback for when it has finished processing. Each of these callback takes 2 arguments: 
+an `error`, and the transformed item from `arr`. If `iterator` passes an error to his 
+callback, the main `callback` (for the `map` function) is immediately called with the error.
+
+Note, that since this function applies the `iterator` to each item in parallel,
+there is no guarantee that the `iterator` functions will complete in order. 
+However, the results array will be in the same order as the original `arr`.
+
+__Arguments__
+
+* `arr` - An array to iterate over.
+* `iterator(item, callback)` - A function to apply to each item in `arr`.
+  The iterator is passed a `callback(err, transformed)` which must be called once 
+  it has completed with an error (which can be `null`) and a transformed item.
+* `callback(err, results)` - A callback which is called when all `iterator`
+  functions have finished, or an error occurs. Results is an array of the
+  transformed items from the `arr`.
+
+__Example__
+
+```js
+async.map(['file1','file2','file3'], fs.stat, function(err, results){
+    // results is now an array of stats for each file
+});
+```
+
+---------------------------------------
+
+<a name="mapSeries" />
+### mapSeries(arr, iterator, callback)
+
+The same as [`map`](#map), only the `iterator` is applied to each item in `arr` in
+series. The next `iterator` is only called once the current one has completed. 
+The results array will be in the same order as the original.
+
+
+---------------------------------------
+
+<a name="mapLimit" />
+### mapLimit(arr, limit, iterator, callback)
+
+The same as [`map`](#map), only no more than `limit` `iterator`s will be simultaneously 
+running at any time.
+
+Note that the items are not processed in batches, so there is no guarantee that 
+the first `limit` `iterator` functions will complete before any others are started.
+
+__Arguments__
+
+* `arr` - An array to iterate over.
+* `limit` - The maximum number of `iterator`s to run at any time.
+* `iterator(item, callback)` - A function to apply to each item in `arr`.
+  The iterator is passed a `callback(err, transformed)` which must be called once 
+  it has completed with an error (which can be `null`) and a transformed item.
+* `callback(err, results)` - A callback which is called when all `iterator`
+  calls have finished, or an error occurs. The result is an array of the
+  transformed items from the original `arr`.
+
+__Example__
+
+```js
+async.mapLimit(['file1','file2','file3'], 1, fs.stat, function(err, results){
+    // results is now an array of stats for each file
+});
+```
+
+---------------------------------------
+
+<a name="select" />
+<a name="filter" />
+### filter(arr, iterator, callback)
+
+__Alias:__ `select`
+
+Returns a new array of all the values in `arr` which pass an async truth test.
+_The callback for each `iterator` call only accepts a single argument of `true` or
+`false`; it does not accept an error argument first!_ This is in-line with the
+way node libraries work with truth tests like `fs.exists`. This operation is
+performed in parallel, but the results array will be in the same order as the
+original.
+
+__Arguments__
+
+* `arr` - An array to iterate over.
+* `iterator(item, callback)` - A truth test to apply to each item in `arr`.
+  The `iterator` is passed a `callback(truthValue)`, which must be called with a 
+  boolean argument once it has completed.
+* `callback(results)` - A callback which is called after all the `iterator`
+  functions have finished.
+
+__Example__
+
+```js
+async.filter(['file1','file2','file3'], fs.exists, function(results){
+    // results now equals an array of the existing files
+});
+```
+
+---------------------------------------
+
+<a name="selectSeries" />
+<a name="filterSeries" />
+### filterSeries(arr, iterator, callback)
+
+__Alias:__ `selectSeries`
+
+The same as [`filter`](#filter) only the `iterator` is applied to each item in `arr` in
+series. The next `iterator` is only called once the current one has completed. 
+The results array will be in the same order as the original.
+
+---------------------------------------
+
+<a name="reject" />
+### reject(arr, iterator, callback)
+
+The opposite of [`filter`](#filter). Removes values that pass an `async` truth test.
+
+---------------------------------------
+
+<a name="rejectSeries" />
+### rejectSeries(arr, iterator, callback)
+
+The same as [`reject`](#reject), only the `iterator` is applied to each item in `arr`
+in series.
+
+
+---------------------------------------
+
+<a name="reduce" />
+### reduce(arr, memo, iterator, callback)
+
+__Aliases:__ `inject`, `foldl`
+
+Reduces `arr` into a single value using an async `iterator` to return
+each successive step. `memo` is the initial state of the reduction. 
+This function only operates in series. 
+
+For performance reasons, it may make sense to split a call to this function into 
+a parallel map, and then use the normal `Array.prototype.reduce` on the results. 
+This function is for situations where each step in the reduction needs to be async; 
+if you can get the data before reducing it, then it's probably a good idea to do so.
+
+__Arguments__
+
+* `arr` - An array to iterate over.
+* `memo` - The initial state of the reduction.
+* `iterator(memo, item, callback)` - A function applied to each item in the
+  array to produce the next step in the reduction. The `iterator` is passed a
+  `callback(err, reduction)` which accepts an optional error as its first 
+  argument, and the state of the reduction as the second. If an error is 
+  passed to the callback, the reduction is stopped and the main `callback` is 
+  immediately called with the error.
+* `callback(err, result)` - A callback which is called after all the `iterator`
+  functions have finished. Result is the reduced value.
+
+__Example__
+
+```js
+async.reduce([1,2,3], 0, function(memo, item, callback){
+    // pointless async:
+    process.nextTick(function(){
+        callback(null, memo + item)
+    });
+}, function(err, result){
+    // result is now equal to the last value of memo, which is 6
+});
+```
+
+---------------------------------------
+
+<a name="reduceRight" />
+### reduceRight(arr, memo, iterator, callback)
+
+__Alias:__ `foldr`
+
+Same as [`reduce`](#reduce), only operates on `arr` in reverse order.
+
+
+---------------------------------------
+
+<a name="detect" />
+### detect(arr, iterator, callback)
+
+Returns the first value in `arr` that passes an async truth test. The
+`iterator` is applied in parallel, meaning the first iterator to return `true` will
+fire the detect `callback` with that result. That means the result might not be
+the first item in the original `arr` (in terms of order) that passes the test.
+
+If order within the original `arr` is important, then look at [`detectSeries`](#detectSeries).
+
+__Arguments__
+
+* `arr` - An array to iterate over.
+* `iterator(item, callback)` - A truth test to apply to each item in `arr`.
+  The iterator is passed a `callback(truthValue)` which must be called with a 
+  boolean argument once it has completed.
+* `callback(result)` - A callback which is called as soon as any iterator returns
+  `true`, or after all the `iterator` functions have finished. Result will be
+  the first item in the array that passes the truth test (iterator) or the
+  value `undefined` if none passed.
+
+__Example__
+
+```js
+async.detect(['file1','file2','file3'], fs.exists, function(result){
+    // result now equals the first file in the list that exists
+});
+```
+
+---------------------------------------
+
+<a name="detectSeries" />
+### detectSeries(arr, iterator, callback)
+
+The same as [`detect`](#detect), only the `iterator` is applied to each item in `arr`
+in series. This means the result is always the first in the original `arr` (in
+terms of array order) that passes the truth test.
+
+
+---------------------------------------
+
+<a name="sortBy" />
+### sortBy(arr, iterator, callback)
+
+Sorts a list by the results of running each `arr` value through an async `iterator`.
+
+__Arguments__
+
+* `arr` - An array to iterate over.
+* `iterator(item, callback)` - A function to apply to each item in `arr`.
+  The iterator is passed a `callback(err, sortValue)` which must be called once it
+  has completed with an error (which can be `null`) and a value to use as the sort
+  criteria.
+* `callback(err, results)` - A callback which is called after all the `iterator`
+  functions have finished, or an error occurs. Results is the items from
+  the original `arr` sorted by the values returned by the `iterator` calls.
+
+__Example__
+
+```js
+async.sortBy(['file1','file2','file3'], function(file, callback){
+    fs.stat(file, function(err, stats){
+        callback(err, stats.mtime);
+    });
+}, function(err, results){
+    // results is now the original array of files sorted by
+    // modified date
+});
+```
+
+__Sort Order__
+
+By modifying the callback parameter the sorting order can be influenced:
+
+```js
+//ascending order
+async.sortBy([1,9,3,5], function(x, callback){
+    callback(null, x);
+}, function(err,result){
+    //result callback
+} );
+
+//descending order
+async.sortBy([1,9,3,5], function(x, callback){
+    callback(null, x*-1);    //<- x*-1 instead of x, turns the order around
+}, function(err,result){
+    //result callback
+} );
+```
+
+---------------------------------------
+
+<a name="some" />
+### some(arr, iterator, callback)
+
+__Alias:__ `any`
+
+Returns `true` if at least one element in the `arr` satisfies an async test.
+_The callback for each iterator call only accepts a single argument of `true` or
+`false`; it does not accept an error argument first!_ This is in-line with the
+way node libraries work with truth tests like `fs.exists`. Once any iterator
+call returns `true`, the main `callback` is immediately called.
+
+__Arguments__
+
+* `arr` - An array to iterate over.
+* `iterator(item, callback)` - A truth test to apply to each item in the array
+  in parallel. The iterator is passed a callback(truthValue) which must be 
+  called with a boolean argument once it has completed.
+* `callback(result)` - A callback which is called as soon as any iterator returns
+  `true`, or after all the iterator functions have finished. Result will be
+  either `true` or `false` depending on the values of the async tests.
+
+__Example__
+
+```js
+async.some(['file1','file2','file3'], fs.exists, function(result){
+    // if result is true then at least one of the files exists
+});
+```
+
+---------------------------------------
+
+<a name="every" />
+### every(arr, iterator, callback)
+
+__Alias:__ `all`
+
+Returns `true` if every element in `arr` satisfies an async test.
+_The callback for each `iterator` call only accepts a single argument of `true` or
+`false`; it does not accept an error argument first!_ This is in-line with the
+way node libraries work with truth tests like `fs.exists`.
+
+__Arguments__
+
+* `arr` - An array to iterate over.
+* `iterator(item, callback)` - A truth test to apply to each item in the array
+  in parallel. The iterator is passed a callback(truthValue) which must be 
+  called with a  boolean argument once it has completed.
+* `callback(result)` - A callback which is called after all the `iterator`
+  functions have finished. Result will be either `true` or `false` depending on
+  the values of the async tests.
+
+__Example__
+
+```js
+async.every(['file1','file2','file3'], fs.exists, function(result){
+    // if result is true then every file exists
+});
+```
+
+---------------------------------------
+
+<a name="concat" />
+### concat(arr, iterator, callback)
+
+Applies `iterator` to each item in `arr`, concatenating the results. Returns the
+concatenated list. The `iterator`s are called in parallel, and the results are
+concatenated as they return. There is no guarantee that the results array will
+be returned in the original order of `arr` passed to the `iterator` function.
+
+__Arguments__
+
+* `arr` - An array to iterate over.
+* `iterator(item, callback)` - A function to apply to each item in `arr`.
+  The iterator is passed a `callback(err, results)` which must be called once it 
+  has completed with an error (which can be `null`) and an array of results.
+* `callback(err, results)` - A callback which is called after all the `iterator`
+  functions have finished, or an error occurs. Results is an array containing
+  the concatenated results of the `iterator` function.
+
+__Example__
+
+```js
+async.concat(['dir1','dir2','dir3'], fs.readdir, function(err, files){
+    // files is now a list of filenames that exist in the 3 directories
+});
+```
+
+---------------------------------------
+
+<a name="concatSeries" />
+### concatSeries(arr, iterator, callback)
+
+Same as [`concat`](#concat), but executes in series instead of parallel.
+
+
+## Control Flow
+
+<a name="series" />
+### series(tasks, [callback])
+
+Run the functions in the `tasks` array in series, each one running once the previous
+function has completed. If any functions in the series pass an error to its
+callback, no more functions are run, and `callback` is immediately called with the value of the error. 
+Otherwise, `callback` receives an array of results when `tasks` have completed.
+
+It is also possible to use an object instead of an array. Each property will be
+run as a function, and the results will be passed to the final `callback` as an object
+instead of an array. This can be a more readable way of handling results from
+[`series`](#series).
+
+**Note** that while many implementations preserve the order of object properties, the
+[ECMAScript Language Specifcation](http://www.ecma-international.org/ecma-262/5.1/#sec-8.6) 
+explicitly states that
+
+> The mechanics and order of enumerating the properties is not specified.
+
+So if you rely on the order in which your series of functions are executed, and want
+this to work on all platforms, consider using an array. 
+
+__Arguments__
+
+* `tasks` - An array or object containing functions to run, each function is passed
+  a `callback(err, result)` it must call on completion with an error `err` (which can
+  be `null`) and an optional `result` value.
+* `callback(err, results)` - An optional callback to run once all the functions
+  have completed. This function gets a results array (or object) containing all 
+  the result arguments passed to the `task` callbacks.
+
+__Example__
+
+```js
+async.series([
+    function(callback){
+        // do some stuff ...
+        callback(null, 'one');
+    },
+    function(callback){
+        // do some more stuff ...
+        callback(null, 'two');
+    }
+],
+// optional callback
+function(err, results){
+    // results is now equal to ['one', 'two']
+});
+
+
+// an example using an object instead of an array
+async.series({
+    one: function(callback){
+        setTimeout(function(){
+            callback(null, 1);
+        }, 200);
+    },
+    two: function(callback){
+        setTimeout(function(){
+            callback(null, 2);
+        }, 100);
+    }
+},
+function(err, results) {
+    // results is now equal to: {one: 1, two: 2}
+});
+```
+
+---------------------------------------
+
+<a name="parallel" />
+### parallel(tasks, [callback])
+
+Run the `tasks` array of functions in parallel, without waiting until the previous
+function has completed. If any of the functions pass an error to its
+callback, the main `callback` is immediately called with the value of the error.
+Once the `tasks` have completed, the results are passed to the final `callback` as an
+array.
+
+It is also possible to use an object instead of an array. Each property will be
+run as a function and the results will be passed to the final `callback` as an object
+instead of an array. This can be a more readable way of handling results from
+[`parallel`](#parallel).
+
+
+__Arguments__
+
+* `tasks` - An array or object containing functions to run. Each function is passed 
+  a `callback(err, result)` which it must call on completion with an error `err` 
+  (which can be `null`) and an optional `result` value.
+* `callback(err, results)` - An optional callback to run once all the functions
+  have completed. This function gets a results array (or object) containing all 
+  the result arguments passed to the task callbacks.
+
+__Example__
+
+```js
+async.parallel([
+    function(callback){
+        setTimeout(function(){
+            callback(null, 'one');
+        }, 200);
+    },
+    function(callback){
+        setTimeout(function(){
+            callback(null, 'two');
+        }, 100);
+    }
+],
+// optional callback
+function(err, results){
+    // the results array will equal ['one','two'] even though
+    // the second function had a shorter timeout.
+});
+
+
+// an example using an object instead of an array
+async.parallel({
+    one: function(callback){
+        setTimeout(function(){
+            callback(null, 1);
+        }, 200);
+    },
+    two: function(callback){
+        setTimeout(function(){
+            callback(null, 2);
+        }, 100);
+    }
+},
+function(err, results) {
+    // results is now equals to: {one: 1, two: 2}
+});
+```
+
+---------------------------------------
+
+<a name="parallelLimit" />
+### parallelLimit(tasks, limit, [callback])
+
+The same as [`parallel`](#parallel), only `tasks` are executed in parallel 
+with a maximum of `limit` tasks executing at any time.
+
+Note that the `tasks` are not executed in batches, so there is no guarantee that 
+the first `limit` tasks will complete before any others are started.
+
+__Arguments__
+
+* `tasks` - An array or object containing functions to run, each function is passed 
+  a `callback(err, result)` it must call on completion with an error `err` (which can
+  be `null`) and an optional `result` value.
+* `limit` - The maximum number of `tasks` to run at any time.
+* `callback(err, results)` - An optional callback to run once all the functions
+  have completed. This function gets a results array (or object) containing all 
+  the result arguments passed to the `task` callbacks.
+
+---------------------------------------
+
+<a name="whilst" />
+### whilst(test, fn, callback)
+
+Repeatedly call `fn`, while `test` returns `true`. Calls `callback` when stopped,
+or an error occurs.
+
+__Arguments__
+
+* `test()` - synchronous truth test to perform before each execution of `fn`.
+* `fn(callback)` - A function which is called each time `test` passes. The function is
+  passed a `callback(err)`, which must be called once it has completed with an 
+  optional `err` argument.
+* `callback(err)` - A callback which is called after the test fails and repeated
+  execution of `fn` has stopped.
+
+__Example__
+
+```js
+var count = 0;
+
+async.whilst(
+    function () { return count < 5; },
+    function (callback) {
+        count++;
+        setTimeout(callback, 1000);
+    },
+    function (err) {
+        // 5 seconds have passed
+    }
+);
+```
+
+---------------------------------------
+
+<a name="doWhilst" />
+### doWhilst(fn, test, callback)
+
+The post-check version of [`whilst`](#whilst). To reflect the difference in 
+the order of operations, the arguments `test` and `fn` are switched. 
+
+`doWhilst` is to `whilst` as `do while` is to `while` in plain JavaScript.
+
+---------------------------------------
+
+<a name="until" />
+### until(test, fn, callback)
+
+Repeatedly call `fn` until `test` returns `true`. Calls `callback` when stopped,
+or an error occurs.
+
+The inverse of [`whilst`](#whilst).
+
+---------------------------------------
+
+<a name="doUntil" />
+### doUntil(fn, test, callback)
+
+Like [`doWhilst`](#doWhilst), except the `test` is inverted. Note the argument ordering differs from `until`.
+
+---------------------------------------
+
+<a name="forever" />
+### forever(fn, errback)
+
+Calls the asynchronous function `fn` with a callback parameter that allows it to
+call itself again, in series, indefinitely.
+
+If an error is passed to the callback then `errback` is called with the
+error, and execution stops, otherwise it will never be called.
+
+```js
+async.forever(
+    function(next) {
+        // next is suitable for passing to things that need a callback(err [, whatever]);
+        // it will result in this function being called again.
+    },
+    function(err) {
+        // if next is called with a value in its first parameter, it will appear
+        // in here as 'err', and execution will stop.
+    }
+);
+```
+
+---------------------------------------
+
+<a name="waterfall" />
+### waterfall(tasks, [callback])
+
+Runs the `tasks` array of functions in series, each passing their results to the next in
+the array. However, if any of the `tasks` pass an error to their own callback, the
+next function is not executed, and the main `callback` is immediately called with
+the error.
+
+__Arguments__
+
+* `tasks` - An array of functions to run, each function is passed a 
+  `callback(err, result1, result2, ...)` it must call on completion. The first
+  argument is an error (which can be `null`) and any further arguments will be 
+  passed as arguments in order to the next task.
+* `callback(err, [results])` - An optional callback to run once all the functions
+  have completed. This will be passed the results of the last task's callback.
+
+
+
+__Example__
+
+```js
+async.waterfall([
+    function(callback) {
+        callback(null, 'one', 'two');
+    },
+    function(arg1, arg2, callback) {
+      // arg1 now equals 'one' and arg2 now equals 'two'
+        callback(null, 'three');
+    },
+    function(arg1, callback) {
+        // arg1 now equals 'three'
+        callback(null, 'done');
+    }
+], function (err, result) {
+    // result now equals 'done'    
+});
+```
+
+---------------------------------------
+<a name="compose" />
+### compose(fn1, fn2...)
+
+Creates a function which is a composition of the passed asynchronous
+functions. Each function consumes the return value of the function that
+follows. Composing functions `f()`, `g()`, and `h()` would produce the result of
+`f(g(h()))`, only this version uses callbacks to obtain the return values.
+
+Each function is executed with the `this` binding of the composed function.
+
+__Arguments__
+
+* `functions...` - the asynchronous functions to compose
+
+
+__Example__
+
+```js
+function add1(n, callback) {
+    setTimeout(function () {
+        callback(null, n + 1);
+    }, 10);
+}
+
+function mul3(n, callback) {
+    setTimeout(function () {
+        callback(null, n * 3);
+    }, 10);
+}
+
+var add1mul3 = async.compose(mul3, add1);
+
+add1mul3(4, function (err, result) {
+   // result now equals 15
+});
+```
+
+---------------------------------------
+<a name="seq" />
+### seq(fn1, fn2...)
+
+Version of the compose function that is more natural to read.
+Each function consumes the return value of the previous function.
+It is the equivalent of [`compose`](#compose) with the arguments reversed.
+
+Each function is executed with the `this` binding of the composed function.
+
+__Arguments__
+
+* functions... - the asynchronous functions to compose
+
+
+__Example__
+
+```js
+// Requires lodash (or underscore), express3 and dresende's orm2.
+// Part of an app, that fetches cats of the logged user.
+// This example uses `seq` function to avoid overnesting and error 
+// handling clutter.
+app.get('/cats', function(request, response) {
+  var User = request.models.User;
+  async.seq(
+    _.bind(User.get, User),  // 'User.get' has signature (id, callback(err, data))
+    function(user, fn) {
+      user.getCats(fn);      // 'getCats' has signature (callback(err, data))
+    }
+  )(req.session.user_id, function (err, cats) {
+    if (err) {
+      console.error(err);
+      response.json({ status: 'error', message: err.message });
+    } else {
+      response.json({ status: 'ok', message: 'Cats found', data: cats });
+    }
+  });
+});
+```
+
+---------------------------------------
+<a name="applyEach" />
+### applyEach(fns, args..., callback)
+
+Applies the provided arguments to each function in the array, calling 
+`callback` after all functions have completed. If you only provide the first
+argument, then it will return a function which lets you pass in the
+arguments as if it were a single function call.
+
+__Arguments__
+
+* `fns` - the asynchronous functions to all call with the same arguments
+* `args...` - any number of separate arguments to pass to the function
+* `callback` - the final argument should be the callback, called when all
+  functions have completed processing
+
+
+__Example__
+
+```js
+async.applyEach([enableSearch, updateSchema], 'bucket', callback);
+
+// partial application example:
+async.each(
+    buckets,
+    async.applyEach([enableSearch, updateSchema]),
+    callback
+);
+```
+
+---------------------------------------
+
+<a name="applyEachSeries" />
+### applyEachSeries(arr, iterator, callback)
+
+The same as [`applyEach`](#applyEach) only the functions are applied in series.
+
+---------------------------------------
+
+<a name="queue" />
+### queue(worker, concurrency)
+
+Creates a `queue` object with the specified `concurrency`. Tasks added to the
+`queue` are processed in parallel (up to the `concurrency` limit). If all
+`worker`s are in progress, the task is queued until one becomes available. 
+Once a `worker` completes a `task`, that `task`'s callback is called.
+
+__Arguments__
+
+* `worker(task, callback)` - An asynchronous function for processing a queued
+  task, which must call its `callback(err)` argument when finished, with an 
+  optional `error` as an argument.
+* `concurrency` - An `integer` for determining how many `worker` functions should be
+  run in parallel.
+
+__Queue objects__
+
+The `queue` object returned by this function has the following properties and
+methods:
+
+* `length()` - a function returning the number of items waiting to be processed.
+* `started` - a function returning whether or not any items have been pushed and processed by the queue
+* `running()` - a function returning the number of items currently being processed.
+* `idle()` - a function returning false if there are items waiting or being processed, or true if not.
+* `concurrency` - an integer for determining how many `worker` functions should be
+  run in parallel. This property can be changed after a `queue` is created to
+  alter the concurrency on-the-fly.
+* `push(task, [callback])` - add a new task to the `queue`. Calls `callback` once 
+  the `worker` has finished processing the task. Instead of a single task, a `tasks` array
+  can be submitted. The respective callback is used for every task in the list.
+* `unshift(task, [callback])` - add a new task to the front of the `queue`.
+* `saturated` - a callback that is called when the `queue` length hits the `concurrency` limit, 
+   and further tasks will be queued.
+* `empty` - a callback that is called when the last item from the `queue` is given to a `worker`.
+* `drain` - a callback that is called when the last item from the `queue` has returned from the `worker`.
+* `paused` - a boolean for determining whether the queue is in a paused state
+* `pause()` - a function that pauses the processing of tasks until `resume()` is called.
+* `resume()` - a function that resumes the processing of queued tasks when the queue is paused.
+* `kill()` - a function that removes the `drain` callback and empties remaining tasks from the queue forcing it to go idle.
+
+__Example__
+
+```js
+// create a queue object with concurrency 2
+
+var q = async.queue(function (task, callback) {
+    console.log('hello ' + task.name);
+    callback();
+}, 2);
+
+
+// assign a callback
+q.drain = function() {
+    console.log('all items have been processed');
+}
+
+// add some items to the queue
+
+q.push({name: 'foo'}, function (err) {
+    console.log('finished processing foo');
+});
+q.push({name: 'bar'}, function (err) {
+    console.log('finished processing bar');
+});
+
+// add some items to the queue (batch-wise)
+
+q.push([{name: 'baz'},{name: 'bay'},{name: 'bax'}], function (err) {
+    console.log('finished processing item');
+});
+
+// add some items to the front of the queue
+
+q.unshift({name: 'bar'}, function (err) {
+    console.log('finished processing bar');
+});
+```
+
+
+---------------------------------------
+
+<a name="priorityQueue" />
+### priorityQueue(worker, concurrency)
+
+The same as [`queue`](#queue) only tasks are assigned a priority and completed in ascending priority order. There are two differences between `queue` and `priorityQueue` objects:
+
+* `push(task, priority, [callback])` - `priority` should be a number. If an array of
+  `tasks` is given, all tasks will be assigned the same priority.
+* The `unshift` method was removed.
+
+---------------------------------------
+
+<a name="cargo" />
+### cargo(worker, [payload])
+
+Creates a `cargo` object with the specified payload. Tasks added to the
+cargo will be processed altogether (up to the `payload` limit). If the
+`worker` is in progress, the task is queued until it becomes available. Once
+the `worker` has completed some tasks, each callback of those tasks is called.
+Check out [this animation](https://camo.githubusercontent.com/6bbd36f4cf5b35a0f11a96dcd2e97711ffc2fb37/68747470733a2f2f662e636c6f75642e6769746875622e636f6d2f6173736574732f313637363837312f36383130382f62626330636662302d356632392d313165322d393734662d3333393763363464633835382e676966) for how `cargo` and `queue` work.
+
+While [queue](#queue) passes only one task to one of a group of workers
+at a time, cargo passes an array of tasks to a single worker, repeating
+when the worker is finished.
+
+__Arguments__
+
+* `worker(tasks, callback)` - An asynchronous function for processing an array of
+  queued tasks, which must call its `callback(err)` argument when finished, with 
+  an optional `err` argument.
+* `payload` - An optional `integer` for determining how many tasks should be
+  processed per round; if omitted, the default is unlimited.
+
+__Cargo objects__
+
+The `cargo` object returned by this function has the following properties and
+methods:
+
+* `length()` - A function returning the number of items waiting to be processed.
+* `payload` - An `integer` for determining how many tasks should be
+  process per round. This property can be changed after a `cargo` is created to
+  alter the payload on-the-fly.
+* `push(task, [callback])` - Adds `task` to the `queue`. The callback is called
+  once the `worker` has finished processing the task. Instead of a single task, an array of `tasks` 
+  can be submitted. The respective callback is used for every task in the list.
+* `saturated` - A callback that is called when the `queue.length()` hits the concurrency and further tasks will be queued.
+* `empty` - A callback that is called when the last item from the `queue` is given to a `worker`.
+* `drain` - A callback that is called when the last item from the `queue` has returned from the `worker`.
+
+__Example__
+
+```js
+// create a cargo object with payload 2
+
+var cargo = async.cargo(function (tasks, callback) {
+    for(var i=0; i<tasks.length; i++){
+      console.log('hello ' + tasks[i].name);
+    }
+    callback();
+}, 2);
+
+
+// add some items
+
+cargo.push({name: 'foo'}, function (err) {
+    console.log('finished processing foo');
+});
+cargo.push({name: 'bar'}, function (err) {
+    console.log('finished processing bar');
+});
+cargo.push({name: 'baz'}, function (err) {
+    console.log('finished processing baz');
+});
+```
+
+---------------------------------------
+
+<a name="auto" />
+### auto(tasks, [callback])
+
+Determines the best order for running the functions in `tasks`, based on their 
+requirements. Each function can optionally depend on other functions being completed 
+first, and each function is run as soon as its requirements are satisfied. 
+
+If any of the functions pass an error to their callback, it will not 
+complete (so any other functions depending on it will not run), and the main 
+`callback` is immediately called with the error. Functions also receive an 
+object containing the results of functions which have completed so far.
+
+Note, all functions are called with a `results` object as a second argument, 
+so it is unsafe to pass functions in the `tasks` object which cannot handle the
+extra argument. 
+
+For example, this snippet of code:
+
+```js
+async.auto({
+  readData: async.apply(fs.readFile, 'data.txt', 'utf-8')
+}, callback);
+```
+
+will have the effect of calling `readFile` with the results object as the last
+argument, which will fail:
+
+```js
+fs.readFile('data.txt', 'utf-8', cb, {});
+```
+
+Instead, wrap the call to `readFile` in a function which does not forward the 
+`results` object:
+
+```js
+async.auto({
+  readData: function(cb, results){
+    fs.readFile('data.txt', 'utf-8', cb);
+  }
+}, callback);
+```
+
+__Arguments__
+
+* `tasks` - An object. Each of its properties is either a function or an array of
+  requirements, with the function itself the last item in the array. The object's key
+  of a property serves as the name of the task defined by that property,
+  i.e. can be used when specifying requirements for other tasks.
+  The function receives two arguments: (1) a `callback(err, result)` which must be 
+  called when finished, passing an `error` (which can be `null`) and the result of 
+  the function's execution, and (2) a `results` object, containing the results of
+  the previously executed functions.
+* `callback(err, results)` - An optional callback which is called when all the
+  tasks have been completed. It receives the `err` argument if any `tasks` 
+  pass an error to their callback. Results are always returned; however, if 
+  an error occurs, no further `tasks` will be performed, and the results
+  object will only contain partial results.
+
+
+__Example__
+
+```js
+async.auto({
+    get_data: function(callback){
+        console.log('in get_data');
+        // async code to get some data
+        callback(null, 'data', 'converted to array');
+    },
+    make_folder: function(callback){
+        console.log('in make_folder');
+        // async code to create a directory to store a file in
+        // this is run at the same time as getting the data
+        callback(null, 'folder');
+    },
+    write_file: ['get_data', 'make_folder', function(callback, results){
+        console.log('in write_file', JSON.stringify(results));
+        // once there is some data and the directory exists,
+        // write the data to a file in the directory
+        callback(null, 'filename');
+    }],
+    email_link: ['write_file', function(callback, results){
+        console.log('in email_link', JSON.stringify(results));
+        // once the file is written let's email a link to it...
+        // results.write_file contains the filename returned by write_file.
+        callback(null, {'file':results.write_file, 'email':'[email protected]'});
+    }]
+}, function(err, results) {
+    console.log('err = ', err);
+    console.log('results = ', results);
+});
+```
+
+This is a fairly trivial example, but to do this using the basic parallel and
+series functions would look like this:
+
+```js
+async.parallel([
+    function(callback){
+        console.log('in get_data');
+        // async code to get some data
+        callback(null, 'data', 'converted to array');
+    },
+    function(callback){
+        console.log('in make_folder');
+        // async code to create a directory to store a file in
+        // this is run at the same time as getting the data
+        callback(null, 'folder');
+    }
+],
+function(err, results){
+    async.series([
+        function(callback){
+            console.log('in write_file', JSON.stringify(results));
+            // once there is some data and the directory exists,
+            // write the data to a file in the directory
+            results.push('filename');
+            callback(null);
+        },
+        function(callback){
+            console.log('in email_link', JSON.stringify(results));
+            // once the file is written let's email a link to it...
+            callback(null, {'file':results.pop(), 'email':'[email protected]'});
+        }
+    ]);
+});
+```
+
+For a complicated series of `async` tasks, using the [`auto`](#auto) function makes adding
+new tasks much easier (and the code more readable).
+
+
+---------------------------------------
+
+<a name="retry" />
+### retry([times = 5], task, [callback])
+
+Attempts to get a successful response from `task` no more than `times` times before
+returning an error. If the task is successful, the `callback` will be passed the result
+of the successful task. If all attempts fail, the callback will be passed the error and
+result (if any) of the final attempt.
+
+__Arguments__
+
+* `times` - An integer indicating how many times to attempt the `task` before giving up. Defaults to 5.
+* `task(callback, results)` - A function which receives two arguments: (1) a `callback(err, result)`
+  which must be called when finished, passing `err` (which can be `null`) and the `result` of 
+  the function's execution, and (2) a `results` object, containing the results of
+  the previously executed functions (if nested inside another control flow).
+* `callback(err, results)` - An optional callback which is called when the
+  task has succeeded, or after the final failed attempt. It receives the `err` and `result` arguments of the last attempt at completing the `task`.
+
+The [`retry`](#retry) function can be used as a stand-alone control flow by passing a
+callback, as shown below:
+
+```js
+async.retry(3, apiMethod, function(err, result) {
+    // do something with the result
+});
+```
+
+It can also be embeded within other control flow functions to retry individual methods
+that are not as reliable, like this:
+
+```js
+async.auto({
+    users: api.getUsers.bind(api),
+    payments: async.retry(3, api.getPayments.bind(api))
+}, function(err, results) {
+  // do something with the results
+});
+```
+
+
+---------------------------------------
+
+<a name="iterator" />
+### iterator(tasks)
+
+Creates an iterator function which calls the next function in the `tasks` array,
+returning a continuation to call the next one after that. It's also possible to
+“peek” at the next iterator with `iterator.next()`.
+
+This function is used internally by the `async` module, but can be useful when
+you want to manually control the flow of functions in series.
+
+__Arguments__
+
+* `tasks` - An array of functions to run.
+
+__Example__
+
+```js
+var iterator = async.iterator([
+    function(){ sys.p('one'); },
+    function(){ sys.p('two'); },
+    function(){ sys.p('three'); }
+]);
+
+node> var iterator2 = iterator();
+'one'
+node> var iterator3 = iterator2();
+'two'
+node> iterator3();
+'three'
+node> var nextfn = iterator2.next();
+node> nextfn();
+'three'
+```
+
+---------------------------------------
+
+<a name="apply" />
+### apply(function, arguments..)
+
+Creates a continuation function with some arguments already applied. 
+
+Useful as a shorthand when combined with other control flow functions. Any arguments
+passed to the returned function are added to the arguments originally passed
+to apply.
+
+__Arguments__
+
+* `function` - The function you want to eventually apply all arguments to.
+* `arguments...` - Any number of arguments to automatically apply when the
+  continuation is called.
+
+__Example__
+
+```js
+// using apply
+
+async.parallel([
+    async.apply(fs.writeFile, 'testfile1', 'test1'),
+    async.apply(fs.writeFile, 'testfile2', 'test2'),
+]);
+
+
+// the same process without using apply
+
+async.parallel([
+    function(callback){
+        fs.writeFile('testfile1', 'test1', callback);
+    },
+    function(callback){
+        fs.writeFile('testfile2', 'test2', callback);
+    }
+]);
+```
+
+It's possible to pass any number of additional arguments when calling the
+continuation:
+
+```js
+node> var fn = async.apply(sys.puts, 'one');
+node> fn('two', 'three');
+one
+two
+three
+```
+
+---------------------------------------
+
+<a name="nextTick" />
+### nextTick(callback), setImmediate(callback)
+
+Calls `callback` on a later loop around the event loop. In Node.js this just
+calls `process.nextTick`; in the browser it falls back to `setImmediate(callback)`
+if available, otherwise `setTimeout(callback, 0)`, which means other higher priority
+events may precede the execution of `callback`.
+
+This is used internally for browser-compatibility purposes.
+
+__Arguments__
+
+* `callback` - The function to call on a later loop around the event loop.
+
+__Example__
+
+```js
+var call_order = [];
+async.nextTick(function(){
+    call_order.push('two');
+    // call_order now equals ['one','two']
+});
+call_order.push('one')
+```
+
+<a name="times" />
+### times(n, callback)
+
+Calls the `callback` function `n` times, and accumulates results in the same manner
+you would use with [`map`](#map).
+
+__Arguments__
+
+* `n` - The number of times to run the function.
+* `callback` - The function to call `n` times.
+
+__Example__
+
+```js
+// Pretend this is some complicated async factory
+var createUser = function(id, callback) {
+  callback(null, {
+    id: 'user' + id
+  })
+}
+// generate 5 users
+async.times(5, function(n, next){
+    createUser(n, function(err, user) {
+      next(err, user)
+    })
+}, function(err, users) {
+  // we should now have 5 users
+});
+```
+
+<a name="timesSeries" />
+### timesSeries(n, callback)
+
+The same as [`times`](#times), only the iterator is applied to each item in `arr` in
+series. The next `iterator` is only called once the current one has completed. 
+The results array will be in the same order as the original.
+
+
+## Utils
+
+<a name="memoize" />
+### memoize(fn, [hasher])
+
+Caches the results of an `async` function. When creating a hash to store function
+results against, the callback is omitted from the hash and an optional hash
+function can be used.
+
+The cache of results is exposed as the `memo` property of the function returned
+by `memoize`.
+
+__Arguments__
+
+* `fn` - The function to proxy and cache results from.
+* `hasher` - Tn optional function for generating a custom hash for storing
+  results. It has all the arguments applied to it apart from the callback, and
+  must be synchronous.
+
+__Example__
+
+```js
+var slow_fn = function (name, callback) {
+    // do something
+    callback(null, result);
+};
+var fn = async.memoize(slow_fn);
+
+// fn can now be used as if it were slow_fn
+fn('some name', function () {
+    // callback
+});
+```
+
+<a name="unmemoize" />
+### unmemoize(fn)
+
+Undoes a [`memoize`](#memoize)d function, reverting it to the original, unmemoized
+form. Handy for testing.
+
+__Arguments__
+
+* `fn` - the memoized function
+
+<a name="log" />
+### log(function, arguments)
+
+Logs the result of an `async` function to the `console`. Only works in Node.js or
+in browsers that support `console.log` and `console.error` (such as FF and Chrome).
+If multiple arguments are returned from the async function, `console.log` is
+called on each argument in order.
+
+__Arguments__
+
+* `function` - The function you want to eventually apply all arguments to.
+* `arguments...` - Any number of arguments to apply to the function.
+
+__Example__
+
+```js
+var hello = function(name, callback){
+    setTimeout(function(){
+        callback(null, 'hello ' + name);
+    }, 1000);
+};
+```
+```js
+node> async.log(hello, 'world');
+'hello world'
+```
+
+---------------------------------------
+
+<a name="dir" />
+### dir(function, arguments)
+
+Logs the result of an `async` function to the `console` using `console.dir` to
+display the properties of the resulting object. Only works in Node.js or
+in browsers that support `console.dir` and `console.error` (such as FF and Chrome).
+If multiple arguments are returned from the async function, `console.dir` is
+called on each argument in order.
+
+__Arguments__
+
+* `function` - The function you want to eventually apply all arguments to.
+* `arguments...` - Any number of arguments to apply to the function.
+
+__Example__
+
+```js
+var hello = function(name, callback){
+    setTimeout(function(){
+        callback(null, {hello: name});
+    }, 1000);
+};
+```
+```js
+node> async.dir(hello, 'world');
+{hello: 'world'}
+```
+
+---------------------------------------
+
+<a name="noConflict" />
+### noConflict()
+
+Changes the value of `async` back to its original value, returning a reference to the
+`async` object.

+ 38 - 0
Build/node_modules/jake/node_modules/async/bower.json

@@ -0,0 +1,38 @@
+{
+  "name": "async",
+  "description": "Higher-order functions and common patterns for asynchronous code",
+  "version": "0.9.2",
+  "main": "lib/async.js",
+  "keywords": [
+    "async",
+    "callback",
+    "utility",
+    "module"
+  ],
+  "license": "MIT",
+  "repository": {
+    "type": "git",
+    "url": "https://github.com/caolan/async.git"
+  },
+  "devDependencies": {
+    "nodeunit": ">0.0.0",
+    "uglify-js": "1.2.x",
+    "nodelint": ">0.0.0",
+    "lodash": ">=2.4.1"
+  },
+  "moduleType": [
+    "amd",
+    "globals",
+    "node"
+  ],
+  "ignore": [
+    "**/.*",
+    "node_modules",
+    "bower_components",
+    "test",
+    "tests"
+  ],
+  "authors": [
+    "Caolan McMahon"
+  ]
+}

+ 16 - 0
Build/node_modules/jake/node_modules/async/component.json

@@ -0,0 +1,16 @@
+{
+  "name": "async",
+  "description": "Higher-order functions and common patterns for asynchronous code",
+  "version": "0.9.2",
+  "keywords": [
+    "async",
+    "callback",
+    "utility",
+    "module"
+  ],
+  "license": "MIT",
+  "repository": "caolan/async",
+  "scripts": [
+    "lib/async.js"
+  ]
+}

+ 1123 - 0
Build/node_modules/jake/node_modules/async/lib/async.js

@@ -0,0 +1,1123 @@
+/*!
+ * async
+ * https://github.com/caolan/async
+ *
+ * Copyright 2010-2014 Caolan McMahon
+ * Released under the MIT license
+ */
+/*jshint onevar: false, indent:4 */
+/*global setImmediate: false, setTimeout: false, console: false */
+(function () {
+
+    var async = {};
+
+    // global on the server, window in the browser
+    var root, previous_async;
+
+    root = this;
+    if (root != null) {
+      previous_async = root.async;
+    }
+
+    async.noConflict = function () {
+        root.async = previous_async;
+        return async;
+    };
+
+    function only_once(fn) {
+        var called = false;
+        return function() {
+            if (called) throw new Error("Callback was already called.");
+            called = true;
+            fn.apply(root, arguments);
+        }
+    }
+
+    //// cross-browser compatiblity functions ////
+
+    var _toString = Object.prototype.toString;
+
+    var _isArray = Array.isArray || function (obj) {
+        return _toString.call(obj) === '[object Array]';
+    };
+
+    var _each = function (arr, iterator) {
+        for (var i = 0; i < arr.length; i += 1) {
+            iterator(arr[i], i, arr);
+        }
+    };
+
+    var _map = function (arr, iterator) {
+        if (arr.map) {
+            return arr.map(iterator);
+        }
+        var results = [];
+        _each(arr, function (x, i, a) {
+            results.push(iterator(x, i, a));
+        });
+        return results;
+    };
+
+    var _reduce = function (arr, iterator, memo) {
+        if (arr.reduce) {
+            return arr.reduce(iterator, memo);
+        }
+        _each(arr, function (x, i, a) {
+            memo = iterator(memo, x, i, a);
+        });
+        return memo;
+    };
+
+    var _keys = function (obj) {
+        if (Object.keys) {
+            return Object.keys(obj);
+        }
+        var keys = [];
+        for (var k in obj) {
+            if (obj.hasOwnProperty(k)) {
+                keys.push(k);
+            }
+        }
+        return keys;
+    };
+
+    //// exported async module functions ////
+
+    //// nextTick implementation with browser-compatible fallback ////
+    if (typeof process === 'undefined' || !(process.nextTick)) {
+        if (typeof setImmediate === 'function') {
+            async.nextTick = function (fn) {
+                // not a direct alias for IE10 compatibility
+                setImmediate(fn);
+            };
+            async.setImmediate = async.nextTick;
+        }
+        else {
+            async.nextTick = function (fn) {
+                setTimeout(fn, 0);
+            };
+            async.setImmediate = async.nextTick;
+        }
+    }
+    else {
+        async.nextTick = process.nextTick;
+        if (typeof setImmediate !== 'undefined') {
+            async.setImmediate = function (fn) {
+              // not a direct alias for IE10 compatibility
+              setImmediate(fn);
+            };
+        }
+        else {
+            async.setImmediate = async.nextTick;
+        }
+    }
+
+    async.each = function (arr, iterator, callback) {
+        callback = callback || function () {};
+        if (!arr.length) {
+            return callback();
+        }
+        var completed = 0;
+        _each(arr, function (x) {
+            iterator(x, only_once(done) );
+        });
+        function done(err) {
+          if (err) {
+              callback(err);
+              callback = function () {};
+          }
+          else {
+              completed += 1;
+              if (completed >= arr.length) {
+                  callback();
+              }
+          }
+        }
+    };
+    async.forEach = async.each;
+
+    async.eachSeries = function (arr, iterator, callback) {
+        callback = callback || function () {};
+        if (!arr.length) {
+            return callback();
+        }
+        var completed = 0;
+        var iterate = function () {
+            iterator(arr[completed], function (err) {
+                if (err) {
+                    callback(err);
+                    callback = function () {};
+                }
+                else {
+                    completed += 1;
+                    if (completed >= arr.length) {
+                        callback();
+                    }
+                    else {
+                        iterate();
+                    }
+                }
+            });
+        };
+        iterate();
+    };
+    async.forEachSeries = async.eachSeries;
+
+    async.eachLimit = function (arr, limit, iterator, callback) {
+        var fn = _eachLimit(limit);
+        fn.apply(null, [arr, iterator, callback]);
+    };
+    async.forEachLimit = async.eachLimit;
+
+    var _eachLimit = function (limit) {
+
+        return function (arr, iterator, callback) {
+            callback = callback || function () {};
+            if (!arr.length || limit <= 0) {
+                return callback();
+            }
+            var completed = 0;
+            var started = 0;
+            var running = 0;
+
+            (function replenish () {
+                if (completed >= arr.length) {
+                    return callback();
+                }
+
+                while (running < limit && started < arr.length) {
+                    started += 1;
+                    running += 1;
+                    iterator(arr[started - 1], function (err) {
+                        if (err) {
+                            callback(err);
+                            callback = function () {};
+                        }
+                        else {
+                            completed += 1;
+                            running -= 1;
+                            if (completed >= arr.length) {
+                                callback();
+                            }
+                            else {
+                                replenish();
+                            }
+                        }
+                    });
+                }
+            })();
+        };
+    };
+
+
+    var doParallel = function (fn) {
+        return function () {
+            var args = Array.prototype.slice.call(arguments);
+            return fn.apply(null, [async.each].concat(args));
+        };
+    };
+    var doParallelLimit = function(limit, fn) {
+        return function () {
+            var args = Array.prototype.slice.call(arguments);
+            return fn.apply(null, [_eachLimit(limit)].concat(args));
+        };
+    };
+    var doSeries = function (fn) {
+        return function () {
+            var args = Array.prototype.slice.call(arguments);
+            return fn.apply(null, [async.eachSeries].concat(args));
+        };
+    };
+
+
+    var _asyncMap = function (eachfn, arr, iterator, callback) {
+        arr = _map(arr, function (x, i) {
+            return {index: i, value: x};
+        });
+        if (!callback) {
+            eachfn(arr, function (x, callback) {
+                iterator(x.value, function (err) {
+                    callback(err);
+                });
+            });
+        } else {
+            var results = [];
+            eachfn(arr, function (x, callback) {
+                iterator(x.value, function (err, v) {
+                    results[x.index] = v;
+                    callback(err);
+                });
+            }, function (err) {
+                callback(err, results);
+            });
+        }
+    };
+    async.map = doParallel(_asyncMap);
+    async.mapSeries = doSeries(_asyncMap);
+    async.mapLimit = function (arr, limit, iterator, callback) {
+        return _mapLimit(limit)(arr, iterator, callback);
+    };
+
+    var _mapLimit = function(limit) {
+        return doParallelLimit(limit, _asyncMap);
+    };
+
+    // reduce only has a series version, as doing reduce in parallel won't
+    // work in many situations.
+    async.reduce = function (arr, memo, iterator, callback) {
+        async.eachSeries(arr, function (x, callback) {
+            iterator(memo, x, function (err, v) {
+                memo = v;
+                callback(err);
+            });
+        }, function (err) {
+            callback(err, memo);
+        });
+    };
+    // inject alias
+    async.inject = async.reduce;
+    // foldl alias
+    async.foldl = async.reduce;
+
+    async.reduceRight = function (arr, memo, iterator, callback) {
+        var reversed = _map(arr, function (x) {
+            return x;
+        }).reverse();
+        async.reduce(reversed, memo, iterator, callback);
+    };
+    // foldr alias
+    async.foldr = async.reduceRight;
+
+    var _filter = function (eachfn, arr, iterator, callback) {
+        var results = [];
+        arr = _map(arr, function (x, i) {
+            return {index: i, value: x};
+        });
+        eachfn(arr, function (x, callback) {
+            iterator(x.value, function (v) {
+                if (v) {
+                    results.push(x);
+                }
+                callback();
+            });
+        }, function (err) {
+            callback(_map(results.sort(function (a, b) {
+                return a.index - b.index;
+            }), function (x) {
+                return x.value;
+            }));
+        });
+    };
+    async.filter = doParallel(_filter);
+    async.filterSeries = doSeries(_filter);
+    // select alias
+    async.select = async.filter;
+    async.selectSeries = async.filterSeries;
+
+    var _reject = function (eachfn, arr, iterator, callback) {
+        var results = [];
+        arr = _map(arr, function (x, i) {
+            return {index: i, value: x};
+        });
+        eachfn(arr, function (x, callback) {
+            iterator(x.value, function (v) {
+                if (!v) {
+                    results.push(x);
+                }
+                callback();
+            });
+        }, function (err) {
+            callback(_map(results.sort(function (a, b) {
+                return a.index - b.index;
+            }), function (x) {
+                return x.value;
+            }));
+        });
+    };
+    async.reject = doParallel(_reject);
+    async.rejectSeries = doSeries(_reject);
+
+    var _detect = function (eachfn, arr, iterator, main_callback) {
+        eachfn(arr, function (x, callback) {
+            iterator(x, function (result) {
+                if (result) {
+                    main_callback(x);
+                    main_callback = function () {};
+                }
+                else {
+                    callback();
+                }
+            });
+        }, function (err) {
+            main_callback();
+        });
+    };
+    async.detect = doParallel(_detect);
+    async.detectSeries = doSeries(_detect);
+
+    async.some = function (arr, iterator, main_callback) {
+        async.each(arr, function (x, callback) {
+            iterator(x, function (v) {
+                if (v) {
+                    main_callback(true);
+                    main_callback = function () {};
+                }
+                callback();
+            });
+        }, function (err) {
+            main_callback(false);
+        });
+    };
+    // any alias
+    async.any = async.some;
+
+    async.every = function (arr, iterator, main_callback) {
+        async.each(arr, function (x, callback) {
+            iterator(x, function (v) {
+                if (!v) {
+                    main_callback(false);
+                    main_callback = function () {};
+                }
+                callback();
+            });
+        }, function (err) {
+            main_callback(true);
+        });
+    };
+    // all alias
+    async.all = async.every;
+
+    async.sortBy = function (arr, iterator, callback) {
+        async.map(arr, function (x, callback) {
+            iterator(x, function (err, criteria) {
+                if (err) {
+                    callback(err);
+                }
+                else {
+                    callback(null, {value: x, criteria: criteria});
+                }
+            });
+        }, function (err, results) {
+            if (err) {
+                return callback(err);
+            }
+            else {
+                var fn = function (left, right) {
+                    var a = left.criteria, b = right.criteria;
+                    return a < b ? -1 : a > b ? 1 : 0;
+                };
+                callback(null, _map(results.sort(fn), function (x) {
+                    return x.value;
+                }));
+            }
+        });
+    };
+
+    async.auto = function (tasks, callback) {
+        callback = callback || function () {};
+        var keys = _keys(tasks);
+        var remainingTasks = keys.length
+        if (!remainingTasks) {
+            return callback();
+        }
+
+        var results = {};
+
+        var listeners = [];
+        var addListener = function (fn) {
+            listeners.unshift(fn);
+        };
+        var removeListener = function (fn) {
+            for (var i = 0; i < listeners.length; i += 1) {
+                if (listeners[i] === fn) {
+                    listeners.splice(i, 1);
+                    return;
+                }
+            }
+        };
+        var taskComplete = function () {
+            remainingTasks--
+            _each(listeners.slice(0), function (fn) {
+                fn();
+            });
+        };
+
+        addListener(function () {
+            if (!remainingTasks) {
+                var theCallback = callback;
+                // prevent final callback from calling itself if it errors
+                callback = function () {};
+
+                theCallback(null, results);
+            }
+        });
+
+        _each(keys, function (k) {
+            var task = _isArray(tasks[k]) ? tasks[k]: [tasks[k]];
+            var taskCallback = function (err) {
+                var args = Array.prototype.slice.call(arguments, 1);
+                if (args.length <= 1) {
+                    args = args[0];
+                }
+                if (err) {
+                    var safeResults = {};
+                    _each(_keys(results), function(rkey) {
+                        safeResults[rkey] = results[rkey];
+                    });
+                    safeResults[k] = args;
+                    callback(err, safeResults);
+                    // stop subsequent errors hitting callback multiple times
+                    callback = function () {};
+                }
+                else {
+                    results[k] = args;
+                    async.setImmediate(taskComplete);
+                }
+            };
+            var requires = task.slice(0, Math.abs(task.length - 1)) || [];
+            var ready = function () {
+                return _reduce(requires, function (a, x) {
+                    return (a && results.hasOwnProperty(x));
+                }, true) && !results.hasOwnProperty(k);
+            };
+            if (ready()) {
+                task[task.length - 1](taskCallback, results);
+            }
+            else {
+                var listener = function () {
+                    if (ready()) {
+                        removeListener(listener);
+                        task[task.length - 1](taskCallback, results);
+                    }
+                };
+                addListener(listener);
+            }
+        });
+    };
+
+    async.retry = function(times, task, callback) {
+        var DEFAULT_TIMES = 5;
+        var attempts = [];
+        // Use defaults if times not passed
+        if (typeof times === 'function') {
+            callback = task;
+            task = times;
+            times = DEFAULT_TIMES;
+        }
+        // Make sure times is a number
+        times = parseInt(times, 10) || DEFAULT_TIMES;
+        var wrappedTask = function(wrappedCallback, wrappedResults) {
+            var retryAttempt = function(task, finalAttempt) {
+                return function(seriesCallback) {
+                    task(function(err, result){
+                        seriesCallback(!err || finalAttempt, {err: err, result: result});
+                    }, wrappedResults);
+                };
+            };
+            while (times) {
+                attempts.push(retryAttempt(task, !(times-=1)));
+            }
+            async.series(attempts, function(done, data){
+                data = data[data.length - 1];
+                (wrappedCallback || callback)(data.err, data.result);
+            });
+        }
+        // If a callback is passed, run this as a controll flow
+        return callback ? wrappedTask() : wrappedTask
+    };
+
+    async.waterfall = function (tasks, callback) {
+        callback = callback || function () {};
+        if (!_isArray(tasks)) {
+          var err = new Error('First argument to waterfall must be an array of functions');
+          return callback(err);
+        }
+        if (!tasks.length) {
+            return callback();
+        }
+        var wrapIterator = function (iterator) {
+            return function (err) {
+                if (err) {
+                    callback.apply(null, arguments);
+                    callback = function () {};
+                }
+                else {
+                    var args = Array.prototype.slice.call(arguments, 1);
+                    var next = iterator.next();
+                    if (next) {
+                        args.push(wrapIterator(next));
+                    }
+                    else {
+                        args.push(callback);
+                    }
+                    async.setImmediate(function () {
+                        iterator.apply(null, args);
+                    });
+                }
+            };
+        };
+        wrapIterator(async.iterator(tasks))();
+    };
+
+    var _parallel = function(eachfn, tasks, callback) {
+        callback = callback || function () {};
+        if (_isArray(tasks)) {
+            eachfn.map(tasks, function (fn, callback) {
+                if (fn) {
+                    fn(function (err) {
+                        var args = Array.prototype.slice.call(arguments, 1);
+                        if (args.length <= 1) {
+                            args = args[0];
+                        }
+                        callback.call(null, err, args);
+                    });
+                }
+            }, callback);
+        }
+        else {
+            var results = {};
+            eachfn.each(_keys(tasks), function (k, callback) {
+                tasks[k](function (err) {
+                    var args = Array.prototype.slice.call(arguments, 1);
+                    if (args.length <= 1) {
+                        args = args[0];
+                    }
+                    results[k] = args;
+                    callback(err);
+                });
+            }, function (err) {
+                callback(err, results);
+            });
+        }
+    };
+
+    async.parallel = function (tasks, callback) {
+        _parallel({ map: async.map, each: async.each }, tasks, callback);
+    };
+
+    async.parallelLimit = function(tasks, limit, callback) {
+        _parallel({ map: _mapLimit(limit), each: _eachLimit(limit) }, tasks, callback);
+    };
+
+    async.series = function (tasks, callback) {
+        callback = callback || function () {};
+        if (_isArray(tasks)) {
+            async.mapSeries(tasks, function (fn, callback) {
+                if (fn) {
+                    fn(function (err) {
+                        var args = Array.prototype.slice.call(arguments, 1);
+                        if (args.length <= 1) {
+                            args = args[0];
+                        }
+                        callback.call(null, err, args);
+                    });
+                }
+            }, callback);
+        }
+        else {
+            var results = {};
+            async.eachSeries(_keys(tasks), function (k, callback) {
+                tasks[k](function (err) {
+                    var args = Array.prototype.slice.call(arguments, 1);
+                    if (args.length <= 1) {
+                        args = args[0];
+                    }
+                    results[k] = args;
+                    callback(err);
+                });
+            }, function (err) {
+                callback(err, results);
+            });
+        }
+    };
+
+    async.iterator = function (tasks) {
+        var makeCallback = function (index) {
+            var fn = function () {
+                if (tasks.length) {
+                    tasks[index].apply(null, arguments);
+                }
+                return fn.next();
+            };
+            fn.next = function () {
+                return (index < tasks.length - 1) ? makeCallback(index + 1): null;
+            };
+            return fn;
+        };
+        return makeCallback(0);
+    };
+
+    async.apply = function (fn) {
+        var args = Array.prototype.slice.call(arguments, 1);
+        return function () {
+            return fn.apply(
+                null, args.concat(Array.prototype.slice.call(arguments))
+            );
+        };
+    };
+
+    var _concat = function (eachfn, arr, fn, callback) {
+        var r = [];
+        eachfn(arr, function (x, cb) {
+            fn(x, function (err, y) {
+                r = r.concat(y || []);
+                cb(err);
+            });
+        }, function (err) {
+            callback(err, r);
+        });
+    };
+    async.concat = doParallel(_concat);
+    async.concatSeries = doSeries(_concat);
+
+    async.whilst = function (test, iterator, callback) {
+        if (test()) {
+            iterator(function (err) {
+                if (err) {
+                    return callback(err);
+                }
+                async.whilst(test, iterator, callback);
+            });
+        }
+        else {
+            callback();
+        }
+    };
+
+    async.doWhilst = function (iterator, test, callback) {
+        iterator(function (err) {
+            if (err) {
+                return callback(err);
+            }
+            var args = Array.prototype.slice.call(arguments, 1);
+            if (test.apply(null, args)) {
+                async.doWhilst(iterator, test, callback);
+            }
+            else {
+                callback();
+            }
+        });
+    };
+
+    async.until = function (test, iterator, callback) {
+        if (!test()) {
+            iterator(function (err) {
+                if (err) {
+                    return callback(err);
+                }
+                async.until(test, iterator, callback);
+            });
+        }
+        else {
+            callback();
+        }
+    };
+
+    async.doUntil = function (iterator, test, callback) {
+        iterator(function (err) {
+            if (err) {
+                return callback(err);
+            }
+            var args = Array.prototype.slice.call(arguments, 1);
+            if (!test.apply(null, args)) {
+                async.doUntil(iterator, test, callback);
+            }
+            else {
+                callback();
+            }
+        });
+    };
+
+    async.queue = function (worker, concurrency) {
+        if (concurrency === undefined) {
+            concurrency = 1;
+        }
+        function _insert(q, data, pos, callback) {
+          if (!q.started){
+            q.started = true;
+          }
+          if (!_isArray(data)) {
+              data = [data];
+          }
+          if(data.length == 0) {
+             // call drain immediately if there are no tasks
+             return async.setImmediate(function() {
+                 if (q.drain) {
+                     q.drain();
+                 }
+             });
+          }
+          _each(data, function(task) {
+              var item = {
+                  data: task,
+                  callback: typeof callback === 'function' ? callback : null
+              };
+
+              if (pos) {
+                q.tasks.unshift(item);
+              } else {
+                q.tasks.push(item);
+              }
+
+              if (q.saturated && q.tasks.length === q.concurrency) {
+                  q.saturated();
+              }
+              async.setImmediate(q.process);
+          });
+        }
+
+        var workers = 0;
+        var q = {
+            tasks: [],
+            concurrency: concurrency,
+            saturated: null,
+            empty: null,
+            drain: null,
+            started: false,
+            paused: false,
+            push: function (data, callback) {
+              _insert(q, data, false, callback);
+            },
+            kill: function () {
+              q.drain = null;
+              q.tasks = [];
+            },
+            unshift: function (data, callback) {
+              _insert(q, data, true, callback);
+            },
+            process: function () {
+                if (!q.paused && workers < q.concurrency && q.tasks.length) {
+                    var task = q.tasks.shift();
+                    if (q.empty && q.tasks.length === 0) {
+                        q.empty();
+                    }
+                    workers += 1;
+                    var next = function () {
+                        workers -= 1;
+                        if (task.callback) {
+                            task.callback.apply(task, arguments);
+                        }
+                        if (q.drain && q.tasks.length + workers === 0) {
+                            q.drain();
+                        }
+                        q.process();
+                    };
+                    var cb = only_once(next);
+                    worker(task.data, cb);
+                }
+            },
+            length: function () {
+                return q.tasks.length;
+            },
+            running: function () {
+                return workers;
+            },
+            idle: function() {
+                return q.tasks.length + workers === 0;
+            },
+            pause: function () {
+                if (q.paused === true) { return; }
+                q.paused = true;
+            },
+            resume: function () {
+                if (q.paused === false) { return; }
+                q.paused = false;
+                // Need to call q.process once per concurrent
+                // worker to preserve full concurrency after pause
+                for (var w = 1; w <= q.concurrency; w++) {
+                    async.setImmediate(q.process);
+                }
+            }
+        };
+        return q;
+    };
+
+    async.priorityQueue = function (worker, concurrency) {
+
+        function _compareTasks(a, b){
+          return a.priority - b.priority;
+        };
+
+        function _binarySearch(sequence, item, compare) {
+          var beg = -1,
+              end = sequence.length - 1;
+          while (beg < end) {
+            var mid = beg + ((end - beg + 1) >>> 1);
+            if (compare(item, sequence[mid]) >= 0) {
+              beg = mid;
+            } else {
+              end = mid - 1;
+            }
+          }
+          return beg;
+        }
+
+        function _insert(q, data, priority, callback) {
+          if (!q.started){
+            q.started = true;
+          }
+          if (!_isArray(data)) {
+              data = [data];
+          }
+          if(data.length == 0) {
+             // call drain immediately if there are no tasks
+             return async.setImmediate(function() {
+                 if (q.drain) {
+                     q.drain();
+                 }
+             });
+          }
+          _each(data, function(task) {
+              var item = {
+                  data: task,
+                  priority: priority,
+                  callback: typeof callback === 'function' ? callback : null
+              };
+
+              q.tasks.splice(_binarySearch(q.tasks, item, _compareTasks) + 1, 0, item);
+
+              if (q.saturated && q.tasks.length === q.concurrency) {
+                  q.saturated();
+              }
+              async.setImmediate(q.process);
+          });
+        }
+
+        // Start with a normal queue
+        var q = async.queue(worker, concurrency);
+
+        // Override push to accept second parameter representing priority
+        q.push = function (data, priority, callback) {
+          _insert(q, data, priority, callback);
+        };
+
+        // Remove unshift function
+        delete q.unshift;
+
+        return q;
+    };
+
+    async.cargo = function (worker, payload) {
+        var working     = false,
+            tasks       = [];
+
+        var cargo = {
+            tasks: tasks,
+            payload: payload,
+            saturated: null,
+            empty: null,
+            drain: null,
+            drained: true,
+            push: function (data, callback) {
+                if (!_isArray(data)) {
+                    data = [data];
+                }
+                _each(data, function(task) {
+                    tasks.push({
+                        data: task,
+                        callback: typeof callback === 'function' ? callback : null
+                    });
+                    cargo.drained = false;
+                    if (cargo.saturated && tasks.length === payload) {
+                        cargo.saturated();
+                    }
+                });
+                async.setImmediate(cargo.process);
+            },
+            process: function process() {
+                if (working) return;
+                if (tasks.length === 0) {
+                    if(cargo.drain && !cargo.drained) cargo.drain();
+                    cargo.drained = true;
+                    return;
+                }
+
+                var ts = typeof payload === 'number'
+                            ? tasks.splice(0, payload)
+                            : tasks.splice(0, tasks.length);
+
+                var ds = _map(ts, function (task) {
+                    return task.data;
+                });
+
+                if(cargo.empty) cargo.empty();
+                working = true;
+                worker(ds, function () {
+                    working = false;
+
+                    var args = arguments;
+                    _each(ts, function (data) {
+                        if (data.callback) {
+                            data.callback.apply(null, args);
+                        }
+                    });
+
+                    process();
+                });
+            },
+            length: function () {
+                return tasks.length;
+            },
+            running: function () {
+                return working;
+            }
+        };
+        return cargo;
+    };
+
+    var _console_fn = function (name) {
+        return function (fn) {
+            var args = Array.prototype.slice.call(arguments, 1);
+            fn.apply(null, args.concat([function (err) {
+                var args = Array.prototype.slice.call(arguments, 1);
+                if (typeof console !== 'undefined') {
+                    if (err) {
+                        if (console.error) {
+                            console.error(err);
+                        }
+                    }
+                    else if (console[name]) {
+                        _each(args, function (x) {
+                            console[name](x);
+                        });
+                    }
+                }
+            }]));
+        };
+    };
+    async.log = _console_fn('log');
+    async.dir = _console_fn('dir');
+    /*async.info = _console_fn('info');
+    async.warn = _console_fn('warn');
+    async.error = _console_fn('error');*/
+
+    async.memoize = function (fn, hasher) {
+        var memo = {};
+        var queues = {};
+        hasher = hasher || function (x) {
+            return x;
+        };
+        var memoized = function () {
+            var args = Array.prototype.slice.call(arguments);
+            var callback = args.pop();
+            var key = hasher.apply(null, args);
+            if (key in memo) {
+                async.nextTick(function () {
+                    callback.apply(null, memo[key]);
+                });
+            }
+            else if (key in queues) {
+                queues[key].push(callback);
+            }
+            else {
+                queues[key] = [callback];
+                fn.apply(null, args.concat([function () {
+                    memo[key] = arguments;
+                    var q = queues[key];
+                    delete queues[key];
+                    for (var i = 0, l = q.length; i < l; i++) {
+                      q[i].apply(null, arguments);
+                    }
+                }]));
+            }
+        };
+        memoized.memo = memo;
+        memoized.unmemoized = fn;
+        return memoized;
+    };
+
+    async.unmemoize = function (fn) {
+      return function () {
+        return (fn.unmemoized || fn).apply(null, arguments);
+      };
+    };
+
+    async.times = function (count, iterator, callback) {
+        var counter = [];
+        for (var i = 0; i < count; i++) {
+            counter.push(i);
+        }
+        return async.map(counter, iterator, callback);
+    };
+
+    async.timesSeries = function (count, iterator, callback) {
+        var counter = [];
+        for (var i = 0; i < count; i++) {
+            counter.push(i);
+        }
+        return async.mapSeries(counter, iterator, callback);
+    };
+
+    async.seq = function (/* functions... */) {
+        var fns = arguments;
+        return function () {
+            var that = this;
+            var args = Array.prototype.slice.call(arguments);
+            var callback = args.pop();
+            async.reduce(fns, args, function (newargs, fn, cb) {
+                fn.apply(that, newargs.concat([function () {
+                    var err = arguments[0];
+                    var nextargs = Array.prototype.slice.call(arguments, 1);
+                    cb(err, nextargs);
+                }]))
+            },
+            function (err, results) {
+                callback.apply(that, [err].concat(results));
+            });
+        };
+    };
+
+    async.compose = function (/* functions... */) {
+      return async.seq.apply(null, Array.prototype.reverse.call(arguments));
+    };
+
+    var _applyEach = function (eachfn, fns /*args...*/) {
+        var go = function () {
+            var that = this;
+            var args = Array.prototype.slice.call(arguments);
+            var callback = args.pop();
+            return eachfn(fns, function (fn, cb) {
+                fn.apply(that, args.concat([cb]));
+            },
+            callback);
+        };
+        if (arguments.length > 2) {
+            var args = Array.prototype.slice.call(arguments, 2);
+            return go.apply(this, args);
+        }
+        else {
+            return go;
+        }
+    };
+    async.applyEach = doParallel(_applyEach);
+    async.applyEachSeries = doSeries(_applyEach);
+
+    async.forever = function (fn, callback) {
+        function next(err) {
+            if (err) {
+                if (callback) {
+                    return callback(err);
+                }
+                throw err;
+            }
+            fn(next);
+        }
+        next();
+    };
+
+    // Node.js
+    if (typeof module !== 'undefined' && module.exports) {
+        module.exports = async;
+    }
+    // AMD / RequireJS
+    else if (typeof define !== 'undefined' && define.amd) {
+        define([], function () {
+            return async;
+        });
+    }
+    // included directly via <script> tag
+    else {
+        root.async = async;
+    }
+
+}());

+ 84 - 0
Build/node_modules/jake/node_modules/async/package.json

@@ -0,0 +1,84 @@
+{
+  "name": "async",
+  "description": "Higher-order functions and common patterns for asynchronous code",
+  "main": "lib/async.js",
+  "author": {
+    "name": "Caolan McMahon"
+  },
+  "version": "0.9.2",
+  "keywords": [
+    "async",
+    "callback",
+    "utility",
+    "module"
+  ],
+  "repository": {
+    "type": "git",
+    "url": "git+https://github.com/caolan/async.git"
+  },
+  "bugs": {
+    "url": "https://github.com/caolan/async/issues"
+  },
+  "license": "MIT",
+  "devDependencies": {
+    "nodeunit": ">0.0.0",
+    "uglify-js": "1.2.x",
+    "nodelint": ">0.0.0",
+    "lodash": ">=2.4.1"
+  },
+  "jam": {
+    "main": "lib/async.js",
+    "include": [
+      "lib/async.js",
+      "README.md",
+      "LICENSE"
+    ],
+    "categories": [
+      "Utilities"
+    ]
+  },
+  "scripts": {
+    "test": "nodeunit test/test-async.js"
+  },
+  "spm": {
+    "main": "lib/async.js"
+  },
+  "volo": {
+    "main": "lib/async.js",
+    "ignore": [
+      "**/.*",
+      "node_modules",
+      "bower_components",
+      "test",
+      "tests"
+    ]
+  },
+  "gitHead": "de3a16091d5125384eff4a54deb3998b13c3814c",
+  "homepage": "https://github.com/caolan/async#readme",
+  "_id": "[email protected]",
+  "_shasum": "aea74d5e61c1f899613bf64bda66d4c78f2fd17d",
+  "_from": "async@>=0.9.0 <0.10.0",
+  "_npmVersion": "2.9.0",
+  "_nodeVersion": "2.0.1",
+  "_npmUser": {
+    "name": "beaugunderson",
+    "email": "[email protected]"
+  },
+  "maintainers": [
+    {
+      "name": "caolan",
+      "email": "[email protected]"
+    },
+    {
+      "name": "beaugunderson",
+      "email": "[email protected]"
+    }
+  ],
+  "dist": {
+    "shasum": "aea74d5e61c1f899613bf64bda66d4c78f2fd17d",
+    "tarball": "http://registry.npmjs.org/async/-/async-0.9.2.tgz"
+  },
+  "directories": {},
+  "_resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz",
+  "readme": "ERROR: No README data found!"
+}

+ 53 - 0
Build/node_modules/jake/node_modules/async/support/sync-package-managers.js

@@ -0,0 +1,53 @@
+#!/usr/bin/env node
+
+// This should probably be its own module but complaints about bower/etc.
+// support keep coming up and I'd rather just enable the workflow here for now
+// and figure out where this should live later. -- @beaugunderson
+
+var fs = require('fs');
+var _ = require('lodash');
+
+var packageJson = require('../package.json');
+
+var IGNORES = ['**/.*', 'node_modules', 'bower_components', 'test', 'tests'];
+var INCLUDES = ['lib/async.js', 'README.md', 'LICENSE'];
+var REPOSITORY_NAME = 'caolan/async';
+
+packageJson.jam = {
+  main: packageJson.main,
+  include: INCLUDES,
+  categories: ['Utilities']
+};
+
+packageJson.spm = {
+  main: packageJson.main
+};
+
+packageJson.volo = {
+  main: packageJson.main,
+  ignore: IGNORES
+};
+
+var bowerSpecific = {
+  moduleType: ['amd', 'globals', 'node'],
+  ignore: IGNORES,
+  authors: [packageJson.author]
+};
+
+var bowerInclude = ['name', 'description', 'version', 'main', 'keywords',
+  'license', 'homepage', 'repository', 'devDependencies'];
+
+var componentSpecific = {
+  repository: REPOSITORY_NAME,
+  scripts: [packageJson.main]
+};
+
+var componentInclude = ['name', 'description', 'version', 'keywords',
+  'license'];
+
+var bowerJson = _.merge({}, _.pick(packageJson, bowerInclude), bowerSpecific);
+var componentJson = _.merge({}, _.pick(packageJson, componentInclude), componentSpecific);
+
+fs.writeFileSync('./bower.json', JSON.stringify(bowerJson, null, 2));
+fs.writeFileSync('./component.json', JSON.stringify(componentJson, null, 2));
+fs.writeFileSync('./package.json', JSON.stringify(packageJson, null, 2));

+ 63 - 0
Build/node_modules/jake/node_modules/chalk/index.js

@@ -0,0 +1,63 @@
+'use strict';
+var ansi = require('ansi-styles');
+var stripAnsi = require('strip-ansi');
+var hasColor = require('has-color');
+var defineProps = Object.defineProperties;
+var chalk = module.exports;
+
+var styles = (function () {
+	var ret = {};
+
+	ansi.grey = ansi.gray;
+
+	Object.keys(ansi).forEach(function (key) {
+		ret[key] = {
+			get: function () {
+				this._styles.push(key);
+				return this;
+			}
+		};
+	});
+
+	return ret;
+})();
+
+function init() {
+	var ret = {};
+
+	Object.keys(styles).forEach(function (name) {
+		ret[name] = {
+			get: function () {
+				var obj = defineProps(function self() {
+					var str = [].slice.call(arguments).join(' ');
+
+					if (!chalk.enabled) {
+						return str;
+					}
+
+					return self._styles.reduce(function (str, name) {
+						var code = ansi[name];
+						return str ? code.open + str + code.close : '';
+					}, str);
+				}, styles);
+
+				obj._styles = [];
+
+				return obj[name];
+			}
+		}
+	});
+
+	return ret;
+}
+
+defineProps(chalk, init());
+
+chalk.styles = ansi;
+chalk.stripColor = stripAnsi;
+chalk.supportsColor = hasColor;
+
+// detect mode if not set manually
+if (chalk.enabled === undefined) {
+	chalk.enabled = chalk.supportsColor;
+}

+ 1 - 0
Build/node_modules/jake/node_modules/chalk/node_modules/.bin/strip-ansi

@@ -0,0 +1 @@
+../strip-ansi/cli.js

+ 38 - 0
Build/node_modules/jake/node_modules/chalk/node_modules/ansi-styles/ansi-styles.js

@@ -0,0 +1,38 @@
+'use strict';
+var styles = module.exports;
+
+var codes = {
+	reset: [0, 0],
+
+	bold: [1, 22],
+	italic: [3, 23],
+	underline: [4, 24],
+	inverse: [7, 27],
+	strikethrough: [9, 29],
+
+	black: [30, 39],
+	red: [31, 39],
+	green: [32, 39],
+	yellow: [33, 39],
+	blue: [34, 39],
+	magenta: [35, 39],
+	cyan: [36, 39],
+	white: [37, 39],
+	gray: [90, 39],
+
+	bgBlack: [40, 49],
+	bgRed: [41, 49],
+	bgGreen: [42, 49],
+	bgYellow: [43, 49],
+	bgBlue: [44, 49],
+	bgMagenta: [45, 49],
+	bgCyan: [46, 49],
+	bgWhite: [47, 49]
+};
+
+Object.keys(codes).forEach(function (key) {
+	var val = codes[key];
+	var style = styles[key] = {};
+	style.open = '\x1b[' + val[0] + 'm';
+	style.close = '\x1b[' + val[1] + 'm';
+});

+ 75 - 0
Build/node_modules/jake/node_modules/chalk/node_modules/ansi-styles/package.json

@@ -0,0 +1,75 @@
+{
+  "name": "ansi-styles",
+  "version": "1.0.0",
+  "description": "ANSI escape codes for colorizing strings in the terminal",
+  "keywords": [
+    "ansi",
+    "styles",
+    "color",
+    "colour",
+    "colors",
+    "terminal",
+    "console",
+    "cli",
+    "string",
+    "tty",
+    "escape",
+    "formatting",
+    "rgb",
+    "256",
+    "shell",
+    "xterm",
+    "log",
+    "logging",
+    "command-line",
+    "text"
+  ],
+  "homepage": "https://github.com/sindresorhus/ansi-styles",
+  "bugs": {
+    "url": "https://github.com/sindresorhus/ansi-styles/issues"
+  },
+  "license": "MIT",
+  "author": {
+    "name": "Sindre Sorhus",
+    "email": "[email protected]",
+    "url": "http://sindresorhus.com"
+  },
+  "files": [
+    "ansi-styles.js"
+  ],
+  "main": "ansi-styles",
+  "repository": {
+    "type": "git",
+    "url": "git://github.com/sindresorhus/ansi-styles.git"
+  },
+  "scripts": {
+    "test": "mocha"
+  },
+  "devDependencies": {
+    "mocha": "~1.12.0"
+  },
+  "engines": {
+    "node": ">=0.8.0"
+  },
+  "_id": "[email protected]",
+  "dist": {
+    "shasum": "cb102df1c56f5123eab8b67cd7b98027a0279178",
+    "tarball": "http://registry.npmjs.org/ansi-styles/-/ansi-styles-1.0.0.tgz"
+  },
+  "_from": "ansi-styles@>=1.0.0 <1.1.0",
+  "_npmVersion": "1.3.15",
+  "_npmUser": {
+    "name": "sindresorhus",
+    "email": "[email protected]"
+  },
+  "maintainers": [
+    {
+      "name": "sindresorhus",
+      "email": "[email protected]"
+    }
+  ],
+  "directories": {},
+  "_shasum": "cb102df1c56f5123eab8b67cd7b98027a0279178",
+  "_resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.0.0.tgz",
+  "readme": "ERROR: No README data found!"
+}

+ 65 - 0
Build/node_modules/jake/node_modules/chalk/node_modules/ansi-styles/readme.md

@@ -0,0 +1,65 @@
+# ansi-styles [![Build Status](https://secure.travis-ci.org/sindresorhus/ansi-styles.png?branch=master)](http://travis-ci.org/sindresorhus/ansi-styles)
+
+> [ANSI escape codes](http://en.wikipedia.org/wiki/ANSI_escape_code#Colors_and_Styles) for colorizing strings in the terminal.
+
+You probably want the higher-level [chalk](https://github.com/sindresorhus/chalk) module for styling your strings.
+
+![screenshot](screenshot.png)
+
+
+## Install
+
+Install with [npm](https://npmjs.org/package/ansi-styles): `npm install --save ansi-styles`
+
+
+## Example
+
+```js
+var ansi = require('ansi-styles');
+
+console.log(ansi.green.open + 'Hello world!' + ansi.green.close);
+```
+
+## API
+
+Each style has an `open` and `close` property.
+
+
+## Styles
+
+### General
+
+- reset
+- bold
+- italic
+- underline
+- inverse
+- strikethrough
+
+### Text colors
+
+- black
+- red
+- green
+- yellow
+- blue
+- magenta
+- cyan
+- white
+- gray
+
+### Background colors
+
+- bgBlack
+- bgRed
+- bgGreen
+- bgYellow
+- bgBlue
+- bgMagenta
+- bgCyan
+- bgWhite
+
+
+## License
+
+MIT © [Sindre Sorhus](http://sindresorhus.com)

+ 32 - 0
Build/node_modules/jake/node_modules/chalk/node_modules/has-color/index.js

@@ -0,0 +1,32 @@
+'use strict';
+module.exports = (function () {
+	if (process.argv.indexOf('--no-color') !== -1) {
+		return false;
+	}
+
+	if (process.argv.indexOf('--color') !== -1) {
+		return true;
+	}
+
+	if (process.stdout && !process.stdout.isTTY) {
+		return false;
+	}
+
+	if (process.platform === 'win32') {
+		return true;
+	}
+
+	if ('COLORTERM' in process.env) {
+		return true;
+	}
+
+	if (process.env.TERM === 'dumb') {
+		return false;
+	}
+
+	if (/^screen|^xterm|^vt100|color|ansi|cygwin|linux/i.test(process.env.TERM)) {
+		return true;
+	}
+
+	return false;
+})();

+ 71 - 0
Build/node_modules/jake/node_modules/chalk/node_modules/has-color/package.json

@@ -0,0 +1,71 @@
+{
+  "name": "has-color",
+  "version": "0.1.7",
+  "description": "Detect whether a terminal supports color",
+  "license": "MIT",
+  "repository": {
+    "type": "git",
+    "url": "git://github.com/sindresorhus/has-color.git"
+  },
+  "author": {
+    "name": "Sindre Sorhus",
+    "email": "[email protected]",
+    "url": "http://sindresorhus.com"
+  },
+  "engines": {
+    "node": ">=0.10.0"
+  },
+  "scripts": {
+    "test": "mocha"
+  },
+  "files": [
+    "index.js"
+  ],
+  "keywords": [
+    "color",
+    "colour",
+    "colors",
+    "terminal",
+    "console",
+    "cli",
+    "ansi",
+    "styles",
+    "tty",
+    "rgb",
+    "256",
+    "shell",
+    "xterm",
+    "command-line",
+    "support",
+    "capability",
+    "detect"
+  ],
+  "devDependencies": {
+    "mocha": "*"
+  },
+  "bugs": {
+    "url": "https://github.com/sindresorhus/has-color/issues"
+  },
+  "homepage": "https://github.com/sindresorhus/has-color",
+  "_id": "[email protected]",
+  "dist": {
+    "shasum": "67144a5260c34fc3cca677d041daf52fe7b78b2f",
+    "tarball": "http://registry.npmjs.org/has-color/-/has-color-0.1.7.tgz"
+  },
+  "_from": "has-color@>=0.1.0 <0.2.0",
+  "_npmVersion": "1.4.6",
+  "_npmUser": {
+    "name": "sindresorhus",
+    "email": "[email protected]"
+  },
+  "maintainers": [
+    {
+      "name": "sindresorhus",
+      "email": "[email protected]"
+    }
+  ],
+  "directories": {},
+  "_shasum": "67144a5260c34fc3cca677d041daf52fe7b78b2f",
+  "_resolved": "https://registry.npmjs.org/has-color/-/has-color-0.1.7.tgz",
+  "readme": "ERROR: No README data found!"
+}

+ 30 - 0
Build/node_modules/jake/node_modules/chalk/node_modules/has-color/readme.md

@@ -0,0 +1,30 @@
+# has-color [![Build Status](https://travis-ci.org/sindresorhus/has-color.svg?branch=master)](https://travis-ci.org/sindresorhus/has-color)
+
+> Detect whether a terminal supports color.
+
+Used in the terminal color module [chalk](https://github.com/sindresorhus/chalk).
+
+
+## Install
+
+```bash
+$ npm install --save has-color
+```
+
+
+## Usage
+
+```js
+var hasColor = require('has-color');
+
+if (hasColor) {
+	console.log('Terminal supports color.');
+}
+```
+
+It obeys the `--color` and `--no-color` CLI flags.
+
+
+## License
+
+[MIT](http://opensource.org/licenses/MIT) © [Sindre Sorhus](http://sindresorhus.com)

+ 27 - 0
Build/node_modules/jake/node_modules/chalk/node_modules/strip-ansi/cli.js

@@ -0,0 +1,27 @@
+#!/usr/bin/env node
+'use strict';
+var fs = require('fs');
+var strip = require('./index');
+var input = process.argv[2];
+
+if (process.argv.indexOf('-h') !== -1 || process.argv.indexOf('--help') !== -1) {
+	console.log('strip-ansi <input file> > <output file>');
+	console.log('or');
+	console.log('cat <input file> | strip-ansi > <output file>');
+	return;
+}
+
+if (process.argv.indexOf('-v') !== -1 || process.argv.indexOf('--version') !== -1) {
+	console.log(require('./package').version);
+	return;
+}
+
+if (input) {
+	process.stdout.write(strip(fs.readFileSync(input, 'utf8')));
+	return;
+}
+
+process.stdin.setEncoding('utf8');
+process.stdin.on('data', function (data) {
+	process.stdout.write(strip(data));
+});

+ 4 - 0
Build/node_modules/jake/node_modules/chalk/node_modules/strip-ansi/index.js

@@ -0,0 +1,4 @@
+'use strict';
+module.exports = function (str) {
+	return typeof str === 'string' ? str.replace(/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]/g, '') : str;
+};

+ 81 - 0
Build/node_modules/jake/node_modules/chalk/node_modules/strip-ansi/package.json

@@ -0,0 +1,81 @@
+{
+  "name": "strip-ansi",
+  "version": "0.1.1",
+  "description": "Strip ANSI escape codes (used for colorizing strings in the terminal)",
+  "license": "MIT",
+  "bin": {
+    "strip-ansi": "cli.js"
+  },
+  "repository": {
+    "type": "git",
+    "url": "git://github.com/sindresorhus/strip-ansi.git"
+  },
+  "author": {
+    "name": "Sindre Sorhus",
+    "email": "[email protected]",
+    "url": "http://sindresorhus.com"
+  },
+  "engines": {
+    "node": ">=0.8.0"
+  },
+  "scripts": {
+    "test": "mocha"
+  },
+  "files": [
+    "index.js",
+    "cli.js"
+  ],
+  "keywords": [
+    "strip",
+    "trim",
+    "remove",
+    "ansi",
+    "styles",
+    "color",
+    "colour",
+    "colors",
+    "terminal",
+    "console",
+    "cli",
+    "string",
+    "tty",
+    "escape",
+    "formatting",
+    "rgb",
+    "256",
+    "shell",
+    "xterm",
+    "log",
+    "logging",
+    "command-line",
+    "text"
+  ],
+  "devDependencies": {
+    "mocha": "~1.x"
+  },
+  "bugs": {
+    "url": "https://github.com/sindresorhus/strip-ansi/issues"
+  },
+  "homepage": "https://github.com/sindresorhus/strip-ansi",
+  "_id": "[email protected]",
+  "dist": {
+    "shasum": "39e8a98d044d150660abe4a6808acf70bb7bc991",
+    "tarball": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-0.1.1.tgz"
+  },
+  "_from": "strip-ansi@>=0.1.0 <0.2.0",
+  "_npmVersion": "1.3.15",
+  "_npmUser": {
+    "name": "sindresorhus",
+    "email": "[email protected]"
+  },
+  "maintainers": [
+    {
+      "name": "sindresorhus",
+      "email": "[email protected]"
+    }
+  ],
+  "directories": {},
+  "_shasum": "39e8a98d044d150660abe4a6808acf70bb7bc991",
+  "_resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.1.1.tgz",
+  "readme": "ERROR: No README data found!"
+}

+ 46 - 0
Build/node_modules/jake/node_modules/chalk/node_modules/strip-ansi/readme.md

@@ -0,0 +1,46 @@
+# strip-ansi [![Build Status](https://secure.travis-ci.org/sindresorhus/strip-ansi.png?branch=master)](http://travis-ci.org/sindresorhus/strip-ansi)
+
+> Strip [ANSI escape codes](http://en.wikipedia.org/wiki/ANSI_escape_code#Colors_and_Styles) (used for colorizing strings in the terminal)
+
+Used in the terminal color module [chalk](https://github.com/sindresorhus/chalk).
+
+
+## Install
+
+Install locally with [npm](https://npmjs.org/package/strip-ansi):
+
+```
+npm install --save strip-ansi
+```
+
+Or globally if you want to use it as a CLI app:
+
+```
+npm install --global strip-ansi
+```
+
+You can then use it in your Terminal like:
+
+```
+strip-ansi file-with-color-codes
+```
+
+Or pipe something to it:
+
+```
+ls | strip-ansi
+```
+
+
+## Example
+
+```js
+var stripAnsi = require('strip-ansi');
+stripAnsi('\x1b[4mcake\x1b[0m');
+//=> cake
+```
+
+
+## License
+
+MIT © [Sindre Sorhus](http://sindresorhus.com)

+ 78 - 0
Build/node_modules/jake/node_modules/chalk/package.json

@@ -0,0 +1,78 @@
+{
+  "name": "chalk",
+  "version": "0.4.0",
+  "description": "Terminal string styling done right. Created because the `colors` module does some really horrible things.",
+  "license": "MIT",
+  "repository": {
+    "type": "git",
+    "url": "git://github.com/sindresorhus/chalk.git"
+  },
+  "author": {
+    "name": "Sindre Sorhus",
+    "email": "[email protected]",
+    "url": "http://sindresorhus.com"
+  },
+  "engines": {
+    "node": ">=0.8.0"
+  },
+  "scripts": {
+    "test": "mocha"
+  },
+  "files": [
+    "index.js"
+  ],
+  "keywords": [
+    "color",
+    "colour",
+    "colors",
+    "terminal",
+    "console",
+    "cli",
+    "string",
+    "ansi",
+    "styles",
+    "tty",
+    "formatting",
+    "rgb",
+    "256",
+    "shell",
+    "xterm",
+    "log",
+    "logging",
+    "command-line",
+    "text"
+  ],
+  "dependencies": {
+    "has-color": "~0.1.0",
+    "ansi-styles": "~1.0.0",
+    "strip-ansi": "~0.1.0"
+  },
+  "devDependencies": {
+    "mocha": "~1.x"
+  },
+  "bugs": {
+    "url": "https://github.com/sindresorhus/chalk/issues"
+  },
+  "homepage": "https://github.com/sindresorhus/chalk",
+  "_id": "[email protected]",
+  "dist": {
+    "shasum": "5199a3ddcd0c1efe23bc08c1b027b06176e0c64f",
+    "tarball": "http://registry.npmjs.org/chalk/-/chalk-0.4.0.tgz"
+  },
+  "_from": "chalk@>=0.4.0 <0.5.0",
+  "_npmVersion": "1.3.17",
+  "_npmUser": {
+    "name": "sindresorhus",
+    "email": "[email protected]"
+  },
+  "maintainers": [
+    {
+      "name": "sindresorhus",
+      "email": "[email protected]"
+    }
+  ],
+  "directories": {},
+  "_shasum": "5199a3ddcd0c1efe23bc08c1b027b06176e0c64f",
+  "_resolved": "https://registry.npmjs.org/chalk/-/chalk-0.4.0.tgz",
+  "readme": "ERROR: No README data found!"
+}

+ 158 - 0
Build/node_modules/jake/node_modules/chalk/readme.md

@@ -0,0 +1,158 @@
+# <img width="250" src="logo.png" alt="chalk">
+
+> Terminal string styling done right
+
+[![Build Status](https://secure.travis-ci.org/sindresorhus/chalk.png?branch=master)](http://travis-ci.org/sindresorhus/chalk)
+
+[colors.js](https://github.com/Marak/colors.js) is currently the most popular string styling module, but it has serious deficiencies like extending String.prototype which causes all kinds of [problems](https://github.com/yeoman/yo/issues/68). Although there are other ones, they either do too much or not enough.
+
+**Chalk is a clean and focused alternative.**
+
+![screenshot](screenshot.png)
+
+
+## Why
+
+- **Doesn't extend String.prototype**
+- Expressive API
+- Clean and focused
+- Auto-detects color support
+- Actively maintained
+- [Used by 150+ modules](https://npmjs.org/browse/depended/chalk)
+
+
+## Install
+
+Install with [npm](https://npmjs.org/package/chalk): `npm install --save chalk`
+
+
+## Example
+
+Chalk comes with an easy to use composable API where you just chain and nest the styles you want.
+
+```js
+var chalk = require('chalk');
+
+// style a string
+console.log(  chalk.blue('Hello world!')  );
+
+// combine styled and normal strings
+console.log(  chalk.blue('Hello'), 'World' + chalk.red('!')  );
+
+// compose multiple styles using the chainable API
+console.log(  chalk.blue.bgRed.bold('Hello world!')  );
+
+// nest styles
+console.log(  chalk.red('Hello', chalk.underline.bgBlue('world') + '!')  );
+
+// pass in multiple arguments
+console.log(  chalk.blue('Hello', 'World!', 'Foo', 'bar', 'biz', 'baz')  );
+```
+
+You can easily define your own themes.
+
+```js
+var chalk = require('chalk');
+var error = chalk.bold.red;
+console.log(error('Error!'));
+```
+
+
+## API
+
+### chalk.`<style>[.<style>...](string, [string...])`
+
+Example: `chalk.red.bold.underline('Hello', 'world');`
+
+Chain [styles](#styles) and call the last one as a method with a string argument. Order doesn't matter.
+
+Multiple arguments will be separated by space.
+
+### chalk.enabled
+
+Color support is automatically detected, but you can override it.
+
+### chalk.supportsColor
+
+Detect whether the terminal [supports color](https://github.com/sindresorhus/has-color).
+
+Can be overridden by the user with the flags `--color` and `--no-color`.
+
+Used internally and handled for you, but exposed for convenience.
+
+### chalk.styles
+
+Exposes the styles as [ANSI escape codes](https://github.com/sindresorhus/ansi-styles).
+
+Generally not useful, but you might need just the `.open` or `.close` escape code if you're mixing externally styled strings with yours.
+
+```js
+var chalk = require('chalk');
+
+console.log(chalk.styles.red);
+//=> {open: '\x1b[31m', close: '\x1b[39m'}
+
+console.log(chalk.styles.red.open + 'Hello' + chalk.styles.red.close);
+```
+
+### chalk.stripColor(string)
+
+[Strip color](https://github.com/sindresorhus/strip-ansi) from a string.
+
+Can be useful in combination with `.supportsColor` to strip color on externally styled text when it's not supported.
+
+Example:
+
+```js
+var chalk = require('chalk');
+var styledString = fromExternal();
+
+if (!chalk.supportsColor) {
+	chalk.stripColor(styledString);
+}
+```
+
+
+## Styles
+
+### General
+
+- reset
+- bold
+- italic
+- underline
+- inverse
+- strikethrough
+
+### Text colors
+
+- black
+- red
+- green
+- yellow
+- blue
+- magenta
+- cyan
+- white
+- gray
+
+### Background colors
+
+- bgBlack
+- bgRed
+- bgGreen
+- bgYellow
+- bgBlue
+- bgMagenta
+- bgCyan
+- bgWhite
+
+
+## License
+
+MIT © [Sindre Sorhus](http://sindresorhus.com)
+
+
+-
+
+[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/sindresorhus/chalk/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

+ 14 - 0
Build/node_modules/jake/node_modules/filelist/Jakefile

@@ -0,0 +1,14 @@
+testTask('FileList', function () {
+  this.testFiles.include('test/*.js');
+});
+
+publishTask('FileList', function () {
+  this.packageFiles.include([
+    'Jakefile'
+  , 'README.md'
+  , 'package.json'
+  , 'index.js'
+    ]);
+});
+
+

+ 84 - 0
Build/node_modules/jake/node_modules/filelist/README.md

@@ -0,0 +1,84 @@
+## FileList
+
+A FileList is a lazy-evaluated list of files. When given a list
+of glob patterns for possible files to be included in the file
+list, instead of searching the file structures to find the files,
+a FileList holds the pattern for latter use.
+
+This allows you to define a FileList to match any number of
+files, but only search out the actual files when then FileList
+itself is actually used. The key is that the first time an
+element of the FileList/Array is requested, the pending patterns
+are resolved into a real list of file names.
+
+### Usage
+
+Add files to the list with the `include` method. You can add glob
+patterns, individual files, or RegExp objects. When the Array
+methods are invoked on the FileList, these items are resolved to
+an actual list of files.
+
+```javascript
+var fl = new FileList();
+fl.include('test/*.js');
+fl.exclude('test/helpers.js');
+```
+
+Use the `exclude` method to override inclusions. You can use this
+when your inclusions are too broad.
+
+### Array methods
+
+FileList has lazy-evaluated versions of most of the array
+methods, including the following:
+
+* join
+* pop
+* push
+* concat
+* reverse
+* shift
+* unshift
+* slice
+* splice
+* sort
+* filter
+* forEach
+* some
+* every
+* map
+* indexOf
+* lastIndexOf
+* reduce
+* reduceRight
+
+When you call one of these methods, the items in the FileList
+will be resolved to the full list of files, and the method will
+be invoked on that result.
+
+### Special `length` method
+
+`length`: FileList includes a length *method* (instead of a
+property) which returns the number of actual files in the list
+once it's been resolved.
+
+### FileList-specific methods
+
+`include`: Add a filename/glob/regex to the list
+
+`exclude`: Override inclusions by excluding a filename/glob/regex
+
+`resolve`: Resolve the items in the FileList to the full list of
+files. This method is invoked automatically when one of the array
+methods is called.
+
+`toArray`: Immediately resolves the list of items, and returns an
+actual array of filepaths.
+
+`clearInclusions`: Clears any pending items -- must be used
+before resolving the list.
+
+`clearExclusions`: Clears the list of exclusions rules.
+
+
+

+ 319 - 0
Build/node_modules/jake/node_modules/filelist/index.js

@@ -0,0 +1,319 @@
+/*
+ * Jake JavaScript build tool
+ * Copyright 2112 Matthew Eernisse ([email protected])
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+var fs = require('fs')
+, path = require('path')
+, minimatch = require('minimatch')
+, utils = require('utilities')
+, globSync;
+
+globSync = function (pat) {
+  var dirname = utils.file.basedir(pat)
+    , files
+    , matches;
+
+  try {
+    files = utils.file.readdirR(dirname).map(function(file){
+      return file.replace(/\\/g, '/');
+    });
+  }
+  // Bail if path doesn't exist -- assume no files
+  catch(e) {
+    console.error(e.message);
+  }
+
+  if (files) {
+    pat = path.normalize(pat);
+    // Hack, Minimatch doesn't support backslashes in the pattern
+    // https://github.com/isaacs/minimatch/issues/7
+    pat = pat.replace(/\\/g, '/');
+    matches = minimatch.match(files, pat, {});
+  }
+  return matches || [];
+};
+
+// Constants
+// ---------------
+// List of all the builtin Array methods we want to override
+var ARRAY_METHODS = Object.getOwnPropertyNames(Array.prototype)
+// Array methods that return a copy instead of affecting the original
+  , SPECIAL_RETURN = {
+      'concat': true
+    , 'slice': true
+    , 'filter': true
+    , 'map': true
+    }
+// Default file-patterns we want to ignore
+  , DEFAULT_IGNORE_PATTERNS = [
+      /(^|[\/\\])CVS([\/\\]|$)/
+    , /(^|[\/\\])\.svn([\/\\]|$)/
+    , /(^|[\/\\])\.git([\/\\]|$)/
+    , /\.bak$/
+    , /~$/
+    ]
+// Ignore core files
+  , DEFAULT_IGNORE_FUNCS = [
+      function (name) {
+        var isDir = false
+          , stats;
+        try {
+          stats = fs.statSync(name);
+          isDir = stats.isDirectory();
+        }
+        catch(e) {}
+        return (/(^|[\/\\])core$/).test(name) && !isDir;
+      }
+    ];
+
+var FileList = function () {
+  var self = this
+    , wrap;
+
+  // List of glob-patterns or specific filenames
+  this.pendingAdd = [];
+  // Switched to false after lazy-eval of files
+  this.pending = true;
+  // Used to calculate exclusions from the list of files
+  this.excludes = {
+    pats: DEFAULT_IGNORE_PATTERNS.slice()
+  , funcs: DEFAULT_IGNORE_FUNCS.slice()
+  , regex: null
+  };
+  this.items = [];
+
+  // Wrap the array methods with the delegates
+  wrap = function (prop) {
+    var arr;
+    self[prop] = function () {
+      if (self.pending) {
+        self.resolve();
+      }
+      if (typeof self.items[prop] == 'function') {
+        // Special method that return a copy
+        if (SPECIAL_RETURN[prop]) {
+          arr = self.items[prop].apply(self.items, arguments);
+          return FileList.clone(self, arr);
+        }
+        else {
+          return self.items[prop].apply(self.items, arguments);
+        }
+      }
+      else {
+        return self.items[prop];
+      }
+    };
+  };
+  for (var i = 0, ii = ARRAY_METHODS.length; i < ii; i++) {
+    wrap(ARRAY_METHODS[i]);
+  }
+
+  // Include whatever files got passed to the constructor
+  this.include.apply(this, arguments);
+
+  // Fix constructor linkage
+  this.constructor = FileList;
+};
+
+FileList.prototype = new (function () {
+  var globPattern = /[*?\[\{]/;
+
+  var _addMatching = function (pat) {
+        var matches = globSync(pat);
+        this.items = this.items.concat(matches);
+      }
+
+    , _resolveAdd = function (name) {
+        if (globPattern.test(name)) {
+          _addMatching.call(this, name);
+        }
+        else {
+          this.push(name);
+        }
+      }
+
+    , _calculateExcludeRe = function () {
+        var pats = this.excludes.pats
+          , pat
+          , excl = []
+          , matches = [];
+
+        for (var i = 0, ii = pats.length; i < ii; i++) {
+          pat = pats[i];
+          if (typeof pat == 'string') {
+            // Glob, look up files
+            if (/[*?]/.test(pat)) {
+              matches = globSync(pat);
+              matches = matches.map(function (m) {
+                return utils.string.escapeRegExpChars(m);
+              });
+              excl = excl.concat(matches);
+            }
+            // String for regex
+            else {
+              excl.push(utils.string.escapeRegExpChars(pat));
+            }
+          }
+          // Regex, grab the string-representation
+          else if (pat instanceof RegExp) {
+            excl.push(pat.toString().replace(/^\/|\/$/g, ''));
+          }
+        }
+        if (excl.length) {
+          this.excludes.regex = new RegExp('(' + excl.join(')|(') + ')');
+        }
+        else {
+          this.excludes.regex = /^$/;
+        }
+      }
+
+    , _resolveExclude = function () {
+        var self = this;
+        _calculateExcludeRe.call(this);
+        // No `reject` method, so use reverse-filter
+        this.items = this.items.filter(function (name) {
+          return !self.shouldExclude(name);
+        });
+      };
+
+  /**
+   * Includes file-patterns in the FileList. Should be called with one or more
+   * pattern for finding file to include in the list. Arguments should be strings
+   * for either a glob-pattern or a specific file-name, or an array of them
+   */
+  this.include = function (items) {
+    if (items) {
+      this.pendingAdd = this.pendingAdd.concat(items).filter(function (item) {
+        return !!item;
+      });
+    }
+    return this;
+  };
+
+  /**
+   * Indicates whether a particular file would be filtered out by the current
+   * exclusion rules for this FileList.
+   * @param {String} name The filename to check
+   * @return {Boolean} Whether or not the file should be excluded
+   */
+  this.shouldExclude = function (name) {
+    if (!this.excludes.regex) {
+      _calculateExcludeRe.call(this);
+    }
+    var excl = this.excludes;
+    return excl.regex.test(name) || excl.funcs.some(function (f) {
+      return !!f(name);
+    });
+  };
+
+  /**
+   * Excludes file-patterns from the FileList. Should be called with one or more
+   * pattern for finding file to include in the list. Arguments can be:
+   * 1. Strings for either a glob-pattern or a specific file-name
+   * 2. Regular expression literals
+   * 3. Functions to be run on the filename that return a true/false
+   */
+  this.exclude = function () {
+    var args = Array.isArray(arguments[0]) ? arguments[0] : arguments
+      , arg;
+    for (var i = 0, ii = args.length; i < ii; i++) {
+      arg = args[i];
+      if (typeof arg == 'function' && !(arg instanceof RegExp)) {
+        this.excludes.funcs.push(arg);
+      }
+      else {
+        this.excludes.pats.push(arg);
+      }
+    }
+    if (!this.pending) {
+      _resolveExclude.call(this);
+    }
+    return this;
+  };
+
+  /**
+   * Populates the FileList from the include/exclude rules with a list of
+   * actual files
+   */
+  this.resolve = function () {
+    var name
+      , uniqueFunc = function (p, c) {
+          if (p.indexOf(c) < 0) {
+            p.push(c);
+          }
+          return p;
+        };
+    if (this.pending) {
+      this.pending = false;
+      while ((name = this.pendingAdd.shift())) {
+        _resolveAdd.call(this, name);
+      }
+      // Reduce to a unique list
+      this.items = this.items.reduce(uniqueFunc, []);
+      // Remove exclusions
+      _resolveExclude.call(this);
+    }
+    return this;
+  };
+
+  /**
+   * Convert to a plain-jane array
+   */
+  this.toArray = function () {
+    // Call slice to ensure lazy-resolution before slicing items
+    var ret = this.slice().items.slice();
+    return ret;
+  };
+
+  /**
+   * Clear any pending items -- only useful before
+   * calling `resolve`
+   */
+  this.clearInclusions = function () {
+    this.pendingAdd = [];
+    return this;
+  };
+
+  /**
+   * Clear any current exclusion rules
+   */
+  this.clearExclusions = function () {
+    this.excludes = {
+      pats: []
+    , funcs: []
+    , regex: null
+    };
+    return this;
+  };
+
+})();
+
+// Static method, used to create copy returned by special
+// array methods
+FileList.clone = function (list, items) {
+  var clone = new FileList();
+  if (items) {
+    clone.items = items;
+  }
+  clone.pendingAdd = list.pendingAdd;
+  clone.pending = list.pending;
+  for (var p in list.excludes) {
+    clone.excludes[p] = list.excludes[p];
+  }
+  return clone;
+};
+
+exports.FileList = FileList;

+ 1 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/.npmignore

@@ -0,0 +1 @@
+node_modules

+ 23 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/LICENSE

@@ -0,0 +1,23 @@
+Copyright 2009, 2010, 2011 Isaac Z. Schlueter.
+All rights reserved.
+
+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.

+ 218 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/README.md

@@ -0,0 +1,218 @@
+# minimatch
+
+A minimal matching utility.
+
+[![Build Status](https://secure.travis-ci.org/isaacs/minimatch.png)](http://travis-ci.org/isaacs/minimatch)
+
+
+This is the matching library used internally by npm.
+
+Eventually, it will replace the C binding in node-glob.
+
+It works by converting glob expressions into JavaScript `RegExp`
+objects.
+
+## Usage
+
+```javascript
+var minimatch = require("minimatch")
+
+minimatch("bar.foo", "*.foo") // true!
+minimatch("bar.foo", "*.bar") // false!
+minimatch("bar.foo", "*.+(bar|foo)", { debug: true }) // true, and noisy!
+```
+
+## Features
+
+Supports these glob features:
+
+* Brace Expansion
+* Extended glob matching
+* "Globstar" `**` matching
+
+See:
+
+* `man sh`
+* `man bash`
+* `man 3 fnmatch`
+* `man 5 gitignore`
+
+## Minimatch Class
+
+Create a minimatch object by instanting the `minimatch.Minimatch` class.
+
+```javascript
+var Minimatch = require("minimatch").Minimatch
+var mm = new Minimatch(pattern, options)
+```
+
+### Properties
+
+* `pattern` The original pattern the minimatch object represents.
+* `options` The options supplied to the constructor.
+* `set` A 2-dimensional array of regexp or string expressions.
+  Each row in the
+  array corresponds to a brace-expanded pattern.  Each item in the row
+  corresponds to a single path-part.  For example, the pattern
+  `{a,b/c}/d` would expand to a set of patterns like:
+
+        [ [ a, d ]
+        , [ b, c, d ] ]
+
+    If a portion of the pattern doesn't have any "magic" in it
+    (that is, it's something like `"foo"` rather than `fo*o?`), then it
+    will be left as a string rather than converted to a regular
+    expression.
+
+* `regexp` Created by the `makeRe` method.  A single regular expression
+  expressing the entire pattern.  This is useful in cases where you wish
+  to use the pattern somewhat like `fnmatch(3)` with `FNM_PATH` enabled.
+* `negate` True if the pattern is negated.
+* `comment` True if the pattern is a comment.
+* `empty` True if the pattern is `""`.
+
+### Methods
+
+* `makeRe` Generate the `regexp` member if necessary, and return it.
+  Will return `false` if the pattern is invalid.
+* `match(fname)` Return true if the filename matches the pattern, or
+  false otherwise.
+* `matchOne(fileArray, patternArray, partial)` Take a `/`-split
+  filename, and match it against a single row in the `regExpSet`.  This
+  method is mainly for internal use, but is exposed so that it can be
+  used by a glob-walker that needs to avoid excessive filesystem calls.
+
+All other methods are internal, and will be called as necessary.
+
+## Functions
+
+The top-level exported function has a `cache` property, which is an LRU
+cache set to store 100 items.  So, calling these methods repeatedly
+with the same pattern and options will use the same Minimatch object,
+saving the cost of parsing it multiple times.
+
+### minimatch(path, pattern, options)
+
+Main export.  Tests a path against the pattern using the options.
+
+```javascript
+var isJS = minimatch(file, "*.js", { matchBase: true })
+```
+
+### minimatch.filter(pattern, options)
+
+Returns a function that tests its
+supplied argument, suitable for use with `Array.filter`.  Example:
+
+```javascript
+var javascripts = fileList.filter(minimatch.filter("*.js", {matchBase: true}))
+```
+
+### minimatch.match(list, pattern, options)
+
+Match against the list of
+files, in the style of fnmatch or glob.  If nothing is matched, and
+options.nonull is set, then return a list containing the pattern itself.
+
+```javascript
+var javascripts = minimatch.match(fileList, "*.js", {matchBase: true}))
+```
+
+### minimatch.makeRe(pattern, options)
+
+Make a regular expression object from the pattern.
+
+## Options
+
+All options are `false` by default.
+
+### debug
+
+Dump a ton of stuff to stderr.
+
+### nobrace
+
+Do not expand `{a,b}` and `{1..3}` brace sets.
+
+### noglobstar
+
+Disable `**` matching against multiple folder names.
+
+### dot
+
+Allow patterns to match filenames starting with a period, even if
+the pattern does not explicitly have a period in that spot.
+
+Note that by default, `a/**/b` will **not** match `a/.d/b`, unless `dot`
+is set.
+
+### noext
+
+Disable "extglob" style patterns like `+(a|b)`.
+
+### nocase
+
+Perform a case-insensitive match.
+
+### nonull
+
+When a match is not found by `minimatch.match`, return a list containing
+the pattern itself if this option is set.  When not set, an empty list
+is returned if there are no matches.
+
+### matchBase
+
+If set, then patterns without slashes will be matched
+against the basename of the path if it contains slashes.  For example,
+`a?b` would match the path `/xyz/123/acb`, but not `/xyz/acb/123`.
+
+### nocomment
+
+Suppress the behavior of treating `#` at the start of a pattern as a
+comment.
+
+### nonegate
+
+Suppress the behavior of treating a leading `!` character as negation.
+
+### flipNegate
+
+Returns from negate expressions the same as if they were not negated.
+(Ie, true on a hit, false on a miss.)
+
+
+## Comparisons to other fnmatch/glob implementations
+
+While strict compliance with the existing standards is a worthwhile
+goal, some discrepancies exist between minimatch and other
+implementations, and are intentional.
+
+If the pattern starts with a `!` character, then it is negated.  Set the
+`nonegate` flag to suppress this behavior, and treat leading `!`
+characters normally.  This is perhaps relevant if you wish to start the
+pattern with a negative extglob pattern like `!(a|B)`.  Multiple `!`
+characters at the start of a pattern will negate the pattern multiple
+times.
+
+If a pattern starts with `#`, then it is treated as a comment, and
+will not match anything.  Use `\#` to match a literal `#` at the
+start of a line, or set the `nocomment` flag to suppress this behavior.
+
+The double-star character `**` is supported by default, unless the
+`noglobstar` flag is set.  This is supported in the manner of bsdglob
+and bash 4.1, where `**` only has special significance if it is the only
+thing in a path part.  That is, `a/**/b` will match `a/x/y/b`, but
+`a/**b` will not.
+
+If an escaped pattern has no matches, and the `nonull` flag is set,
+then minimatch.match returns the pattern as-provided, rather than
+interpreting the character escapes.  For example,
+`minimatch.match([], "\\*a\\?")` will return `"\\*a\\?"` rather than
+`"*a?"`.  This is akin to setting the `nullglob` option in bash, except
+that it does not resolve escaped pattern characters.
+
+If brace expansion is not disabled, then it is performed before any
+other interpretation of the glob pattern.  Thus, a pattern like
+`+(a|{b),c)}`, which would not be valid in bash or zsh, is expanded
+**first** into the set of `+(a|b)` and `+(a|c)`, and those patterns are
+checked for validity.  Since those two are valid, matching proceeds.

+ 1061 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/minimatch.js

@@ -0,0 +1,1061 @@
+;(function (require, exports, module, platform) {
+
+if (module) module.exports = minimatch
+else exports.minimatch = minimatch
+
+if (!require) {
+  require = function (id) {
+    switch (id) {
+      case "sigmund": return function sigmund (obj) {
+        return JSON.stringify(obj)
+      }
+      case "path": return { basename: function (f) {
+        f = f.split(/[\/\\]/)
+        var e = f.pop()
+        if (!e) e = f.pop()
+        return e
+      }}
+      case "lru-cache": return function LRUCache () {
+        // not quite an LRU, but still space-limited.
+        var cache = {}
+        var cnt = 0
+        this.set = function (k, v) {
+          cnt ++
+          if (cnt >= 100) cache = {}
+          cache[k] = v
+        }
+        this.get = function (k) { return cache[k] }
+      }
+    }
+  }
+}
+
+minimatch.Minimatch = Minimatch
+
+var LRU = require("lru-cache")
+  , cache = minimatch.cache = new LRU({max: 100})
+  , GLOBSTAR = minimatch.GLOBSTAR = Minimatch.GLOBSTAR = {}
+  , sigmund = require("sigmund")
+
+var path = require("path")
+  // any single thing other than /
+  // don't need to escape / when using new RegExp()
+  , qmark = "[^/]"
+
+  // * => any number of characters
+  , star = qmark + "*?"
+
+  // ** when dots are allowed.  Anything goes, except .. and .
+  // not (^ or / followed by one or two dots followed by $ or /),
+  // followed by anything, any number of times.
+  , twoStarDot = "(?:(?!(?:\\\/|^)(?:\\.{1,2})($|\\\/)).)*?"
+
+  // not a ^ or / followed by a dot,
+  // followed by anything, any number of times.
+  , twoStarNoDot = "(?:(?!(?:\\\/|^)\\.).)*?"
+
+  // characters that need to be escaped in RegExp.
+  , reSpecials = charSet("().*{}+?[]^$\\!")
+
+// "abc" -> { a:true, b:true, c:true }
+function charSet (s) {
+  return s.split("").reduce(function (set, c) {
+    set[c] = true
+    return set
+  }, {})
+}
+
+// normalizes slashes.
+var slashSplit = /\/+/
+
+minimatch.filter = filter
+function filter (pattern, options) {
+  options = options || {}
+  return function (p, i, list) {
+    return minimatch(p, pattern, options)
+  }
+}
+
+function ext (a, b) {
+  a = a || {}
+  b = b || {}
+  var t = {}
+  Object.keys(b).forEach(function (k) {
+    t[k] = b[k]
+  })
+  Object.keys(a).forEach(function (k) {
+    t[k] = a[k]
+  })
+  return t
+}
+
+minimatch.defaults = function (def) {
+  if (!def || !Object.keys(def).length) return minimatch
+
+  var orig = minimatch
+
+  var m = function minimatch (p, pattern, options) {
+    return orig.minimatch(p, pattern, ext(def, options))
+  }
+
+  m.Minimatch = function Minimatch (pattern, options) {
+    return new orig.Minimatch(pattern, ext(def, options))
+  }
+
+  return m
+}
+
+Minimatch.defaults = function (def) {
+  if (!def || !Object.keys(def).length) return Minimatch
+  return minimatch.defaults(def).Minimatch
+}
+
+
+function minimatch (p, pattern, options) {
+  if (typeof pattern !== "string") {
+    throw new TypeError("glob pattern string required")
+  }
+
+  if (!options) options = {}
+
+  // shortcut: comments match nothing.
+  if (!options.nocomment && pattern.charAt(0) === "#") {
+    return false
+  }
+
+  // "" only matches ""
+  if (pattern.trim() === "") return p === ""
+
+  return new Minimatch(pattern, options).match(p)
+}
+
+function Minimatch (pattern, options) {
+  if (!(this instanceof Minimatch)) {
+    return new Minimatch(pattern, options, cache)
+  }
+
+  if (typeof pattern !== "string") {
+    throw new TypeError("glob pattern string required")
+  }
+
+  if (!options) options = {}
+  pattern = pattern.trim()
+
+  // windows: need to use /, not \
+  // On other platforms, \ is a valid (albeit bad) filename char.
+  if (platform === "win32") {
+    pattern = pattern.split("\\").join("/")
+  }
+
+  // lru storage.
+  // these things aren't particularly big, but walking down the string
+  // and turning it into a regexp can get pretty costly.
+  var cacheKey = pattern + "\n" + sigmund(options)
+  var cached = minimatch.cache.get(cacheKey)
+  if (cached) return cached
+  minimatch.cache.set(cacheKey, this)
+
+  this.options = options
+  this.set = []
+  this.pattern = pattern
+  this.regexp = null
+  this.negate = false
+  this.comment = false
+  this.empty = false
+
+  // make the set of regexps etc.
+  this.make()
+}
+
+Minimatch.prototype.debug = function() {}
+
+Minimatch.prototype.make = make
+function make () {
+  // don't do it more than once.
+  if (this._made) return
+
+  var pattern = this.pattern
+  var options = this.options
+
+  // empty patterns and comments match nothing.
+  if (!options.nocomment && pattern.charAt(0) === "#") {
+    this.comment = true
+    return
+  }
+  if (!pattern) {
+    this.empty = true
+    return
+  }
+
+  // step 1: figure out negation, etc.
+  this.parseNegate()
+
+  // step 2: expand braces
+  var set = this.globSet = this.braceExpand()
+
+  if (options.debug) this.debug = console.error
+
+  this.debug(this.pattern, set)
+
+  // step 3: now we have a set, so turn each one into a series of path-portion
+  // matching patterns.
+  // These will be regexps, except in the case of "**", which is
+  // set to the GLOBSTAR object for globstar behavior,
+  // and will not contain any / characters
+  set = this.globParts = set.map(function (s) {
+    return s.split(slashSplit)
+  })
+
+  this.debug(this.pattern, set)
+
+  // glob --> regexps
+  set = set.map(function (s, si, set) {
+    return s.map(this.parse, this)
+  }, this)
+
+  this.debug(this.pattern, set)
+
+  // filter out everything that didn't compile properly.
+  set = set.filter(function (s) {
+    return -1 === s.indexOf(false)
+  })
+
+  this.debug(this.pattern, set)
+
+  this.set = set
+}
+
+Minimatch.prototype.parseNegate = parseNegate
+function parseNegate () {
+  var pattern = this.pattern
+    , negate = false
+    , options = this.options
+    , negateOffset = 0
+
+  if (options.nonegate) return
+
+  for ( var i = 0, l = pattern.length
+      ; i < l && pattern.charAt(i) === "!"
+      ; i ++) {
+    negate = !negate
+    negateOffset ++
+  }
+
+  if (negateOffset) this.pattern = pattern.substr(negateOffset)
+  this.negate = negate
+}
+
+// Brace expansion:
+// a{b,c}d -> abd acd
+// a{b,}c -> abc ac
+// a{0..3}d -> a0d a1d a2d a3d
+// a{b,c{d,e}f}g -> abg acdfg acefg
+// a{b,c}d{e,f}g -> abdeg acdeg abdeg abdfg
+//
+// Invalid sets are not expanded.
+// a{2..}b -> a{2..}b
+// a{b}c -> a{b}c
+minimatch.braceExpand = function (pattern, options) {
+  return new Minimatch(pattern, options).braceExpand()
+}
+
+Minimatch.prototype.braceExpand = braceExpand
+function braceExpand (pattern, options) {
+  options = options || this.options
+  pattern = typeof pattern === "undefined"
+    ? this.pattern : pattern
+
+  if (typeof pattern === "undefined") {
+    throw new Error("undefined pattern")
+  }
+
+  if (options.nobrace ||
+      !pattern.match(/\{.*\}/)) {
+    // shortcut. no need to expand.
+    return [pattern]
+  }
+
+  var escaping = false
+
+  // examples and comments refer to this crazy pattern:
+  // a{b,c{d,e},{f,g}h}x{y,z}
+  // expected:
+  // abxy
+  // abxz
+  // acdxy
+  // acdxz
+  // acexy
+  // acexz
+  // afhxy
+  // afhxz
+  // aghxy
+  // aghxz
+
+  // everything before the first \{ is just a prefix.
+  // So, we pluck that off, and work with the rest,
+  // and then prepend it to everything we find.
+  if (pattern.charAt(0) !== "{") {
+    this.debug(pattern)
+    var prefix = null
+    for (var i = 0, l = pattern.length; i < l; i ++) {
+      var c = pattern.charAt(i)
+      this.debug(i, c)
+      if (c === "\\") {
+        escaping = !escaping
+      } else if (c === "{" && !escaping) {
+        prefix = pattern.substr(0, i)
+        break
+      }
+    }
+
+    // actually no sets, all { were escaped.
+    if (prefix === null) {
+      this.debug("no sets")
+      return [pattern]
+    }
+
+   var tail = braceExpand.call(this, pattern.substr(i), options)
+    return tail.map(function (t) {
+      return prefix + t
+    })
+  }
+
+  // now we have something like:
+  // {b,c{d,e},{f,g}h}x{y,z}
+  // walk through the set, expanding each part, until
+  // the set ends.  then, we'll expand the suffix.
+  // If the set only has a single member, then'll put the {} back
+
+  // first, handle numeric sets, since they're easier
+  var numset = pattern.match(/^\{(-?[0-9]+)\.\.(-?[0-9]+)\}/)
+  if (numset) {
+    this.debug("numset", numset[1], numset[2])
+    var suf = braceExpand.call(this, pattern.substr(numset[0].length), options)
+      , start = +numset[1]
+      , end = +numset[2]
+      , inc = start > end ? -1 : 1
+      , set = []
+    for (var i = start; i != (end + inc); i += inc) {
+      // append all the suffixes
+      for (var ii = 0, ll = suf.length; ii < ll; ii ++) {
+        set.push(i + suf[ii])
+      }
+    }
+    return set
+  }
+
+  // ok, walk through the set
+  // We hope, somewhat optimistically, that there
+  // will be a } at the end.
+  // If the closing brace isn't found, then the pattern is
+  // interpreted as braceExpand("\\" + pattern) so that
+  // the leading \{ will be interpreted literally.
+  var i = 1 // skip the \{
+    , depth = 1
+    , set = []
+    , member = ""
+    , sawEnd = false
+    , escaping = false
+
+  function addMember () {
+    set.push(member)
+    member = ""
+  }
+
+  this.debug("Entering for")
+  FOR: for (i = 1, l = pattern.length; i < l; i ++) {
+    var c = pattern.charAt(i)
+    this.debug("", i, c)
+
+    if (escaping) {
+      escaping = false
+      member += "\\" + c
+    } else {
+      switch (c) {
+        case "\\":
+          escaping = true
+          continue
+
+        case "{":
+          depth ++
+          member += "{"
+          continue
+
+        case "}":
+          depth --
+          // if this closes the actual set, then we're done
+          if (depth === 0) {
+            addMember()
+            // pluck off the close-brace
+            i ++
+            break FOR
+          } else {
+            member += c
+            continue
+          }
+
+        case ",":
+          if (depth === 1) {
+            addMember()
+          } else {
+            member += c
+          }
+          continue
+
+        default:
+          member += c
+          continue
+      } // switch
+    } // else
+  } // for
+
+  // now we've either finished the set, and the suffix is
+  // pattern.substr(i), or we have *not* closed the set,
+  // and need to escape the leading brace
+  if (depth !== 0) {
+    this.debug("didn't close", pattern)
+    return braceExpand.call(this, "\\" + pattern, options)
+  }
+
+  // x{y,z} -> ["xy", "xz"]
+  this.debug("set", set)
+  this.debug("suffix", pattern.substr(i))
+  var suf = braceExpand.call(this, pattern.substr(i), options)
+  // ["b", "c{d,e}","{f,g}h"] ->
+  //   [["b"], ["cd", "ce"], ["fh", "gh"]]
+  var addBraces = set.length === 1
+  this.debug("set pre-expanded", set)
+  set = set.map(function (p) {
+    return braceExpand.call(this, p, options)
+  }, this)
+  this.debug("set expanded", set)
+
+
+  // [["b"], ["cd", "ce"], ["fh", "gh"]] ->
+  //   ["b", "cd", "ce", "fh", "gh"]
+  set = set.reduce(function (l, r) {
+    return l.concat(r)
+  })
+
+  if (addBraces) {
+    set = set.map(function (s) {
+      return "{" + s + "}"
+    })
+  }
+
+  // now attach the suffixes.
+  var ret = []
+  for (var i = 0, l = set.length; i < l; i ++) {
+    for (var ii = 0, ll = suf.length; ii < ll; ii ++) {
+      ret.push(set[i] + suf[ii])
+    }
+  }
+  return ret
+}
+
+// parse a component of the expanded set.
+// At this point, no pattern may contain "/" in it
+// so we're going to return a 2d array, where each entry is the full
+// pattern, split on '/', and then turned into a regular expression.
+// A regexp is made at the end which joins each array with an
+// escaped /, and another full one which joins each regexp with |.
+//
+// Following the lead of Bash 4.1, note that "**" only has special meaning
+// when it is the *only* thing in a path portion.  Otherwise, any series
+// of * is equivalent to a single *.  Globstar behavior is enabled by
+// default, and can be disabled by setting options.noglobstar.
+Minimatch.prototype.parse = parse
+var SUBPARSE = {}
+function parse (pattern, isSub) {
+  var options = this.options
+
+  // shortcuts
+  if (!options.noglobstar && pattern === "**") return GLOBSTAR
+  if (pattern === "") return ""
+
+  var re = ""
+    , hasMagic = !!options.nocase
+    , escaping = false
+    // ? => one single character
+    , patternListStack = []
+    , plType
+    , stateChar
+    , inClass = false
+    , reClassStart = -1
+    , classStart = -1
+    // . and .. never match anything that doesn't start with .,
+    // even when options.dot is set.
+    , patternStart = pattern.charAt(0) === "." ? "" // anything
+      // not (start or / followed by . or .. followed by / or end)
+      : options.dot ? "(?!(?:^|\\\/)\\.{1,2}(?:$|\\\/))"
+      : "(?!\\.)"
+    , self = this
+
+  function clearStateChar () {
+    if (stateChar) {
+      // we had some state-tracking character
+      // that wasn't consumed by this pass.
+      switch (stateChar) {
+        case "*":
+          re += star
+          hasMagic = true
+          break
+        case "?":
+          re += qmark
+          hasMagic = true
+          break
+        default:
+          re += "\\"+stateChar
+          break
+      }
+      self.debug('clearStateChar %j %j', stateChar, re)
+      stateChar = false
+    }
+  }
+
+  for ( var i = 0, len = pattern.length, c
+      ; (i < len) && (c = pattern.charAt(i))
+      ; i ++ ) {
+
+    this.debug("%s\t%s %s %j", pattern, i, re, c)
+
+    // skip over any that are escaped.
+    if (escaping && reSpecials[c]) {
+      re += "\\" + c
+      escaping = false
+      continue
+    }
+
+    SWITCH: switch (c) {
+      case "/":
+        // completely not allowed, even escaped.
+        // Should already be path-split by now.
+        return false
+
+      case "\\":
+        clearStateChar()
+        escaping = true
+        continue
+
+      // the various stateChar values
+      // for the "extglob" stuff.
+      case "?":
+      case "*":
+      case "+":
+      case "@":
+      case "!":
+        this.debug("%s\t%s %s %j <-- stateChar", pattern, i, re, c)
+
+        // all of those are literals inside a class, except that
+        // the glob [!a] means [^a] in regexp
+        if (inClass) {
+          this.debug('  in class')
+          if (c === "!" && i === classStart + 1) c = "^"
+          re += c
+          continue
+        }
+
+        // if we already have a stateChar, then it means
+        // that there was something like ** or +? in there.
+        // Handle the stateChar, then proceed with this one.
+        self.debug('call clearStateChar %j', stateChar)
+        clearStateChar()
+        stateChar = c
+        // if extglob is disabled, then +(asdf|foo) isn't a thing.
+        // just clear the statechar *now*, rather than even diving into
+        // the patternList stuff.
+        if (options.noext) clearStateChar()
+        continue
+
+      case "(":
+        if (inClass) {
+          re += "("
+          continue
+        }
+
+        if (!stateChar) {
+          re += "\\("
+          continue
+        }
+
+        plType = stateChar
+        patternListStack.push({ type: plType
+                              , start: i - 1
+                              , reStart: re.length })
+        // negation is (?:(?!js)[^/]*)
+        re += stateChar === "!" ? "(?:(?!" : "(?:"
+        this.debug('plType %j %j', stateChar, re)
+        stateChar = false
+        continue
+
+      case ")":
+        if (inClass || !patternListStack.length) {
+          re += "\\)"
+          continue
+        }
+
+        clearStateChar()
+        hasMagic = true
+        re += ")"
+        plType = patternListStack.pop().type
+        // negation is (?:(?!js)[^/]*)
+        // The others are (?:<pattern>)<type>
+        switch (plType) {
+          case "!":
+            re += "[^/]*?)"
+            break
+          case "?":
+          case "+":
+          case "*": re += plType
+          case "@": break // the default anyway
+        }
+        continue
+
+      case "|":
+        if (inClass || !patternListStack.length || escaping) {
+          re += "\\|"
+          escaping = false
+          continue
+        }
+
+        clearStateChar()
+        re += "|"
+        continue
+
+      // these are mostly the same in regexp and glob
+      case "[":
+        // swallow any state-tracking char before the [
+        clearStateChar()
+
+        if (inClass) {
+          re += "\\" + c
+          continue
+        }
+
+        inClass = true
+        classStart = i
+        reClassStart = re.length
+        re += c
+        continue
+
+      case "]":
+        //  a right bracket shall lose its special
+        //  meaning and represent itself in
+        //  a bracket expression if it occurs
+        //  first in the list.  -- POSIX.2 2.8.3.2
+        if (i === classStart + 1 || !inClass) {
+          re += "\\" + c
+          escaping = false
+          continue
+        }
+
+        // finish up the class.
+        hasMagic = true
+        inClass = false
+        re += c
+        continue
+
+      default:
+        // swallow any state char that wasn't consumed
+        clearStateChar()
+
+        if (escaping) {
+          // no need
+          escaping = false
+        } else if (reSpecials[c]
+                   && !(c === "^" && inClass)) {
+          re += "\\"
+        }
+
+        re += c
+
+    } // switch
+  } // for
+
+
+  // handle the case where we left a class open.
+  // "[abc" is valid, equivalent to "\[abc"
+  if (inClass) {
+    // split where the last [ was, and escape it
+    // this is a huge pita.  We now have to re-walk
+    // the contents of the would-be class to re-translate
+    // any characters that were passed through as-is
+    var cs = pattern.substr(classStart + 1)
+      , sp = this.parse(cs, SUBPARSE)
+    re = re.substr(0, reClassStart) + "\\[" + sp[0]
+    hasMagic = hasMagic || sp[1]
+  }
+
+  // handle the case where we had a +( thing at the *end*
+  // of the pattern.
+  // each pattern list stack adds 3 chars, and we need to go through
+  // and escape any | chars that were passed through as-is for the regexp.
+  // Go through and escape them, taking care not to double-escape any
+  // | chars that were already escaped.
+  var pl
+  while (pl = patternListStack.pop()) {
+    var tail = re.slice(pl.reStart + 3)
+    // maybe some even number of \, then maybe 1 \, followed by a |
+    tail = tail.replace(/((?:\\{2})*)(\\?)\|/g, function (_, $1, $2) {
+      if (!$2) {
+        // the | isn't already escaped, so escape it.
+        $2 = "\\"
+      }
+
+      // need to escape all those slashes *again*, without escaping the
+      // one that we need for escaping the | character.  As it works out,
+      // escaping an even number of slashes can be done by simply repeating
+      // it exactly after itself.  That's why this trick works.
+      //
+      // I am sorry that you have to see this.
+      return $1 + $1 + $2 + "|"
+    })
+
+    this.debug("tail=%j\n   %s", tail, tail)
+    var t = pl.type === "*" ? star
+          : pl.type === "?" ? qmark
+          : "\\" + pl.type
+
+    hasMagic = true
+    re = re.slice(0, pl.reStart)
+       + t + "\\("
+       + tail
+  }
+
+  // handle trailing things that only matter at the very end.
+  clearStateChar()
+  if (escaping) {
+    // trailing \\
+    re += "\\\\"
+  }
+
+  // only need to apply the nodot start if the re starts with
+  // something that could conceivably capture a dot
+  var addPatternStart = false
+  switch (re.charAt(0)) {
+    case ".":
+    case "[":
+    case "(": addPatternStart = true
+  }
+
+  // if the re is not "" at this point, then we need to make sure
+  // it doesn't match against an empty path part.
+  // Otherwise a/* will match a/, which it should not.
+  if (re !== "" && hasMagic) re = "(?=.)" + re
+
+  if (addPatternStart) re = patternStart + re
+
+  // parsing just a piece of a larger pattern.
+  if (isSub === SUBPARSE) {
+    return [ re, hasMagic ]
+  }
+
+  // skip the regexp for non-magical patterns
+  // unescape anything in it, though, so that it'll be
+  // an exact match against a file etc.
+  if (!hasMagic) {
+    return globUnescape(pattern)
+  }
+
+  var flags = options.nocase ? "i" : ""
+    , regExp = new RegExp("^" + re + "$", flags)
+
+  regExp._glob = pattern
+  regExp._src = re
+
+  return regExp
+}
+
+minimatch.makeRe = function (pattern, options) {
+  return new Minimatch(pattern, options || {}).makeRe()
+}
+
+Minimatch.prototype.makeRe = makeRe
+function makeRe () {
+  if (this.regexp || this.regexp === false) return this.regexp
+
+  // at this point, this.set is a 2d array of partial
+  // pattern strings, or "**".
+  //
+  // It's better to use .match().  This function shouldn't
+  // be used, really, but it's pretty convenient sometimes,
+  // when you just want to work with a regex.
+  var set = this.set
+
+  if (!set.length) return this.regexp = false
+  var options = this.options
+
+  var twoStar = options.noglobstar ? star
+      : options.dot ? twoStarDot
+      : twoStarNoDot
+    , flags = options.nocase ? "i" : ""
+
+  var re = set.map(function (pattern) {
+    return pattern.map(function (p) {
+      return (p === GLOBSTAR) ? twoStar
+           : (typeof p === "string") ? regExpEscape(p)
+           : p._src
+    }).join("\\\/")
+  }).join("|")
+
+  // must match entire pattern
+  // ending in a * or ** will make it less strict.
+  re = "^(?:" + re + ")$"
+
+  // can match anything, as long as it's not this.
+  if (this.negate) re = "^(?!" + re + ").*$"
+
+  try {
+    return this.regexp = new RegExp(re, flags)
+  } catch (ex) {
+    return this.regexp = false
+  }
+}
+
+minimatch.match = function (list, pattern, options) {
+  options = options || {}
+  var mm = new Minimatch(pattern, options)
+  list = list.filter(function (f) {
+    return mm.match(f)
+  })
+  if (mm.options.nonull && !list.length) {
+    list.push(pattern)
+  }
+  return list
+}
+
+Minimatch.prototype.match = match
+function match (f, partial) {
+  this.debug("match", f, this.pattern)
+  // short-circuit in the case of busted things.
+  // comments, etc.
+  if (this.comment) return false
+  if (this.empty) return f === ""
+
+  if (f === "/" && partial) return true
+
+  var options = this.options
+
+  // windows: need to use /, not \
+  // On other platforms, \ is a valid (albeit bad) filename char.
+  if (platform === "win32") {
+    f = f.split("\\").join("/")
+  }
+
+  // treat the test path as a set of pathparts.
+  f = f.split(slashSplit)
+  this.debug(this.pattern, "split", f)
+
+  // just ONE of the pattern sets in this.set needs to match
+  // in order for it to be valid.  If negating, then just one
+  // match means that we have failed.
+  // Either way, return on the first hit.
+
+  var set = this.set
+  this.debug(this.pattern, "set", set)
+
+  // Find the basename of the path by looking for the last non-empty segment
+  var filename;
+  for (var i = f.length - 1; i >= 0; i--) {
+    filename = f[i]
+    if (filename) break
+  }
+
+  for (var i = 0, l = set.length; i < l; i ++) {
+    var pattern = set[i], file = f
+    if (options.matchBase && pattern.length === 1) {
+      file = [filename]
+    }
+    var hit = this.matchOne(file, pattern, partial)
+    if (hit) {
+      if (options.flipNegate) return true
+      return !this.negate
+    }
+  }
+
+  // didn't get any hits.  this is success if it's a negative
+  // pattern, failure otherwise.
+  if (options.flipNegate) return false
+  return this.negate
+}
+
+// set partial to true to test if, for example,
+// "/a/b" matches the start of "/*/b/*/d"
+// Partial means, if you run out of file before you run
+// out of pattern, then that's fine, as long as all
+// the parts match.
+Minimatch.prototype.matchOne = function (file, pattern, partial) {
+  var options = this.options
+
+  this.debug("matchOne",
+              { "this": this
+              , file: file
+              , pattern: pattern })
+
+  this.debug("matchOne", file.length, pattern.length)
+
+  for ( var fi = 0
+          , pi = 0
+          , fl = file.length
+          , pl = pattern.length
+      ; (fi < fl) && (pi < pl)
+      ; fi ++, pi ++ ) {
+
+    this.debug("matchOne loop")
+    var p = pattern[pi]
+      , f = file[fi]
+
+    this.debug(pattern, p, f)
+
+    // should be impossible.
+    // some invalid regexp stuff in the set.
+    if (p === false) return false
+
+    if (p === GLOBSTAR) {
+      this.debug('GLOBSTAR', [pattern, p, f])
+
+      // "**"
+      // a/**/b/**/c would match the following:
+      // a/b/x/y/z/c
+      // a/x/y/z/b/c
+      // a/b/x/b/x/c
+      // a/b/c
+      // To do this, take the rest of the pattern after
+      // the **, and see if it would match the file remainder.
+      // If so, return success.
+      // If not, the ** "swallows" a segment, and try again.
+      // This is recursively awful.
+      //
+      // a/**/b/**/c matching a/b/x/y/z/c
+      // - a matches a
+      // - doublestar
+      //   - matchOne(b/x/y/z/c, b/**/c)
+      //     - b matches b
+      //     - doublestar
+      //       - matchOne(x/y/z/c, c) -> no
+      //       - matchOne(y/z/c, c) -> no
+      //       - matchOne(z/c, c) -> no
+      //       - matchOne(c, c) yes, hit
+      var fr = fi
+        , pr = pi + 1
+      if (pr === pl) {
+        this.debug('** at the end')
+        // a ** at the end will just swallow the rest.
+        // We have found a match.
+        // however, it will not swallow /.x, unless
+        // options.dot is set.
+        // . and .. are *never* matched by **, for explosively
+        // exponential reasons.
+        for ( ; fi < fl; fi ++) {
+          if (file[fi] === "." || file[fi] === ".." ||
+              (!options.dot && file[fi].charAt(0) === ".")) return false
+        }
+        return true
+      }
+
+      // ok, let's see if we can swallow whatever we can.
+      WHILE: while (fr < fl) {
+        var swallowee = file[fr]
+
+        this.debug('\nglobstar while',
+                    file, fr, pattern, pr, swallowee)
+
+        // XXX remove this slice.  Just pass the start index.
+        if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) {
+          this.debug('globstar found match!', fr, fl, swallowee)
+          // found a match.
+          return true
+        } else {
+          // can't swallow "." or ".." ever.
+          // can only swallow ".foo" when explicitly asked.
+          if (swallowee === "." || swallowee === ".." ||
+              (!options.dot && swallowee.charAt(0) === ".")) {
+            this.debug("dot detected!", file, fr, pattern, pr)
+            break WHILE
+          }
+
+          // ** swallows a segment, and continue.
+          this.debug('globstar swallow a segment, and continue')
+          fr ++
+        }
+      }
+      // no match was found.
+      // However, in partial mode, we can't say this is necessarily over.
+      // If there's more *pattern* left, then
+      if (partial) {
+        // ran out of file
+        this.debug("\n>>> no match, partial?", file, fr, pattern, pr)
+        if (fr === fl) return true
+      }
+      return false
+    }
+
+    // something other than **
+    // non-magic patterns just have to match exactly
+    // patterns with magic have been turned into regexps.
+    var hit
+    if (typeof p === "string") {
+      if (options.nocase) {
+        hit = f.toLowerCase() === p.toLowerCase()
+      } else {
+        hit = f === p
+      }
+      this.debug("string match", p, f, hit)
+    } else {
+      hit = f.match(p)
+      this.debug("pattern match", p, f, hit)
+    }
+
+    if (!hit) return false
+  }
+
+  // Note: ending in / means that we'll get a final ""
+  // at the end of the pattern.  This can only match a
+  // corresponding "" at the end of the file.
+  // If the file ends in /, then it can only match a
+  // a pattern that ends in /, unless the pattern just
+  // doesn't have any more for it. But, a/b/ should *not*
+  // match "a/b/*", even though "" matches against the
+  // [^/]*? pattern, except in partial mode, where it might
+  // simply not be reached yet.
+  // However, a/b/ should still satisfy a/*
+
+  // now either we fell off the end of the pattern, or we're done.
+  if (fi === fl && pi === pl) {
+    // ran out of pattern and filename at the same time.
+    // an exact hit!
+    return true
+  } else if (fi === fl) {
+    // ran out of file, but still had pattern left.
+    // this is ok if we're doing the match as part of
+    // a glob fs traversal.
+    return partial
+  } else if (pi === pl) {
+    // ran out of pattern, still have file left.
+    // this is only acceptable if we're on the very last
+    // empty segment of a file with a trailing slash.
+    // a/* should match a/b/
+    var emptyFileEnd = (fi === fl - 1) && (file[fi] === "")
+    return emptyFileEnd
+  }
+
+  // should be unreachable.
+  throw new Error("wtf?")
+}
+
+
+// replace stuff like \* with *
+function globUnescape (s) {
+  return s.replace(/\\(.)/g, "$1")
+}
+
+
+function regExpEscape (s) {
+  return s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&")
+}
+
+})( typeof require === "function" ? require : null,
+    this,
+    typeof module === "object" ? module : null,
+    typeof process === "object" ? process.platform : "win32"
+  )

+ 1 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/node_modules/lru-cache/.npmignore

@@ -0,0 +1 @@
+/node_modules

+ 8 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/node_modules/lru-cache/.travis.yml

@@ -0,0 +1,8 @@
+language: node_js
+node_js:
+  - '0.8'
+  - '0.10'
+  - '0.12'
+  - 'iojs'
+before_install:
+  - npm install -g npm@latest

+ 14 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/node_modules/lru-cache/CONTRIBUTORS

@@ -0,0 +1,14 @@
+# Authors, sorted by whether or not they are me
+Isaac Z. Schlueter <[email protected]>
+Brian Cottingham <[email protected]>
+Carlos Brito Lage <[email protected]>
+Jesse Dailey <[email protected]>
+Kevin O'Hara <[email protected]>
+Marco Rogers <[email protected]>
+Mark Cavage <[email protected]>
+Marko Mikulicic <[email protected]>
+Nathan Rajlich <[email protected]>
+Satheesh Natesan <[email protected]>
+Trent Mick <[email protected]>
+ashleybrener <[email protected]>
+n4kz <[email protected]>

+ 15 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/node_modules/lru-cache/LICENSE

@@ -0,0 +1,15 @@
+The ISC License
+
+Copyright (c) Isaac Z. Schlueter and Contributors
+
+Permission to use, copy, modify, and/or distribute this software for any
+purpose with or without fee is hereby granted, provided that the above
+copyright notice and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

+ 109 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/node_modules/lru-cache/README.md

@@ -0,0 +1,109 @@
+# lru cache
+
+A cache object that deletes the least-recently-used items.
+
+## Usage:
+
+```javascript
+var LRU = require("lru-cache")
+  , options = { max: 500
+              , length: function (n) { return n * 2 }
+              , dispose: function (key, n) { n.close() }
+              , maxAge: 1000 * 60 * 60 }
+  , cache = LRU(options)
+  , otherCache = LRU(50) // sets just the max size
+
+cache.set("key", "value")
+cache.get("key") // "value"
+
+cache.reset()    // empty the cache
+```
+
+If you put more stuff in it, then items will fall out.
+
+If you try to put an oversized thing in it, then it'll fall out right
+away.
+
+## Options
+
+* `max` The maximum size of the cache, checked by applying the length
+  function to all values in the cache.  Not setting this is kind of
+  silly, since that's the whole purpose of this lib, but it defaults
+  to `Infinity`.
+* `maxAge` Maximum age in ms.  Items are not pro-actively pruned out
+  as they age, but if you try to get an item that is too old, it'll
+  drop it and return undefined instead of giving it to you.
+* `length` Function that is used to calculate the length of stored
+  items.  If you're storing strings or buffers, then you probably want
+  to do something like `function(n){return n.length}`.  The default is
+  `function(n){return 1}`, which is fine if you want to store `n`
+  like-sized things.
+* `dispose` Function that is called on items when they are dropped
+  from the cache.  This can be handy if you want to close file
+  descriptors or do other cleanup tasks when items are no longer
+  accessible.  Called with `key, value`.  It's called *before*
+  actually removing the item from the internal cache, so if you want
+  to immediately put it back in, you'll have to do that in a
+  `nextTick` or `setTimeout` callback or it won't do anything.
+* `stale` By default, if you set a `maxAge`, it'll only actually pull
+  stale items out of the cache when you `get(key)`.  (That is, it's
+  not pre-emptively doing a `setTimeout` or anything.)  If you set
+  `stale:true`, it'll return the stale value before deleting it.  If
+  you don't set this, then it'll return `undefined` when you try to
+  get a stale entry, as if it had already been deleted.
+
+## API
+
+* `set(key, value, maxAge)`
+* `get(key) => value`
+
+    Both of these will update the "recently used"-ness of the key.
+    They do what you think. `max` is optional and overrides the
+    cache `max` option if provided.
+
+* `peek(key)`
+
+    Returns the key value (or `undefined` if not found) without
+    updating the "recently used"-ness of the key.
+
+    (If you find yourself using this a lot, you *might* be using the
+    wrong sort of data structure, but there are some use cases where
+    it's handy.)
+
+* `del(key)`
+
+    Deletes a key out of the cache.
+
+* `reset()`
+
+    Clear the cache entirely, throwing away all values.
+
+* `has(key)`
+
+    Check if a key is in the cache, without updating the recent-ness
+    or deleting it for being stale.
+
+* `forEach(function(value,key,cache), [thisp])`
+
+    Just like `Array.prototype.forEach`.  Iterates over all the keys
+    in the cache, in order of recent-ness.  (Ie, more recently used
+    items are iterated over first.)
+
+* `keys()`
+
+    Return an array of the keys in the cache.
+
+* `values()`
+
+    Return an array of the values in the cache.
+
+* `length()`
+
+    Return total length of objects in cache taking into account
+    `length` options function.
+
+* `itemCount()`
+
+    Return total quantity of objects currently in cache. Note, that
+    `stale` (see options) items are returned as part of this item
+    count.

+ 274 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/node_modules/lru-cache/lib/lru-cache.js

@@ -0,0 +1,274 @@
+;(function () { // closure for web browsers
+
+if (typeof module === 'object' && module.exports) {
+  module.exports = LRUCache
+} else {
+  // just set the global for non-node platforms.
+  this.LRUCache = LRUCache
+}
+
+function hOP (obj, key) {
+  return Object.prototype.hasOwnProperty.call(obj, key)
+}
+
+function naiveLength () { return 1 }
+
+function LRUCache (options) {
+  if (!(this instanceof LRUCache))
+    return new LRUCache(options)
+
+  if (typeof options === 'number')
+    options = { max: options }
+
+  if (!options)
+    options = {}
+
+  this._max = options.max
+  // Kind of weird to have a default max of Infinity, but oh well.
+  if (!this._max || !(typeof this._max === "number") || this._max <= 0 )
+    this._max = Infinity
+
+  this._lengthCalculator = options.length || naiveLength
+  if (typeof this._lengthCalculator !== "function")
+    this._lengthCalculator = naiveLength
+
+  this._allowStale = options.stale || false
+  this._maxAge = options.maxAge || null
+  this._dispose = options.dispose
+  this.reset()
+}
+
+// resize the cache when the max changes.
+Object.defineProperty(LRUCache.prototype, "max",
+  { set : function (mL) {
+      if (!mL || !(typeof mL === "number") || mL <= 0 ) mL = Infinity
+      this._max = mL
+      if (this._length > this._max) trim(this)
+    }
+  , get : function () { return this._max }
+  , enumerable : true
+  })
+
+// resize the cache when the lengthCalculator changes.
+Object.defineProperty(LRUCache.prototype, "lengthCalculator",
+  { set : function (lC) {
+      if (typeof lC !== "function") {
+        this._lengthCalculator = naiveLength
+        this._length = this._itemCount
+        for (var key in this._cache) {
+          this._cache[key].length = 1
+        }
+      } else {
+        this._lengthCalculator = lC
+        this._length = 0
+        for (var key in this._cache) {
+          this._cache[key].length = this._lengthCalculator(this._cache[key].value)
+          this._length += this._cache[key].length
+        }
+      }
+
+      if (this._length > this._max) trim(this)
+    }
+  , get : function () { return this._lengthCalculator }
+  , enumerable : true
+  })
+
+Object.defineProperty(LRUCache.prototype, "length",
+  { get : function () { return this._length }
+  , enumerable : true
+  })
+
+
+Object.defineProperty(LRUCache.prototype, "itemCount",
+  { get : function () { return this._itemCount }
+  , enumerable : true
+  })
+
+LRUCache.prototype.forEach = function (fn, thisp) {
+  thisp = thisp || this
+  var i = 0
+  var itemCount = this._itemCount
+
+  for (var k = this._mru - 1; k >= 0 && i < itemCount; k--) if (this._lruList[k]) {
+    i++
+    var hit = this._lruList[k]
+    if (isStale(this, hit)) {
+      del(this, hit)
+      if (!this._allowStale) hit = undefined
+    }
+    if (hit) {
+      fn.call(thisp, hit.value, hit.key, this)
+    }
+  }
+}
+
+LRUCache.prototype.keys = function () {
+  var keys = new Array(this._itemCount)
+  var i = 0
+  for (var k = this._mru - 1; k >= 0 && i < this._itemCount; k--) if (this._lruList[k]) {
+    var hit = this._lruList[k]
+    keys[i++] = hit.key
+  }
+  return keys
+}
+
+LRUCache.prototype.values = function () {
+  var values = new Array(this._itemCount)
+  var i = 0
+  for (var k = this._mru - 1; k >= 0 && i < this._itemCount; k--) if (this._lruList[k]) {
+    var hit = this._lruList[k]
+    values[i++] = hit.value
+  }
+  return values
+}
+
+LRUCache.prototype.reset = function () {
+  if (this._dispose && this._cache) {
+    for (var k in this._cache) {
+      this._dispose(k, this._cache[k].value)
+    }
+  }
+
+  this._cache = Object.create(null) // hash of items by key
+  this._lruList = Object.create(null) // list of items in order of use recency
+  this._mru = 0 // most recently used
+  this._lru = 0 // least recently used
+  this._length = 0 // number of items in the list
+  this._itemCount = 0
+}
+
+// Provided for debugging/dev purposes only. No promises whatsoever that
+// this API stays stable.
+LRUCache.prototype.dump = function () {
+  return this._cache
+}
+
+LRUCache.prototype.dumpLru = function () {
+  return this._lruList
+}
+
+LRUCache.prototype.set = function (key, value, maxAge) {
+  maxAge = maxAge || this._maxAge
+  var now = maxAge ? Date.now() : 0
+
+  if (hOP(this._cache, key)) {
+    // dispose of the old one before overwriting
+    if (this._dispose)
+      this._dispose(key, this._cache[key].value)
+
+    this._cache[key].now = now
+    this._cache[key].maxAge = maxAge
+    this._cache[key].value = value
+    this.get(key)
+    return true
+  }
+
+  var len = this._lengthCalculator(value)
+  var hit = new Entry(key, value, this._mru++, len, now, maxAge)
+
+  // oversized objects fall out of cache automatically.
+  if (hit.length > this._max) {
+    if (this._dispose) this._dispose(key, value)
+    return false
+  }
+
+  this._length += hit.length
+  this._lruList[hit.lu] = this._cache[key] = hit
+  this._itemCount ++
+
+  if (this._length > this._max)
+    trim(this)
+
+  return true
+}
+
+LRUCache.prototype.has = function (key) {
+  if (!hOP(this._cache, key)) return false
+  var hit = this._cache[key]
+  if (isStale(this, hit)) {
+    return false
+  }
+  return true
+}
+
+LRUCache.prototype.get = function (key) {
+  return get(this, key, true)
+}
+
+LRUCache.prototype.peek = function (key) {
+  return get(this, key, false)
+}
+
+LRUCache.prototype.pop = function () {
+  var hit = this._lruList[this._lru]
+  del(this, hit)
+  return hit || null
+}
+
+LRUCache.prototype.del = function (key) {
+  del(this, this._cache[key])
+}
+
+function get (self, key, doUse) {
+  var hit = self._cache[key]
+  if (hit) {
+    if (isStale(self, hit)) {
+      del(self, hit)
+      if (!self._allowStale) hit = undefined
+    } else {
+      if (doUse) use(self, hit)
+    }
+    if (hit) hit = hit.value
+  }
+  return hit
+}
+
+function isStale(self, hit) {
+  if (!hit || (!hit.maxAge && !self._maxAge)) return false
+  var stale = false;
+  var diff = Date.now() - hit.now
+  if (hit.maxAge) {
+    stale = diff > hit.maxAge
+  } else {
+    stale = self._maxAge && (diff > self._maxAge)
+  }
+  return stale;
+}
+
+function use (self, hit) {
+  shiftLU(self, hit)
+  hit.lu = self._mru ++
+  self._lruList[hit.lu] = hit
+}
+
+function trim (self) {
+  while (self._lru < self._mru && self._length > self._max)
+    del(self, self._lruList[self._lru])
+}
+
+function shiftLU (self, hit) {
+  delete self._lruList[ hit.lu ]
+  while (self._lru < self._mru && !self._lruList[self._lru]) self._lru ++
+}
+
+function del (self, hit) {
+  if (hit) {
+    if (self._dispose) self._dispose(hit.key, hit.value)
+    self._length -= hit.length
+    self._itemCount --
+    delete self._cache[ hit.key ]
+    shiftLU(self, hit)
+  }
+}
+
+// classy, since V8 prefers predictable objects.
+function Entry (key, value, lu, length, now, maxAge) {
+  this.key = key
+  this.value = value
+  this.lu = lu
+  this.length = length
+  this.now = now
+  if (maxAge) this.maxAge = maxAge
+}
+
+})()

+ 58 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/node_modules/lru-cache/package.json

@@ -0,0 +1,58 @@
+{
+  "name": "lru-cache",
+  "description": "A cache object that deletes the least-recently-used items.",
+  "version": "2.6.5",
+  "author": {
+    "name": "Isaac Z. Schlueter",
+    "email": "[email protected]"
+  },
+  "keywords": [
+    "mru",
+    "lru",
+    "cache"
+  ],
+  "scripts": {
+    "test": "tap test --gc"
+  },
+  "main": "lib/lru-cache.js",
+  "repository": {
+    "type": "git",
+    "url": "git://github.com/isaacs/node-lru-cache.git"
+  },
+  "devDependencies": {
+    "tap": "^1.2.0",
+    "weak": ""
+  },
+  "license": "ISC",
+  "gitHead": "7062a0c891bfb80a294be9217e4de0f882e75776",
+  "bugs": {
+    "url": "https://github.com/isaacs/node-lru-cache/issues"
+  },
+  "homepage": "https://github.com/isaacs/node-lru-cache#readme",
+  "_id": "[email protected]",
+  "_shasum": "e56d6354148ede8d7707b58d143220fd08df0fd5",
+  "_from": "lru-cache@>=2.0.0 <3.0.0",
+  "_npmVersion": "3.0.0",
+  "_nodeVersion": "2.2.1",
+  "_npmUser": {
+    "name": "isaacs",
+    "email": "[email protected]"
+  },
+  "dist": {
+    "shasum": "e56d6354148ede8d7707b58d143220fd08df0fd5",
+    "tarball": "http://registry.npmjs.org/lru-cache/-/lru-cache-2.6.5.tgz"
+  },
+  "maintainers": [
+    {
+      "name": "isaacs",
+      "email": "[email protected]"
+    },
+    {
+      "name": "othiym23",
+      "email": "[email protected]"
+    }
+  ],
+  "directories": {},
+  "_resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.6.5.tgz",
+  "readme": "ERROR: No README data found!"
+}

+ 395 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/node_modules/lru-cache/test/basic.js

@@ -0,0 +1,395 @@
+var test = require("tap").test
+  , LRU = require("../")
+
+test("basic", function (t) {
+  var cache = new LRU({max: 10})
+  cache.set("key", "value")
+  t.equal(cache.get("key"), "value")
+  t.equal(cache.get("nada"), undefined)
+  t.equal(cache.length, 1)
+  t.equal(cache.max, 10)
+  t.end()
+})
+
+test("least recently set", function (t) {
+  var cache = new LRU(2)
+  cache.set("a", "A")
+  cache.set("b", "B")
+  cache.set("c", "C")
+  t.equal(cache.get("c"), "C")
+  t.equal(cache.get("b"), "B")
+  t.equal(cache.get("a"), undefined)
+  t.end()
+})
+
+test("lru recently gotten", function (t) {
+  var cache = new LRU(2)
+  cache.set("a", "A")
+  cache.set("b", "B")
+  cache.get("a")
+  cache.set("c", "C")
+  t.equal(cache.get("c"), "C")
+  t.equal(cache.get("b"), undefined)
+  t.equal(cache.get("a"), "A")
+  t.end()
+})
+
+test("del", function (t) {
+  var cache = new LRU(2)
+  cache.set("a", "A")
+  cache.del("a")
+  t.equal(cache.get("a"), undefined)
+  t.end()
+})
+
+test("max", function (t) {
+  var cache = new LRU(3)
+
+  // test changing the max, verify that the LRU items get dropped.
+  cache.max = 100
+  for (var i = 0; i < 100; i ++) cache.set(i, i)
+  t.equal(cache.length, 100)
+  for (var i = 0; i < 100; i ++) {
+    t.equal(cache.get(i), i)
+  }
+  cache.max = 3
+  t.equal(cache.length, 3)
+  for (var i = 0; i < 97; i ++) {
+    t.equal(cache.get(i), undefined)
+  }
+  for (var i = 98; i < 100; i ++) {
+    t.equal(cache.get(i), i)
+  }
+
+  // now remove the max restriction, and try again.
+  cache.max = "hello"
+  for (var i = 0; i < 100; i ++) cache.set(i, i)
+  t.equal(cache.length, 100)
+  for (var i = 0; i < 100; i ++) {
+    t.equal(cache.get(i), i)
+  }
+  // should trigger an immediate resize
+  cache.max = 3
+  t.equal(cache.length, 3)
+  for (var i = 0; i < 97; i ++) {
+    t.equal(cache.get(i), undefined)
+  }
+  for (var i = 98; i < 100; i ++) {
+    t.equal(cache.get(i), i)
+  }
+  t.end()
+})
+
+test("reset", function (t) {
+  var cache = new LRU(10)
+  cache.set("a", "A")
+  cache.set("b", "B")
+  cache.reset()
+  t.equal(cache.length, 0)
+  t.equal(cache.max, 10)
+  t.equal(cache.get("a"), undefined)
+  t.equal(cache.get("b"), undefined)
+  t.end()
+})
+
+
+// Note: `<cache>.dump()` is a debugging tool only. No guarantees are made
+// about the format/layout of the response.
+test("dump", function (t) {
+  var cache = new LRU(10)
+  var d = cache.dump();
+  t.equal(Object.keys(d).length, 0, "nothing in dump for empty cache")
+  cache.set("a", "A")
+  var d = cache.dump()  // { a: { key: "a", value: "A", lu: 0 } }
+  t.ok(d.a)
+  t.equal(d.a.key, "a")
+  t.equal(d.a.value, "A")
+  t.equal(d.a.lu, 0)
+
+  cache.set("b", "B")
+  cache.get("b")
+  d = cache.dump()
+  t.ok(d.b)
+  t.equal(d.b.key, "b")
+  t.equal(d.b.value, "B")
+  t.equal(d.b.lu, 2)
+
+  t.end()
+})
+
+
+test("basic with weighed length", function (t) {
+  var cache = new LRU({
+    max: 100,
+    length: function (item) { return item.size }
+  })
+  cache.set("key", {val: "value", size: 50})
+  t.equal(cache.get("key").val, "value")
+  t.equal(cache.get("nada"), undefined)
+  t.equal(cache.lengthCalculator(cache.get("key")), 50)
+  t.equal(cache.length, 50)
+  t.equal(cache.max, 100)
+  t.end()
+})
+
+
+test("weighed length item too large", function (t) {
+  var cache = new LRU({
+    max: 10,
+    length: function (item) { return item.size }
+  })
+  t.equal(cache.max, 10)
+
+  // should fall out immediately
+  cache.set("key", {val: "value", size: 50})
+
+  t.equal(cache.length, 0)
+  t.equal(cache.get("key"), undefined)
+  t.end()
+})
+
+test("least recently set with weighed length", function (t) {
+  var cache = new LRU({
+    max:8,
+    length: function (item) { return item.length }
+  })
+  cache.set("a", "A")
+  cache.set("b", "BB")
+  cache.set("c", "CCC")
+  cache.set("d", "DDDD")
+  t.equal(cache.get("d"), "DDDD")
+  t.equal(cache.get("c"), "CCC")
+  t.equal(cache.get("b"), undefined)
+  t.equal(cache.get("a"), undefined)
+  t.end()
+})
+
+test("lru recently gotten with weighed length", function (t) {
+  var cache = new LRU({
+    max: 8,
+    length: function (item) { return item.length }
+  })
+  cache.set("a", "A")
+  cache.set("b", "BB")
+  cache.set("c", "CCC")
+  cache.get("a")
+  cache.get("b")
+  cache.set("d", "DDDD")
+  t.equal(cache.get("c"), undefined)
+  t.equal(cache.get("d"), "DDDD")
+  t.equal(cache.get("b"), "BB")
+  t.equal(cache.get("a"), "A")
+  t.end()
+})
+
+test("set returns proper booleans", function(t) {
+  var cache = new LRU({
+    max: 5,
+    length: function (item) { return item.length }
+  })
+
+  t.equal(cache.set("a", "A"), true)
+
+  // should return false for max exceeded
+  t.equal(cache.set("b", "donuts"), false)
+
+  t.equal(cache.set("b", "B"), true)
+  t.equal(cache.set("c", "CCCC"), true)
+  t.end()
+})
+
+test("drop the old items", function(t) {
+  var cache = new LRU({
+    max: 5,
+    maxAge: 50
+  })
+
+  cache.set("a", "A")
+
+  setTimeout(function () {
+    cache.set("b", "b")
+    t.equal(cache.get("a"), "A")
+  }, 25)
+
+  setTimeout(function () {
+    cache.set("c", "C")
+    // timed out
+    t.notOk(cache.get("a"))
+  }, 60 + 25)
+
+  setTimeout(function () {
+    t.notOk(cache.get("b"))
+    t.equal(cache.get("c"), "C")
+  }, 90)
+
+  setTimeout(function () {
+    t.notOk(cache.get("c"))
+    t.end()
+  }, 155)
+})
+
+test("individual item can have it's own maxAge", function(t) {
+  var cache = new LRU({
+    max: 5,
+    maxAge: 50
+  })
+
+  cache.set("a", "A", 20)
+  setTimeout(function () {
+    t.notOk(cache.get("a"))
+    t.end()
+  }, 25)
+})
+
+test("individual item can have it's own maxAge > cache's", function(t) {
+  var cache = new LRU({
+    max: 5,
+    maxAge: 20
+  })
+
+  cache.set("a", "A", 50)
+  setTimeout(function () {
+    t.equal(cache.get("a"), "A")
+    t.end()
+  }, 25)
+})
+
+test("disposal function", function(t) {
+  var disposed = false
+  var cache = new LRU({
+    max: 1,
+    dispose: function (k, n) {
+      disposed = n
+    }
+  })
+
+  cache.set(1, 1)
+  cache.set(2, 2)
+  t.equal(disposed, 1)
+  cache.set(3, 3)
+  t.equal(disposed, 2)
+  cache.reset()
+  t.equal(disposed, 3)
+  t.end()
+})
+
+test("disposal function on too big of item", function(t) {
+  var disposed = false
+  var cache = new LRU({
+    max: 1,
+    length: function (k) {
+      return k.length
+    },
+    dispose: function (k, n) {
+      disposed = n
+    }
+  })
+  var obj = [ 1, 2 ]
+
+  t.equal(disposed, false)
+  cache.set("obj", obj)
+  t.equal(disposed, obj)
+  t.end()
+})
+
+test("has()", function(t) {
+  var cache = new LRU({
+    max: 1,
+    maxAge: 10
+  })
+
+  cache.set('foo', 'bar')
+  t.equal(cache.has('foo'), true)
+  cache.set('blu', 'baz')
+  t.equal(cache.has('foo'), false)
+  t.equal(cache.has('blu'), true)
+  setTimeout(function() {
+    t.equal(cache.has('blu'), false)
+    t.end()
+  }, 15)
+})
+
+test("stale", function(t) {
+  var cache = new LRU({
+    maxAge: 10,
+    stale: true
+  })
+
+  cache.set('foo', 'bar')
+  t.equal(cache.get('foo'), 'bar')
+  t.equal(cache.has('foo'), true)
+  setTimeout(function() {
+    t.equal(cache.has('foo'), false)
+    t.equal(cache.get('foo'), 'bar')
+    t.equal(cache.get('foo'), undefined)
+    t.end()
+  }, 15)
+})
+
+test("lru update via set", function(t) {
+  var cache = LRU({ max: 2 });
+
+  cache.set('foo', 1);
+  cache.set('bar', 2);
+  cache.del('bar');
+  cache.set('baz', 3);
+  cache.set('qux', 4);
+
+  t.equal(cache.get('foo'), undefined)
+  t.equal(cache.get('bar'), undefined)
+  t.equal(cache.get('baz'), 3)
+  t.equal(cache.get('qux'), 4)
+  t.end()
+})
+
+test("least recently set w/ peek", function (t) {
+  var cache = new LRU(2)
+  cache.set("a", "A")
+  cache.set("b", "B")
+  t.equal(cache.peek("a"), "A")
+  cache.set("c", "C")
+  t.equal(cache.get("c"), "C")
+  t.equal(cache.get("b"), "B")
+  t.equal(cache.get("a"), undefined)
+  t.end()
+})
+
+test("pop the least used item", function (t) {
+  var cache = new LRU(3)
+  , last
+
+  cache.set("a", "A")
+  cache.set("b", "B")
+  cache.set("c", "C")
+
+  t.equal(cache.length, 3)
+  t.equal(cache.max, 3)
+
+  // Ensure we pop a, c, b
+  cache.get("b", "B")
+
+  last = cache.pop()
+  t.equal(last.key, "a")
+  t.equal(last.value, "A")
+  t.equal(cache.length, 2)
+  t.equal(cache.max, 3)
+
+  last = cache.pop()
+  t.equal(last.key, "c")
+  t.equal(last.value, "C")
+  t.equal(cache.length, 1)
+  t.equal(cache.max, 3)
+
+  last = cache.pop()
+  t.equal(last.key, "b")
+  t.equal(last.value, "B")
+  t.equal(cache.length, 0)
+  t.equal(cache.max, 3)
+
+  last = cache.pop()
+  t.equal(last, null)
+  t.equal(cache.length, 0)
+  t.equal(cache.max, 3)
+
+  t.end()
+})

+ 120 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/node_modules/lru-cache/test/foreach.js

@@ -0,0 +1,120 @@
+var test = require('tap').test
+var LRU = require('../')
+
+test('forEach', function (t) {
+  var l = new LRU(5)
+  for (var i = 0; i < 10; i ++) {
+    l.set(i.toString(), i.toString(2))
+  }
+
+  var i = 9
+  l.forEach(function (val, key, cache) {
+    t.equal(cache, l)
+    t.equal(key, i.toString())
+    t.equal(val, i.toString(2))
+    i -= 1
+  })
+
+  // get in order of most recently used
+  l.get(6)
+  l.get(8)
+
+  var order = [ 8, 6, 9, 7, 5 ]
+  var i = 0
+
+  l.forEach(function (val, key, cache) {
+    var j = order[i ++]
+    t.equal(cache, l)
+    t.equal(key, j.toString())
+    t.equal(val, j.toString(2))
+  })
+  t.equal(i, order.length);
+
+  t.end()
+})
+
+test('keys() and values()', function (t) {
+  var l = new LRU(5)
+  for (var i = 0; i < 10; i ++) {
+    l.set(i.toString(), i.toString(2))
+  }
+
+  t.similar(l.keys(), ['9', '8', '7', '6', '5'])
+  t.similar(l.values(), ['1001', '1000', '111', '110', '101'])
+
+  // get in order of most recently used
+  l.get(6)
+  l.get(8)
+
+  t.similar(l.keys(), ['8', '6', '9', '7', '5'])
+  t.similar(l.values(), ['1000', '110', '1001', '111', '101'])
+
+  t.end()
+})
+
+test('all entries are iterated over', function(t) {
+  var l = new LRU(5)
+  for (var i = 0; i < 10; i ++) {
+    l.set(i.toString(), i.toString(2))
+  }
+
+  var i = 0
+  l.forEach(function (val, key, cache) {
+    if (i > 0) {
+      cache.del(key)
+    }
+    i += 1
+  })
+
+  t.equal(i, 5)
+  t.equal(l.keys().length, 1)
+
+  t.end()
+})
+
+test('all stale entries are removed', function(t) {
+  var l = new LRU({ max: 5, maxAge: -5, stale: true })
+  for (var i = 0; i < 10; i ++) {
+    l.set(i.toString(), i.toString(2))
+  }
+
+  var i = 0
+  l.forEach(function () {
+    i += 1
+  })
+
+  t.equal(i, 5)
+  t.equal(l.keys().length, 0)
+
+  t.end()
+})
+
+test('expires', function (t) {
+  var l = new LRU({
+    max: 10,
+    maxAge: 50
+  })
+  for (var i = 0; i < 10; i++) {
+    l.set(i.toString(), i.toString(2), ((i % 2) ? 25 : undefined))
+  }
+
+  var i = 0
+  var order = [ 8, 6, 4, 2, 0 ]
+  setTimeout(function () {
+    l.forEach(function (val, key, cache) {
+      var j = order[i++]
+      t.equal(cache, l)
+      t.equal(key, j.toString())
+      t.equal(val, j.toString(2))
+    })
+    t.equal(i, order.length);
+
+    setTimeout(function () {
+      var count = 0;
+      l.forEach(function (val, key, cache) { count++; })
+      t.equal(0, count);
+      t.end()
+    }, 25)
+
+  }, 26)
+})

+ 51 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/node_modules/lru-cache/test/memory-leak.js

@@ -0,0 +1,51 @@
+#!/usr/bin/env node --expose_gc
+
+
+var weak = require('weak');
+var test = require('tap').test
+var LRU = require('../')
+var l = new LRU({ max: 10 })
+var refs = 0
+function X() {
+  refs ++
+  weak(this, deref)
+}
+
+function deref() {
+  refs --
+}
+
+test('no leaks', function (t) {
+  // fill up the cache
+  for (var i = 0; i < 100; i++) {
+    l.set(i, new X);
+    // throw some gets in there, too.
+    if (i % 2 === 0)
+      l.get(i / 2)
+  }
+
+  gc()
+
+  var start = process.memoryUsage()
+
+  // capture the memory
+  var startRefs = refs
+
+  // do it again, but more
+  for (var i = 0; i < 10000; i++) {
+    l.set(i, new X);
+    // throw some gets in there, too.
+    if (i % 2 === 0)
+      l.get(i / 2)
+  }
+
+  gc()
+
+  var end = process.memoryUsage()
+  t.equal(refs, startRefs, 'no leaky refs')
+
+  console.error('start: %j\n' +
+                'end:   %j', start, end);
+  t.pass();
+  t.end();
+})

+ 15 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/node_modules/sigmund/LICENSE

@@ -0,0 +1,15 @@
+The ISC License
+
+Copyright (c) Isaac Z. Schlueter and Contributors
+
+Permission to use, copy, modify, and/or distribute this software for any
+purpose with or without fee is hereby granted, provided that the above
+copyright notice and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

+ 53 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/node_modules/sigmund/README.md

@@ -0,0 +1,53 @@
+# sigmund
+
+Quick and dirty signatures for Objects.
+
+This is like a much faster `deepEquals` comparison, which returns a
+string key suitable for caches and the like.
+
+## Usage
+
+```javascript
+function doSomething (someObj) {
+  var key = sigmund(someObj, maxDepth) // max depth defaults to 10
+  var cached = cache.get(key)
+  if (cached) return cached
+
+  var result = expensiveCalculation(someObj)
+  cache.set(key, result)
+  return result
+}
+```
+
+The resulting key will be as unique and reproducible as calling
+`JSON.stringify` or `util.inspect` on the object, but is much faster.
+In order to achieve this speed, some differences are glossed over.
+For example, the object `{0:'foo'}` will be treated identically to the
+array `['foo']`.
+
+Also, just as there is no way to summon the soul from the scribblings
+of a cocaine-addled psychoanalyst, there is no way to revive the object
+from the signature string that sigmund gives you.  In fact, it's
+barely even readable.
+
+As with `util.inspect` and `JSON.stringify`, larger objects will
+produce larger signature strings.
+
+Because sigmund is a bit less strict than the more thorough
+alternatives, the strings will be shorter, and also there is a
+slightly higher chance for collisions.  For example, these objects
+have the same signature:
+
+    var obj1 = {a:'b',c:/def/,g:['h','i',{j:'',k:'l'}]}
+    var obj2 = {a:'b',c:'/def/',g:['h','i','{jkl']}
+
+Like a good Freudian, sigmund is most effective when you already have
+some understanding of what you're looking for.  It can help you help
+yourself, but you must be willing to do some work as well.
+
+Cycles are handled, and cyclical objects are silently omitted (though
+the key is included in the signature output.)
+
+The second argument is the maximum depth, which defaults to 10,
+because that is the maximum object traversal depth covered by most
+insurance carriers.

+ 283 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/node_modules/sigmund/bench.js

@@ -0,0 +1,283 @@
+// different ways to id objects
+// use a req/res pair, since it's crazy deep and cyclical
+
+// sparseFE10 and sigmund are usually pretty close, which is to be expected,
+// since they are essentially the same algorithm, except that sigmund handles
+// regular expression objects properly.
+
+
+var http = require('http')
+var util = require('util')
+var sigmund = require('./sigmund.js')
+var sreq, sres, creq, cres, test
+
+http.createServer(function (q, s) {
+  sreq = q
+  sres = s
+  sres.end('ok')
+  this.close(function () { setTimeout(function () {
+    start()
+  }, 200) })
+}).listen(1337, function () {
+  creq = http.get({ port: 1337 })
+  creq.on('response', function (s) { cres = s })
+})
+
+function start () {
+  test = [sreq, sres, creq, cres]
+  // test = sreq
+  // sreq.sres = sres
+  // sreq.creq = creq
+  // sreq.cres = cres
+
+  for (var i in exports.compare) {
+    console.log(i)
+    var hash = exports.compare[i]()
+    console.log(hash)
+    console.log(hash.length)
+    console.log('')
+  }
+
+  require('bench').runMain()
+}
+
+function customWs (obj, md, d) {
+  d = d || 0
+  var to = typeof obj
+  if (to === 'undefined' || to === 'function' || to === null) return ''
+  if (d > md || !obj || to !== 'object') return ('' + obj).replace(/[\n ]+/g, '')
+
+  if (Array.isArray(obj)) {
+    return obj.map(function (i, _, __) {
+      return customWs(i, md, d + 1)
+    }).reduce(function (a, b) { return a + b }, '')
+  }
+
+  var keys = Object.keys(obj)
+  return keys.map(function (k, _, __) {
+    return k + ':' + customWs(obj[k], md, d + 1)
+  }).reduce(function (a, b) { return a + b }, '')
+}
+
+function custom (obj, md, d) {
+  d = d || 0
+  var to = typeof obj
+  if (to === 'undefined' || to === 'function' || to === null) return ''
+  if (d > md || !obj || to !== 'object') return '' + obj
+
+  if (Array.isArray(obj)) {
+    return obj.map(function (i, _, __) {
+      return custom(i, md, d + 1)
+    }).reduce(function (a, b) { return a + b }, '')
+  }
+
+  var keys = Object.keys(obj)
+  return keys.map(function (k, _, __) {
+    return k + ':' + custom(obj[k], md, d + 1)
+  }).reduce(function (a, b) { return a + b }, '')
+}
+
+function sparseFE2 (obj, maxDepth) {
+  var seen = []
+  var soFar = ''
+  function ch (v, depth) {
+    if (depth > maxDepth) return
+    if (typeof v === 'function' || typeof v === 'undefined') return
+    if (typeof v !== 'object' || !v) {
+      soFar += v
+      return
+    }
+    if (seen.indexOf(v) !== -1 || depth === maxDepth) return
+    seen.push(v)
+    soFar += '{'
+    Object.keys(v).forEach(function (k, _, __) {
+      // pseudo-private values.  skip those.
+      if (k.charAt(0) === '_') return
+      var to = typeof v[k]
+      if (to === 'function' || to === 'undefined') return
+      soFar += k + ':'
+      ch(v[k], depth + 1)
+    })
+    soFar += '}'
+  }
+  ch(obj, 0)
+  return soFar
+}
+
+function sparseFE (obj, maxDepth) {
+  var seen = []
+  var soFar = ''
+  function ch (v, depth) {
+    if (depth > maxDepth) return
+    if (typeof v === 'function' || typeof v === 'undefined') return
+    if (typeof v !== 'object' || !v) {
+      soFar += v
+      return
+    }
+    if (seen.indexOf(v) !== -1 || depth === maxDepth) return
+    seen.push(v)
+    soFar += '{'
+    Object.keys(v).forEach(function (k, _, __) {
+      // pseudo-private values.  skip those.
+      if (k.charAt(0) === '_') return
+      var to = typeof v[k]
+      if (to === 'function' || to === 'undefined') return
+      soFar += k
+      ch(v[k], depth + 1)
+    })
+  }
+  ch(obj, 0)
+  return soFar
+}
+
+function sparse (obj, maxDepth) {
+  var seen = []
+  var soFar = ''
+  function ch (v, depth) {
+    if (depth > maxDepth) return
+    if (typeof v === 'function' || typeof v === 'undefined') return
+    if (typeof v !== 'object' || !v) {
+      soFar += v
+      return
+    }
+    if (seen.indexOf(v) !== -1 || depth === maxDepth) return
+    seen.push(v)
+    soFar += '{'
+    for (var k in v) {
+      // pseudo-private values.  skip those.
+      if (k.charAt(0) === '_') continue
+      var to = typeof v[k]
+      if (to === 'function' || to === 'undefined') continue
+      soFar += k
+      ch(v[k], depth + 1)
+    }
+  }
+  ch(obj, 0)
+  return soFar
+}
+
+function noCommas (obj, maxDepth) {
+  var seen = []
+  var soFar = ''
+  function ch (v, depth) {
+    if (depth > maxDepth) return
+    if (typeof v === 'function' || typeof v === 'undefined') return
+    if (typeof v !== 'object' || !v) {
+      soFar += v
+      return
+    }
+    if (seen.indexOf(v) !== -1 || depth === maxDepth) return
+    seen.push(v)
+    soFar += '{'
+    for (var k in v) {
+      // pseudo-private values.  skip those.
+      if (k.charAt(0) === '_') continue
+      var to = typeof v[k]
+      if (to === 'function' || to === 'undefined') continue
+      soFar += k + ':'
+      ch(v[k], depth + 1)
+    }
+    soFar += '}'
+  }
+  ch(obj, 0)
+  return soFar
+}
+
+
+function flatten (obj, maxDepth) {
+  var seen = []
+  var soFar = ''
+  function ch (v, depth) {
+    if (depth > maxDepth) return
+    if (typeof v === 'function' || typeof v === 'undefined') return
+    if (typeof v !== 'object' || !v) {
+      soFar += v
+      return
+    }
+    if (seen.indexOf(v) !== -1 || depth === maxDepth) return
+    seen.push(v)
+    soFar += '{'
+    for (var k in v) {
+      // pseudo-private values.  skip those.
+      if (k.charAt(0) === '_') continue
+      var to = typeof v[k]
+      if (to === 'function' || to === 'undefined') continue
+      soFar += k + ':'
+      ch(v[k], depth + 1)
+      soFar += ','
+    }
+    soFar += '}'
+  }
+  ch(obj, 0)
+  return soFar
+}
+
+exports.compare =
+{
+  // 'custom 2': function () {
+  //   return custom(test, 2, 0)
+  // },
+  // 'customWs 2': function () {
+  //   return customWs(test, 2, 0)
+  // },
+  'JSON.stringify (guarded)': function () {
+    var seen = []
+    return JSON.stringify(test, function (k, v) {
+      if (typeof v !== 'object' || !v) return v
+      if (seen.indexOf(v) !== -1) return undefined
+      seen.push(v)
+      return v
+    })
+  },
+
+  'flatten 10': function () {
+    return flatten(test, 10)
+  },
+
+  // 'flattenFE 10': function () {
+  //   return flattenFE(test, 10)
+  // },
+
+  'noCommas 10': function () {
+    return noCommas(test, 10)
+  },
+
+  'sparse 10': function () {
+    return sparse(test, 10)
+  },
+
+  'sparseFE 10': function () {
+    return sparseFE(test, 10)
+  },
+
+  'sparseFE2 10': function () {
+    return sparseFE2(test, 10)
+  },
+
+  sigmund: function() {
+    return sigmund(test, 10)
+  },
+
+
+  // 'util.inspect 1': function () {
+  //   return util.inspect(test, false, 1, false)
+  // },
+  // 'util.inspect undefined': function () {
+  //   util.inspect(test)
+  // },
+  // 'util.inspect 2': function () {
+  //   util.inspect(test, false, 2, false)
+  // },
+  // 'util.inspect 3': function () {
+  //   util.inspect(test, false, 3, false)
+  // },
+  // 'util.inspect 4': function () {
+  //   util.inspect(test, false, 4, false)
+  // },
+  // 'util.inspect Infinity': function () {
+  //   util.inspect(test, false, Infinity, false)
+  // }
+}
+
+/** results
+**/

+ 60 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/node_modules/sigmund/package.json

@@ -0,0 +1,60 @@
+{
+  "name": "sigmund",
+  "version": "1.0.1",
+  "description": "Quick and dirty signatures for Objects.",
+  "main": "sigmund.js",
+  "directories": {
+    "test": "test"
+  },
+  "dependencies": {},
+  "devDependencies": {
+    "tap": "~0.3.0"
+  },
+  "scripts": {
+    "test": "tap test/*.js",
+    "bench": "node bench.js"
+  },
+  "repository": {
+    "type": "git",
+    "url": "git://github.com/isaacs/sigmund.git"
+  },
+  "keywords": [
+    "object",
+    "signature",
+    "key",
+    "data",
+    "psychoanalysis"
+  ],
+  "author": {
+    "name": "Isaac Z. Schlueter",
+    "email": "[email protected]",
+    "url": "http://blog.izs.me/"
+  },
+  "license": "ISC",
+  "gitHead": "527f97aa5bb253d927348698c0cd3bb267d098c6",
+  "bugs": {
+    "url": "https://github.com/isaacs/sigmund/issues"
+  },
+  "homepage": "https://github.com/isaacs/sigmund#readme",
+  "_id": "[email protected]",
+  "_shasum": "3ff21f198cad2175f9f3b781853fd94d0d19b590",
+  "_from": "sigmund@>=1.0.0 <1.1.0",
+  "_npmVersion": "2.10.0",
+  "_nodeVersion": "2.0.1",
+  "_npmUser": {
+    "name": "isaacs",
+    "email": "[email protected]"
+  },
+  "dist": {
+    "shasum": "3ff21f198cad2175f9f3b781853fd94d0d19b590",
+    "tarball": "http://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz"
+  },
+  "maintainers": [
+    {
+      "name": "isaacs",
+      "email": "[email protected]"
+    }
+  ],
+  "_resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz",
+  "readme": "ERROR: No README data found!"
+}

+ 39 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/node_modules/sigmund/sigmund.js

@@ -0,0 +1,39 @@
+module.exports = sigmund
+function sigmund (subject, maxSessions) {
+    maxSessions = maxSessions || 10;
+    var notes = [];
+    var analysis = '';
+    var RE = RegExp;
+
+    function psychoAnalyze (subject, session) {
+        if (session > maxSessions) return;
+
+        if (typeof subject === 'function' ||
+            typeof subject === 'undefined') {
+            return;
+        }
+
+        if (typeof subject !== 'object' || !subject ||
+            (subject instanceof RE)) {
+            analysis += subject;
+            return;
+        }
+
+        if (notes.indexOf(subject) !== -1 || session === maxSessions) return;
+
+        notes.push(subject);
+        analysis += '{';
+        Object.keys(subject).forEach(function (issue, _, __) {
+            // pseudo-private values.  skip those.
+            if (issue.charAt(0) === '_') return;
+            var to = typeof subject[issue];
+            if (to === 'function' || to === 'undefined') return;
+            analysis += issue;
+            psychoAnalyze(subject[issue], session + 1);
+        });
+    }
+    psychoAnalyze(subject, 0);
+    return analysis;
+}
+
+// vim: set softtabstop=4 shiftwidth=4:

+ 24 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/node_modules/sigmund/test/basic.js

@@ -0,0 +1,24 @@
+var test = require('tap').test
+var sigmund = require('../sigmund.js')
+
+
+// occasionally there are duplicates
+// that's an acceptable edge-case.  JSON.stringify and util.inspect
+// have some collision potential as well, though less, and collision
+// detection is expensive.
+var hash = '{abc/def/g{0h1i2{jkl'
+var obj1 = {a:'b',c:/def/,g:['h','i',{j:'',k:'l'}]}
+var obj2 = {a:'b',c:'/def/',g:['h','i','{jkl']}
+
+var obj3 = JSON.parse(JSON.stringify(obj1))
+obj3.c = /def/
+obj3.g[2].cycle = obj3
+var cycleHash = '{abc/def/g{0h1i2{jklcycle'
+
+test('basic', function (t) {
+    t.equal(sigmund(obj1), hash)
+    t.equal(sigmund(obj2), hash)
+    t.equal(sigmund(obj3), cycleHash)
+    t.end()
+})
+

File diff suppressed because it is too large
+ 31 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/package.json


+ 399 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/test/basic.js

@@ -0,0 +1,399 @@
+// http://www.bashcookbook.com/bashinfo/source/bash-1.14.7/tests/glob-test
+//
+// TODO: Some of these tests do very bad things with backslashes, and will
+// most likely fail badly on windows.  They should probably be skipped.
+
+var tap = require("tap")
+  , globalBefore = Object.keys(global)
+  , mm = require("../")
+  , files = [ "a", "b", "c", "d", "abc"
+            , "abd", "abe", "bb", "bcd"
+            , "ca", "cb", "dd", "de"
+            , "bdir/", "bdir/cfile"]
+  , next = files.concat([ "a-b", "aXb"
+                        , ".x", ".y" ])
+
+
+var patterns =
+  [ "http://www.bashcookbook.com/bashinfo/source/bash-1.14.7/tests/glob-test"
+  , ["a*", ["a", "abc", "abd", "abe"]]
+  , ["X*", ["X*"], {nonull: true}]
+
+  // allow null glob expansion
+  , ["X*", []]
+
+  // isaacs: Slightly different than bash/sh/ksh
+  // \\* is not un-escaped to literal "*" in a failed match,
+  // but it does make it get treated as a literal star
+  , ["\\*", ["\\*"], {nonull: true}]
+  , ["\\**", ["\\**"], {nonull: true}]
+  , ["\\*\\*", ["\\*\\*"], {nonull: true}]
+
+  , ["b*/", ["bdir/"]]
+  , ["c*", ["c", "ca", "cb"]]
+  , ["**", files]
+
+  , ["\\.\\./*/", ["\\.\\./*/"], {nonull: true}]
+  , ["s/\\..*//", ["s/\\..*//"], {nonull: true}]
+
+  , "legendary larry crashes bashes"
+  , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\\1/"
+    , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\\1/"], {nonull: true}]
+  , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\1/"
+    , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\1/"], {nonull: true}]
+
+  , "character classes"
+  , ["[a-c]b*", ["abc", "abd", "abe", "bb", "cb"]]
+  , ["[a-y]*[^c]", ["abd", "abe", "bb", "bcd",
+     "bdir/", "ca", "cb", "dd", "de"]]
+  , ["a*[^c]", ["abd", "abe"]]
+  , function () { files.push("a-b", "aXb") }
+  , ["a[X-]b", ["a-b", "aXb"]]
+  , function () { files.push(".x", ".y") }
+  , ["[^a-c]*", ["d", "dd", "de"]]
+  , function () { files.push("a*b/", "a*b/ooo") }
+  , ["a\\*b/*", ["a*b/ooo"]]
+  , ["a\\*?/*", ["a*b/ooo"]]
+  , ["*\\\\!*", [], {null: true}, ["echo !7"]]
+  , ["*\\!*", ["echo !7"], null, ["echo !7"]]
+  , ["*.\\*", ["r.*"], null, ["r.*"]]
+  , ["a[b]c", ["abc"]]
+  , ["a[\\b]c", ["abc"]]
+  , ["a?c", ["abc"]]
+  , ["a\\*c", [], {null: true}, ["abc"]]
+  , ["", [""], { null: true }, [""]]
+
+  , "http://www.opensource.apple.com/source/bash/bash-23/" +
+    "bash/tests/glob-test"
+  , function () { files.push("man/", "man/man1/", "man/man1/bash.1") }
+  , ["*/man*/bash.*", ["man/man1/bash.1"]]
+  , ["man/man1/bash.1", ["man/man1/bash.1"]]
+  , ["a***c", ["abc"], null, ["abc"]]
+  , ["a*****?c", ["abc"], null, ["abc"]]
+  , ["?*****??", ["abc"], null, ["abc"]]
+  , ["*****??", ["abc"], null, ["abc"]]
+  , ["?*****?c", ["abc"], null, ["abc"]]
+  , ["?***?****c", ["abc"], null, ["abc"]]
+  , ["?***?****?", ["abc"], null, ["abc"]]
+  , ["?***?****", ["abc"], null, ["abc"]]
+  , ["*******c", ["abc"], null, ["abc"]]
+  , ["*******?", ["abc"], null, ["abc"]]
+  , ["a*cd**?**??k", ["abcdecdhjk"], null, ["abcdecdhjk"]]
+  , ["a**?**cd**?**??k", ["abcdecdhjk"], null, ["abcdecdhjk"]]
+  , ["a**?**cd**?**??k***", ["abcdecdhjk"], null, ["abcdecdhjk"]]
+  , ["a**?**cd**?**??***k", ["abcdecdhjk"], null, ["abcdecdhjk"]]
+  , ["a**?**cd**?**??***k**", ["abcdecdhjk"], null, ["abcdecdhjk"]]
+  , ["a****c**?**??*****", ["abcdecdhjk"], null, ["abcdecdhjk"]]
+  , ["[-abc]", ["-"], null, ["-"]]
+  , ["[abc-]", ["-"], null, ["-"]]
+  , ["\\", ["\\"], null, ["\\"]]
+  , ["[\\\\]", ["\\"], null, ["\\"]]
+  , ["[[]", ["["], null, ["["]]
+  , ["[", ["["], null, ["["]]
+  , ["[*", ["[abc"], null, ["[abc"]]
+  , "a right bracket shall lose its special meaning and\n" +
+    "represent itself in a bracket expression if it occurs\n" +
+    "first in the list.  -- POSIX.2 2.8.3.2"
+  , ["[]]", ["]"], null, ["]"]]
+  , ["[]-]", ["]"], null, ["]"]]
+  , ["[a-\z]", ["p"], null, ["p"]]
+  , ["??**********?****?", [], { null: true }, ["abc"]]
+  , ["??**********?****c", [], { null: true }, ["abc"]]
+  , ["?************c****?****", [], { null: true }, ["abc"]]
+  , ["*c*?**", [], { null: true }, ["abc"]]
+  , ["a*****c*?**", [], { null: true }, ["abc"]]
+  , ["a********???*******", [], { null: true }, ["abc"]]
+  , ["[]", [], { null: true }, ["a"]]
+  , ["[abc", [], { null: true }, ["["]]
+
+  , "nocase tests"
+  , ["XYZ", ["xYz"], { nocase: true, null: true }
+    , ["xYz", "ABC", "IjK"]]
+  , ["ab*", ["ABC"], { nocase: true, null: true }
+    , ["xYz", "ABC", "IjK"]]
+  , ["[ia]?[ck]", ["ABC", "IjK"], { nocase: true, null: true }
+    , ["xYz", "ABC", "IjK"]]
+
+  // [ pattern, [matches], MM opts, files, TAP opts]
+  , "onestar/twostar"
+  , ["{/*,*}", [], {null: true}, ["/asdf/asdf/asdf"]]
+  , ["{/?,*}", ["/a", "bb"], {null: true}
+    , ["/a", "/b/b", "/a/b/c", "bb"]]
+
+  , "dots should not match unless requested"
+  , ["**", ["a/b"], {}, ["a/b", "a/.d", ".a/.d"]]
+
+  // .. and . can only match patterns starting with .,
+  // even when options.dot is set.
+  , function () {
+      files = ["a/./b", "a/../b", "a/c/b", "a/.d/b"]
+    }
+  , ["a/*/b", ["a/c/b", "a/.d/b"], {dot: true}]
+  , ["a/.*/b", ["a/./b", "a/../b", "a/.d/b"], {dot: true}]
+  , ["a/*/b", ["a/c/b"], {dot:false}]
+  , ["a/.*/b", ["a/./b", "a/../b", "a/.d/b"], {dot: false}]
+
+
+  // this also tests that changing the options needs
+  // to change the cache key, even if the pattern is
+  // the same!
+  , ["**", ["a/b","a/.d",".a/.d"], { dot: true }
+    , [ ".a/.d", "a/.d", "a/b"]]
+
+  , "paren sets cannot contain slashes"
+  , ["*(a/b)", ["*(a/b)"], {nonull: true}, ["a/b"]]
+
+  // brace sets trump all else.
+  //
+  // invalid glob pattern.  fails on bash4 and bsdglob.
+  // however, in this implementation, it's easier just
+  // to do the intuitive thing, and let brace-expansion
+  // actually come before parsing any extglob patterns,
+  // like the documentation seems to say.
+  //
+  // XXX: if anyone complains about this, either fix it
+  // or tell them to grow up and stop complaining.
+  //
+  // bash/bsdglob says this:
+  // , ["*(a|{b),c)}", ["*(a|{b),c)}"], {}, ["a", "ab", "ac", "ad"]]
+  // but we do this instead:
+  , ["*(a|{b),c)}", ["a", "ab", "ac"], {}, ["a", "ab", "ac", "ad"]]
+
+  // test partial parsing in the presence of comment/negation chars
+  , ["[!a*", ["[!ab"], {}, ["[!ab", "[ab"]]
+  , ["[#a*", ["[#ab"], {}, ["[#ab", "[ab"]]
+
+  // like: {a,b|c\\,d\\\|e} except it's unclosed, so it has to be escaped.
+  , ["+(a|*\\|c\\\\|d\\\\\\|e\\\\\\\\|f\\\\\\\\\\|g"
+    , ["+(a|b\\|c\\\\|d\\\\|e\\\\\\\\|f\\\\\\\\|g"]
+    , {}
+    , ["+(a|b\\|c\\\\|d\\\\|e\\\\\\\\|f\\\\\\\\|g", "a", "b\\c"]]
+
+
+  // crazy nested {,,} and *(||) tests.
+  , function () {
+      files = [ "a", "b", "c", "d"
+              , "ab", "ac", "ad"
+              , "bc", "cb"
+              , "bc,d", "c,db", "c,d"
+              , "d)", "(b|c", "*(b|c"
+              , "b|c", "b|cc", "cb|c"
+              , "x(a|b|c)", "x(a|c)"
+              , "(a|b|c)", "(a|c)"]
+    }
+  , ["*(a|{b,c})", ["a", "b", "c", "ab", "ac"]]
+  , ["{a,*(b|c,d)}", ["a","(b|c", "*(b|c", "d)"]]
+  // a
+  // *(b|c)
+  // *(b|d)
+  , ["{a,*(b|{c,d})}", ["a","b", "bc", "cb", "c", "d"]]
+  , ["*(a|{b|c,c})", ["a", "b", "c", "ab", "ac", "bc", "cb"]]
+
+
+  // test various flag settings.
+  , [ "*(a|{b|c,c})", ["x(a|b|c)", "x(a|c)", "(a|b|c)", "(a|c)"]
+    , { noext: true } ]
+  , ["a?b", ["x/y/acb", "acb/"], {matchBase: true}
+    , ["x/y/acb", "acb/", "acb/d/e", "x/y/acb/d"] ]
+  , ["#*", ["#a", "#b"], {nocomment: true}, ["#a", "#b", "c#d"]]
+
+
+  // begin channelling Boole and deMorgan...
+  , "negation tests"
+  , function () {
+      files = ["d", "e", "!ab", "!abc", "a!b", "\\!a"]
+    }
+
+  // anything that is NOT a* matches.
+  , ["!a*", ["\\!a", "d", "e", "!ab", "!abc"]]
+
+  // anything that IS !a* matches.
+  , ["!a*", ["!ab", "!abc"], {nonegate: true}]
+
+  // anything that IS a* matches
+  , ["!!a*", ["a!b"]]
+
+  // anything that is NOT !a* matches
+  , ["!\\!a*", ["a!b", "d", "e", "\\!a"]]
+
+  // negation nestled within a pattern
+  , function () {
+      files = [ "foo.js"
+              , "foo.bar"
+              // can't match this one without negative lookbehind.
+              , "foo.js.js"
+              , "blar.js"
+              , "foo."
+              , "boo.js.boo" ]
+    }
+  , ["*.!(js)", ["foo.bar", "foo.", "boo.js.boo"] ]
+
+  // https://github.com/isaacs/minimatch/issues/5
+  , function () {
+      files = [ 'a/b/.x/c'
+              , 'a/b/.x/c/d'
+              , 'a/b/.x/c/d/e'
+              , 'a/b/.x'
+              , 'a/b/.x/'
+              , 'a/.x/b'
+              , '.x'
+              , '.x/'
+              , '.x/a'
+              , '.x/a/b'
+              , 'a/.x/b/.x/c'
+              , '.x/.x' ]
+  }
+  , ["**/.x/**", [ '.x/'
+                 , '.x/a'
+                 , '.x/a/b'
+                 , 'a/.x/b'
+                 , 'a/b/.x/'
+                 , 'a/b/.x/c'
+                 , 'a/b/.x/c/d'
+                 , 'a/b/.x/c/d/e' ] ]
+
+  ]
+
+var regexps =
+  [ '/^(?:(?=.)a[^/]*?)$/',
+    '/^(?:(?=.)X[^/]*?)$/',
+    '/^(?:(?=.)X[^/]*?)$/',
+    '/^(?:\\*)$/',
+    '/^(?:(?=.)\\*[^/]*?)$/',
+    '/^(?:\\*\\*)$/',
+    '/^(?:(?=.)b[^/]*?\\/)$/',
+    '/^(?:(?=.)c[^/]*?)$/',
+    '/^(?:(?:(?!(?:\\/|^)\\.).)*?)$/',
+    '/^(?:\\.\\.\\/(?!\\.)(?=.)[^/]*?\\/)$/',
+    '/^(?:s\\/(?=.)\\.\\.[^/]*?\\/)$/',
+    '/^(?:\\/\\^root:\\/\\{s\\/(?=.)\\^[^:][^/]*?:[^:][^/]*?:\\([^:]\\)[^/]*?\\.[^/]*?\\$\\/1\\/)$/',
+    '/^(?:\\/\\^root:\\/\\{s\\/(?=.)\\^[^:][^/]*?:[^:][^/]*?:\\([^:]\\)[^/]*?\\.[^/]*?\\$\\/\u0001\\/)$/',
+    '/^(?:(?!\\.)(?=.)[a-c]b[^/]*?)$/',
+    '/^(?:(?!\\.)(?=.)[a-y][^/]*?[^c])$/',
+    '/^(?:(?=.)a[^/]*?[^c])$/',
+    '/^(?:(?=.)a[X-]b)$/',
+    '/^(?:(?!\\.)(?=.)[^a-c][^/]*?)$/',
+    '/^(?:a\\*b\\/(?!\\.)(?=.)[^/]*?)$/',
+    '/^(?:(?=.)a\\*[^/]\\/(?!\\.)(?=.)[^/]*?)$/',
+    '/^(?:(?!\\.)(?=.)[^/]*?\\\\\\![^/]*?)$/',
+    '/^(?:(?!\\.)(?=.)[^/]*?\\![^/]*?)$/',
+    '/^(?:(?!\\.)(?=.)[^/]*?\\.\\*)$/',
+    '/^(?:(?=.)a[b]c)$/',
+    '/^(?:(?=.)a[b]c)$/',
+    '/^(?:(?=.)a[^/]c)$/',
+    '/^(?:a\\*c)$/',
+    'false',
+    '/^(?:(?!\\.)(?=.)[^/]*?\\/(?=.)man[^/]*?\\/(?=.)bash\\.[^/]*?)$/',
+    '/^(?:man\\/man1\\/bash\\.1)$/',
+    '/^(?:(?=.)a[^/]*?[^/]*?[^/]*?c)$/',
+    '/^(?:(?=.)a[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]c)$/',
+    '/^(?:(?!\\.)(?=.)[^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/][^/])$/',
+    '/^(?:(?!\\.)(?=.)[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/][^/])$/',
+    '/^(?:(?!\\.)(?=.)[^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]c)$/',
+    '/^(?:(?!\\.)(?=.)[^/][^/]*?[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/]*?[^/]*?c)$/',
+    '/^(?:(?!\\.)(?=.)[^/][^/]*?[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/]*?[^/]*?[^/])$/',
+    '/^(?:(?!\\.)(?=.)[^/][^/]*?[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/]*?[^/]*?)$/',
+    '/^(?:(?!\\.)(?=.)[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?c)$/',
+    '/^(?:(?!\\.)(?=.)[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/])$/',
+    '/^(?:(?=.)a[^/]*?cd[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/][^/]k)$/',
+    '/^(?:(?=.)a[^/]*?[^/]*?[^/][^/]*?[^/]*?cd[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/][^/]k)$/',
+    '/^(?:(?=.)a[^/]*?[^/]*?[^/][^/]*?[^/]*?cd[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/][^/]k[^/]*?[^/]*?[^/]*?)$/',
+    '/^(?:(?=.)a[^/]*?[^/]*?[^/][^/]*?[^/]*?cd[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/][^/][^/]*?[^/]*?[^/]*?k)$/',
+    '/^(?:(?=.)a[^/]*?[^/]*?[^/][^/]*?[^/]*?cd[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/][^/][^/]*?[^/]*?[^/]*?k[^/]*?[^/]*?)$/',
+    '/^(?:(?=.)a[^/]*?[^/]*?[^/]*?[^/]*?c[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/][^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?)$/',
+    '/^(?:(?!\\.)(?=.)[-abc])$/',
+    '/^(?:(?!\\.)(?=.)[abc-])$/',
+    '/^(?:\\\\)$/',
+    '/^(?:(?!\\.)(?=.)[\\\\])$/',
+    '/^(?:(?!\\.)(?=.)[\\[])$/',
+    '/^(?:\\[)$/',
+    '/^(?:(?=.)\\[(?!\\.)(?=.)[^/]*?)$/',
+    '/^(?:(?!\\.)(?=.)[\\]])$/',
+    '/^(?:(?!\\.)(?=.)[\\]-])$/',
+    '/^(?:(?!\\.)(?=.)[a-z])$/',
+    '/^(?:(?!\\.)(?=.)[^/][^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/]*?[^/]*?[^/])$/',
+    '/^(?:(?!\\.)(?=.)[^/][^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/]*?[^/]*?c)$/',
+    '/^(?:(?!\\.)(?=.)[^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?c[^/]*?[^/]*?[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/]*?[^/]*?)$/',
+    '/^(?:(?!\\.)(?=.)[^/]*?c[^/]*?[^/][^/]*?[^/]*?)$/',
+    '/^(?:(?=.)a[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?c[^/]*?[^/][^/]*?[^/]*?)$/',
+    '/^(?:(?=.)a[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/][^/][^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?)$/',
+    '/^(?:\\[\\])$/',
+    '/^(?:\\[abc)$/',
+    '/^(?:(?=.)XYZ)$/i',
+    '/^(?:(?=.)ab[^/]*?)$/i',
+    '/^(?:(?!\\.)(?=.)[ia][^/][ck])$/i',
+    '/^(?:\\/(?!\\.)(?=.)[^/]*?|(?!\\.)(?=.)[^/]*?)$/',
+    '/^(?:\\/(?!\\.)(?=.)[^/]|(?!\\.)(?=.)[^/]*?)$/',
+    '/^(?:(?:(?!(?:\\/|^)\\.).)*?)$/',
+    '/^(?:a\\/(?!(?:^|\\/)\\.{1,2}(?:$|\\/))(?=.)[^/]*?\\/b)$/',
+    '/^(?:a\\/(?=.)\\.[^/]*?\\/b)$/',
+    '/^(?:a\\/(?!\\.)(?=.)[^/]*?\\/b)$/',
+    '/^(?:a\\/(?=.)\\.[^/]*?\\/b)$/',
+    '/^(?:(?:(?!(?:\\/|^)(?:\\.{1,2})($|\\/)).)*?)$/',
+    '/^(?:(?!\\.)(?=.)[^/]*?\\(a\\/b\\))$/',
+    '/^(?:(?!\\.)(?=.)(?:a|b)*|(?!\\.)(?=.)(?:a|c)*)$/',
+    '/^(?:(?=.)\\[(?=.)\\!a[^/]*?)$/',
+    '/^(?:(?=.)\\[(?=.)#a[^/]*?)$/',
+    '/^(?:(?=.)\\+\\(a\\|[^/]*?\\|c\\\\\\\\\\|d\\\\\\\\\\|e\\\\\\\\\\\\\\\\\\|f\\\\\\\\\\\\\\\\\\|g)$/',
+    '/^(?:(?!\\.)(?=.)(?:a|b)*|(?!\\.)(?=.)(?:a|c)*)$/',
+    '/^(?:a|(?!\\.)(?=.)[^/]*?\\(b\\|c|d\\))$/',
+    '/^(?:a|(?!\\.)(?=.)(?:b|c)*|(?!\\.)(?=.)(?:b|d)*)$/',
+    '/^(?:(?!\\.)(?=.)(?:a|b|c)*|(?!\\.)(?=.)(?:a|c)*)$/',
+    '/^(?:(?!\\.)(?=.)[^/]*?\\(a\\|b\\|c\\)|(?!\\.)(?=.)[^/]*?\\(a\\|c\\))$/',
+    '/^(?:(?=.)a[^/]b)$/',
+    '/^(?:(?=.)#[^/]*?)$/',
+    '/^(?!^(?:(?=.)a[^/]*?)$).*$/',
+    '/^(?:(?=.)\\!a[^/]*?)$/',
+    '/^(?:(?=.)a[^/]*?)$/',
+    '/^(?!^(?:(?=.)\\!a[^/]*?)$).*$/',
+    '/^(?:(?!\\.)(?=.)[^/]*?\\.(?:(?!js)[^/]*?))$/',
+    '/^(?:(?:(?!(?:\\/|^)\\.).)*?\\/\\.x\\/(?:(?!(?:\\/|^)\\.).)*?)$/' ]
+var re = 0;
+
+tap.test("basic tests", function (t) {
+  var start = Date.now()
+
+  // [ pattern, [matches], MM opts, files, TAP opts]
+  patterns.forEach(function (c) {
+    if (typeof c === "function") return c()
+    if (typeof c === "string") return t.comment(c)
+
+    var pattern = c[0]
+      , expect = c[1].sort(alpha)
+      , options = c[2] || {}
+      , f = c[3] || files
+      , tapOpts = c[4] || {}
+
+    // options.debug = true
+    var m = new mm.Minimatch(pattern, options)
+    var r = m.makeRe()
+    var expectRe = regexps[re++]
+    tapOpts.re = String(r) || JSON.stringify(r)
+    tapOpts.files = JSON.stringify(f)
+    tapOpts.pattern = pattern
+    tapOpts.set = m.set
+    tapOpts.negated = m.negate
+
+    var actual = mm.match(f, pattern, options)
+    actual.sort(alpha)
+
+    t.equivalent( actual, expect
+                , JSON.stringify(pattern) + " " + JSON.stringify(expect)
+                , tapOpts )
+
+    t.equal(tapOpts.re, expectRe, tapOpts)
+  })
+
+  t.comment("time=" + (Date.now() - start) + "ms")
+  t.end()
+})
+
+tap.test("global leak test", function (t) {
+  var globalAfter = Object.keys(global)
+  t.equivalent(globalAfter, globalBefore, "no new globals, please")
+  t.end()
+})
+
+function alpha (a, b) {
+  return a > b ? 1 : -1
+}

+ 33 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/test/brace-expand.js

@@ -0,0 +1,33 @@
+var tap = require("tap")
+  , minimatch = require("../")
+
+tap.test("brace expansion", function (t) {
+  // [ pattern, [expanded] ]
+  ; [ [ "a{b,c{d,e},{f,g}h}x{y,z}"
+      , [ "abxy"
+        , "abxz"
+        , "acdxy"
+        , "acdxz"
+        , "acexy"
+        , "acexz"
+        , "afhxy"
+        , "afhxz"
+        , "aghxy"
+        , "aghxz" ] ]
+    , [ "a{1..5}b"
+      , [ "a1b"
+        , "a2b"
+        , "a3b"
+        , "a4b"
+        , "a5b" ] ]
+    , [ "a{b}c", ["a{b}c"] ]
+  ].forEach(function (tc) {
+    var p = tc[0]
+      , expect = tc[1]
+    t.equivalent(minimatch.braceExpand(p), expect, p)
+  })
+  console.error("ending")
+  t.end()
+})
+
+

+ 14 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/test/caching.js

@@ -0,0 +1,14 @@
+var Minimatch = require("../minimatch.js").Minimatch
+var tap = require("tap")
+tap.test("cache test", function (t) {
+  var mm1 = new Minimatch("a?b")
+  var mm2 = new Minimatch("a?b")
+  t.equal(mm1, mm2, "should get the same object")
+  // the lru should drop it after 100 entries
+  for (var i = 0; i < 100; i ++) {
+    new Minimatch("a"+i)
+  }
+  mm2 = new Minimatch("a?b")
+  t.notEqual(mm1, mm2, "cache should have dropped")
+  t.end()
+})

+ 274 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/test/defaults.js

@@ -0,0 +1,274 @@
+// http://www.bashcookbook.com/bashinfo/source/bash-1.14.7/tests/glob-test
+//
+// TODO: Some of these tests do very bad things with backslashes, and will
+// most likely fail badly on windows.  They should probably be skipped.
+
+var tap = require("tap")
+  , globalBefore = Object.keys(global)
+  , mm = require("../")
+  , files = [ "a", "b", "c", "d", "abc"
+            , "abd", "abe", "bb", "bcd"
+            , "ca", "cb", "dd", "de"
+            , "bdir/", "bdir/cfile"]
+  , next = files.concat([ "a-b", "aXb"
+                        , ".x", ".y" ])
+
+tap.test("basic tests", function (t) {
+  var start = Date.now()
+
+  // [ pattern, [matches], MM opts, files, TAP opts]
+  ; [ "http://www.bashcookbook.com/bashinfo" +
+      "/source/bash-1.14.7/tests/glob-test"
+    , ["a*", ["a", "abc", "abd", "abe"]]
+    , ["X*", ["X*"], {nonull: true}]
+
+    // allow null glob expansion
+    , ["X*", []]
+
+    // isaacs: Slightly different than bash/sh/ksh
+    // \\* is not un-escaped to literal "*" in a failed match,
+    // but it does make it get treated as a literal star
+    , ["\\*", ["\\*"], {nonull: true}]
+    , ["\\**", ["\\**"], {nonull: true}]
+    , ["\\*\\*", ["\\*\\*"], {nonull: true}]
+
+    , ["b*/", ["bdir/"]]
+    , ["c*", ["c", "ca", "cb"]]
+    , ["**", files]
+
+    , ["\\.\\./*/", ["\\.\\./*/"], {nonull: true}]
+    , ["s/\\..*//", ["s/\\..*//"], {nonull: true}]
+
+    , "legendary larry crashes bashes"
+    , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\\1/"
+      , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\\1/"], {nonull: true}]
+    , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\1/"
+      , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\1/"], {nonull: true}]
+
+    , "character classes"
+    , ["[a-c]b*", ["abc", "abd", "abe", "bb", "cb"]]
+    , ["[a-y]*[^c]", ["abd", "abe", "bb", "bcd",
+       "bdir/", "ca", "cb", "dd", "de"]]
+    , ["a*[^c]", ["abd", "abe"]]
+    , function () { files.push("a-b", "aXb") }
+    , ["a[X-]b", ["a-b", "aXb"]]
+    , function () { files.push(".x", ".y") }
+    , ["[^a-c]*", ["d", "dd", "de"]]
+    , function () { files.push("a*b/", "a*b/ooo") }
+    , ["a\\*b/*", ["a*b/ooo"]]
+    , ["a\\*?/*", ["a*b/ooo"]]
+    , ["*\\\\!*", [], {null: true}, ["echo !7"]]
+    , ["*\\!*", ["echo !7"], null, ["echo !7"]]
+    , ["*.\\*", ["r.*"], null, ["r.*"]]
+    , ["a[b]c", ["abc"]]
+    , ["a[\\b]c", ["abc"]]
+    , ["a?c", ["abc"]]
+    , ["a\\*c", [], {null: true}, ["abc"]]
+    , ["", [""], { null: true }, [""]]
+
+    , "http://www.opensource.apple.com/source/bash/bash-23/" +
+      "bash/tests/glob-test"
+    , function () { files.push("man/", "man/man1/", "man/man1/bash.1") }
+    , ["*/man*/bash.*", ["man/man1/bash.1"]]
+    , ["man/man1/bash.1", ["man/man1/bash.1"]]
+    , ["a***c", ["abc"], null, ["abc"]]
+    , ["a*****?c", ["abc"], null, ["abc"]]
+    , ["?*****??", ["abc"], null, ["abc"]]
+    , ["*****??", ["abc"], null, ["abc"]]
+    , ["?*****?c", ["abc"], null, ["abc"]]
+    , ["?***?****c", ["abc"], null, ["abc"]]
+    , ["?***?****?", ["abc"], null, ["abc"]]
+    , ["?***?****", ["abc"], null, ["abc"]]
+    , ["*******c", ["abc"], null, ["abc"]]
+    , ["*******?", ["abc"], null, ["abc"]]
+    , ["a*cd**?**??k", ["abcdecdhjk"], null, ["abcdecdhjk"]]
+    , ["a**?**cd**?**??k", ["abcdecdhjk"], null, ["abcdecdhjk"]]
+    , ["a**?**cd**?**??k***", ["abcdecdhjk"], null, ["abcdecdhjk"]]
+    , ["a**?**cd**?**??***k", ["abcdecdhjk"], null, ["abcdecdhjk"]]
+    , ["a**?**cd**?**??***k**", ["abcdecdhjk"], null, ["abcdecdhjk"]]
+    , ["a****c**?**??*****", ["abcdecdhjk"], null, ["abcdecdhjk"]]
+    , ["[-abc]", ["-"], null, ["-"]]
+    , ["[abc-]", ["-"], null, ["-"]]
+    , ["\\", ["\\"], null, ["\\"]]
+    , ["[\\\\]", ["\\"], null, ["\\"]]
+    , ["[[]", ["["], null, ["["]]
+    , ["[", ["["], null, ["["]]
+    , ["[*", ["[abc"], null, ["[abc"]]
+    , "a right bracket shall lose its special meaning and\n" +
+      "represent itself in a bracket expression if it occurs\n" +
+      "first in the list.  -- POSIX.2 2.8.3.2"
+    , ["[]]", ["]"], null, ["]"]]
+    , ["[]-]", ["]"], null, ["]"]]
+    , ["[a-\z]", ["p"], null, ["p"]]
+    , ["??**********?****?", [], { null: true }, ["abc"]]
+    , ["??**********?****c", [], { null: true }, ["abc"]]
+    , ["?************c****?****", [], { null: true }, ["abc"]]
+    , ["*c*?**", [], { null: true }, ["abc"]]
+    , ["a*****c*?**", [], { null: true }, ["abc"]]
+    , ["a********???*******", [], { null: true }, ["abc"]]
+    , ["[]", [], { null: true }, ["a"]]
+    , ["[abc", [], { null: true }, ["["]]
+
+    , "nocase tests"
+    , ["XYZ", ["xYz"], { nocase: true, null: true }
+      , ["xYz", "ABC", "IjK"]]
+    , ["ab*", ["ABC"], { nocase: true, null: true }
+      , ["xYz", "ABC", "IjK"]]
+    , ["[ia]?[ck]", ["ABC", "IjK"], { nocase: true, null: true }
+      , ["xYz", "ABC", "IjK"]]
+
+    // [ pattern, [matches], MM opts, files, TAP opts]
+    , "onestar/twostar"
+    , ["{/*,*}", [], {null: true}, ["/asdf/asdf/asdf"]]
+    , ["{/?,*}", ["/a", "bb"], {null: true}
+      , ["/a", "/b/b", "/a/b/c", "bb"]]
+
+    , "dots should not match unless requested"
+    , ["**", ["a/b"], {}, ["a/b", "a/.d", ".a/.d"]]
+
+    // .. and . can only match patterns starting with .,
+    // even when options.dot is set.
+    , function () {
+        files = ["a/./b", "a/../b", "a/c/b", "a/.d/b"]
+      }
+    , ["a/*/b", ["a/c/b", "a/.d/b"], {dot: true}]
+    , ["a/.*/b", ["a/./b", "a/../b", "a/.d/b"], {dot: true}]
+    , ["a/*/b", ["a/c/b"], {dot:false}]
+    , ["a/.*/b", ["a/./b", "a/../b", "a/.d/b"], {dot: false}]
+
+
+    // this also tests that changing the options needs
+    // to change the cache key, even if the pattern is
+    // the same!
+    , ["**", ["a/b","a/.d",".a/.d"], { dot: true }
+      , [ ".a/.d", "a/.d", "a/b"]]
+
+    , "paren sets cannot contain slashes"
+    , ["*(a/b)", ["*(a/b)"], {nonull: true}, ["a/b"]]
+
+    // brace sets trump all else.
+    //
+    // invalid glob pattern.  fails on bash4 and bsdglob.
+    // however, in this implementation, it's easier just
+    // to do the intuitive thing, and let brace-expansion
+    // actually come before parsing any extglob patterns,
+    // like the documentation seems to say.
+    //
+    // XXX: if anyone complains about this, either fix it
+    // or tell them to grow up and stop complaining.
+    //
+    // bash/bsdglob says this:
+    // , ["*(a|{b),c)}", ["*(a|{b),c)}"], {}, ["a", "ab", "ac", "ad"]]
+    // but we do this instead:
+    , ["*(a|{b),c)}", ["a", "ab", "ac"], {}, ["a", "ab", "ac", "ad"]]
+
+    // test partial parsing in the presence of comment/negation chars
+    , ["[!a*", ["[!ab"], {}, ["[!ab", "[ab"]]
+    , ["[#a*", ["[#ab"], {}, ["[#ab", "[ab"]]
+
+    // like: {a,b|c\\,d\\\|e} except it's unclosed, so it has to be escaped.
+    , ["+(a|*\\|c\\\\|d\\\\\\|e\\\\\\\\|f\\\\\\\\\\|g"
+      , ["+(a|b\\|c\\\\|d\\\\|e\\\\\\\\|f\\\\\\\\|g"]
+      , {}
+      , ["+(a|b\\|c\\\\|d\\\\|e\\\\\\\\|f\\\\\\\\|g", "a", "b\\c"]]
+
+
+    // crazy nested {,,} and *(||) tests.
+    , function () {
+        files = [ "a", "b", "c", "d"
+                , "ab", "ac", "ad"
+                , "bc", "cb"
+                , "bc,d", "c,db", "c,d"
+                , "d)", "(b|c", "*(b|c"
+                , "b|c", "b|cc", "cb|c"
+                , "x(a|b|c)", "x(a|c)"
+                , "(a|b|c)", "(a|c)"]
+      }
+    , ["*(a|{b,c})", ["a", "b", "c", "ab", "ac"]]
+    , ["{a,*(b|c,d)}", ["a","(b|c", "*(b|c", "d)"]]
+    // a
+    // *(b|c)
+    // *(b|d)
+    , ["{a,*(b|{c,d})}", ["a","b", "bc", "cb", "c", "d"]]
+    , ["*(a|{b|c,c})", ["a", "b", "c", "ab", "ac", "bc", "cb"]]
+
+
+    // test various flag settings.
+    , [ "*(a|{b|c,c})", ["x(a|b|c)", "x(a|c)", "(a|b|c)", "(a|c)"]
+      , { noext: true } ]
+    , ["a?b", ["x/y/acb", "acb/"], {matchBase: true}
+      , ["x/y/acb", "acb/", "acb/d/e", "x/y/acb/d"] ]
+    , ["#*", ["#a", "#b"], {nocomment: true}, ["#a", "#b", "c#d"]]
+
+
+    // begin channelling Boole and deMorgan...
+    , "negation tests"
+    , function () {
+        files = ["d", "e", "!ab", "!abc", "a!b", "\\!a"]
+      }
+
+    // anything that is NOT a* matches.
+    , ["!a*", ["\\!a", "d", "e", "!ab", "!abc"]]
+
+    // anything that IS !a* matches.
+    , ["!a*", ["!ab", "!abc"], {nonegate: true}]
+
+    // anything that IS a* matches
+    , ["!!a*", ["a!b"]]
+
+    // anything that is NOT !a* matches
+    , ["!\\!a*", ["a!b", "d", "e", "\\!a"]]
+
+    // negation nestled within a pattern
+    , function () {
+        files = [ "foo.js"
+                , "foo.bar"
+                // can't match this one without negative lookbehind.
+                , "foo.js.js"
+                , "blar.js"
+                , "foo."
+                , "boo.js.boo" ]
+      }
+    , ["*.!(js)", ["foo.bar", "foo.", "boo.js.boo"] ]
+
+    ].forEach(function (c) {
+      if (typeof c === "function") return c()
+      if (typeof c === "string") return t.comment(c)
+
+      var pattern = c[0]
+        , expect = c[1].sort(alpha)
+        , options = c[2]
+        , f = c[3] || files
+        , tapOpts = c[4] || {}
+
+      // options.debug = true
+      var Class = mm.defaults(options).Minimatch
+      var m = new Class(pattern, {})
+      var r = m.makeRe()
+      tapOpts.re = String(r) || JSON.stringify(r)
+      tapOpts.files = JSON.stringify(f)
+      tapOpts.pattern = pattern
+      tapOpts.set = m.set
+      tapOpts.negated = m.negate
+
+      var actual = mm.match(f, pattern, options)
+      actual.sort(alpha)
+
+      t.equivalent( actual, expect
+                  , JSON.stringify(pattern) + " " + JSON.stringify(expect)
+                  , tapOpts )
+    })
+
+  t.comment("time=" + (Date.now() - start) + "ms")
+  t.end()
+})
+
+tap.test("global leak test", function (t) {
+  var globalAfter = Object.keys(global)
+  t.equivalent(globalAfter, globalBefore, "no new globals, please")
+  t.end()
+})
+
+function alpha (a, b) {
+  return a > b ? 1 : -1
+}

+ 8 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/minimatch/test/extglob-ending-with-state-char.js

@@ -0,0 +1,8 @@
+var test = require('tap').test
+var minimatch = require('../')
+
+test('extglob ending with statechar', function(t) {
+  t.notOk(minimatch('ax', 'a?(b*)'))
+  t.ok(minimatch('ax', '?(a*|b)'))
+  t.end()
+})

+ 42 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/utilities/Jakefile

@@ -0,0 +1,42 @@
+
+var t = new jake.TestTask('Utilities', function () {
+  this.testFiles.include('test/*.js');
+  
+  // Can't reliably test ports on travis
+  if(process.env.CI) {
+    this.testFiles.exclude('test/network.js');
+  }
+});
+
+namespace('doc', function () {
+  task('generate', ['doc:clobber'], function () {
+    var cmd = '../node-jsdoc-toolkit/app/run.js -n -r=100 ' +
+        '-t=../node-jsdoc-toolkit/templates/codeview -d=./doc/ ./lib';
+    console.log('Generating docs ...');
+    jake.exec([cmd], function () {
+      console.log('Done.');
+      complete();
+    });
+  }, {async: true});
+
+  task('clobber', function () {
+    var cmd = 'rm -fr ./doc/**';
+    jake.exec([cmd], function () {
+      console.log('Clobbered old docs.');
+      complete();
+    });
+  }, {async: true});
+
+});
+
+desc('Generate docs for Utilities');
+task('doc', ['doc:generate']);
+
+var p = new jake.NpmPublishTask('utilities', [
+  'Jakefile'
+, 'README.md'
+, 'package.json'
+, 'lib/**'
+, 'test/**'
+]);
+

+ 6 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/utilities/README.md

@@ -0,0 +1,6 @@
+utilities
+=========
+
+[![Build Status](https://travis-ci.org/mde/utilities.png?branch=master)](https://travis-ci.org/mde/utilities)
+
+A classic collection of JavaScript utilities

+ 94 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/utilities/lib/array.js

@@ -0,0 +1,94 @@
+/*
+ * Utilities: A classic collection of JavaScript utilities
+ * Copyright 2112 Matthew Eernisse ([email protected])
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+
+/**
+  @name array
+  @namespace array
+*/
+
+var array = new (function () {
+
+  /**
+    @name array#humanize
+    @public
+    @function
+    @return {String} A string containing the array elements in a readable format
+    @description Creates a string containing the array elements in a readable format
+    @param {Array} array The array to humanize
+  */
+  this.humanize = function (a) {
+    var array = a.slice();
+    // If array only has one item then just return it
+    if (array.length <= 1) {
+      return String(array);
+    }
+
+    var last = array.pop()
+      , items = array.join(', ');
+
+    return items + ' and ' + last;
+  };
+
+  /**
+    @name array#included
+    @public
+    @function
+    @return {Array/Boolean} If `item` is included the `array` is
+      returned otherwise false
+    @description Checks if an `item` is included in an `array`
+    @param {Any} item The item to look for
+    @param {Array} array The array to check
+  */
+  this.included = function (item, array) {
+    var result = array.indexOf(item);
+
+    if (result === -1) {
+      return false;
+    } else {
+      return array;
+    }
+  };
+
+  /**
+    @name array#include
+    @public
+    @function
+    @return {Boolean} Return true if the item is included in the array
+    @description Checks if an `item` is included in an `array`
+    @param {Array} array The array to check
+    @param {Any} item The item to look for
+  */
+  this.include = function (array, item) {
+    var res = -1;
+    if (typeof array.indexOf == 'function') {
+      res = array.indexOf(item);
+    }
+    else {
+      for (var i = 0, ii = array.length; i < ii; i++) {
+        if (array[i] == item) {
+          res = i;
+          break;
+        }
+      }
+    }
+    return res > -1;
+  };
+
+})();
+
+module.exports = array;

+ 298 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/utilities/lib/async.js

@@ -0,0 +1,298 @@
+/*
+ * Utilities: A classic collection of JavaScript utilities
+ * Copyright 2112 Matthew Eernisse ([email protected])
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+
+var async = {};
+
+/*
+AsyncChain -- performs a list of asynchronous calls in a desired order.
+Optional "last" method can be set to run after all the items in the
+chain have completed.
+
+  // Example usage
+  var asyncChain = new async.AsyncChain([
+    {
+      func: app.trainToBangkok,
+      args: [geddy, neil, alex],
+      callback: null, // No callback for this action
+    },
+    {
+      func: fs.readdir,
+      args: [geddy.config.dirname + '/thailand/express'],
+      callback: function (err, result) {
+        if (err) {
+          // Bail out completely
+          arguments.callee.chain.abort();
+        }
+        else if (result.theBest) {
+          // Don't run the next item in the chain; go directly
+          // to the 'last' method.
+          arguments.callee.chain.shortCircuit();
+        }
+        else {
+          // Otherwise do some other stuff and
+          // then go to the next link
+        }
+      }
+    },
+    {
+      func: child_process.exec,
+      args: ['ls ./'],
+      callback: this.hitTheStops
+    }
+  ]);
+
+  // Function to exec after all the links in the chain finish
+  asyncChain.last = function () { // Do some final stuff };
+
+  // Start the async-chain
+  asyncChain.run();
+
+*/
+async.execNonBlocking = function (func) {
+  if (typeof process != 'undefined' && typeof process.nextTick == 'function') {
+    process.nextTick(func);
+  }
+  else {
+    setTimeout(func, 0);
+  }
+};
+
+async.AsyncBase = new (function () {
+
+  this.init = function (chain) {
+    var item;
+    this.chain = [];
+    this.currentItem = null;
+    this.shortCircuited = false;
+    this.shortCircuitedArgs = undefined;
+    this.aborted = false;
+
+    for (var i = 0; i < chain.length; i++) {
+      item = chain[i];
+      this.addItem(item);
+    }
+  };
+
+  this.addItem = function(item) {
+    this.chain.push(new async.AsyncCall(
+      item.func, item.args || [], item.callback, item.context));
+  };
+
+  // alias
+  this.push = this.addItem;
+
+  this.runItem = function (item) {
+    // Reference to the current item in the chain -- used
+    // to look up the callback to execute with execCallback
+    this.currentItem = item;
+    // Scopage
+    var _this = this;
+    // Pass the arguments passed to the current async call
+    // to the callback executor, execute it in the correct scope
+    var executor = function () {
+      _this.execCallback.apply(_this, arguments);
+    };
+    // Append the callback executor to the end of the arguments
+    // Node helpfully always has the callback func last
+    var args = item.args.concat(executor);
+    var func = item.func;
+    // Run the async call
+    func.apply(item.context, args);
+  };
+
+  this.next = function () {
+    if (this.chain.length) {
+      this.runItem(this.chain.shift());
+    }
+    else {
+      this.last();
+    }
+  };
+
+  this.execCallback = function () {
+    // Look up the callback, if any, specified for this async call
+    var callback = this.currentItem.callback;
+    // If there's a callback, do it
+    if (callback && typeof callback == 'function') {
+      // Allow access to the chain from inside the callback by setting
+      // callback.chain = this, and then using arguments.callee.chain
+      callback.chain = this;
+      callback.apply(this.currentItem.context, arguments);
+    }
+
+    this.currentItem.finished = true;
+
+    // If one of the async callbacks called chain.shortCircuit,
+    // skip to the 'last' function for the chain
+    if (this.shortCircuited) {
+      this.last.apply(null, this.shortCircuitedArgs);
+    }
+    // If one of the async callbacks called chain.abort,
+    // bail completely out
+    else if (this.aborted) {
+      return;
+    }
+    // Otherwise run the next item, if any, in the chain
+    // Let's try not to block if we don't have to
+    else {
+      // Scopage
+      var _this = this;
+      async.execNonBlocking(function () { _this.next.call(_this); });
+    }
+  }
+
+  // Short-circuit the chain, jump straight to the 'last' function
+  this.shortCircuit = function () {
+    this.shortCircuitedArgs = arguments;
+    this.shortCircuited = true;
+  }
+
+  // Stop execution of the chain, bail completely out
+  this.abort = function () {
+    this.aborted = true;
+  }
+
+  // Kick off the chain by grabbing the first item and running it
+  this.run = this.next;
+
+  // Function to run when the chain is done -- default is a no-op
+  this.last = function () {};
+
+})();
+
+async.AsyncChain = function (chain) {
+  this.init(chain);
+};
+
+async.AsyncChain.prototype = async.AsyncBase;
+
+async.AsyncGroup = function (group) {
+  var item;
+  var callback;
+  var args;
+
+  this.group = [];
+  this.outstandingCount = 0;
+
+  for (var i = 0; i < group.length; i++) {
+    item = group[i];
+    this.group.push(new async.AsyncCall(
+        item.func, item.args, item.callback, item.context));
+    this.outstandingCount++;
+  }
+
+};
+
+/*
+Simpler way to group async calls -- doesn't ensure completion order,
+but still has a "last" method called when the entire group of calls
+have completed.
+*/
+async.AsyncGroup.prototype = new function () {
+  this.run = function () {
+    var _this = this
+      , group = this.group
+      , item
+      , createItem = function (item, args) {
+          return function () {
+            item.func.apply(item.context, args);
+          };
+        }
+      , createCallback = function (item) {
+          return function () {
+            if (item.callback) {
+              item.callback.apply(null, arguments);
+            }
+            _this.finish.call(_this);
+          }
+        };
+
+    for (var i = 0; i < group.length; i++) {
+      item = group[i];
+      callback = createCallback(item);
+      args = item.args.concat(callback);
+      // Run the async call
+      async.execNonBlocking(createItem(item, args));
+    }
+  };
+
+  this.finish = function () {
+    this.outstandingCount--;
+    if (!this.outstandingCount) {
+      this.last();
+    };
+  };
+
+  this.last = function () {};
+
+};
+
+var _createSimpleAsyncCall = function (func, context) {
+  return {
+    func: func
+  , args: []
+  , callback: function () {}
+  , context: context
+  };
+};
+
+async.SimpleAsyncChain = function (funcs, context) {
+  chain = [];
+  for (var i = 0, ii = funcs.length; i < ii; i++) {
+    chain.push(_createSimpleAsyncCall(funcs[i], context));
+  }
+  this.init(chain);
+};
+
+async.SimpleAsyncChain.prototype = async.AsyncBase;
+
+async.AsyncCall = function (func, args, callback, context) {
+  this.func = func;
+  this.args = args;
+  this.callback = callback || null;
+  this.context = context || null;
+};
+
+async.Initializer = function (steps, callback) {
+  var self = this;
+  this.steps = {};
+  this.callback = callback;
+  // Create an object-literal of the steps to tick off
+  steps.forEach(function (step) {
+    self.steps[step] = false;
+  });
+};
+
+async.Initializer.prototype = new (function () {
+  this.complete = function (step) {
+    var steps = this.steps;
+    // Tick this step off
+    steps[step] = true;
+    // Iterate the steps -- if any are not done, bail out
+    for (var p in steps) {
+      if (!steps[p]) {
+        return false;
+      }
+    }
+    // If all steps are done, run the callback
+    this.callback();
+  };
+})();
+
+module.exports = async;
+

+ 128 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/utilities/lib/core.js

@@ -0,0 +1,128 @@
+/*
+ * Utilities: A classic collection of JavaScript utilities
+ * Copyright 2112 Matthew Eernisse ([email protected])
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+
+var core = new (function () {
+
+  var _mix = function (targ, src, merge, includeProto) {
+    for (var p in src) {
+      // Don't copy stuff from the prototype
+      if (src.hasOwnProperty(p) || includeProto) {
+        if (merge &&
+            // Assumes the source property is an Object you can
+            // actually recurse down into
+            (typeof src[p] == 'object') &&
+            (src[p] !== null) &&
+            !(src[p] instanceof Array)) {
+          // Create the source property if it doesn't exist
+          // Double-equal to undefined includes both null and undefined
+          if (targ[p] == undefined) {
+            targ[p] = {};
+          }
+          _mix(targ[p], src[p], merge, includeProto); // Recurse
+        }
+        // If it's not a merge-copy, just set and forget
+        else {
+          targ[p] = src[p];
+        }
+      }
+    }
+  };
+
+  /*
+   * Mix in the properties on an object to another object
+   * yam.mixin(target, source, [source,] [source, etc.] [merge-flag]);
+   * 'merge' recurses, to merge object sub-properties together instead
+   * of just overwriting with the source object.
+   */
+  this.mixin = function () {
+    var args = Array.prototype.slice.apply(arguments),
+        merge = false,
+        targ, sources;
+    if (args.length > 2) {
+      if (typeof args[args.length - 1] == 'boolean') {
+        merge = args.pop();
+      }
+    }
+    targ = args.shift();
+    sources = args;
+    for (var i = 0, ii = sources.length; i < ii; i++) {
+      _mix(targ, sources[i], merge);
+    }
+    return targ;
+  };
+
+  this.enhance = function () {
+    var args = Array.prototype.slice.apply(arguments),
+        merge = false,
+        targ, sources;
+    if (args.length > 2) {
+      if (typeof args[args.length - 1] == 'boolean') {
+        merge = args.pop();
+      }
+    }
+    targ = args.shift();
+    sources = args;
+    for (var i = 0, ii = sources.length; i < ii; i++) {
+      _mix(targ, sources[i], merge, true);
+    }
+    return targ;
+  };
+
+  // Idea to add invalid number & Date from Michael J. Ryan,
+  // http://frugalcoder.us/post/2010/02/15/js-is-empty.aspx
+  this.isEmpty = function (val) {
+    // Empty string, null or undefined (these two are double-equal)
+    if (val === '' || val == undefined) {
+      return true;
+    }
+    // Invalid numerics
+    if (typeof val == 'number' && isNaN(val)) {
+      return true;
+    }
+    // Invalid Dates
+    if (val instanceof Date && isNaN(val.getTime())) {
+      return true;
+    }
+    return false;
+  };
+
+  /*
+  binds a function to an object
+   */
+  this.bind = function () {
+    var args = Array.prototype.slice.call(arguments)
+      , ctxt = args.shift()
+      , fn = args.shift();
+
+    if (typeof fn === 'function') {
+      if (typeof Function.bind === 'function') {
+        return fn.bind.apply(ctxt, args);
+      }
+      else {
+        return fn.apply(ctxt, args);
+      }
+    }
+    // in IE, native methods are not functions so they cannot be bound,
+    // and don't need to be
+    else {
+      return fn;
+    }
+  }
+})();
+
+module.exports = core;

+ 928 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/utilities/lib/date.js

@@ -0,0 +1,928 @@
+/*
+ * Utilities: A classic collection of JavaScript utilities
+ * Copyright 2112 Matthew Eernisse ([email protected])
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+
+var string = require('./string')
+  , date
+  , log = require('./log');
+
+/**
+  @name date
+  @namespace date
+*/
+
+date = new (function () {
+  var _this = this
+    , _date = new Date();
+
+  var _US_DATE_PAT = /^(\d{1,2})(?:\-|\/|\.)(\d{1,2})(?:\-|\/|\.)(\d{4})/;
+  var _DATETIME_PAT = /^(\d{4})(?:\-|\/|\.)(\d{1,2})(?:\-|\/|\.)(\d{1,2})(?:T| )?(\d{2})?(?::)?(\d{2})?(?::)?(\d{2})?(?:\.)?(\d+)?(?: *)?(Z|[+-]\d{4}|[+-]\d{2}:\d{2}|[+-]\d{2})?/;
+  // TODO Add am/pm parsing instead of dumb, 24-hour clock.
+  var _TIME_PAT = /^(\d{1,2})?(?::)?(\d{2})?(?::)?(\d{2})?(?:\.)?(\d+)?$/;
+
+  var _dateMethods = [
+      'FullYear'
+    , 'Month'
+    , 'Date'
+    , 'Hours'
+    , 'Minutes'
+    , 'Seconds'
+    , 'Milliseconds'
+  ];
+
+  var _isArray = function (obj) {
+    return obj &&
+      typeof obj === 'object' &&
+      typeof obj.length === 'number' &&
+      typeof obj.splice === 'function' &&
+      !(obj.propertyIsEnumerable('length'));
+  };
+
+  this.weekdayLong = ['Sunday', 'Monday', 'Tuesday',
+    'Wednesday', 'Thursday', 'Friday', 'Saturday'];
+  this.weekdayShort = ['Sun', 'Mon', 'Tue', 'Wed',
+    'Thu', 'Fri', 'Sat'];
+  this.monthLong = ['January', 'February', 'March',
+    'April', 'May', 'June', 'July', 'August', 'September',
+    'October', 'November', 'December'];
+  this.monthShort = ['Jan', 'Feb', 'Mar', 'Apr',
+    'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
+  this.meridiem = {
+    'AM': 'AM',
+    'PM': 'PM'
+  }
+  // compat
+  this.meridian = this.meridiem
+
+  /**
+    @name date#supportedFormats
+    @public
+    @object
+    @description List of supported strftime formats
+  */
+  this.supportedFormats = {
+    // abbreviated weekday name according to the current locale
+    'a': function (dt) { return _this.weekdayShort[dt.getDay()]; },
+    // full weekday name according to the current locale
+    'A': function (dt) { return _this.weekdayLong[dt.getDay()]; },
+    //  abbreviated month name according to the current locale
+    'b': function (dt) { return _this.monthShort[dt.getMonth()]; },
+    'h': function (dt) { return _this.strftime(dt, '%b'); },
+    // full month name according to the current locale
+    'B': function (dt) { return _this.monthLong[dt.getMonth()]; },
+    // preferred date and time representation for the current locale
+    'c': function (dt) { return _this.strftime(dt, '%a %b %d %T %Y'); },
+    // century number (the year divided by 100 and truncated
+    // to an integer, range 00 to 99)
+    'C': function (dt) { return _this.calcCentury(dt.getFullYear());; },
+    // day of the month as a decimal number (range 01 to 31)
+    'd': function (dt) { return string.lpad(dt.getDate(), '0', 2); },
+    // same as %m/%d/%y
+    'D': function (dt) { return _this.strftime(dt, '%m/%d/%y') },
+    // day of the month as a decimal number, a single digit is
+    // preceded by a space (range ' 1' to '31')
+    'e': function (dt) { return string.lpad(dt.getDate(), ' ', 2); },
+    // month as a decimal number, a single digit is
+    // preceded by a space (range ' 1' to '12')
+    'f': function () { return _this.strftimeNotImplemented('f'); },
+    // same as %Y-%m-%d
+    'F': function (dt) { return _this.strftime(dt, '%Y-%m-%d');  },
+    // like %G, but without the century.
+    'g': function () { return _this.strftimeNotImplemented('g'); },
+    // The 4-digit year corresponding to the ISO week number
+    // (see %V).  This has the same format and value as %Y,
+    // except that if the ISO week number belongs to the
+    // previous or next year, that year is used instead.
+    'G': function () { return _this.strftimeNotImplemented('G'); },
+    // hour as a decimal number using a 24-hour clock (range
+    // 00 to 23)
+    'H': function (dt) { return string.lpad(dt.getHours(), '0', 2); },
+    // hour as a decimal number using a 12-hour clock (range
+    // 01 to 12)
+    'I': function (dt) { return string.lpad(
+      _this.hrMil2Std(dt.getHours()), '0', 2); },
+    // day of the year as a decimal number (range 001 to 366)
+    'j': function (dt) { return string.lpad(
+      _this.calcDays(dt), '0', 3); },
+    // Hour as a decimal number using a 24-hour clock (range
+    // 0 to 23 (space-padded))
+    'k': function (dt) { return string.lpad(dt.getHours(), ' ', 2); },
+    // Hour as a decimal number using a 12-hour clock (range
+    // 1 to 12 (space-padded))
+    'l': function (dt) { return string.lpad(
+      _this.hrMil2Std(dt.getHours()), ' ', 2); },
+    // month as a decimal number (range 01 to 12)
+    'm': function (dt) { return string.lpad((dt.getMonth()+1), '0', 2); },
+    // minute as a decimal number
+    'M': function (dt) { return string.lpad(dt.getMinutes(), '0', 2); },
+    // Linebreak
+    'n': function () { return '\n'; },
+    // either `am' or `pm' according to the given time value,
+    // or the corresponding strings for the current locale
+    'p': function (dt) { return _this.getMeridian(dt.getHours()); },
+    // time in a.m. and p.m. notation
+    'r': function (dt) { return _this.strftime(dt, '%I:%M:%S %p'); },
+    // time in 24 hour notation
+    'R': function (dt) { return _this.strftime(dt, '%H:%M'); },
+    // second as a decimal number
+    'S': function (dt) { return string.lpad(dt.getSeconds(), '0', 2); },
+    // Tab char
+    't': function () { return '\t'; },
+    // current time, equal to %H:%M:%S
+    'T': function (dt) { return _this.strftime(dt, '%H:%M:%S'); },
+    // weekday as a decimal number [1,7], with 1 representing
+    // Monday
+    'u': function (dt) { return _this.convertOneBase(dt.getDay()); },
+    // week number of the current year as a decimal number,
+    // starting with the first Sunday as the first day of the
+    // first week
+    'U': function () { return _this.strftimeNotImplemented('U'); },
+    // week number of the year (Monday as the first day of the
+    // week) as a decimal number [01,53]. If the week containing
+    // 1 January has four or more days in the new year, then it
+    // is considered week 1. Otherwise, it is the last week of
+    // the previous year, and the next week is week 1.
+    'V': function () { return _this.strftimeNotImplemented('V'); },
+    // week number of the current year as a decimal number,
+    // starting with the first Monday as the first day of the
+    // first week
+    'W': function () { return _this.strftimeNotImplemented('W'); },
+    // day of the week as a decimal, Sunday being 0
+    'w': function (dt) { return dt.getDay(); },
+    // preferred date representation for the current locale
+    // without the time
+    'x': function (dt) { return _this.strftime(dt, '%D'); },
+    // preferred time representation for the current locale
+    // without the date
+    'X': function (dt) { return _this.strftime(dt, '%T'); },
+    // year as a decimal number without a century (range 00 to
+    // 99)
+    'y': function (dt) { return _this.getTwoDigitYear(dt.getFullYear()); },
+    // year as a decimal number including the century
+    'Y': function (dt) { return string.lpad(dt.getFullYear(), '0', 4); },
+    // time zone or name or abbreviation
+    'z': function () { return _this.strftimeNotImplemented('z'); },
+    'Z': function () { return _this.strftimeNotImplemented('Z'); },
+    // Literal percent char
+    '%': function (dt) { return '%'; }
+  };
+
+  /**
+    @name date#getSupportedFormats
+    @public
+    @function
+    @description return the list of formats in a string
+    @return {String} The list of supported formats
+  */
+  this.getSupportedFormats = function () {
+    var str = '';
+    for (var i in this.supportedFormats) { str += i; }
+    return str;
+  }
+
+  this.supportedFormatsPat = new RegExp('%[' +
+      this.getSupportedFormats() + ']{1}', 'g');
+
+  /**
+    @name date#strftime
+    @public
+    @function
+    @return {String} The `dt` formated with the given `format`
+    @description Formats the given date with the strftime formated
+    @param {Date} dt the date object to format
+    @param {String} format the format to convert the date to
+  */
+  this.strftime = function (dt, format) {
+    if (!dt) { return '' }
+
+    var d = dt;
+    var pats = [];
+    var dts = [];
+    var str = format;
+
+    // Allow either Date obj or UTC stamp
+    d = typeof dt == 'number' ? new Date(dt) : dt;
+
+    // Grab all instances of expected formats into array
+    while (pats = this.supportedFormatsPat.exec(format)) {
+      dts.push(pats[0]);
+    }
+
+    // Process any hits
+    for (var i = 0; i < dts.length; i++) {
+      key = dts[i].replace(/%/, '');
+      str = str.replace('%' + key,
+        this.supportedFormats[key](d));
+    }
+    return str;
+
+  };
+
+  this.strftimeNotImplemented = function (s) {
+    throw('this.strftime format "' + s + '" not implemented.');
+  };
+
+  /**
+    @name date#calcCentury
+    @public
+    @function
+    @return {String} The century for the given date
+    @description Find the century for the given `year`
+    @param {Number} year The year to find the century for
+  */
+  this.calcCentury = function (year) {
+    if(!year) {
+      year = _date.getFullYear();
+    }
+
+    var ret = parseInt((year / 100) + 1);
+    year = year.toString();
+
+    // If year ends in 00 subtract one, because it's still the century before the one
+    // it divides to
+    if (year.substring(year.length - 2) === '00') {
+      ret--;
+    }
+
+    return ret.toString();
+  };
+
+  /**
+    @name date#calcDays
+    @public
+    @function
+    @return {Number} The number of days so far for the given date
+    @description Calculate the day number in the year a particular date is on
+    @param {Date} dt The date to use
+  */
+  this.calcDays = function (dt) {
+    var first = new Date(dt.getFullYear(), 0, 1);
+    var diff = 0;
+    var ret = 0;
+    first = first.getTime();
+    diff = (dt.getTime() - first);
+    ret = parseInt(((((diff/1000)/60)/60)/24))+1;
+    return ret;
+  };
+
+  /**
+   * Adjust from 0-6 base week to 1-7 base week
+   * @param d integer for day of week
+   * @return Integer day number for 1-7 base week
+   */
+  this.convertOneBase = function (d) {
+    return d == 0 ? 7 : d;
+  };
+
+  this.getTwoDigitYear = function (yr) {
+    // Add a millenium to take care of years before the year 1000,
+    // (e.g, the year 7) since we're only taking the last two digits
+    // If we overshoot, it doesn't matter
+    var millenYear = yr + 1000;
+    var str = millenYear.toString();
+    str = str.substr(2); // Get the last two digits
+    return str
+  };
+
+  /**
+    @name date#getMeridiem
+    @public
+    @function
+    @return {String} Return 'AM' or 'PM' based on hour in 24-hour format
+    @description Return 'AM' or 'PM' based on hour in 24-hour format
+    @param {Number} h The hour to check
+  */
+  this.getMeridiem = function (h) {
+    return h > 11 ? this.meridiem.PM :
+      this.meridiem.AM;
+  };
+  // Compat
+  this.getMeridian = this.getMeridiem;
+
+  /**
+    @name date#hrMil2Std
+    @public
+    @function
+    @return {String} Return a 12 hour version of the given time
+    @description Convert a 24-hour formatted hour to 12-hour format
+    @param {String} hour The hour to convert
+  */
+  this.hrMil2Std = function (hour) {
+    var h = typeof hour == 'number' ? hour : parseInt(hour);
+    var str = h > 12 ? h - 12 : h;
+    str = str == 0 ? 12 : str;
+    return str;
+  };
+
+  /**
+    @name date#hrStd2Mil
+    @public
+    @function
+    @return {String} Return a 24 hour version of the given time
+    @description Convert a 12-hour formatted hour with meridian flag to 24-hour format
+    @param {String} hour The hour to convert
+    @param {Boolean} pm hour is PM then this should be true
+  */
+  this.hrStd2Mil = function  (hour, pm) {
+    var h = typeof hour == 'number' ? hour : parseInt(hour);
+    var str = '';
+    // PM
+    if (pm) {
+      str = h < 12 ? (h+12) : h;
+    }
+    // AM
+    else {
+      str = h == 12 ? 0 : h;
+    }
+    return str;
+  };
+
+  // Constants for use in this.add
+  var dateParts = {
+    YEAR: 'year'
+    , MONTH: 'month'
+    , DAY: 'day'
+    , HOUR: 'hour'
+    , MINUTE: 'minute'
+    , SECOND: 'second'
+    , MILLISECOND: 'millisecond'
+    , QUARTER: 'quarter'
+    , WEEK: 'week'
+    , WEEKDAY: 'weekday'
+  };
+  // Create a map for singular/plural lookup, e.g., day/days
+  var datePartsMap = {};
+  for (var p in dateParts) {
+    datePartsMap[dateParts[p]] = dateParts[p];
+    datePartsMap[dateParts[p] + 's'] = dateParts[p];
+  }
+  this.dateParts = dateParts;
+
+  /**
+    @name date#add
+    @public
+    @function
+    @return {Date} Incremented date
+    @description Add to a Date in intervals of different size, from
+                 milliseconds to years
+    @param {Date} dt Date (or timestamp Number), date to increment
+    @param {String} interv a constant representing the interval,
+    e.g. YEAR, MONTH, DAY.  See this.dateParts
+    @param {Number} incr how much to add to the date
+  */
+  this.add = function (dt, interv, incr) {
+    if (typeof dt == 'number') { dt = new Date(dt); }
+    function fixOvershoot() {
+      if (sum.getDate() < dt.getDate()) {
+        sum.setDate(0);
+      }
+    }
+    var key = datePartsMap[interv];
+    var sum = new Date(dt);
+    switch (key) {
+      case dateParts.YEAR:
+        sum.setFullYear(dt.getFullYear()+incr);
+        // Keep increment/decrement from 2/29 out of March
+        fixOvershoot();
+        break;
+      case dateParts.QUARTER:
+        // Naive quarter is just three months
+        incr*=3;
+        // fallthrough...
+      case dateParts.MONTH:
+        sum.setMonth(dt.getMonth()+incr);
+        // Reset to last day of month if you overshoot
+        fixOvershoot();
+        break;
+      case dateParts.WEEK:
+        incr*=7;
+        // fallthrough...
+      case dateParts.DAY:
+        sum.setDate(dt.getDate() + incr);
+        break;
+      case dateParts.WEEKDAY:
+        //FIXME: assumes Saturday/Sunday weekend, but even this is not fixed.
+        // There are CLDR entries to localize this.
+        var dat = dt.getDate();
+        var weeks = 0;
+        var days = 0;
+        var strt = 0;
+        var trgt = 0;
+        var adj = 0;
+        // Divide the increment time span into weekspans plus leftover days
+        // e.g., 8 days is one 5-day weekspan / and two leftover days
+        // Can't have zero leftover days, so numbers divisible by 5 get
+        // a days value of 5, and the remaining days make up the number of weeks
+        var mod = incr % 5;
+        if (mod == 0) {
+          days = (incr > 0) ? 5 : -5;
+          weeks = (incr > 0) ? ((incr-5)/5) : ((incr+5)/5);
+        }
+        else {
+          days = mod;
+          weeks = parseInt(incr/5);
+        }
+        // Get weekday value for orig date param
+        strt = dt.getDay();
+        // Orig date is Sat / positive incrementer
+        // Jump over Sun
+        if (strt == 6 && incr > 0) {
+          adj = 1;
+        }
+        // Orig date is Sun / negative incrementer
+        // Jump back over Sat
+        else if (strt == 0 && incr < 0) {
+          adj = -1;
+        }
+        // Get weekday val for the new date
+        trgt = strt + days;
+        // New date is on Sat or Sun
+        if (trgt == 0 || trgt == 6) {
+          adj = (incr > 0) ? 2 : -2;
+        }
+        // Increment by number of weeks plus leftover days plus
+        // weekend adjustments
+        sum.setDate(dat + (7*weeks) + days + adj);
+        break;
+      case dateParts.HOUR:
+        sum.setHours(sum.getHours()+incr);
+        break;
+      case dateParts.MINUTE:
+        sum.setMinutes(sum.getMinutes()+incr);
+        break;
+      case dateParts.SECOND:
+        sum.setSeconds(sum.getSeconds()+incr);
+        break;
+      case dateParts.MILLISECOND:
+        sum.setMilliseconds(sum.getMilliseconds()+incr);
+        break;
+      default:
+        // Do nothing
+        break;
+    }
+    return sum; // Date
+  };
+
+  /**
+    @name date#diff
+    @public
+    @function
+    @return {Number} number of (interv) units apart that
+    the two dates are
+    @description Get the difference in a specific unit of time (e.g., number
+                 of months, weeks, days, etc.) between two dates.
+    @param {Date} date1 First date to check
+    @param {Date} date2 Date to compate `date1` with
+    @param {String} interv a constant representing the interval,
+    e.g. YEAR, MONTH, DAY.  See this.dateParts
+  */
+  this.diff = function (date1, date2, interv) {
+    //  date1
+    //    Date object or Number equivalent
+    //
+    //  date2
+    //    Date object or Number equivalent
+    //
+    //  interval
+    //    A constant representing the interval, e.g. YEAR, MONTH, DAY.  See this.dateParts.
+
+    // Accept timestamp input
+    if (typeof date1 == 'number') { date1 = new Date(date1); }
+    if (typeof date2 == 'number') { date2 = new Date(date2); }
+    var yeaDiff = date2.getFullYear() - date1.getFullYear();
+    var monDiff = (date2.getMonth() - date1.getMonth()) + (yeaDiff * 12);
+    var msDiff = date2.getTime() - date1.getTime(); // Millisecs
+    var secDiff = msDiff/1000;
+    var minDiff = secDiff/60;
+    var houDiff = minDiff/60;
+    var dayDiff = houDiff/24;
+    var weeDiff = dayDiff/7;
+    var delta = 0; // Integer return value
+
+    var key = datePartsMap[interv];
+    switch (key) {
+      case dateParts.YEAR:
+        delta = yeaDiff;
+        break;
+      case dateParts.QUARTER:
+        var m1 = date1.getMonth();
+        var m2 = date2.getMonth();
+        // Figure out which quarter the months are in
+        var q1 = Math.floor(m1/3) + 1;
+        var q2 = Math.floor(m2/3) + 1;
+        // Add quarters for any year difference between the dates
+        q2 += (yeaDiff * 4);
+        delta = q2 - q1;
+        break;
+      case dateParts.MONTH:
+        delta = monDiff;
+        break;
+      case dateParts.WEEK:
+        // Truncate instead of rounding
+        // Don't use Math.floor -- value may be negative
+        delta = parseInt(weeDiff);
+        break;
+      case dateParts.DAY:
+        delta = dayDiff;
+        break;
+      case dateParts.WEEKDAY:
+        var days = Math.round(dayDiff);
+        var weeks = parseInt(days/7);
+        var mod = days % 7;
+
+        // Even number of weeks
+        if (mod == 0) {
+          days = weeks*5;
+        }
+        else {
+          // Weeks plus spare change (< 7 days)
+          var adj = 0;
+          var aDay = date1.getDay();
+          var bDay = date2.getDay();
+
+          weeks = parseInt(days/7);
+          mod = days % 7;
+          // Mark the date advanced by the number of
+          // round weeks (may be zero)
+          var dtMark = new Date(date1);
+          dtMark.setDate(dtMark.getDate()+(weeks*7));
+          var dayMark = dtMark.getDay();
+
+          // Spare change days -- 6 or less
+          if (dayDiff > 0) {
+            switch (true) {
+              // Range starts on Sat
+              case aDay == 6:
+                adj = -1;
+                break;
+              // Range starts on Sun
+              case aDay == 0:
+                adj = 0;
+                break;
+              // Range ends on Sat
+              case bDay == 6:
+                adj = -1;
+                break;
+              // Range ends on Sun
+              case bDay == 0:
+                adj = -2;
+                break;
+              // Range contains weekend
+              case (dayMark + mod) > 5:
+                adj = -2;
+                break;
+              default:
+                // Do nothing
+                break;
+            }
+          }
+          else if (dayDiff < 0) {
+            switch (true) {
+              // Range starts on Sat
+              case aDay == 6:
+                adj = 0;
+                break;
+              // Range starts on Sun
+              case aDay == 0:
+                adj = 1;
+                break;
+              // Range ends on Sat
+              case bDay == 6:
+                adj = 2;
+                break;
+              // Range ends on Sun
+              case bDay == 0:
+                adj = 1;
+                break;
+              // Range contains weekend
+              case (dayMark + mod) < 0:
+                adj = 2;
+                break;
+              default:
+                // Do nothing
+                break;
+            }
+          }
+          days += adj;
+          days -= (weeks*2);
+        }
+        delta = days;
+
+        break;
+      case dateParts.HOUR:
+        delta = houDiff;
+        break;
+      case dateParts.MINUTE:
+        delta = minDiff;
+        break;
+      case dateParts.SECOND:
+        delta = secDiff;
+        break;
+      case dateParts.MILLISECOND:
+        delta = msDiff;
+        break;
+      default:
+        // Do nothing
+        break;
+    }
+    // Round for fractional values and DST leaps
+    return Math.round(delta); // Number (integer)
+  };
+
+  /**
+    @name date#parse
+    @public
+    @function
+    @return {Date} a JavaScript Date object
+    @description Convert various sorts of strings to JavaScript
+                 Date objects
+    @param {String} val The string to convert to a Date
+  */
+  this.parse = function (val) {
+    var dt
+      , matches
+      , reordered
+      , off
+      , posOff
+      , offHours
+      , offMinutes
+      , offSeconds
+      , curr
+      , stamp
+      , utc;
+
+    // Yay, we have a date, use it as-is
+    if (val instanceof Date || typeof val.getFullYear == 'function') {
+      dt = val;
+    }
+
+    // Timestamp?
+    else if (typeof val == 'number') {
+      dt = new Date(val);
+    }
+
+    // String or Array
+    else {
+      // Value preparsed, looks like [yyyy, mo, dd, hh, mi, ss, ms, (offset?)]
+      if (_isArray(val)) {
+        matches = val;
+        matches.unshift(null);
+        matches[8] = null;
+      }
+
+      // Oh, crap, it's a string -- parse this bitch
+      else if (typeof val == 'string') {
+        matches = val.match(_DATETIME_PAT);
+
+        // Stupid US-only format?
+        if (!matches) {
+          matches = val.match(_US_DATE_PAT);
+          if (matches) {
+            reordered = [matches[0], matches[3], matches[1], matches[2]];
+            // Pad the results to the same length as ISO8601
+            reordered[8] = null;
+            matches = reordered;
+          }
+        }
+
+        // Time-stored-in-Date hack?
+        if (!matches) {
+          matches = val.match(_TIME_PAT);
+          if (matches) {
+            reordered = [matches[0], 0, 1, 0, matches[1],
+                matches[2], matches[3], matches[4], null];
+            matches = reordered;
+          }
+        }
+
+      }
+
+      // Sweet, the regex actually parsed it into something useful
+      if (matches) {
+        matches.shift(); // First match is entire match, DO NOT WANT
+
+        off = matches.pop();
+        // If there's an offset (or the 'Z' non-offset offset), use UTC
+        // methods to set everything
+        if (off) {
+          if (off == 'Z') {
+            utc = true;
+            offSeconds = 0;
+          }
+          else {
+            utc = false;
+            // Convert from extended to basic if necessary
+            off = off.replace(/:/g, '');
+            // '+0000' will still be zero
+            if (parseInt(off, 10) === 0) {
+              utc = true;
+            }
+            else {
+              posOff = off.indexOf('+') === 0;
+              // Strip plus or minus
+              off = off.substr(1);
+
+              offHours = parseInt(off.substr(0, 2), 10);
+
+              offMinutes = off.substr(2, 2);
+              if (offMinutes) {
+                offMinutes = parseInt(offMinutes, 10);
+              }
+              else {
+                offMinutes = 0;
+              }
+
+              offSeconds = off.substr(4, 2);
+              if (offSeconds) {
+                offSeconds = parseInt(offSeconds, 10);
+              }
+              else {
+                offSeconds = 0;
+              }
+
+              offSeconds += (offMinutes * 60)
+              offSeconds += (offHours * 60 * 60);
+              if (!posOff) {
+                offSeconds = 0 - offSeconds;
+              }
+            }
+          }
+        }
+
+        dt = new Date(0);
+
+        // Stupid zero-based months
+        matches[1] = parseInt(matches[1], 10) - 1;
+
+        // Specific offset, iterate the array and set each date property
+        // using UTC setters, then adjust time using offset
+        if (off) {
+          for (var i = matches.length - 1; i > -1; i--) {
+            curr = parseInt(matches[i], 10) || 0;
+            dt['setUTC' + _dateMethods[i]](curr);
+          }
+          // Add any offset
+          dt.setSeconds(dt.getSeconds() - offSeconds);
+        }
+        // Otherwise we know nothing about the offset, just iterate the
+        // array and set each date property using regular setters
+        else {
+          for (var i = matches.length - 1; i > -1; i--) {
+            curr = parseInt(matches[i], 10) || 0;
+            dt['set' + _dateMethods[i]](curr);
+          }
+        }
+      }
+
+      // Shit, last-ditch effort using Date.parse
+      else {
+        stamp = Date.parse(val);
+        // Failures to parse yield NaN
+        if (!isNaN(stamp)) {
+          dt = new Date(stamp);
+        }
+      }
+
+    }
+
+    return dt || null;
+  };
+
+  /**
+    @name date#relativeTime
+    @public
+    @function
+    @return {String} A string describing the amount of time ago
+    the passed-in Date is
+    @description Convert a Date to an English sentence representing
+    how long ago the Date was
+    @param {Date} dt The Date to to convert to a relative time string
+    @param {Object} [opts]
+      @param {Boolean} [opts.abbreviated=false] Use short strings
+      (e.g., '<1m') for the relative-time string
+  */
+  this.relativeTime = function (dt, options) {
+    var opts = options || {}
+      , now = opts.now || new Date()
+      , abbr = opts.abbreviated || false
+      , format = opts.format || '%F %T'
+    // Diff in seconds
+      , diff = (now.getTime() - dt.getTime()) / 1000
+      , ret
+      , num
+      , hour = 60*60
+      , day = 24*hour
+      , week = 7*day
+      , month = 30*day;
+    switch (true) {
+      case diff < 60:
+        ret = abbr ? '<1m' : 'less than a minute ago';
+        break;
+      case diff < 120:
+        ret = abbr ? '1m' : 'about a minute ago';
+        break;
+      case diff < (45*60):
+        num = parseInt((diff / 60), 10);
+        ret = abbr ? num + 'm' : num + ' minutes ago';
+        break;
+      case diff < (2*hour):
+        ret = abbr ? '1h' : 'about an hour ago';
+        break;
+      case diff < (1*day):
+        num = parseInt((diff / hour), 10);
+        ret = abbr ? num + 'h' : 'about ' + num + ' hours ago';
+        break;
+      case diff < (2*day):
+        ret = abbr ? '1d' : 'one day ago';
+        break;
+      case diff < (7*day):
+        num = parseInt((diff / day), 10);
+        ret = abbr ? num + 'd' : 'about ' + num + ' days ago';
+        break;
+      case diff < (11*day):
+        ret = abbr ? '1w': 'one week ago';
+        break;
+      case diff < (1*month):
+        num = Math.round(diff / week);
+        ret = abbr ? num + 'w' : 'about ' + num + ' weeks ago';
+        break;
+      default:
+        ret = date.strftime(dt, format);
+        break;
+    }
+    return ret;
+  };
+
+  /**
+    @name date#toISO8601
+    @public
+    @function
+    @return {String} A string describing the amount of time ago
+    @description Convert a Date to an ISO8601-formatted string
+    @param {Date} dt The Date to to convert to an ISO8601 string
+  */
+  var _pad = function (n) {
+    return n < 10 ? '0' + n : n;
+  };
+  this.toISO8601 = function (dt, options) {
+    var opts = options || {}
+      , off = dt.getTimezoneOffset()
+      , offHours
+      , offMinutes
+      , str = this.strftime(dt, '%F') + 'T'
+          + this.strftime(dt, '%T') + '.'
+          + string.lpad(dt.getMilliseconds(), '0', 3);
+
+    if (opts.tz) {
+      // Pos and neg numbers are both truthy; only
+      // zero is falsy
+      if (off && !opts.utc) {
+        str += off > 0 ? '-' : '+';
+        offHours = parseInt(off / 60, 10);
+        str += string.lpad(offHours, '0', 2);
+        offMinutes = off % 60;
+        if (offMinutes) {
+          str += string.lpad(offMinutes, '0', 2);
+        }
+      }
+      else {
+        str += 'Z';
+      }
+    }
+
+    return str;
+  };
+
+  // Alias
+  this.toIso8601 = this.toISO8601;
+
+  this.toUTC = function (dt) {
+    return new Date(
+        dt.getUTCFullYear()
+      , dt.getUTCMonth()
+      , dt.getUTCDate()
+      , dt.getUTCHours()
+      , dt.getUTCMinutes()
+      , dt.getUTCSeconds()
+      , dt.getUTCMilliseconds());
+  };
+
+})();
+
+module.exports = date;
+
+

+ 109 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/utilities/lib/event_buffer.js

@@ -0,0 +1,109 @@
+/*
+ * Utilities: A classic collection of JavaScript utilities
+ * Copyright 2112 Matthew Eernisse ([email protected])
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+
+/*
+This is a very simple buffer for a predetermined set of events. It is unbounded.
+It forwards all arguments to any outlet emitter attached with sync().
+
+Example:
+    var source = new Stream()
+      , dest = new EventEmitter()
+      , buff = new EventBuffer(source)
+      , data = '';
+    dest.on('data', function (d) { data += d; });
+    source.writeable = true;
+    source.readable = true;
+    source.emit('data', 'abcdef');
+    source.emit('data', '123456');
+    buff.sync(dest);
+*/
+
+/**
+  @name EventBuffer
+  @namespace EventBuffer
+  @constructor
+*/
+
+var EventBuffer = function (src, events) {
+  // By default, we service the default stream events
+  var self = this
+    , streamEvents = ['data', 'end', 'error', 'close', 'fd', 'drain', 'pipe'];
+  this.events = events || streamEvents;
+  this.emitter = src;
+  this.eventBuffer = [];
+  this.outlet = null;
+  this.events.forEach(function (name) {
+    self.emitter.addListener(name, function () {
+      self.proxyEmit(name, arguments);
+    });
+  });
+};
+
+EventBuffer.prototype = new (function () {
+  /**
+    @name EventBuffer#proxyEmit
+    @public
+    @function
+    @description Emit an event by name and arguments or add it to the buffer if
+                 no outlet is set
+    @param {String} name The name to use for the event
+    @param {Array} args An array of arguments to emit
+  */
+  this.proxyEmit = function (name, args) {
+    if (this.outlet) {
+      this.emit(name, args);
+    }
+    else {
+      this.eventBuffer.push({name: name, args: args});
+    }
+  };
+
+  /**
+    @name EventBuffer#emit
+    @public
+    @function
+    @description Emit an event by name and arguments
+    @param {String} name The name to use for the event
+    @param {Array} args An array of arguments to emit
+  */
+  this.emit = function (name, args) {
+    // Prepend name to args
+    var outlet = this.outlet;
+    Array.prototype.splice.call(args, 0, 0, name);
+    outlet.emit.apply(outlet, args);
+  };
+
+  /**
+    @name EventBuffer#sync
+    @public
+    @function
+    @description Flush the buffer and continue piping new events to the outlet
+    @param {Object} outlet The emitter to send events to
+  */
+  this.sync = function (outlet) {
+    var buffer = this.eventBuffer
+      , bufferItem;
+    this.outlet = outlet;
+    while ((bufferItem = buffer.shift())) {
+      this.emit(bufferItem.name, bufferItem.args);
+    }
+  };
+})();
+EventBuffer.prototype.constructor = EventBuffer;
+
+module.exports.EventBuffer = EventBuffer;

+ 557 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/utilities/lib/file.js

@@ -0,0 +1,557 @@
+/*
+ * Utilities: A classic collection of JavaScript utilities
+ * Copyright 2112 Matthew Eernisse ([email protected])
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+
+var fs = require('fs')
+  , path = require('path')
+  , DEFAULT_INCLUDE_PAT = /\.(js|coffee|css|less|scss)$/
+  , DEFAULT_EXCLUDE_PAT = /\.git|node_modules/
+  , logger;
+
+var logger = new (function () {
+  var out;
+  try {
+    out = require('./log');
+  }
+  catch (e) {
+    out = console;
+  }
+
+  this.log = function (o) {
+    out.log(o);
+  };
+})();
+
+/**
+  @name file
+  @namespace file
+*/
+
+var fileUtils = new (function () {
+  var _copyFile
+    , _copyDir
+    , _readDir
+    , _rmDir
+    , _watch;
+
+
+  // Recursively copy files and directories
+  _copyFile = function (fromPath, toPath, opts) {
+    var from = path.normalize(fromPath)
+      , to = path.normalize(toPath)
+      , options = opts || {}
+      , fromStat
+      , toStat
+      , destExists
+      , destDoesNotExistErr
+      , content
+      , filename
+      , dirContents
+      , targetDir;
+
+    fromStat = fs.statSync(from);
+
+    try {
+      //console.dir(to + ' destExists');
+      toStat = fs.statSync(to);
+      destExists = true;
+    }
+    catch(e) {
+      //console.dir(to + ' does not exist');
+      destDoesNotExistErr = e;
+      destExists = false;
+    }
+    // Destination dir or file exists, copy into (directory)
+    // or overwrite (file)
+    if (destExists) {
+
+      // If there's a rename-via-copy file/dir name passed, use it.
+      // Otherwise use the actual file/dir name
+      filename = options.rename || path.basename(from);
+
+      // Copying a directory
+      if (fromStat.isDirectory()) {
+        dirContents = fs.readdirSync(from);
+        targetDir = path.join(to, filename);
+        // We don't care if the target dir already exists
+        try {
+          fs.mkdirSync(targetDir, options.mode || 0755);
+        }
+        catch(e) {
+          if (e.code != 'EEXIST') {
+            throw e;
+          }
+        }
+        for (var i = 0, ii = dirContents.length; i < ii; i++) {
+          //console.log(dirContents[i]);
+          _copyFile(path.join(from, dirContents[i]), targetDir);
+        }
+      }
+      // Copying a file
+      else {
+        content = fs.readFileSync(from);
+        // Copy into dir
+        if (toStat.isDirectory()) {
+          //console.log('copy into dir ' + to);
+          fs.writeFileSync(path.join(to, filename), content);
+        }
+        // Overwrite file
+        else {
+          //console.log('overwriting ' + to);
+          fs.writeFileSync(to, content);
+        }
+      }
+    }
+    // Dest doesn't exist, can't create it
+    else {
+      throw destDoesNotExistErr;
+    }
+  };
+
+  _copyDir = function (from, to, opts) {
+    var createDir = opts.createDir;
+  };
+
+  // Return the contents of a given directory
+  _readDir = function (dirPath) {
+    var dir = path.normalize(dirPath)
+      , paths = []
+      , ret = [dir]
+      , msg;
+
+    try {
+      paths = fs.readdirSync(dir);
+    }
+    catch (e) {
+      msg = 'Could not read path ' + dir + '\n';
+      if (e.stack) {
+        msg += e.stack;
+      }
+      throw new Error(msg);
+    }
+
+    paths.forEach(function (p) {
+      var curr = path.join(dir, p);
+      var stat = fs.statSync(curr);
+      if (stat.isDirectory()) {
+        ret = ret.concat(_readDir(curr));
+      }
+      else {
+        ret.push(curr);
+      }
+    });
+
+    return ret;
+  };
+
+  // Remove the given directory
+  _rmDir = function (dirPath) {
+    var dir = path.normalize(dirPath)
+      , paths = [];
+    paths = fs.readdirSync(dir);
+    paths.forEach(function (p) {
+      var curr = path.join(dir, p);
+      var stat = fs.statSync(curr);
+      if (stat.isDirectory()) {
+        _rmDir(curr);
+      }
+      else {
+        try {
+          fs.unlinkSync(curr);
+        } catch(e) {
+          if (e.code === 'EPERM') {
+            fs.chmodSync(curr, '0666');
+            fs.unlinkSync(curr);
+          } else {
+            throw e;
+          }
+        }
+      }
+    });
+    fs.rmdirSync(dir);
+  };
+
+  // Recursively watch files with a callback
+  _watch = function () {
+    var args = Array.prototype.slice.call(arguments)
+      , filePath
+      , opts
+      , callback
+      , inclPat
+      , exclPat
+      , createWatcher;
+
+    filePath = args.shift();
+    callback = args.pop();
+    opts = args.pop() || {};
+    inclPat = opts.includePattern || DEFAULT_INCLUDE_PAT;
+    exclPat = opts.excludePattern || DEFAULT_EXCLUDE_PAT;
+
+    opts.level = opts.level || 1;
+
+    createWatcher = function (watchPath) {
+      if (!exclPat.test(watchPath)) {
+        fs.watch(watchPath, function (ev, p) {
+          if (inclPat.test(p) && !exclPat.test(p)) {
+            callback(path.join(watchPath, p));
+          }
+        });
+      }
+    };
+
+    fs.stat(filePath, function (err, stats) {
+      if (err) {
+        return false;
+      }
+      // Watch files at the top level
+      if (stats.isFile() && opts.level == 1) {
+        createWatcher(filePath);
+        opts.level++;
+      }
+      else if (stats.isDirectory()) {
+        createWatcher(filePath);
+        opts.level++;
+        fs.readdir(filePath, function (err, files) {
+          if (err) {
+            return log.fatal(err);
+          }
+          for (var f in files) {
+            _watch(path.join(filePath, files[f]), opts, callback);
+          }
+        });
+      }
+    });
+  };
+
+  /**
+    @name file#cpR
+    @public
+    @function
+    @description Copies a directory/file to a destination
+    @param {String} fromPath The source path to copy from
+    @param {String} toPath The destination path to copy to
+    @param {Object} opts Options to use
+      @param {Boolean} [opts.silent] If false then will log the command
+  */
+  this.cpR = function (fromPath, toPath, options) {
+    var from = path.normalize(fromPath)
+      , to = path.normalize(toPath)
+      , toStat
+      , doesNotExistErr
+      , paths
+      , filename
+      , opts = options || {};
+
+    if (!opts.silent) {
+      logger.log('cp -r ' + fromPath + ' ' + toPath);
+    }
+
+    if (from == to) {
+      throw new Error('Cannot copy ' + from + ' to itself.');
+    }
+
+    // Handle rename-via-copy
+    try {
+      toStat = fs.statSync(to);
+    }
+    catch(e) {
+      doesNotExistErr = e;
+
+      // Get abs path so it's possible to check parent dir
+      if (!this.isAbsolute(to)) {
+        to = path.join(process.cwd() , to);
+      }
+
+      // Save the file/dir name
+      filename = path.basename(to);
+      // See if a parent dir exists, so there's a place to put the
+      /// renamed file/dir (resets the destination for the copy)
+      to = path.dirname(to);
+      try {
+        toStat = fs.statSync(to);
+      }
+      catch(e) {}
+      if (toStat && toStat.isDirectory()) {
+        // Set the rename opt to pass to the copy func, will be used
+        // as the new file/dir name
+        opts.rename = filename;
+        //console.log('filename ' + filename);
+      }
+      else {
+        throw doesNotExistErr;
+      }
+    }
+
+    _copyFile(from, to, opts);
+  };
+
+  /**
+    @name file#mkdirP
+    @public
+    @function
+    @description Create the given directory(ies) using the given mode permissions
+    @param {String} dir The directory to create
+    @param {Number} mode The mode to give the created directory(ies)(Default: 0755)
+  */
+  this.mkdirP = function (dir, mode) {
+    var dirPath = path.normalize(dir)
+      , paths = dirPath.split(/\/|\\/)
+      , currPath = ''
+      , next;
+
+    if (paths[0] == '' || /^[A-Za-z]+:/.test(paths[0])) {
+      currPath = paths.shift() || '/';
+      currPath = path.join(currPath, paths.shift());
+      //console.log('basedir');
+    }
+    while ((next = paths.shift())) {
+      if (next == '..') {
+        currPath = path.join(currPath, next);
+        continue;
+      }
+      currPath = path.join(currPath, next);
+      try {
+        //console.log('making ' + currPath);
+        fs.mkdirSync(currPath, mode || 0755);
+      }
+      catch(e) {
+        if (e.code != 'EEXIST') {
+          throw e;
+        }
+      }
+    }
+  };
+
+  /**
+    @name file#readdirR
+    @public
+    @function
+    @return {Array} Returns the contents as an Array, can be configured via opts.format
+    @description Reads the given directory returning it's contents
+    @param {String} dir The directory to read
+    @param {Object} opts Options to use
+      @param {String} [opts.format] Set the format to return(Default: Array)
+  */
+  this.readdirR = function (dir, opts) {
+    var options = opts || {}
+      , format = options.format || 'array'
+      , ret;
+    ret = _readDir(dir);
+    return format == 'string' ? ret.join('\n') : ret;
+  };
+
+  /**
+    @name file#rmRf
+    @public
+    @function
+    @description Deletes the given directory/file
+    @param {String} p The path to delete, can be a directory or file
+    @param {Object} opts Options to use
+      @param {String} [opts.silent] If false then logs the command
+  */
+  this.rmRf = function (p, options) {
+    var stat
+      , opts = options || {};
+    if (!opts.silent) {
+      logger.log('rm -rf ' + p);
+    }
+    try {
+      stat = fs.statSync(p);
+      if (stat.isDirectory()) {
+        _rmDir(p);
+      }
+      else {
+        fs.unlinkSync(p);
+      }
+    }
+    catch (e) {}
+  };
+
+  /**
+    @name file#isAbsolute
+    @public
+    @function
+    @return {Boolean/String} If it's absolute the first character is returned otherwise false
+    @description Checks if a given path is absolute or relative
+    @param {String} p Path to check
+  */
+  this.isAbsolute = function (p) {
+    var match = /^[A-Za-z]+:\\|^\//.exec(p);
+    if (match && match.length) {
+      return match[0];
+    }
+    return false;
+  };
+
+  /**
+    @name file#absolutize
+    @public
+    @function
+    @return {String} Returns the absolute path for the given path
+    @description Returns the absolute path for the given path
+    @param {String} p The path to get the absolute path for
+  */
+  this.absolutize = function (p) {
+    if (this.isAbsolute(p)) {
+      return p;
+    }
+    else {
+      return path.join(process.cwd(), p);
+    }
+  };
+
+  /**
+    Given a patern, return the base directory of it (ie. the folder
+    that will contain all the files matching the path).
+    eg. file.basedir('/test/**') => '/test/'
+    Path ending by '/' are considerd as folder while other are considerd
+    as files, eg.:
+        file.basedir('/test/a/') => '/test/a'
+        file.basedir('/test/a') => '/test'
+    The returned path always end with a '/' so we have:
+        file.basedir(file.basedir(x)) == file.basedir(x)
+  */
+  this.basedir = function (pathParam) {
+    var basedir = ''
+      , parts
+      , part
+      , pos = 0
+      , p = pathParam || '';
+
+    // If the path has a leading asterisk, basedir is the current dir
+    if (p.indexOf('*') == 0 || p.indexOf('**') == 0) {
+      return '.';
+    }
+
+    // always consider .. at the end as a folder and not a filename
+    if (/(?:^|\/|\\)\.\.$/.test(p.slice(-3))) {
+      p += '/';
+    }
+
+    parts = p.split(/\\|\//);
+    for (var i = 0, l = parts.length - 1; i < l; i++) {
+      part = parts[i];
+      if (part.indexOf('*') > -1 || part.indexOf('**') > -1) {
+        break;
+      }
+      pos += part.length + 1;
+      basedir += part + p[pos - 1];
+    }
+    if (!basedir) {
+      basedir = '.';
+    }
+    // Strip trailing slashes
+    if (!(basedir == '\\' || basedir == '/')) {
+      basedir = basedir.replace(/\\$|\/$/, '');
+    }
+    return basedir;
+
+  };
+
+  /**
+    @name file#searchParentPath
+    @public
+    @function
+    @description Search for a directory/file in the current directory and parent directories
+    @param {String} p The path to search for
+    @param {Function} callback The function to call once the path is found
+  */
+  this.searchParentPath = function (location, beginPath, callback) {
+    if (typeof beginPath === 'function' && !callback) {
+      callback = beginPath;
+      beginPath = process.cwd();
+    }
+    var cwd = beginPath || process.cwd();
+
+    if (!location) {
+      // Return if no path is given
+      return;
+    }
+    var relPath = ''
+      , i = 5 // Only search up to 5 directories
+      , pathLoc
+      , pathExists;
+
+    while (--i >= 0) {
+      pathLoc = path.join(cwd, relPath, location);
+      pathExists = this.existsSync(pathLoc);
+
+      if (pathExists) {
+        callback && callback(undefined, pathLoc);
+        break;
+      } else {
+        // Dir could not be found
+        if (i === 0) {
+          callback && callback(new Error("Path \"" + pathLoc + "\" not found"), undefined);
+          break;
+        }
+
+        // Add a relative parent directory
+        relPath += '../';
+        // Switch to relative parent directory
+        process.chdir(path.join(cwd, relPath));
+      }
+    }
+  };
+
+  /**
+    @name file#watch
+    @public
+    @function
+    @description Watch a given path then calls the callback once a change occurs
+    @param {String} path The path to watch
+    @param {Function} callback The function to call when a change occurs
+  */
+  this.watch = function () {
+    _watch.apply(this, arguments);
+  };
+
+  // Compatibility for fs.exists(0.8) and path.exists(0.6)
+  this.exists = (typeof fs.exists === 'function') ? fs.exists : path.exists;
+
+  // Compatibility for fs.existsSync(0.8) and path.existsSync(0.6)
+  this.existsSync = (typeof fs.existsSync === 'function') ? fs.existsSync : path.existsSync;
+
+  /**
+    @name file#requireLocal
+    @public
+    @function
+    @return {Object} The given module is returned
+    @description Require a local module from the node_modules in the current directory
+    @param {String} module The module to require
+    @param {String} message An option message to throw if the module doesn't exist
+  */
+  this.requireLocal = function (module, message) {
+    // Try to require in the application directory
+    try {
+      dep = require(path.join(process.cwd(), 'node_modules', module));
+    }
+    catch(err) {
+      if (message) {
+        throw new Error(message);
+      }
+      throw new Error('Module "' + module + '" could not be found as a ' +
+          'local module. Please install it by doing "npm install ' +
+          module + '"');
+    }
+    return dep;
+  };
+
+})();
+
+module.exports = fileUtils;
+

+ 73 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/utilities/lib/i18n.js

@@ -0,0 +1,73 @@
+/*
+ * Utilities: A classic collection of JavaScript utilities
+ * Copyright 2112 Matthew Eernisse ([email protected])
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+var core = require('./core')
+  , i18n;
+
+var DEFAULT_LOCALE = 'en-us';
+
+i18n = new (function () {
+  var _defaultLocale = DEFAULT_LOCALE
+    , _strings = {};
+
+  this.getText = function (key, opts, locale) {
+    var currentLocale = locale || _defaultLocale
+      , currentLocaleStrings = _strings[currentLocale] || {}
+      , defaultLocaleStrings = _strings[_defaultLocale] || {}
+      , str = currentLocaleStrings[key]
+            || defaultLocaleStrings[key] || "[[" + key + "]]";
+    for (p in opts) {
+      str = str.replace(new RegExp('\\{' + p + '\\}', 'g'), opts[p]);
+    }
+    return str;
+  };
+
+  this.getDefaultLocale = function () {
+    return _defaultLocale;
+  };
+
+  this.setDefaultLocale = function (locale) {
+    _defaultLocale = locale;
+  };
+
+  this.loadLocale = function (locale, strings) {
+    _strings[locale] = _strings[locale] || {};
+    core.mixin(_strings[locale], strings);
+  };
+
+})();
+
+i18n.I18n = function (locale) {
+  var _locale = locale || i18n.getDefaultLocale();
+
+  this.getLocale = function (locale) {
+    return _locale;
+  };
+
+  this.setLocale = function (locale) {
+    _locale = locale;
+  };
+
+  this.getText = function (key, opts, locale) {
+    return i18n.getText(key,
+        opts || {}, locale || _locale);
+  };
+  this.t = this.getText;
+};
+
+module.exports = i18n;
+

+ 59 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/utilities/lib/index.js

@@ -0,0 +1,59 @@
+/*
+ * Utilities: A classic collection of JavaScript utilities
+ * Copyright 2112 Matthew Eernisse ([email protected])
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+var utils = {}
+// Core methods
+  , core = require('./core')
+// Namespaces with methods
+  , string = require('./string')
+  , file = require('./file')
+  , async = require('./async')
+  , i18n = require('./i18n')
+  , uri = require('./uri')
+  , array = require('./array')
+  , object = require('./object')
+  , date = require('./date')
+  , request = require('./request')
+  , log = require('./log')
+  , network = require('./network')
+// Third-party -- remove this if possible
+  , inflection = require('./inflection')
+// Constructors
+  , EventBuffer = require('./event_buffer').EventBuffer
+  , XML = require('./xml').XML
+  , SortedCollection = require('./sorted_collection').SortedCollection;
+
+core.mixin(utils, core);
+
+utils.string = string;
+utils.file = file;
+utils.async = async;
+utils.i18n = i18n;
+utils.uri = uri;
+utils.array = array;
+utils.object = object;
+utils.date = date;
+utils.request = request;
+utils.log = log;
+utils.network = network;
+utils.inflection = inflection;
+utils.SortedCollection = SortedCollection;
+utils.EventBuffer = EventBuffer;
+utils.XML = XML;
+
+module.exports = utils;
+

+ 222 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/utilities/lib/inflection.js

@@ -0,0 +1,222 @@
+/*
+ * Copyright (c) 2010 George Moschovitis, http://www.gmosx.com
+ *
+ * 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 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.
+ *
+ * A port of the Rails/ActiveSupport Inflector class
+ * http://api.rubyonrails.org/classes/ActiveSupport/Inflector.html
+*/
+
+/**
+  @name inflection
+  @namespace inflection
+*/
+
+var inflection = new (function () {
+
+  /**
+    @name inflection#inflections
+    @public
+    @object
+    @description A list of rules and replacements for different inflection types
+  */
+  this.inflections = {
+      plurals: []
+    , singulars: []
+    , uncountables: []
+  };
+
+  var self = this
+    , setInflection
+    , setPlural
+    , setSingular
+    , setUncountable
+    , setIrregular;
+
+  // Add a new inflection rule/replacement to the beginning of the array for the
+  // inflection type
+  setInflection = function (type, rule, replacement) {
+    self.inflections[type].unshift([rule, replacement]);
+  };
+
+  // Add a new plural inflection rule
+  setPlural = function (rule, replacement) {
+    setInflection('plurals', rule, replacement);
+  };
+
+  // Add a new singular inflection rule
+  setSingular = function (rule, replacement) {
+    setInflection('singulars', rule, replacement);
+  };
+
+  // Add a new irregular word to the inflection list, by a given singular and plural inflection
+  setIrregular = function (singular, plural) {
+    if (singular.substr(0, 1).toUpperCase() == plural.substr(0, 1).toUpperCase()) {
+      setPlural(new RegExp("(" + singular.substr(0, 1) + ")" + singular.substr(1) + "$", "i"),
+        '$1' + plural.substr(1));
+      setPlural(new RegExp("(" + plural.substr(0, 1) + ")" + plural.substr(1) + "$", "i"),
+        '$1' + plural.substr(1));
+      setSingular(new RegExp("(" + plural.substr(0, 1) + ")" + plural.substr(1) + "$", "i"),
+        '$1' + singular.substr(1));
+    } else {
+      setPlural(new RegExp(singular.substr(0, 1).toUpperCase() + singular.substr(1) + "$"),
+        plural.substr(0, 1).toUpperCase() + plural.substr(1));
+      setPlural(new RegExp(singular.substr(0, 1).toLowerCase() + singular.substr(1) + "$"),
+        plural.substr(0, 1).toLowerCase() + plural.substr(1));
+      setPlural(new RegExp(plural.substr(0, 1).toUpperCase() + plural.substr(1) + "$"),
+        plural.substr(0, 1).toUpperCase() + plural.substr(1));
+      setPlural(new RegExp(plural.substr(0, 1).toLowerCase() + plural.substr(1) + "$"),
+        plural.substr(0, 1).toLowerCase() + plural.substr(1));
+      setSingular(new RegExp(plural.substr(0, 1).toUpperCase() + plural.substr(1) + "$"),
+        singular.substr(0, 1).toUpperCase() + singular.substr(1));
+      setSingular(new RegExp(plural.substr(0, 1).toLowerCase() + plural.substr(1) + "$"),
+        singular.substr(0, 1).toLowerCase() + singular.substr(1));
+    }
+  };
+
+  // Add a new word to the uncountable inflection list
+  setUncountable = function (word) {
+    self.inflections.uncountables[word] = true;
+  };
+
+  // Create inflections
+  (function () {
+    setPlural(/$/, "s");
+    setPlural(/s$/i, "s");
+    setPlural(/(ax|test)is$/i, "$1es");
+    setPlural(/(octop|vir)us$/i, "$1i");
+    setPlural(/(alias|status)$/i, "$1es");
+    setPlural(/(bu)s$/i, "$1ses");
+    setPlural(/(buffal|tomat)o$/i, "$1oes");
+    setPlural(/([ti])um$/i, "$1a");
+    setPlural(/sis$/i, "ses");
+    setPlural(/(?:([^f])fe|([lr])f)$/i, "$1$2ves");
+    setPlural(/(hive)$/i, "$1s");
+    setPlural(/([^aeiouy]|qu)y$/i, "$1ies");
+    setPlural(/(x|ch|ss|sh)$/i, "$1es");
+    setPlural(/(matr|vert|ind)(?:ix|ex)$/i, "$1ices");
+    setPlural(/([m|l])ouse$/i, "$1ice");
+    setPlural(/^(ox)$/i, "$1en");
+    setPlural(/(quiz)$/i, "$1zes");
+
+    setSingular(/s$/i, "")
+		setSingular(/ss$/i, "ss")
+    setSingular(/(n)ews$/i, "$1ews")
+    setSingular(/([ti])a$/i, "$1um")
+    setSingular(/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i, "$1$2sis")
+    setSingular(/(^analy)ses$/i, "$1sis")
+    setSingular(/([^f])ves$/i, "$1fe")
+    setSingular(/(hive)s$/i, "$1")
+    setSingular(/(tive)s$/i, "$1")
+    setSingular(/([lr])ves$/i, "$1f")
+    setSingular(/([^aeiouy]|qu)ies$/i, "$1y")
+    setSingular(/(s)eries$/i, "$1eries")
+    setSingular(/(m)ovies$/i, "$1ovie")
+    setSingular(/(x|ch|ss|sh)es$/i, "$1")
+    setSingular(/([m|l])ice$/i, "$1ouse")
+    setSingular(/(bus)es$/i, "$1")
+    setSingular(/(o)es$/i, "$1")
+    setSingular(/(shoe)s$/i, "$1")
+    setSingular(/(cris|ax|test)es$/i, "$1is")
+    setSingular(/(octop|vir)i$/i, "$1us")
+    setSingular(/(alias|status)es$/i, "$1")
+    setSingular(/^(ox)en/i, "$1")
+    setSingular(/(vert|ind)ices$/i, "$1ex")
+    setSingular(/(matr)ices$/i, "$1ix")
+    setSingular(/(quiz)zes$/i, "$1")
+    setSingular(/(database)s$/i, "$1")
+
+    setIrregular("person", "people");
+    setIrregular("man", "men");
+    setIrregular("child", "children");
+    setIrregular("sex", "sexes");
+    setIrregular("move", "moves");
+    setIrregular("cow", "kine");
+
+    setUncountable("equipment");
+    setUncountable("information");
+    setUncountable("rice");
+    setUncountable("money");
+    setUncountable("species");
+    setUncountable("series");
+    setUncountable("fish");
+    setUncountable("sheep");
+    setUncountable("jeans");
+  })();
+
+  /**
+    @name inflection#parse
+    @public
+    @function
+    @return {String} The inflection of the word from the type given
+    @description Parse a word from the given inflection type
+    @param {String} type A type of the inflection to use
+    @param {String} word the word to parse
+  */
+  this.parse = function (type, word) {
+    var lowWord = word.toLowerCase()
+      , inflections = this.inflections[type];
+
+    if (this.inflections.uncountables[lowWord]) {
+      return word;
+    }
+
+    var i = -1;
+    while (++i < inflections.length) {
+      var rule = inflections[i][0]
+        , replacement = inflections[i][1];
+
+      if (rule.test(word)) {
+        return word.replace(rule, replacement)
+      }
+    }
+
+    return word;
+  };
+
+  /**
+    @name inflection#pluralize
+    @public
+    @function
+    @return {String} The plural inflection for the given word
+    @description Create a plural inflection for a word
+    @param {String} word the word to create a plural version for
+  */
+  this.pluralize = function (word) {
+    return this.parse('plurals', word);
+  };
+
+  /**
+    @name inflection#singularize
+    @public
+    @function
+    @return {String} The singular inflection for the given word
+    @description Create a singular inflection for a word
+    @param {String} word the word to create a singular version for
+  */
+  this.singularize = function (word) {
+    return this.parse('singulars', word);
+  };
+
+})();
+
+module.exports = inflection;

+ 69 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/utilities/lib/log.js

@@ -0,0 +1,69 @@
+var util = require('util')
+  , log
+  , _logger
+  , _levels
+  , _serialize
+  , _output;
+
+_levels = {
+  'debug': 'log'
+, 'log' : 'log'
+, 'info': 'info'
+, 'notice': 'info'
+, 'warning': 'warn'
+, 'warn': 'warn'
+, 'error': 'error'
+, 'critical': 'error'
+, 'alert': 'error'
+, 'emergency': 'error'
+};
+
+_serialize = function (obj) {
+  var out;
+  if (typeof obj == 'string') {
+    out = obj;
+  }
+  else {
+    out = util.inspect(obj);
+  }
+  return out;
+};
+
+_output = function (obj, level) {
+  var out = _serialize(obj);
+  if (_logger) {
+    _logger[level](out);
+  }
+  else {
+    console[_levels[level]](out);
+  }
+};
+
+
+log = function (obj) {
+  _output(obj, 'info');
+};
+
+log.registerLogger = function (logger) {
+  // Malkovitch, Malkovitch
+  if (logger === log) {
+    return;
+  }
+  _logger = logger;
+};
+
+(function () {
+  var level;
+  for (var p in _levels) {
+    (function (p) {
+      level = _levels[p];
+      log[p] = function (obj) {
+        _output(obj, p);
+      };
+    })(p);
+  }
+  // Also handle 'access', not an actual level
+  log.access = log.info;
+})();
+
+module.exports = log;

+ 72 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/utilities/lib/network.js

@@ -0,0 +1,72 @@
+/*
+ * Utilities: A classic collection of JavaScript utilities
+ * Copyright 2112 Matthew Eernisse ([email protected])
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+
+var network
+	, net = require('net');
+
+/**
+  @name network
+  @namespace network
+*/
+
+network = new (function () {
+	/**
+		@name network#isPortOpen
+		@public
+		@function
+		@description Checks if the given port in the given host is open
+		@param {Number} port number
+		@param {String} host
+		@param {Function} callback Callback function -- should be in the format
+			of function(err, result) {}
+	*/
+	this.isPortOpen = function (port, host, callback) {
+		if (typeof host === 'function' && !callback) {
+			callback = host;
+			host = 'localhost';
+		}
+
+		var isOpen = false
+			, connection
+			, error;
+
+		connection = net.createConnection(port, host, function () {
+			isOpen = true;
+			connection.end();
+		});
+
+		connection.on('error', function (err) {
+			// We ignore 'ECONNREFUSED' as it simply indicates the port isn't open.
+			// Anything else is reported
+			if(err.code !== 'ECONNREFUSED') {
+				error = err;
+			}
+		});
+
+		connection.setTimeout(400, function () {
+			connection.end();
+		});
+
+		connection.on('close', function () {
+			callback && callback(error, isOpen);
+		});
+	};
+
+})();
+
+module.exports = network;

+ 108 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/utilities/lib/object.js

@@ -0,0 +1,108 @@
+/*
+ * Utilities: A classic collection of JavaScript utilities
+ * Copyright 2112 Matthew Eernisse ([email protected])
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+
+/**
+  @name object
+  @namespace object
+*/
+
+var object = new (function () {
+
+  /**
+    @name object#merge
+    @public
+    @function
+    @return {Object} Returns the merged object
+    @description Merge merges `otherObject` into `object` and takes care of deep
+                 merging of objects
+    @param {Object} object Object to merge into
+    @param {Object} otherObject Object to read from
+  */
+  this.merge = function (object, otherObject) {
+    var obj = object || {}
+      , otherObj = otherObject || {}
+      , key, value;
+
+    for (key in otherObj) {
+      value = otherObj[key];
+
+      // Check if a value is an Object, if so recursively add it's key/values
+      if (typeof value === 'object' && !(value instanceof Array)) {
+        // Update value of object to the one from otherObj
+        obj[key] = this.merge(obj[key], value);
+      }
+      // Value is anything other than an Object, so just add it
+      else {
+        obj[key] = value;
+      }
+    }
+
+    return obj;
+  };
+
+  /**
+    @name object#reverseMerge
+    @public
+    @function
+    @return {Object} Returns the merged object
+    @description ReverseMerge merges `object` into `defaultObject`
+    @param {Object} object Object to read from
+    @param {Object} defaultObject Object to merge into
+  */
+  this.reverseMerge = function (object, defaultObject) {
+    // Same as `merge` except `defaultObject` is the object being changed
+    // - this is useful if we want to easily deal with default object values
+    return this.merge(defaultObject, object);
+  };
+
+  /**
+    @name object#isEmpty
+    @public
+    @function
+    @return {Boolean} Returns true if empty false otherwise
+    @description isEmpty checks if an Object is empty
+    @param {Object} object Object to check if empty
+  */
+  this.isEmpty = function (object) {
+    // Returns true if a object is empty false if not
+    for (var i in object) { return false; }
+    return true;
+  };
+
+  /**
+    @name object#toArray
+    @public
+    @function
+    @return {Array} Returns an array of objects each including the original key and value
+    @description Converts an object to an array of objects each including the original key/value
+    @param {Object} object Object to convert
+  */
+  this.toArray = function (object) {
+    // Converts an object into an array of objects with the original key, values
+    array = [];
+
+    for (var i in object) {
+      array.push({ key: i, value: object[i] });
+    }
+
+    return array;
+  };
+
+})();
+
+module.exports = object;

+ 143 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/utilities/lib/request.js

@@ -0,0 +1,143 @@
+/*
+ * Utilities: A classic collection of JavaScript utilities
+ * Copyright 2112 Matthew Eernisse ([email protected])
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+var http = require('http')
+  , https = require('https')
+  , url = require('url')
+  , uri = require('./uri')
+  , log = require('./log')
+  , core = require('./core');
+
+var formatters = {
+  xml: function (data) {
+    return data;
+  }
+, html: function (data) {
+    return data;
+  }
+, txt: function (data) {
+    return data;
+  }
+, json: function (data) {
+    return JSON.parse(data);
+  }
+}
+
+/**
+  @name request
+  @namespace request
+  @public
+  @function
+  @description Sends requests to the given url sending any data if the method is POST or PUT
+  @param {Object} opts The options to use for the request
+    @param {String} [opts.url] The URL to send the request to
+    @param {String} [opts.method=GET] The method to use for the request
+    @param {Object} [opts.headers] Headers to send on requests
+    @param {String} [opts.data] Data to send on POST and PUT requests
+    @param {String} [opts.dataType] The type of data to send
+  @param {Function} callback the function to call after, args are `error, data`
+*/
+var request = function (opts, callback) {
+  var client
+    , options = opts || {}
+    , parsed = url.parse(options.url)
+    , path
+    , requester = parsed.protocol == 'http:' ? http : https
+    , method = (options.method && options.method.toUpperCase()) || 'GET'
+    , headers = core.mixin({}, options.headers || {})
+    , contentLength
+    , port
+    , clientOpts;
+
+  if (parsed.port) {
+    port = parsed.port;
+  }
+  else {
+    port = parsed.protocol == 'http:' ? '80' : '443';
+  }
+
+  path = parsed.pathname;
+  if (parsed.search) {
+    path += parsed.search;
+  }
+
+  if (method == 'POST' || method == 'PUT') {
+    if (options.data) {
+      contentLength = options.data.length;
+    }
+    else {
+      contentLength = 0
+    }
+    headers['Content-Length'] = contentLength;
+  }
+
+  clientOpts = {
+    host: parsed.hostname
+  , port: port
+  , method: method
+  , agent: false
+  , path: path
+  , headers: headers
+  };
+  client = requester.request(clientOpts);
+
+  client.addListener('response', function (resp) {
+    var data = ''
+      , dataType;
+    resp.addListener('data', function (chunk) {
+      data += chunk.toString();
+    });
+    resp.addListener('end', function () {
+      var stat = resp.statusCode
+        , err;
+      // Successful response
+      if ((stat > 199 && stat < 300) || stat == 304) {
+        dataType = options.dataType || uri.getFileExtension(parsed.pathname);
+        if (formatters[dataType]) {
+          try {
+            if (data) {
+              data = formatters[dataType](data);
+            }
+          }
+          catch (e) {
+            callback(e, null);
+          }
+        }
+        callback(null, data);
+      }
+      // Something failed
+      else {
+        err = new Error(data);
+        err.statusCode = resp.statusCode;
+        callback(err, null);
+      }
+
+    });
+  });
+
+  client.addListener('error', function (e) {
+    callback(e, null);
+  });
+
+  if ((method == 'POST' || method == 'PUT') && options.data) {
+    client.write(options.data);
+  }
+
+  client.end();
+};
+
+module.exports = request;

+ 558 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/utilities/lib/sorted_collection.js

@@ -0,0 +1,558 @@
+/*
+ * Utilities: A classic collection of JavaScript utilities
+ * Copyright 2112 Matthew Eernisse ([email protected])
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+
+/**
+  @name SortedCollection
+  @namespace SortedCollection
+  @constructor
+*/
+
+var SortedCollection = function (d) {
+  this.count = 0;
+  this.items = {}; // Hash keys and their values
+  this.order = []; // Array for sort order
+  if (d) {
+    this.defaultValue = d;
+  };
+};
+
+SortedCollection.prototype = new (function () {
+  /**
+    @name SortedCollection#addItem
+    @public
+    @function
+    @return {Any} The given val is returned
+    @description Adds a new key/value to the collection
+    @param {String} key The key for the collection item
+    @param {Any} val The value for the collection item
+  */
+  this.addItem = function (key, val) {
+    if (typeof key != 'string') {
+      throw('Hash only allows string keys.');
+    }
+    return this.setByKey(key, val);
+  };
+
+  /**
+    @name SortedCollection#getItem
+    @public
+    @function
+    @return {Any} The value for the given identifier is returned
+    @description Retrieves the value for the given identifier that being a key or index
+    @param {String/Number} p The identifier to look in the collection for, being a key or index
+  */
+  this.getItem = function (p) {
+    if (typeof p == 'string') {
+      return this.getByKey(p);
+    }
+    else if (typeof p == 'number') {
+      return this.getByIndex(p);
+    }
+  };
+
+  /**
+    @name SortedCollection#setItem
+    @public
+    @function
+    @return {Any} The given val is returned
+    @description Sets the item in the collection with the given val, overwriting the existsing item
+      if identifier is an index
+    @param {String/Number} p The identifier set in the collection, being either a key or index
+    @param {Any} val The value for the collection item
+  */
+  this.setItem = function (p, val) {
+    if (typeof p == 'string') {
+      return this.setByKey(p, val);
+    }
+    else if (typeof p == 'number') {
+      return this.setByIndex(p, val);
+    }
+  };
+
+  /**
+    @name SortedCollection#removeItem
+    @public
+    @function
+    @return {Boolean} Returns true if the item has been removed, false otherwise
+    @description Removes the item for the given identifier
+    @param {String/Number} p The identifier to delete the item for, being a key or index
+  */
+  this.removeItem = function (p) {
+    if (typeof p == 'string') {
+      return this.removeByKey(p);
+    }
+    else if (typeof p == 'number') {
+      return this.removeByIndex(p);
+    }
+  };
+
+  /**
+    @name SortedCollection#getByKey
+    @public
+    @function
+    @return {Any} The value for the given key item is returned
+    @description Retrieves the value for the given key
+    @param {String} key The key for the item to lookup
+  */
+  this.getByKey = function (key) {
+    return this.items[key];
+  };
+
+  /**
+    @name SortedCollection#setByKey
+    @public
+    @function
+    @return {Any} The given val is returned
+    @description Sets a item by key assigning the given val
+    @param {String} key The key for the item
+    @param {Any} val The value to set for the item
+  */
+  this.setByKey = function (key, val) {
+    var v = null;
+    if (typeof val == 'undefined') {
+      v = this.defaultValue;
+    }
+    else { v = val; }
+    if (typeof this.items[key] == 'undefined') {
+      this.order[this.count] = key;
+      this.count++;
+    }
+    this.items[key] = v;
+    return this.items[key];
+  };
+
+  /**
+    @name SortedCollection#removeByKey
+    @public
+    @function
+    @return {Boolean} If the item was removed true is returned, false otherwise
+    @description Removes a collection item by key
+    @param {String} key The key for the item to remove
+  */
+  this.removeByKey = function (key) {
+    if (typeof this.items[key] != 'undefined') {
+      var pos = null;
+      delete this.items[key]; // Remove the value
+      // Find the key in the order list
+      for (var i = 0; i < this.order.length; i++) {
+        if (this.order[i] == key) {
+          pos = i;
+        }
+      }
+      this.order.splice(pos, 1); // Remove the key
+      this.count--; // Decrement the length
+      return true;
+    }
+    else {
+      return false;
+    }
+  };
+
+  /**
+    @name SortedCollection#getByIndex
+    @public
+    @function
+    @return {Any} The value for the given index item is returned
+    @description Retrieves the value for the given index
+    @param {Number} ind The index to lookup for the item
+  */
+  this.getByIndex = function (ind) {
+    return this.items[this.order[ind]];
+  };
+
+  /**
+    @name SortedCollection#setByIndex
+    @public
+    @function
+    @return {Any} The given val is returned
+    @description Sets a item by index assigning the given val
+    @param {Number} ind The index for the item
+    @param {Any} val The value to set for the item
+  */
+  this.setByIndex = function (ind, val) {
+    if (ind < 0 || ind >= this.count) {
+      throw('Index out of bounds. Hash length is ' + this.count);
+    }
+    this.items[this.order[ind]] = val;
+    return this.items[this.order[ind]];
+  };
+
+  /**
+    @name SortedCollection#removeByIndex
+    @public
+    @function
+    @return {Boolean} If the item was removed true is returned, false otherwise
+    @description Removes a collection item by index
+    @param {Number} ind The index for the item to remove
+  */
+  this.removeByIndex = function (ind) {
+    var ret = this.items[this.order[ind]];
+    if (typeof ret != 'undefined') {
+      delete this.items[this.order[ind]]
+      this.order.splice(ind, 1);
+      this.count--;
+      return true;
+    }
+    else {
+      return false;
+    }
+  };
+
+  /**
+    @name SortedCollection#hasKey
+    @public
+    @function
+    @return {Boolean} Returns true if the item exists, false otherwise
+    @description Checks if a key item exists in the collection
+    @param {String} key The key to look for in the collection
+  */
+  this.hasKey = function (key) {
+    return typeof this.items[key] != 'undefined';
+  };
+
+  /**
+    @name SortedCollection#hasValue
+    @public
+    @function
+    @return {Boolean} Returns true if a key with the given value exists, false otherwise
+    @description Checks if a key item in the collection has a given val
+    @param {Any} val The value to check for in the collection
+  */
+  this.hasValue = function (val) {
+    for (var i = 0; i < this.order.length; i++) {
+      if (this.items[this.order[i]] == val) {
+        return true;
+      }
+    }
+    return false;
+  };
+
+  /**
+    @name SortedCollection#allKeys
+    @public
+    @function
+    @return {String} Returns all the keys in a string
+    @description Joins all the keys into a string
+    @param {String} str The string to use between each key
+  */
+  this.allKeys = function (str) {
+    return this.order.join(str);
+  };
+
+  /**
+    @name SortedCollection#replaceKey
+    @public
+    @function
+    @description Joins all the keys into a string
+    @param {String} oldKey The key item to change
+    @param {String} newKey The key item to change the name to
+  */
+  this.replaceKey = function (oldKey, newKey) {
+    // If item for newKey exists, nuke it
+    if (this.hasKey(newKey)) {
+      this.removeItem(newKey);
+    }
+    this.items[newKey] = this.items[oldKey];
+    delete this.items[oldKey];
+    for (var i = 0; i < this.order.length; i++) {
+      if (this.order[i] == oldKey) {
+        this.order[i] = newKey;
+      }
+    }
+  };
+
+  /**
+    @name SortedCollection#insertAtIndex
+    @public
+    @function
+    @return {Boolean} Returns true if the item was set at the given index
+    @description Inserts a key/value at a specific index in the collection
+    @param {Number} ind The index to set the item at
+    @param {String} key The key to use at the item index
+    @param {Any} val The value to set for the item
+  */
+  this.insertAtIndex = function (ind, key, val) {
+    this.order.splice(ind, 0, key);
+    this.items[key] = val;
+    this.count++;
+    return true;
+  };
+
+  /**
+    @name SortedCollection#insertAfterKey
+    @public
+    @function
+    @return {Boolean} Returns true if the item was set for the given key
+    @description Inserts a key/value item after the given reference key in the collection
+    @param {String} refKey The key to insert the new item after
+    @param {String} key The key for the new item
+    @param {Any} val The value to set for the item
+  */
+  this.insertAfterKey = function (refKey, key, val) {
+    var pos = this.getPosition(refKey);
+    return this.insertAtIndex(pos, key, val);
+  };
+
+  /**
+    @name SortedCollection#getPosition
+    @public
+    @function
+    @return {Number} Returns the index for the item of the given key
+    @description Retrieves the index of the key item
+    @param {String} key The key to get the index for
+  */
+  this.getPosition = function (key) {
+    var order = this.order;
+    if (typeof order.indexOf == 'function') {
+      return order.indexOf(key);
+    }
+    else {
+      for (var i = 0; i < order.length; i++) {
+        if (order[i] == key) { return i;}
+      }
+    }
+  };
+
+  /**
+    @name SortedCollection#each
+    @public
+    @function
+    @return {Boolean}
+    @description Loops through the collection and calls the given function
+    @param {Function} func The function to call for each collection item, the arguments
+      are the key and value for the current item
+    @param {Object} opts The options to use
+      @param {Boolean} [opts.keyOnly] Only give the function the key
+      @param {Boolean} [opts.valueOnly] Only give the function the value
+  */
+  this.each = function (func, opts) {
+    var options = opts || {}
+      , order = this.order;
+    for (var i = 0, ii = order.length; i < ii; i++) {
+      var key = order[i];
+      var val = this.items[key];
+      if (options.keyOnly) {
+        func(key);
+      }
+      else if (options.valueOnly) {
+        func(val);
+      }
+      else {
+        func(val, key);
+      }
+    }
+    return true;
+  };
+
+  /**
+    @name SortedCollection#eachKey
+    @public
+    @function
+    @return {Boolean}
+    @description Loops through the collection and calls the given function
+    @param {Function} func The function to call for each collection item, only giving the
+      key to the function
+  */
+  this.eachKey = function (func) {
+    return this.each(func, { keyOnly: true });
+  };
+
+  /**
+    @name SortedCollection#eachValue
+    @public
+    @function
+    @return {Boolean}
+    @description Loops through the collection and calls the given function
+    @param {Function} func The function to call for each collection item, only giving the
+      value to the function
+  */
+  this.eachValue = function (func) {
+    return this.each(func, { valueOnly: true });
+  };
+
+  /**
+    @name SortedCollection#clone
+    @public
+    @function
+    @return {Object} Returns a new SortedCollection with the data of the current one
+    @description Creates a cloned version of the current collection and returns it
+  */
+  this.clone = function () {
+    var coll = new SortedCollection()
+      , key
+      , val;
+    for (var i = 0; i < this.order.length; i++) {
+      key = this.order[i];
+      val = this.items[key];
+      coll.setItem(key, val);
+    }
+    return coll;
+  };
+
+  /**
+    @name SortedCollection#concat
+    @public
+    @function
+    @description Join a given collection with the current one
+    @param {Object} hNew A SortedCollection to join from
+  */
+  this.concat = function (hNew) {
+    for (var i = 0; i < hNew.order.length; i++) {
+      var key = hNew.order[i];
+      var val = hNew.items[key];
+      this.setItem(key, val);
+    }
+  };
+
+  /**
+    @name SortedCollection#push
+    @public
+    @function
+    @return {Number} Returns the count of items
+    @description Appends a new item to the collection
+    @param {String} key The key to use for the item
+    @param {Any} val The value to use for the item
+  */
+  this.push = function (key, val) {
+    this.insertAtIndex(this.count, key, val);
+    return this.count;
+  };
+
+  /**
+    @name SortedCollection#pop
+    @public
+    @function
+    @return {Any} Returns the value for the last item in the collection
+    @description Pops off the last item in the collection and returns it's value
+  */
+  this.pop = function () {
+    var pos = this.count-1;
+    var ret = this.items[this.order[pos]];
+    if (typeof ret != 'undefined') {
+      this.removeByIndex(pos);
+      return ret;
+    }
+    else {
+      return;
+    }
+  };
+
+  /**
+    @name SortedCollection#unshift
+    @public
+    @function
+    @return {Number} Returns the count of items
+    @description Prepends a new item to the beginning of the collection
+    @param {String} key The key to use for the item
+    @param {Any} val The value to use for the item
+  */
+  this.unshift = function (key, val) {
+    this.insertAtIndex(0, key, val);
+    return this.count;
+  };
+
+  /**
+    @name SortedCollection#shift
+    @public
+    @function
+    @return {Number} Returns the removed items value
+    @description Removes the first item in the list and returns it's value
+  */
+  this.shift = function () {
+    var pos = 0;
+    var ret = this.items[this.order[pos]];
+    if (typeof ret != 'undefined') {
+      this.removeByIndex(pos);
+      return ret;
+    }
+    else {
+      return;
+    }
+  };
+
+  /**
+    @name SortedCollection#splice
+    @public
+    @function
+    @description Removes items from index to the given max and then adds the given
+      collections items
+    @param {Number} index The index to start at when removing items
+    @param {Number} numToRemove The number of items to remove before adding the new items
+    @param {Object} hash the collection of items to add
+  */
+  this.splice = function (index, numToRemove, hash) {
+    var _this = this;
+    // Removal
+    if (numToRemove > 0) {
+      // Items
+      var limit = index + numToRemove;
+      for (var i = index; i < limit; i++) {
+        delete this.items[this.order[i]];
+      }
+      // Order
+      this.order.splice(index, numToRemove);
+    }
+    // Adding
+    if (hash) {
+      // Items
+      for (var i in hash.items) {
+        this.items[i] = hash.items[i];
+      }
+      // Order
+      var args = hash.order;
+      args.unshift(0);
+      args.unshift(index);
+      this.order.splice.apply(this.order, args);
+    }
+    this.count = this.order.length;
+  };
+
+  this.sort = function (c) {
+    var arr = [];
+    // Assumes vals are comparable scalars
+    var comp = function (a, b) {
+      return c(a.val, b.val);
+    }
+    for (var i = 0; i < this.order.length; i++) {
+      var key = this.order[i];
+      arr[i] = { key: key, val: this.items[key] };
+    }
+    arr.sort(comp);
+    this.order = [];
+    for (var i = 0; i < arr.length; i++) {
+      this.order.push(arr[i].key);
+    }
+  };
+
+  this.sortByKey = function (comp) {
+    this.order.sort(comp);
+  };
+
+  /**
+    @name SortedCollection#reverse
+    @public
+    @function
+    @description Reverse the collection item list
+  */
+  this.reverse = function () {
+    this.order.reverse();
+  };
+
+})();
+
+module.exports.SortedCollection = SortedCollection;

+ 810 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/utilities/lib/string.js

@@ -0,0 +1,810 @@
+/*
+ * Utilities: A classic collection of JavaScript utilities
+ * Copyright 2112 Matthew Eernisse ([email protected])
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+var core = require('./core')
+  , inflection = require('./inflection')
+  , string;
+
+
+/**
+  @name string
+  @namespace string
+*/
+
+string = new (function () {
+
+  // Regexes for trimming, and character maps for escaping
+  var _LTR = /^\s+/
+    , _RTR = /\s+$/
+    , _TR = /^\s+|\s+$/g
+    , _NL = /\n|\r|\r\n/g
+    , _CHARS = {
+          '&': '&amp;'
+        , '<': '&lt;'
+        , '>': '&gt;'
+        , '"': '&quot;'
+        , '\'': '&#39;'
+      }
+    , _UUID_CHARS = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('')
+    , _buildEscape
+    , _buildEscapeTest;
+
+  // Builds the escape/unescape methods using a
+  // map of characters
+  _buildEscape = function (direction) {
+    return function (str) {
+      var string = str;
+
+      // If string is NaN, null or undefined then provide an empty default
+      if((typeof string === 'undefined') ||
+          string === null ||
+          (!string && isNaN(string))) {
+        string = '';
+      }
+      string = string.toString();
+
+      var from, to, p;
+      for (p in _CHARS) {
+        from = direction == 'to' ? p : _CHARS[p];
+        to = direction == 'to' ? _CHARS[p] : p;
+
+        string = string.replace(new RegExp(from, 'gm'), to);
+      }
+
+      return string;
+    }
+  };
+
+  // Builds a method that tests for any escapable
+  // characters, useful for avoiding double-scaping if
+  // you're not sure if a string has already been escaped
+  _buildEscapeTest = function (direction) {
+    return function (string) {
+      var pat = ''
+        , p;
+
+      for (p in _CHARS) {
+        pat += direction == 'to' ? p : _CHARS[p];
+        pat += '|';
+      }
+
+      pat = pat.substr(0, pat.length - 1);
+      pat = new RegExp(pat, "gm");
+      return pat.test(string)
+    }
+  };
+
+  // Escape special XMl chars
+  this.escapeXML = _buildEscape('to');
+
+  // Unescape XML chars to literal representation
+  this.unescapeXML = _buildEscape('from');
+
+  // Test if a string includes special chars
+  // that need escaping
+  this.needsEscape = _buildEscapeTest('to');
+
+  // Test if a string includes escaped chars
+  // that need unescaping
+  this.needsUnescape = _buildEscapeTest('from');
+
+  /**
+    @name string#escapeRegExpChars
+    @public
+    @function
+    @return {String} A string of escaped characters
+    @description Escapes regex control-characters in strings
+                 used to build regexes dynamically
+    @param {String} string The string of chars to escape
+  */
+  this.escapeRegExpChars = (function () {
+    var specials = [ '^', '$', '/', '.', '*', '+', '?', '|', '(', ')',
+        '[', ']', '{', '}', '\\' ];
+    sRE = new RegExp('(\\' + specials.join('|\\') + ')', 'g');
+    return function (string) {
+      var str = string || '';
+      str = String(str);
+      return str.replace(sRE, '\\$1');
+    };
+  }).call(this);
+
+  /**
+    @name string#toArray
+    @public
+    @function
+    @return {Array} Returns an array of characters
+    @description Converts a string to an array
+    @param {String} string The string to convert
+  */
+  this.toArray = function (string) {
+    var str = string || ''
+      , arr = []
+      , i = -1;
+    str = String(str);
+
+    while (++i < str.length) {
+      arr.push(str.substr(i, 1));
+    }
+
+    return arr;
+  };
+
+  /**
+    @name string#reverse
+    @public
+    @function
+    @return {String} Returns the `string` reversed
+    @description Reverses a string
+    @param {String} string The string to reverse
+  */
+  this.reverse = function (string) {
+    var str = string || '';
+    str = String(str);
+    return this.toArray(str).reverse().join('');
+  };
+
+  /**
+    @name string#ltrim
+    @public
+    @function
+    @return {String} Returns the trimmed string
+    @description Ltrim trims `char` from the left of a `string` and returns it
+                 if no `char` is given it will trim spaces
+    @param {String} string The string to trim
+    @param {String} character The character to trim
+  */
+  this.ltrim = function (string, character) {
+    var str = string || ''
+      , pat = character ? new RegExp('^' + character + '+') : _LTR;
+    str = String(str);
+
+    return str.replace(pat, '');
+  };
+
+  /**
+    @name string#rtrim
+    @public
+    @function
+    @return {String} Returns the trimmed string
+    @description Rtrim trims `char` from the right of a `string` and returns it
+                 if no `char` is given it will trim spaces
+    @param {String} string The string to trim
+    @param {String} character The character to trim
+  */
+  this.rtrim = function (string, character) {
+    var str = string || ''
+      , pat = character ? new RegExp(character + '+$') : _RTR;
+    str = String(str);
+
+    return str.replace(pat, '');
+  };
+
+  // Alias
+  this.chomp = this.rtrim;
+
+  /**
+    @name string#trim
+    @public
+    @function
+    @return {String} Returns the trimmed string
+    @description Trim trims `char` from the left and right of a `string` and returns it
+                 if no `char` is given it will trim spaces
+    @param {String} string The string to trim
+    @param {String} character The character to trim
+  */
+  this.trim = function (string, character) {
+    var str = string || ''
+      , pat = character ? new RegExp('^' + character + '+|' + character + '+$', 'g') : _TR;
+    str = String(str);
+
+    return str.replace(pat, '');
+  };
+
+  /**
+    @name string#chop
+    @public
+    @function
+    @description Returns a new String with the last character removed. If the
+                 string ends with \r\n, both characters are removed. Applying chop to an
+                 empty string returns an empty string.
+    @param {String} string to return with the last character removed.
+  */
+  this.chop = function (string) {
+    var index
+      , str = string || '';
+    str = String(str);
+
+    if (str.length) {
+      // Special-case for \r\n
+      index = str.indexOf('\r\n');
+      if (index == str.length - 2) {
+        return str.substring(0, index);
+      }
+      return str.substring(0, str.length - 1);
+    }
+    else {
+      return '';
+    }
+  };
+
+  /**
+    @name string#lpad
+    @public
+    @function
+    @return {String} Returns the padded string
+    @description Lpad adds `char` to the left of `string` until the length
+                 of `string` is more than `width`
+    @param {String} string The string to pad
+    @param {String} character The character to pad with
+    @param {Number} width the width to pad to
+  */
+  this.lpad = function (string, character, width) {
+    var str = string || ''
+      , width;
+    str = String(str);
+
+    // Should width be string.length + 1? or the same to be safe
+    width = parseInt(width, 10) || str.length;
+    character = character || ' ';
+
+    while (str.length < width) {
+      str = character + str;
+    }
+    return str;
+  };
+
+  /**
+    @name string#rpad
+    @public
+    @function
+    @return {String} Returns the padded string
+    @description Rpad adds `char` to the right of `string` until the length
+                 of `string` is more than `width`
+    @param {String} string The string to pad
+    @param {String} character The character to pad with
+    @param {Number} width the width to pad to
+  */
+  this.rpad = function (string, character, width) {
+    var str = string || ''
+      , width;
+    str = String(str);
+
+    // Should width be string.length + 1? or the same to be safe
+    width = parseInt(width, 10) || str.length;
+    character = character || ' ';
+
+    while (str.length < width) {
+      str += character;
+    }
+    return str;
+  };
+
+  /**
+    @name string#pad
+    @public
+    @function
+    @return {String} Returns the padded string
+    @description Pad adds `char` to the left and right of `string` until the length
+                 of `string` is more than `width`
+    @param {String} string The string to pad
+    @param {String} character The character to pad with
+    @param {Number} width the width to pad to
+  */
+  this.pad = function (string, character, width) {
+    var str = string || ''
+      , width;
+    str = String(str);
+
+    // Should width be string.length + 1? or the same to be safe
+    width = parseInt(width, 10) || str.length;
+    character = character || ' ';
+
+    while (str.length < width) {
+      str = character + str + character;
+    }
+    return str;
+  };
+
+  /**
+    @name string#truncate
+    @public
+    @function
+    @return {String} Returns the truncated string
+    @description Truncates a given `string` after a specified `length` if `string` is longer than
+                 `length`. The last characters will be replaced with an `omission` for a total length
+                 not exceeding `length`. If `callback` is given it will fire if `string` is truncated.
+    @param {String} string The string to truncate
+    @param {Integer/Object} options Options for truncation, If options is an Integer it will be length
+      @param {Integer} [options.length=string.length] Length the output string will be
+      @param {Integer} [options.len] Alias for `length`
+      @param {String} [options.omission='...'] Replace last characters with an omission
+      @param {String} [options.ellipsis='...'] Alias for `omission`
+      @param {String/RegExp} [options.seperator] Break the truncated test at the nearest `seperator`
+    @param {Function} callback Callback is called only if a truncation is done
+  */
+  this.truncate = function (string, options, callback) {
+    var str = string || ''
+      , stringLen
+      , opts
+      , stringLenWithOmission
+      , last
+      , ignoreCase
+      , multiLine
+      , stringToWorkWith
+      , lastIndexOf
+      , nextStop
+      , result
+      , returnString;
+
+    str = String(str);
+    stringLen = str.length
+
+    // If `options` is a number, assume it's the length and
+    // create a options object with length
+    if (typeof options === 'number') {
+      opts = {
+        length: options
+      };
+    }
+    else {
+      opts = options || {};
+    }
+
+    // Set `opts` defaults
+    opts.length = opts.length || stringLen;
+    opts.omission = opts.omission || opts.ellipsis || '...';
+
+    stringLenWithOmission = opts.length - opts.omission.length;
+
+    // Set the index to stop at for `string`
+    if (opts.seperator) {
+      if (opts.seperator instanceof RegExp) {
+        // If `seperator` is a regex
+        if (opts.seperator.global) {
+          opts.seperator = opts.seperator;
+        } else {
+          ignoreCase = opts.seperator.ignoreCase ? 'i' : ''
+          multiLine = opts.seperator.multiLine ? 'm' : '';
+          opts.seperator = new RegExp(opts.seperator.source,
+              'g' + ignoreCase + multiLine);
+        }
+        stringToWorkWith = str.substring(0, stringLenWithOmission + 1)
+        lastIndexOf = -1
+        nextStop = 0
+
+        while ((result = opts.seperator.exec(stringToWorkWith))) {
+          lastIndexOf = result.index;
+          opts.seperator.lastIndex = ++nextStop;
+        }
+        last = lastIndexOf;
+      }
+      else {
+        // Seperator is a String
+        last = str.lastIndexOf(opts.seperator, stringLenWithOmission);
+      }
+
+      // If the above couldn't be found, they'll default to -1 so,
+      // we need to just set it as `stringLenWithOmission`
+      if (last === -1) {
+        last = stringLenWithOmission;
+      }
+    }
+    else {
+      last = stringLenWithOmission;
+    }
+
+    if (stringLen < opts.length) {
+      return str;
+    }
+    else {
+      returnString = str.substring(0, last) + opts.omission;
+      returnString += callback && typeof callback === 'function' ? callback() : '';
+      return returnString;
+    }
+  };
+
+  /**
+    @name string#truncateHTML
+    @public
+    @function
+    @return {String} Returns the HTML safe truncated string
+    @description Truncates a given `string` inside HTML tags after a specified `length` if string`
+                 is longer than `length`. The last characters will be replaced with an `omission`
+                 for a total length not exceeding `length`. If `callback` is given it will fire if
+                 `string` is truncated. If `once` is true only the first string in the first HTML
+                 tags will be truncated leaving the others as they were
+    @param {String} string The string to truncate
+    @param {Integer/Object} options Options for truncation, If options is an Integer it will be length
+                            all Object options are the same as `truncate`
+      @param {Boolean} [options.once=false] If true, it will only be truncated once, otherwise the
+                                            truncation will loop through all text inside HTML tags
+    @param {Function} callback Callback is called only if a truncation is done
+  */
+  this.truncateHTML = function (string, options, callback) {
+    var str = string || ''
+      , returnString = ''
+      , opts = options;
+
+    str = String(str);
+
+    // If `options` is a number assume it's the length and create a options object with length
+    if (typeof opts === 'number') {
+      var num = opts;
+
+      opts = {};
+      opts.length = num;
+    } else opts = opts || {};
+
+    // Set `default` options for HTML specifics
+    opts.once = opts.once || false;
+
+    var pat = /(<[^>]*>)/ // Patter for matching HTML tags
+      , arr = [] // Holds the HTML tags and content seperately
+      , truncated = false
+      , result = pat.exec(str)
+      , item
+      , firstPos
+      , lastPos
+      , i;
+
+    // Gather the HTML tags and content into the array
+    while (result) {
+      firstPos = result.index;
+      lastPos = pat.lastIndex;
+
+      if (firstPos !== 0) {
+        // Should be content not HTML tags
+        arr.push(str.substring(0, firstPos));
+        // Slice content from string
+        str = str.slice(firstPos);
+      }
+
+      arr.push(result[0]); // Push HTML tags
+      str = str.slice(result[0].length);
+
+      // Re-run the pattern on the new string
+      result = pat.exec(str);
+    }
+    if (str !== '') {
+      arr.push(str);
+    }
+
+    // Loop through array items appending the tags to the string,
+    // - and truncating the text then appending it to content
+    i = -1;
+    while (++i < arr.length) {
+      item = arr[i];
+      switch (true) {
+        // Closing tag
+        case item.indexOf('</') == 0:
+          returnString += item;
+          openTag = null;
+          break;
+        // Opening tag
+        case item.indexOf('<') == 0:
+          returnString += item;
+          openTag = item;
+          break;
+        // Normal text
+        default:
+          if (opts.once && truncated) {
+            returnString += item;
+          } else {
+            returnString += this.truncate(item, opts, callback);
+            truncated = true;
+          }
+          break;
+      }
+    }
+
+    return returnString;
+  };
+
+  /**
+    @name string#nl2br
+    @public
+    @function
+    @return {String} The string with converted newlines chars to br tags
+    @description Nl2br returns a string where all newline chars are turned
+                 into line break HTML tags
+    @param {String} string The string to convert
+  */
+  this.nl2br = function (string) {
+    var str = string || '';
+    str = String(str);
+
+    return str.replace(_NL,'<br />');
+  };
+
+  /**
+    @name string#snakeize
+    @public
+    @function
+    @return {String} The string in a snake_case version
+    @description Snakeize converts camelCase and CamelCase strings to snake_case strings
+    @param {String} string The string to convert to snake_case
+    @param {String} separ='_' The seperator to use
+  */
+  this.snakeize = (function () {
+    // Only create regexes once on initial load
+    var repl = /([A-Z]+)/g
+      , lead = /^_/g;
+    return function (string, separ) {
+      var str = string || ''
+        , sep = separ || '_'
+        , leading = separ ? new RegExp('^' + sep, 'g') : lead;
+      str = String(str);
+      return str.replace(repl, sep + '$1').toLowerCase().
+        replace(leading, '');
+    };
+  }).call(this);
+
+  // Aliases
+  /**
+    @name string#underscorize
+    @public
+    @function
+    @return {String} The string in a underscorized version
+    @description Underscorize returns the given `string` converting camelCase and snakeCase to underscores
+    @param {String} string The string to underscorize
+  */
+  this.underscorize = this.snakeize;
+  this.underscoreize = this.snakeize;
+  this.decamelize = this.snakeize;
+
+  /**
+    @name string#camelize
+    @public
+    @function
+    @return {String} The string in a camelCase version
+    @description Camelize takes a string and optional options and
+                 returns a camelCase version of the given `string`
+    @param {String} string The string to convert to camelCase
+    @param {Object} options
+      @param {Boolean} [options.initialCap] If initialCap is true the returned
+                                            string will have a capitalized first letter
+      @param {Boolean} [options.leadingUnderscore] If leadingUnderscore os true then if
+                                                   an underscore exists at the beggining
+                                                   of the string, it will stay there.
+                                                   Otherwise it'll be removed.
+  */
+  this.camelize = (function () {
+    // Only create regex once on initial load
+    var repl = /[-_](\w)/g;
+    return function (string, options) {
+      var str = string || ''
+        , ret
+        , config = {
+            initialCap: false
+          , leadingUnderscore: false
+          }
+        , opts = options || {};
+
+      str = String(str);
+
+      // Backward-compat
+      if (typeof opts == 'boolean') {
+        config = {
+          initialCap: true
+        };
+      }
+      else {
+        core.mixin(config, opts);
+      }
+
+      ret = str.replace(repl, function (m, m1) {
+        return m1.toUpperCase();
+      });
+
+      if (config.leadingUnderscore & str.indexOf('_') === 0) {
+        ret = '_' + this.decapitalize(ret);
+      }
+      // If initialCap is true capitalize it
+      ret = config.initialCap ? this.capitalize(ret) : this.decapitalize(ret);
+
+      return ret;
+    };
+  }).call(this);
+
+  /**
+    @name string#decapitalize
+    @public
+    @function
+    @return {String} The string with the first letter decapitalized
+    @description Decapitalize returns the given string with the first letter uncapitalized.
+    @param {String} string The string to decapitalize
+  */
+  this.decapitalize = function (string) {
+    var str = string || '';
+    str = String(str);
+
+    return str.substr(0, 1).toLowerCase() + str.substr(1);
+  };
+
+  /**
+    @name string#capitalize
+    @public
+    @function
+    @return {String} The string with the first letter capitalized
+    @description capitalize returns the given string with the first letter capitalized.
+    @param {String} string The string to capitalize
+  */
+  this.capitalize = function (string) {
+    var str = string || '';
+    str = String(str);
+
+    return str.substr(0, 1).toUpperCase() + str.substr(1);
+  };
+
+  /**
+    @name string#dasherize
+    @public
+    @function
+    @return {String} The string in a dashed version
+    @description Dasherize returns the given `string` converting camelCase and snakeCase
+                 to dashes or replace them with the `replace` character.
+    @param {String} string The string to dasherize
+    @param {String} replace='-' The character to replace with
+  */
+  this.dasherize = function (string, replace) {
+    var repl = replace || '-'
+    return this.snakeize(string, repl);
+  };
+
+  /**
+    @name string#include
+    @public
+    @function
+    @return {Boolean} Returns true if the string is found in the string to search
+    @description Searches for a particular string in another string
+    @param {String} searchIn The string to search for the other string in
+    @param {String} searchFor The string to search for
+  */
+  this.include = function (searchIn, searchFor) {
+    var str = searchFor;
+    if (!str && typeof string != 'string') {
+      return false;
+    }
+    str = String(str);
+    return (searchIn.indexOf(str) > -1);
+  };
+
+  /*
+   * getInflections(name<String>, initialCap<String>)
+   *
+   * Inflection returns an object that contains different inflections
+   * created from the given `name`
+  */
+
+  /**
+    @name string#getInflections
+    @public
+    @function
+    @return {Object} A Object containing multiple different inflects for the given `name`
+    @description Inflection returns an object that contains different inflections
+                 created from the given `name`
+    @param {String} name The string to create inflections from
+  */
+  this.getInflections = function (name) {
+    if (!name) {
+      return;
+    }
+
+    var self = this
+        // Use plural version to fix possible mistakes(e,g,. thingie instead of thingy)
+      , normalizedName = this.snakeize(inflection.pluralize(name))
+      , nameSingular = inflection.singularize(normalizedName)
+      , namePlural = inflection.pluralize(normalizedName);
+
+    return {
+      // For filepaths or URLs
+      filename: {
+        // neil_peart
+        singular: nameSingular
+        // neil_pearts
+      , plural: namePlural
+      }
+      // Constructor names
+    , constructor: {
+        // NeilPeart
+        singular: self.camelize(nameSingular, {initialCap: true})
+        // NeilPearts
+      , plural: self.camelize(namePlural, {initialCap: true})
+      }
+    , property: {
+        // neilPeart
+        singular: self.camelize(nameSingular)
+        // neilPearts
+      , plural: self.camelize(namePlural)
+      }
+    };
+  };
+
+  /**
+    @name string#getInflection
+    @public
+    @function
+    @return {Object} A Object containing multiple different inflects for the given `name`
+    @description Inflection returns an object that contains different inflections
+                 created from the given `name`
+    @param {String} name The string to create inflections from
+  */
+  this.getInflection = function (name, key, pluralization) {
+    var infl = this.getInflections(name);
+    return infl[key][pluralization];
+  };
+
+  // From Math.uuid.js, https://github.com/broofa/node-uuid
+  // Robert Kieffer ([email protected]), MIT license
+  this.uuid = function (length, radix) {
+    var chars = _UUID_CHARS
+      , uuid = []
+      , r
+      , i;
+
+    radix = radix || chars.length;
+
+    if (length) {
+      // Compact form
+      i = -1;
+      while (++i < length) {
+        uuid[i] = chars[0 | Math.random()*radix];
+      }
+    } else {
+      // rfc4122, version 4 form
+
+      // rfc4122 requires these characters
+      uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-';
+      uuid[14] = '4';
+
+      // Fill in random data.  At i==19 set the high bits of clock sequence as
+      // per rfc4122, sec. 4.1.5
+      i = -1;
+      while (++i < 36) {
+        if (!uuid[i]) {
+          r = 0 | Math.random()*16;
+          uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r];
+        }
+      }
+    }
+
+    return uuid.join('');
+  };
+  
+  /**
+    @name string#stripTags
+    @public
+    @function
+    @return {String} A String with HTML tags removed.
+    @description Strips HTML tags from a string.
+    @param {String} The string to strip HTML tags from
+    @param {String|Array} A String or Array containing allowed tags. e.g. "<br><p>"
+  */
+  this.stripTags = function(string, allowed) {
+    // taken from http://phpjs.org/functions/strip_tags/
+    var allowed = (((allowed || "") + "").toLowerCase().match(/<[a-z][a-z0-9]*>/g) || []).join(''); // making sure the allowed arg is a string containing only tags in lowercase (<a><b><c>)
+    var tags = /<\/?([a-z][a-z0-9]*)\b[^>]*>/gi,
+    comments = /<!--[\s\S]*?-->/gi;
+    return string.replace(comments, '').replace(tags, function ($0, $1) {
+      return allowed.indexOf('<' + $1.toLowerCase() + '>') > -1 ? $0 : '';
+    });
+  }
+
+})();
+
+module.exports = string;
+

+ 238 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/utilities/lib/uri.js

@@ -0,0 +1,238 @@
+/*
+ * Utilities: A classic collection of JavaScript utilities
+ * Copyright 2112 Matthew Eernisse ([email protected])
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+var uri
+  , string = require('./string')
+  , mixin = require('./core').mixin;
+
+/**
+  @name uri
+  @namespace uri
+*/
+
+uri = new (function () {
+  var _isArray = function (obj) {
+    return obj &&
+      typeof obj === 'object' &&
+      typeof obj.length === 'number' &&
+      typeof obj.splice === 'function' &&
+      !(obj.propertyIsEnumerable('length'));
+  };
+
+  /**
+    @name uri#getFileExtension
+    @public
+    @function
+    @return {String} Returns the file extension for a given path
+    @description Gets the file extension for a path and returns it
+    @param {String} path The path to get the extension for
+  */
+  this.getFileExtension = function (path) {
+    var match;
+    if (path) {
+      match = /.+\.(\w{2,4}$)/.exec(path);
+    }
+    return (match && match[1]) || '';
+  };
+
+  /**
+    @name uri#paramify
+    @public
+    @function
+    @return {String} Returns a querystring contains the given values
+    @description Convert a JS Object to a querystring (key=val&key=val). Values in arrays
+      will be added as multiple parameters
+    @param {Object} obj An Object containing only scalars and arrays
+    @param {Object} o The options to use for formatting
+      @param {Boolean} [o.consolidate=false] take values from elements that can return
+        multiple values (multi-select, checkbox groups) and collapse into a single,
+        comman-delimited value.
+      @param {Boolean} [o.includeEmpty=false] include keys in the string for all elements, even
+        they have no value set (e.g., even if elemB has no value: elemA=foo&elemB=&elemC=bar).
+        Note that some false-y values are always valid even without this option, [0, ''].
+        This option extends coverage to [null, undefined, NaN]
+      @param {Boolean} [o.snakeize=false] change param names from camelCase to snake_case.
+      @param {Boolean} [o.escapeVals=false] escape the values for XML entities.
+      @param {Boolean} [o.index=false] use numeric indices for arrays
+  */
+  this.paramify = function (obj, o) {
+    var opts = o || {},
+        _opts,
+        str = '',
+        key,
+        val,
+        isValid,
+        itemArray,
+        arr = [],
+        arrVal,
+        prefix = opts.prefix || '',
+        self = this;
+
+    function getParamName(key)
+    {
+      if (opts.prefix) {
+        return prefix + '[' + key + ']';
+      }
+      else {
+        return key;
+      }
+    }
+
+    for (var p in obj) {
+      if (Object.prototype.hasOwnProperty.call(obj, p)) {
+        val = obj[p];
+
+        // This keeps valid falsy values like false and 0
+        // It's duplicated in the array block below. Could
+        // put it in a function but don't want the overhead
+        isValid = !( val === null || val === undefined ||
+                    (typeof val === 'number' && isNaN(val)) );
+
+        key = opts.snakeize ? string.snakeize(p) : p;
+        if (isValid) {
+          // Multiple vals -- array
+          if (_isArray(val) && val.length) {
+            itemArray = [];
+            for (var i = 0, ii = val.length; i < ii; i++) {
+              arrVal = val[i];
+              // This keeps valid falsy values like false and 0
+              isValid = !( arrVal === null || arrVal === undefined ||
+                           (typeof arrVal === 'number' && isNaN(arrVal)) );
+
+              // for index mode, which works recursive
+              // objects and array must not be encoded
+              if (opts.index && typeof arrVal === 'object') {
+                itemArray[i] = arrVal;
+              }
+              else {
+                itemArray[i] = isValid ? encodeURIComponent(arrVal) : '';
+
+                if (opts.escapeVals) {
+                  itemArray[i] = string.escapeXML(itemArray[i]);
+                }
+              }
+            }
+            // Consolidation mode -- single value joined on comma
+            if (opts.consolidate) {
+              arr.push(getParamName(key) + '=' + itemArray.join(','));
+            }
+            // Indexed mode -- multiple, same-named params with numeric indices
+            else if (opts.index) {
+              // {foo: [1, 2, 3]} => 'foo[0]=1&foo[1]=2&foo[2]=3'
+
+              itemArray.forEach(function(item, i) {
+                // recursion of arrays
+                if (_isArray(item) && item.length) {
+                  _opts = mixin(opts, {});
+                  item.forEach(function(_item, ii) {
+
+                    if (typeof _item === 'object') {
+                      _opts.prefix = getParamName(key) + '[' + i + '][' + ii + ']';
+                      arr.push(self.paramify(_item, _opts));
+                    }
+                    else {
+                      arr.push(getParamName(key) + '[' + i + '][' + ii + ']=' + _item);
+                    }
+                  });
+                }
+                // recursion of object in array
+                else if (typeof item === 'object') {
+                  _opts = mixin(opts, {});
+                  _opts.prefix = getParamName(key) + '[' + i + ']';
+                  arr.push(self.paramify(item, _opts));
+                }
+                // primitive
+                else {
+                  arr.push(getParamName(key) + '[' + i + ']=' + item);
+                }
+              });
+            }
+            // Normal mode -- multiple, same-named params with each val
+            else {
+              // {foo: [1, 2, 3]} => 'foo=1&foo=2&foo=3'
+              // Add into results array, as this just ends up getting
+              // joined on ampersand at the end anyhow
+              arr.push(getParamName(key) + '=' + itemArray.join('&' + getParamName(key) + '='));
+            }
+          }
+          // Object -- recursion
+          else if (typeof val === 'object') {
+            _opts = mixin(opts, {});
+            _opts.prefix = getParamName(key);
+
+            arr.push(this.paramify(val, _opts));
+          }
+          // Single val -- string
+          else {
+            if (opts.escapeVals) {
+              val = string.escapeXML(val);
+            }
+            arr.push(getParamName(key) + '=' + encodeURIComponent(val));
+          }
+          str += '&';
+        }
+        else {
+          if (opts.includeEmpty) { arr.push(getParamName(key) + '='); }
+        }
+      }
+    }
+    return arr.join('&');
+  };
+
+  /**
+    @name uri#objectify
+    @public
+    @function
+    @return {Object} JavaScript key/val object with the values from the querystring
+    @description Convert the values in a query string (key=val&key=val) to an Object
+    @param {String} str The querystring to convert to an object
+    @param {Object} o The options to use for formatting
+      @param {Boolean} [o.consolidate=true] Convert multiple instances of the same
+        key into an array of values instead of overwriting
+  */
+  this.objectify = function (str, o) {
+    var opts = o || {};
+    var d = {};
+    var consolidate = typeof opts.consolidate == 'undefined' ?
+        true : opts.consolidate;
+    if (str) {
+      var arr = str.split('&');
+      for (var i = 0; i < arr.length; i++) {
+        var pair = arr[i].split('=');
+        var name = pair[0];
+        var val = decodeURIComponent(pair[1] || '');
+        // "We've already got one!" -- arrayize if the flag
+        // is set
+        if (typeof d[name] != 'undefined' && consolidate) {
+          if (typeof d[name] == 'string') {
+            d[name] = [d[name]];
+          }
+          d[name].push(val);
+        }
+        // Otherwise just set the value
+        else {
+          d[name] = val;
+        }
+      }
+    }
+    return d;
+  };
+
+})();
+
+module.exports = uri;
+

+ 282 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/utilities/lib/xml.js

@@ -0,0 +1,282 @@
+/*
+ * Utilities: A classic collection of JavaScript utilities
+ * Copyright 2112 Matthew Eernisse ([email protected])
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+var core = require('./core')
+  , inflection = require('./inflection')
+
+/**
+  @name xml
+  @namespace xml
+*/
+
+exports.XML = new (function () {
+
+  // Default indention level
+  var indentLevel = 4
+    , tagFromType
+    , obj2xml;
+
+  tagFromType = function (item, prev) {
+    var ret
+      , type
+      , types;
+
+    if (item instanceof Array) {
+      ret = 'array';
+    } else {
+      types = ['string', 'number', 'boolean', 'object'];
+      for (var i = 0, ii = types.length; i < ii; i++) {
+        type = types[i];
+        if (typeof item == type) {
+          ret = type;
+        }
+      }
+    }
+
+    if (prev && ret != prev) {
+      return 'record'
+    } else {
+      return ret;
+    }
+  };
+
+  obj2xml = function (o, opts) {
+    var name = opts.name
+      , level = opts.level
+      , arrayRoot = opts.arrayRoot
+      , pack
+      , item
+      , n
+      , currentIndent = (new Array(level * indentLevel)).join(' ')
+      , nextIndent = (new Array((level + 1) * indentLevel)).join(' ')
+      , xml = '';
+
+    switch (typeof o) {
+      case 'string':
+      case 'number':
+      case 'boolean':
+        xml = o.toString();
+        break;
+      case 'object':
+        // Arrays
+        if (o instanceof Array) {
+
+          // Pack the processed version of each item into an array that
+          // can be turned into a tag-list with a `join` method below
+          // As the list gets iterated, if all items are the same type,
+          // that's the tag-name for the individual tags. If the items are
+          // a mixed, the tag-name is 'record'
+          pack = [];
+          for (var i = 0, ii = o.length; i < ii; i++) {
+            item = o[i];
+            if (!name) {
+              // Pass any previous tag-name, so it's possible to know if
+              // all items are the same type, or it's mixed types
+              n = tagFromType(item, n);
+            }
+            pack.push(obj2xml(item, {
+              name: name
+            , level: level + 1
+            , arrayRoot: arrayRoot
+            }));
+          }
+
+          // If this thing is attached to a named property on an object,
+          // use the name for the containing tag-name
+          if (name) {
+            n = name;
+          }
+
+          // If this is a top-level item, wrap in a top-level containing tag
+          if (level == 0) {
+            xml += currentIndent + '<' + inflection.pluralize(n) + ' type="array">\n'
+          }
+          xml += nextIndent + '<' + n + '>' +
+              pack.join('</' + n + '>\n' + nextIndent +
+                  '<' + n + '>') + '</' + n + '>\n';
+
+          // If this is a top-level item, close the top-level containing tag
+          if (level == 0) {
+            xml += currentIndent + '</' + inflection.pluralize(n) + '>';
+          }
+        }
+        // Generic objects
+        else {
+          n = name || 'object';
+
+          // If this is a top-level item, wrap in a top-level containing tag
+          if (level == 0) {
+            xml += currentIndent + '<' + n;
+            // Lookahead hack to allow tags to have attributes
+            for (var p in o) {
+              if (p.indexOf('attr:') == 0) {
+                xml += ' ' + p.replace(/^attr:/, '') + '="' +
+                    o[p] + '"'
+              }
+            }
+            xml += '>\n';
+          }
+          for (var p in o) {
+            item = o[p];
+
+            // Data properties only
+            if (typeof item == 'function') {
+              continue;
+            }
+            // No attr hack properties
+            if (p.indexOf('attr:') == 0) {
+              continue;
+            }
+
+            xml += nextIndent;
+
+            if (p == '#cdata') {
+              xml += '<![CDATA[' + item + ']]>\n';
+            }
+            else {
+
+              // Complex values, going to have items with multiple tags
+              // inside
+              if (typeof item == 'object') {
+                if (item instanceof Array) {
+                  if (arrayRoot) {
+                    xml += '<' + p + ' type="array">\n'
+                  }
+                }
+                else {
+                  xml += '<' + p;
+                  // Lookahead hack to allow tags to have attributes
+                  for (var q in item) {
+                    if (q.indexOf('attr:') == 0) {
+                      xml += ' ' + q.replace(/^attr:/, '') + '="' +
+                          item[q] + '"'
+                    }
+                  }
+                  xml += '>\n';
+                }
+              }
+              // Scalars, just a value and closing tag
+              else {
+                xml += '<' + p + '>'
+              }
+              xml += obj2xml(item, {
+                name: p
+              , level: level + 1
+              , arrayRoot: arrayRoot
+              });
+
+              // Objects and Arrays, need indentation before closing tag
+              if (typeof item == 'object') {
+                if (item instanceof Array) {
+                  if (arrayRoot) {
+                    xml += nextIndent;
+                    xml += '</' + p + '>\n';
+                  }
+                }
+                else {
+                  xml += nextIndent;
+                  xml += '</' + p + '>\n';
+                }
+              }
+              // Scalars, just close
+              else {
+                xml += '</' + p + '>\n';
+              }
+            }
+          }
+          // If this is a top-level item, close the top-level containing tag
+          if (level == 0) {
+            xml += currentIndent + '</' + n + '>\n';
+          }
+        }
+        break;
+      default:
+        // No default
+    }
+    return xml;
+  }
+
+  /*
+   * XML configuration
+   *
+  */
+  this.config = {
+      whitespace: true
+    , name: null
+    , fragment: false
+    , level: 0
+    , arrayRoot: true
+  };
+
+  /**
+    @name xml#setIndentLevel
+    @public
+    @function
+    @return {Number} Return the given `level`
+    @description SetIndentLevel changes the indent level for XML.stringify and returns it
+    @param {Number} level The indent level to use
+  */
+  this.setIndentLevel = function (level) {
+    if(!level) {
+      return;
+    }
+
+    return indentLevel = level;
+  };
+
+  /**
+    @name xml#stringify
+    @public
+    @function
+    @return {String} Return the XML entities of the given `obj`
+    @description Stringify returns an XML representation of the given `obj`
+    @param {Object} obj The object containing the XML entities to use
+    @param {Object} opts
+      @param {Boolean} [opts.whitespace=true] Don't insert indents and newlines after xml entities
+      @param {String} [opts.name=typeof obj] Use custom name as global namespace
+      @param {Boolean} [opts.fragment=false] If true no header fragment is added to the top
+      @param {Number} [opts.level=0] Remove this many levels from the output
+      @param {Boolean} [opts.arrayRoot=true]
+  */
+  this.stringify = function (obj, opts) {
+    var config = core.mixin({}, this.config)
+      , xml = '';
+    core.mixin(config, (opts || {}));
+
+    if (!config.whitespace) {
+      indentLevel = 0;
+    }
+
+    if (!config.fragment) {
+      xml += '<?xml version="1.0" encoding="UTF-8"?>\n';
+    }
+
+    xml += obj2xml(obj, {
+      name: config.name
+    , level: config.level
+    , arrayRoot: config.arrayRoot
+    });
+
+    if (!config.whitespace) {
+      xml = xml.replace(/>\n/g, '>');
+    }
+
+    return xml;
+  };
+
+})();
+

+ 55 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/utilities/package.json

@@ -0,0 +1,55 @@
+{
+  "name": "utilities",
+  "description": "A classic collection of JavaScript utilities",
+  "keywords": [
+    "utilities",
+    "utils",
+    "jake",
+    "geddy"
+  ],
+  "version": "0.0.37",
+  "author": {
+    "name": "Matthew Eernisse",
+    "email": "[email protected]",
+    "url": "http://fleegix.org"
+  },
+  "main": "./lib/index.js",
+  "scripts": {
+    "test": "jake test"
+  },
+  "repository": {
+    "type": "git",
+    "url": "git://github.com/mde/utilities.git"
+  },
+  "devDependencies": {
+    "jake": "latest"
+  },
+  "engines": {
+    "node": "*"
+  },
+  "bugs": {
+    "url": "https://github.com/mde/utilities/issues"
+  },
+  "homepage": "https://github.com/mde/utilities",
+  "_id": "[email protected]",
+  "_shasum": "a3470d0a7f688142d9e8a57cee1128f12e19e196",
+  "_resolved": "https://registry.npmjs.org/utilities/-/utilities-0.0.37.tgz",
+  "_from": "[email protected]",
+  "_npmVersion": "1.4.9",
+  "_npmUser": {
+    "name": "mde",
+    "email": "[email protected]"
+  },
+  "maintainers": [
+    {
+      "name": "mde",
+      "email": "[email protected]"
+    }
+  ],
+  "dist": {
+    "shasum": "a3470d0a7f688142d9e8a57cee1128f12e19e196",
+    "tarball": "http://registry.npmjs.org/utilities/-/utilities-0.0.37.tgz"
+  },
+  "directories": {},
+  "readme": "ERROR: No README data found!"
+}

+ 71 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/utilities/test/array.js

@@ -0,0 +1,71 @@
+/*
+ * Utilities: A classic collection of JavaScript utilities
+ * Copyright 2112 Matthew Eernisse ([email protected])
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+
+var assert = require('assert')
+  , array = require('../lib/array')
+  , tests;
+
+tests = {
+
+  'test basic humanize for array': function () {
+    var actual = array.humanize(["array", "array", "array"])
+      , expected = "array, array and array";
+    assert.equal(expected, actual);
+  }
+
+, 'test humanize with two items for array': function () {
+    var actual = array.humanize(["array", "array"])
+      , expected = "array and array";
+    assert.equal(expected, actual);
+  }
+
+, 'test humanize with a single item for array': function () {
+    var actual = array.humanize(["array"])
+      , expected = "array";
+    assert.equal(expected, actual);
+  }
+
+, 'test humanize with no items for array': function () {
+    var actual = array.humanize([])
+      , expected = "";
+    assert.equal(expected, actual);
+  }
+
+, 'test basic include for array': function () {
+    var test = ["array"]
+      , actual = array.include(test, "array");
+    assert.equal(true, actual);
+  }
+
+, 'test false include for array': function () {
+    var test = ["array"]
+      , actual = array.include(test, 'nope');
+    assert.equal(false, actual);
+  }
+
+, 'test false boolean include for array': function () {
+    var test = ["array", false]
+      , actual = array.include(test, false);
+    assert.equal(true, actual);
+  }
+
+};
+
+module.exports = tests;
+
+

+ 97 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/utilities/test/core.js

@@ -0,0 +1,97 @@
+/*
+ * Utilities: A classic collection of JavaScript utilities
+ * Copyright 2112 Matthew Eernisse ([email protected])
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+
+var assert = require('assert')
+  , core = require('../lib/core')
+  , tests;
+
+tests = {
+
+  'simple mixin for core': function () {
+    var expected = {secret: 'asdf', geddy: 'geddyKey'}
+      , result = core.mixin({secret: 'asdf'}, {geddy: 'geddyKey'});
+    assert.deepEqual(expected, result);
+  }
+
+, 'mixin with overiding key for core': function () {
+    var expected = {secret: 'geddySecret', geddy: 'geddyKey'}
+      , result = core.mixin({secret: 'asdf'}, {geddy: 'geddyKey', secret: 'geddySecret'});
+    assert.deepEqual(expected, result);
+  }
+
+, 'simple enhance for core': function () {
+    var expected = {secret: 'asdf', geddy: 'geddyKey'}
+      , result = core.enhance({secret: 'asdf'}, {geddy: 'geddyKey'});
+    assert.deepEqual(expected, result);
+  }
+
+, 'enhance with overiding key for core': function () {
+    var expected = {secret: 'geddySecret', geddy: 'geddyKey'}
+      , result = core.enhance({secret: 'asdf'}, {geddy: 'geddyKey', secret: 'geddySecret'});
+    assert.deepEqual(expected, result);
+  }
+
+, 'isEmpty, empty string (true)': function () {
+    assert.ok(core.isEmpty(''));
+  }
+
+, 'isEmpty, null (true)': function () {
+    assert.ok(core.isEmpty(null));
+  }
+
+, 'isEmpty, undefined (true)': function () {
+    assert.ok(core.isEmpty(null));
+  }
+
+, 'isEmpty, NaN (true)': function () {
+    assert.ok(core.isEmpty(NaN));
+  }
+
+, 'isEmpty, invalid Date (true)': function () {
+    assert.ok(core.isEmpty(new Date(NaN)));
+  }
+
+, 'isEmpty, zero (false)': function () {
+    assert.ok(!core.isEmpty(0));
+  }
+,
+  'bind': function () {
+    function bar() {}
+
+    function foo() {
+      assert.equal(this.name, 'bar');
+    }
+
+    var fooBoundToBar = core.bind(bar, foo);
+    fooBoundToBar();
+  }
+,
+  'bind, arguments': function () {
+    function bar() {}
+
+    function foo(arg) {
+      assert.equal(this.name, 'bar');
+      assert.equal(arg, 'cats');
+    }
+
+    var fooBoundToBarWithCats = core.bind(bar, foo, 'cats');
+    fooBoundToBarWithCats();
+  }
+};
+
+module.exports = tests;

+ 84 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/utilities/test/date.js

@@ -0,0 +1,84 @@
+/*
+ * Utilities: A classic collection of JavaScript utilities
+ * Copyright 2112 Matthew Eernisse ([email protected])
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+var date = require('../lib/date')
+  , assert = require('assert')
+  , tests = {}
+  , _date = new Date();
+
+tests = {
+
+  'test strftime for date': function () {
+    var data = date.strftime(_date, "%w")
+      , actual = _date.getDay();
+    assert.equal(actual, data);
+  }
+
+, 'test calcCentury using current year for date': function () {
+    var data = date.calcCentury()
+      , actual = '21';
+    assert.equal(actual, data);
+  }
+
+, 'test calcCentury using 20th century year for date': function () {
+    var data = date.calcCentury(2000)
+      , actual = '20';
+    assert.equal(actual, data);
+  }
+
+, 'test calcCentury using 1st century year for date': function () {
+    var data = date.calcCentury(10)
+      , actual = '1';
+    assert.equal(actual, data);
+  }
+
+, 'test getMeridiem for date': function () {
+    var data = date.getMeridiem(_date.getHours())
+      , actual = (_date.getHours() > 11) ? 'PM' : 'AM';
+    assert.equal(actual, data);
+  }
+
+, 'test parse UTC': function () {
+    var dt = date.parse('1970-01-01T00:00:00Z');
+    assert.equal(0, dt.getTime());
+  }
+
+, 'test parse with offset basic': function () {
+    var dt;
+    dt = date.parse('1970-01-01T00:00:00-0100');
+    assert.equal(3600000, dt.getTime());
+    dt = date.parse('1970-01-01T00:00:00+0100');
+    assert.equal(-3600000, dt.getTime());
+  }
+
+, 'test parse with offset extended': function () {
+    var dt;
+    dt = date.parse('1970-01-01T00:00:00-01:00');
+    assert.equal(3600000, dt.getTime());
+    dt = date.parse('1970-01-01T00:00:00+01:00');
+    assert.equal(-3600000, dt.getTime());
+  }
+
+, 'test parse floating (i.e., local offset)': function () {
+    var dt;
+    dt = date.parse('1970-01-01T00:00:00');
+    assert.equal(dt.getTime() / 1000 / 60, dt.getTimezoneOffset());
+  }
+
+};
+
+module.exports = tests;

+ 45 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/utilities/test/event_buffer.js

@@ -0,0 +1,45 @@
+/*
+ * Utilities: A classic collection of JavaScript utilities
+ * Copyright 2112 Matthew Eernisse ([email protected])
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+
+var Stream = require('stream').Stream
+  , EventEmitter = require('events').EventEmitter
+  , EventBuffer = require('../lib/event_buffer.js').EventBuffer
+  , assert = require('assert')
+  , tests;
+
+tests = {
+
+  'test basic event buffer functionality': function () {
+    var source = new Stream()
+      , dest = new EventEmitter()
+      , buff = new EventBuffer(source)
+      , data = '';
+    dest.on('data', function (d) { data += d; });
+    source.writeable = true;
+    source.readable = true;
+    source.emit('data', 'abcdef');
+    source.emit('data', '123456');
+    buff.sync(dest);
+    assert.equal('abcdef123456', data);
+    source.emit('data', '---');
+    assert.equal('abcdef123456---', data);
+  }
+
+};
+
+module.exports = tests;

+ 228 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/utilities/test/file.js

@@ -0,0 +1,228 @@
+/*
+ * Utilities: A classic collection of JavaScript utilities
+ * Copyright 2112 Matthew Eernisse ([email protected])
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+
+var assert = require('assert')
+  , fs = require('fs')
+  , path = require('path')
+  , file = require('../lib/file')
+  , existsSync = fs.existsSync || path.existsSync
+  , tests;
+
+tests = {
+
+  'before': function () {
+    process.chdir('./test');
+  }
+
+, 'after': function () {
+    process.chdir('../');
+  }
+
+, 'test mkdirP': function () {
+    var expected = [
+          ['foo']
+        , ['foo', 'bar']
+        , ['foo', 'bar', 'baz']
+        , ['foo', 'bar', 'baz', 'qux']
+        ]
+      , res;
+    file.mkdirP('foo/bar/baz/qux');
+    res = file.readdirR('foo');
+    for (var i = 0, ii = res.length; i < ii; i++) {
+      assert.equal(path.join.apply(path, expected[i]), res[i]);
+    }
+    file.rmRf('foo', {silent: true});
+  }
+
+, 'test rmRf': function () {
+    file.mkdirP('foo/bar/baz/qux', {silent: true});
+    file.rmRf('foo/bar', {silent: true});
+    res = file.readdirR('foo');
+    assert.equal(1, res.length);
+    assert.equal('foo', res[0]);
+    fs.rmdirSync('foo');
+  }
+  
+, 'test cpR with same name and different directory': function () {
+      file.mkdirP('foo', {silent: true});
+      fs.writeFileSync('foo/bar.txt', 'w00t');
+      file.cpR('foo', 'bar', {silent: true});
+      assert.ok(existsSync('bar/bar.txt'));
+      file.rmRf('foo', {silent: true});
+      file.rmRf('bar', {silent: true});
+      
+  }
+
+, 'test cpR with same to and from will throw': function () {
+    assert.throws(function () {
+      file.cpR('foo.txt', 'foo.txt', {silent: true});
+    });
+  }
+
+, 'test cpR rename via copy in directory': function () {
+    file.mkdirP('foo', {silent: true});
+    fs.writeFileSync('foo/bar.txt', 'w00t');
+    file.cpR('foo/bar.txt', 'foo/baz.txt', {silent: true});
+    assert.ok(existsSync('foo/baz.txt'));
+    file.rmRf('foo', {silent: true});
+  }
+
+, 'test cpR rename via copy in base': function () {
+    fs.writeFileSync('bar.txt', 'w00t');
+    file.cpR('bar.txt', 'baz.txt', {silent: true});
+    assert.ok(existsSync('baz.txt'));
+    file.rmRf('bar.txt', {silent: true});
+    file.rmRf('baz.txt', {silent: true});
+  }
+
+, 'test readdirR': function () {
+    var expected = [
+          ['foo']
+        , ['foo', 'bar']
+        , ['foo', 'bar', 'baz']
+        , ['foo', 'bar', 'baz', 'qux']
+        ]
+      , res;
+
+    file.mkdirP('foo/bar/baz/qux', {silent: true});
+    res = file.readdirR('foo');
+
+    for (var i = 0, ii = res.length; i < ii; i++) {
+      assert.equal(path.join.apply(path, expected[i]), res[i]);
+    }
+    file.rmRf('foo', {silent: true});
+  }
+
+, 'test isAbsolute with Unix absolute path': function () {
+    var p = '/foo/bar/baz';
+    assert.equal('/', file.isAbsolute(p));
+  }
+
+, 'test isAbsolute with Unix relative path': function () {
+    var p = 'foo/bar/baz';
+    assert.equal(false, file.isAbsolute(p));
+  }
+
+, 'test isAbsolute with Win absolute path': function () {
+    var p = 'C:\\foo\\bar\\baz';
+    assert.equal('C:\\', file.isAbsolute(p));
+  }
+
+, 'test isAbsolute with Win relative path': function () {
+    var p = 'foo\\bar\\baz';
+    assert.equal(false, file.isAbsolute(p));
+  }
+
+, 'test absolutize with Unix absolute path': function () {
+    var expected = '/foo/bar/baz'
+      , actual = file.absolutize('/foo/bar/baz');
+    assert.equal(expected, actual);
+  }
+
+, 'test absolutize with Win absolute path': function () {
+    var expected = 'C:\\foo\\bar\\baz'
+      , actual = file.absolutize('C:\\foo\\bar\\baz');
+    assert.equal(expected, actual);
+  }
+
+, 'test absolutize with relative path': function () {
+    var expected = process.cwd()
+      , actual = '';
+
+    // We can't just create two different tests here
+    // because file.absolutize uses process.cwd()
+    // to get absolute path which is platform
+    // specific
+    if (process.platform === 'win32') {
+      expected += '\\foo\\bar\\baz'
+      actual = file.absolutize('foo\\bar\\baz')
+    }
+    else {
+      expected += '/foo/bar/baz'
+      actual = file.absolutize('foo/bar/baz');
+    }
+
+    assert.equal(expected, actual);
+  }
+
+, 'test basedir with Unix absolute path': function () {
+    var p = '/foo/bar/baz';
+    assert.equal('/foo/bar', file.basedir(p));
+  }
+
+, 'test basedir with Win absolute path': function () {
+    var p = 'C:\\foo\\bar\\baz';
+    assert.equal('C:\\foo\\bar', file.basedir(p));
+  }
+
+, 'test basedir with Unix root path': function () {
+    var p = '/';
+    assert.equal('/', file.basedir(p));
+  }
+
+, 'test basedir with Unix absolute path and double-asterisk': function () {
+    var p = '/**/foo/bar/baz';
+    assert.equal('/', file.basedir(p));
+  }
+
+, 'test basedir with leading double-asterisk': function () {
+    var p = '**/foo';
+    assert.equal('.', file.basedir(p));
+  }
+
+, 'test basedir with leading asterisk': function () {
+    var p = '*.js';
+    assert.equal('.', file.basedir(p));
+  }
+
+, 'test basedir with leading dot-slash and double-asterisk': function () {
+    var p = './**/foo';
+    assert.equal('.', file.basedir(p));
+  }
+
+, 'test basedir with leading dirname and double-asterisk': function () {
+    var p = 'a/**/*.js';
+    assert.equal('a', file.basedir(p));
+  }
+
+, 'test basedir with leading dot-dot-slash and double-asterisk': function () {
+    var p = '../../test/**/*.js';
+    assert.equal('../../test', file.basedir(p));
+  }
+
+, 'test basedir with single-asterisk in dirname': function () {
+    var p = 'a/test*/file';
+    assert.equal('a', file.basedir(p));
+  }
+
+, 'test basedir with single filename': function () {
+    var p = 'filename';
+    assert.equal('.', file.basedir(p));
+  }
+
+, 'test basedir with empty path': function () {
+    var p = '';
+    assert.equal('.', file.basedir(p));
+    assert.equal('.', file.basedir());
+  }
+
+};
+
+module.exports = tests;
+
+

+ 60 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/utilities/test/i18n.js

@@ -0,0 +1,60 @@
+/*
+ * Utilities: A classic collection of JavaScript utilities
+ * Copyright 2112 Matthew Eernisse ([email protected])
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+
+var i18n = require('../lib/i18n')
+  , assert = require('assert')
+  , tests
+  , inst = {};
+
+tests = {
+
+  'before': function () {
+    i18n.loadLocale('en-us', {foo: 'FOO', bar: 'BAR', baz: 'BAZ'});
+    i18n.loadLocale('ja-jp', {foo: 'フー', bar: 'バー'});
+    inst.en = new i18n.I18n('en-us');
+    inst.jp = new i18n.I18n('ja-jp');
+    inst.de = new i18n.I18n('de-de');
+  }
+
+, 'test default-locale fallback, defined strings': function () {
+    var expected = 'BAZ'
+      , actual = inst.jp.t('baz');
+    assert.equal(expected, actual);
+  }
+
+, 'test default-locale fallback, no defined strings': function () {
+    var expected = 'BAZ'
+      , actual = inst.de.t('baz');
+    assert.equal(expected, actual);
+  }
+
+, 'test key lookup, default-locale': function () {
+    var expected = 'FOO'
+      , actual = inst.en.t('foo');
+    assert.equal(expected, actual);
+  }
+
+, 'test key lookup, non-default-locale': function () {
+    var expected = 'フー'
+      , actual = inst.jp.t('foo');
+    assert.equal(expected, actual);
+  }
+
+};
+
+module.exports = tests;

+ 388 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/utilities/test/inflection.js

@@ -0,0 +1,388 @@
+/*
+ * Utilities: A classic collection of JavaScript utilities
+ * Copyright 2112 Matthew Eernisse ([email protected])
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+
+var inflection = require('../lib/inflection')
+  , assert = require('assert')
+  , esInflections
+  , sInflections
+  , iesInflections
+  , vesInflections
+  , icesInflections
+  , renInflections
+  , oesInflections
+  , iInflections
+  , genInflections
+  , irregularInflections
+  , noInflections
+  , tests;
+
+/**
+ * Most test inflections are from Ruby on Rails:
+ *   https://github.com/rails/rails/blob/master/activesupport/test/inflector_test_cases.rb
+ *
+ * Ruby on Rails is MIT licensed: http://www.opensource.org/licenses/MIT
+*/
+esInflections = [
+    ["search", "searches"]
+  , ["switch", "switches"]
+  , ["fix", "fixes"]
+  , ["box", "boxes"]
+  , ["process", "processes"]
+  , ["address", "addresses"]
+  , ["wish", "wishes"]
+  , ["status", "statuses"]
+  , ["alias", "aliases"]
+  , ["basis", "bases"]
+  , ["diagnosis", "diagnoses"]
+  , ["bus", "buses"]
+];
+
+sInflections = [
+    ["stack", "stacks"]
+  , ["shoe", "shoes"]
+  , ["status_code", "status_codes"]
+  , ["case", "cases"]
+  , ["edge", "edges"]
+  , ["archive", "archives"]
+  , ["experience", "experiences"]
+  , ["day", "days"]
+  , ["comment", "comments"]
+  , ["foobar", "foobars"]
+  , ["newsletter", "newsletters"]
+  , ["old_news", "old_news"]
+  , ["perspective", "perspectives"]
+  , ["diagnosis_a", "diagnosis_as"]
+  , ["horse", "horses"]
+  , ["prize", "prizes"]
+];
+
+iesInflections = [
+    ["category", "categories"]
+  , ["query", "queries"]
+  , ["ability", "abilities"]
+  , ["agency", "agencies"]
+];
+
+vesInflections = [
+    ["wife", "wives"]
+  , ["safe", "saves"]
+  , ["half", "halves"]
+  , ["elf", "elves"]
+  , ["dwarf", "dwarves"]
+];
+
+icesInflections = [
+    ["index", "indices"]
+  , ["vertex", "vertices"]
+  , ["matrix", "matrices"]
+];
+
+renInflections = [
+    ["node_child", "node_children"]
+  , ["child", "children"]
+];
+
+oesInflections = [
+    ["buffalo", "buffaloes"]
+  , ["tomato", "tomatoes"]
+];
+
+iInflections = [
+    ["octopus", "octopi"]
+  , ["virus", "viri"]
+];
+
+genInflections = [
+    ["salesperson", "salespeople"]
+  , ["person", "people"]
+  , ["spokesman", "spokesmen"]
+  , ["man", "men"]
+  , ["woman", "women"]
+];
+
+irregularInflections = [
+    ["datum", "data"]
+  , ["medium", "media"]
+  , ["ox", "oxen"]
+  , ["cow", "kine"]
+  , ["mouse", "mice"]
+  , ["louse", "lice"]
+  , ["axis", "axes"]
+  , ["testis", "testes"]
+  , ["crisis", "crises"]
+  , ["analysis", "analyses"]
+  , ["quiz", "quizzes"]
+];
+
+noInflections = [
+    ["fish", "fish"]
+  , ["news", "news"]
+  , ["series", "series"]
+  , ["species", "species"]
+  , ["rice", "rice"]
+  , ["information", "information"]
+  , ["equipment", "equipment"]
+];
+
+tests = {
+
+  'test es plural words for inflection': function () {
+    var i = esInflections.length
+      , value;
+
+    while (--i >= 0) {
+      value = esInflections[i];
+
+      assert.equal(value[1], inflection.pluralize(value[0]))
+    }
+  }
+
+, 'test es singular words for inflection': function () {
+    var i = esInflections.length
+      , value;
+
+    while (--i >= 0) {
+      value = esInflections[i];
+
+      assert.equal(value[0], inflection.singularize(value[1]))
+    }
+  }
+
+, 'test s plural words for inflection': function () {
+    var i = sInflections.length
+      , value;
+
+    while (--i >= 0) {
+      value = sInflections[i];
+
+      assert.equal(value[1], inflection.pluralize(value[0]))
+    }
+  }
+
+, 'test s singular words for inflection': function () {
+    var i = sInflections.length
+      , value;
+
+    while (--i >= 0) {
+      value = sInflections[i];
+
+      assert.equal(value[0], inflection.singularize(value[1]))
+    }
+  }
+
+, 'test ies plural words for inflection': function () {
+    var i = iesInflections.length
+      , value;
+
+    while (--i >= 0) {
+      value = iesInflections[i];
+
+      assert.equal(value[1], inflection.pluralize(value[0]))
+    }
+  }
+
+, 'test ies singular words for inflection': function () {
+    var i = iesInflections.length
+      , value;
+
+    while (--i >= 0) {
+      value = iesInflections[i];
+
+      assert.equal(value[0], inflection.singularize(value[1]))
+    }
+  }
+
+, 'test ves plural words for inflection': function () {
+    var i = vesInflections.length
+      , value;
+
+    while (--i >= 0) {
+      value = vesInflections[i];
+
+      assert.equal(value[1], inflection.pluralize(value[0]))
+    }
+  }
+
+, 'test ves singular words for inflection': function () {
+    var i = vesInflections.length
+      , value;
+
+    while (--i >= 0) {
+      value = vesInflections[i];
+
+      assert.equal(value[0], inflection.singularize(value[1]))
+    }
+  }
+
+, 'test ices plural words for inflection': function () {
+    var i = icesInflections.length
+      , value;
+
+    while (--i >= 0) {
+      value = icesInflections[i];
+
+      assert.equal(value[1], inflection.pluralize(value[0]))
+    }
+  }
+
+, 'test ices singular words for inflection': function () {
+    var i = icesInflections.length
+      , value;
+
+    while (--i >= 0) {
+      value = icesInflections[i];
+
+      assert.equal(value[0], inflection.singularize(value[1]))
+    }
+  }
+
+, 'test ren plural words for inflection': function () {
+    var i = renInflections.length
+      , value;
+
+    while (--i >= 0) {
+      value = renInflections[i];
+
+      assert.equal(value[1], inflection.pluralize(value[0]))
+    }
+  }
+
+, 'test ren singular words for inflection': function () {
+    var i = renInflections.length
+      , value;
+
+    while (--i >= 0) {
+      value = renInflections[i];
+
+      assert.equal(value[0], inflection.singularize(value[1]))
+    }
+  }
+
+, 'test oes plural words for inflection': function () {
+    var i = oesInflections.length
+      , value;
+
+    while (--i >= 0) {
+      value = oesInflections[i];
+
+      assert.equal(value[1], inflection.pluralize(value[0]))
+    }
+  }
+
+, 'test oes singular words for inflection': function () {
+    var i = oesInflections.length
+      , value;
+
+    while (--i >= 0) {
+      value = oesInflections[i];
+
+      assert.equal(value[0], inflection.singularize(value[1]))
+    }
+  }
+
+, 'test i plural words for inflection': function () {
+    var i = iInflections.length
+      , value;
+
+    while (--i >= 0) {
+      value = iInflections[i];
+
+      assert.equal(value[1], inflection.pluralize(value[0]))
+    }
+  }
+
+, 'test i singular words for inflection': function () {
+    var i = iInflections.length
+      , value;
+
+    while (--i >= 0) {
+      value = iInflections[i];
+
+      assert.equal(value[0], inflection.singularize(value[1]))
+    }
+  }
+
+, 'test gender and people plural words for inflection': function () {
+    var i = genInflections.length
+      , value;
+
+    while (--i >= 0) {
+      value = genInflections[i];
+
+      assert.equal(value[1], inflection.pluralize(value[0]))
+    }
+  }
+
+, 'test gender and people singular words for inflection': function () {
+    var i = genInflections.length
+      , value;
+
+    while (--i >= 0) {
+      value = genInflections[i];
+
+      assert.equal(value[0], inflection.singularize(value[1]))
+    }
+  }
+
+, 'test irregular plural words for inflection': function () {
+    var i = irregularInflections.length
+      , value;
+
+    while (--i >= 0) {
+      value = irregularInflections[i];
+
+      assert.equal(value[1], inflection.pluralize(value[0]))
+    }
+  }
+
+, 'test irregular singular words for inflection': function () {
+    var i = irregularInflections.length
+      , value;
+
+    while (--i >= 0) {
+      value = irregularInflections[i];
+
+      assert.equal(value[0], inflection.singularize(value[1]))
+    }
+  }
+
+, 'test no change plural words for inflection': function () {
+    var i = noInflections.length
+      , value;
+
+    while (--i >= 0) {
+      value = noInflections[i];
+
+      assert.equal(value[1], inflection.pluralize(value[0]))
+    }
+  }
+
+, 'test no change singular words for inflection': function () {
+    var i = noInflections.length
+      , value;
+
+    while (--i >= 0) {
+      value = noInflections[i];
+
+      assert.equal(value[0], inflection.singularize(value[1]))
+    }
+  }
+
+};
+
+module.exports = tests;

+ 68 - 0
Build/node_modules/jake/node_modules/filelist/node_modules/utilities/test/logging.js

@@ -0,0 +1,68 @@
+/*
+ * Utilities: A classic collection of JavaScript utilities
+ * Copyright 2112 Matthew Eernisse ([email protected])
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+
+var assert = require('assert')
+  , logger = require('../lib/log')
+  , tests;
+  
+tests = {
+      
+    'test basic logging': function () {
+        var oldLog = console.log;
+        
+        console.log = function (str) {
+                assert.equal(str, "basic log");
+        };
+        logger.log("basic log");
+        
+        console.log = oldLog;
+    }
+,   'test info logging': function () {
+        var oldinfoLog = console.info;
+
+        console.info = function (str) {
+                assert.equal(str, "info log");
+        };
+        logger.info("info log");
+    
+        console.info = oldinfoLog;
+    }
+,   'test warning logging': function () {
+        var oldwarnLog = console.warn;
+
+        console.warn = function (str) {
+                assert.equal(str, "warn log");
+        };
+        logger.warn("warn log");
+
+        console.warn = oldwarnLog;
+    }    
+,   'test error logging': function () {
+        var oldErrorLog = console.error;
+    
+        console.error = function (str) {
+                assert.equal(str, "error log");
+        };
+        logger.error("error log");
+        
+        console.error = oldErrorLog;
+    }
+}
+
+
+module.exports = tests;

Some files were not shown because too many files changed in this diff