diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 00000000..6b78fa6c Binary files /dev/null and b/.DS_Store differ diff --git a/images/skymap/nx.jpg b/images/skymap/nx.jpg new file mode 100644 index 00000000..1cae307a Binary files /dev/null and b/images/skymap/nx.jpg differ diff --git a/images/skymap/ny.jpg b/images/skymap/ny.jpg new file mode 100644 index 00000000..fa7a975d Binary files /dev/null and b/images/skymap/ny.jpg differ diff --git a/images/skymap/nz.jpg b/images/skymap/nz.jpg new file mode 100644 index 00000000..1e9c54ef Binary files /dev/null and b/images/skymap/nz.jpg differ diff --git a/images/skymap/px.jpg b/images/skymap/px.jpg new file mode 100644 index 00000000..0ad2eeaf Binary files /dev/null and b/images/skymap/px.jpg differ diff --git a/images/skymap/py.jpg b/images/skymap/py.jpg new file mode 100644 index 00000000..de7e5cca Binary files /dev/null and b/images/skymap/py.jpg differ diff --git a/images/skymap/pz.jpg b/images/skymap/pz.jpg new file mode 100644 index 00000000..836cdb4a Binary files /dev/null and b/images/skymap/pz.jpg differ diff --git a/index.html b/index.html new file mode 100755 index 00000000..5f502ced --- /dev/null +++ b/index.html @@ -0,0 +1,19 @@ + + +
+
+
+
+ Babylon is a JavaScript parser used in Babel. +
+ + + + - The latest ECMAScript version enabled by default (ES2017). + - Comment attachment. + - Support for JSX and Flow. + - Support for experimental language proposals (accepting PRs for anything at least [stage-0](https://github.com/tc39/proposals/blob/master/stage-0-proposals.md)). + +## Credits + +Heavily based on [acorn](https://github.com/marijnh/acorn) and [acorn-jsx](https://github.com/RReverser/acorn-jsx), +thanks to the awesome work of [@RReverser](https://github.com/RReverser) and [@marijnh](https://github.com/marijnh). + +Significant diversions are expected to occur in the future such as streaming, EBNF definitions, sweet.js integration, interspatial parsing and more. + +## API + +### `babylon.parse(code, [options])` + +### `babylon.parseExpression(code, [options])` + +`parse()` parses the provided `code` as an entire ECMAScript program, while +`parseExpression()` tries to parse a single Expression with performance in +mind. When in doubt, use `.parse()`. + +### Options + +- **allowImportExportEverywhere**: By default, `import` and `export` + declarations can only appear at a program's top level. Setting this + option to `true` allows them anywhere where a statement is allowed. + +- **allowReturnOutsideFunction**: By default, a return statement at + the top level raises an error. Set this to `true` to accept such + code. + +- **allowSuperOutsideMethod**: TODO + +- **sourceType**: Indicate the mode the code should be parsed in. Can be + either `"script"` or `"module"`. + +- **sourceFilename**: Correlate output AST nodes with their source filename. Useful when generating code and source maps from the ASTs of multiple input files. + +- **startLine**: By default, the first line of code parsed is treated as line 1. You can provide a line number to alternatively start with. Useful for integration with other source tools. + +- **plugins**: Array containing the plugins that you want to enable. + +- **strictMode**: TODO + +### Output + +Babylon generates AST according to [Babel AST format][]. +It is based on [ESTree spec][] with the following deviations: + +- [Literal][] token is replaced with [StringLiteral][], [NumericLiteral][], [BooleanLiteral][], [NullLiteral][], [RegExpLiteral][] +- [Property][] token is replaced with [ObjectProperty][] and [ObjectMethod][] +- [MethodDefinition][] is replaced with [ClassMethod][] +- [Program][] and [BlockStatement][] contain additional `directives` field with [Directive][] and [DirectiveLiteral][] +- [ClassMethod][], [ObjectProperty][], and [ObjectMethod][] value property's properties in [FunctionExpression][] is coerced/brought into the main method node. + +AST for JSX code is based on [Facebook JSX AST][] with the addition of one node type: + +- `JSXText` + +[Babel AST format]: https://github.com/babel/babylon/blob/master/ast/spec.md +[ESTree spec]: https://github.com/estree/estree + +[Literal]: https://github.com/estree/estree/blob/master/es5.md#literal +[Property]: https://github.com/estree/estree/blob/master/es5.md#property +[MethodDefinition]: https://github.com/estree/estree/blob/master/es2015.md#methoddefinition + +[StringLiteral]: https://github.com/babel/babylon/blob/master/ast/spec.md#stringliteral +[NumericLiteral]: https://github.com/babel/babylon/blob/master/ast/spec.md#numericliteral +[BooleanLiteral]: https://github.com/babel/babylon/blob/master/ast/spec.md#booleanliteral +[NullLiteral]: https://github.com/babel/babylon/blob/master/ast/spec.md#nullliteral +[RegExpLiteral]: https://github.com/babel/babylon/blob/master/ast/spec.md#regexpliteral +[ObjectProperty]: https://github.com/babel/babylon/blob/master/ast/spec.md#objectproperty +[ObjectMethod]: https://github.com/babel/babylon/blob/master/ast/spec.md#objectmethod +[ClassMethod]: https://github.com/babel/babylon/blob/master/ast/spec.md#classmethod +[Program]: https://github.com/babel/babylon/blob/master/ast/spec.md#programs +[BlockStatement]: https://github.com/babel/babylon/blob/master/ast/spec.md#blockstatement +[Directive]: https://github.com/babel/babylon/blob/master/ast/spec.md#directive +[DirectiveLiteral]: https://github.com/babel/babylon/blob/master/ast/spec.md#directiveliteral +[FunctionExpression]: https://github.com/babel/babylon/blob/master/ast/spec.md#functionexpression + +[Facebook JSX AST]: https://github.com/facebook/jsx/blob/master/AST.md + +### Semver + +Babylon follows semver in most situations. The only thing to note is that some spec-compliancy bug fixes may be released under patch versions. + +For example: We push a fix to early error on something like [#107](https://github.com/babel/babylon/pull/107) - multiple default exports per file. That would be considered a bug fix even though it would cause a build to fail. + +### Example + +```javascript +require("babylon").parse("code", { + // parse in strict mode and allow module declarations + sourceType: "module", + + plugins: [ + // enable jsx and flow syntax + "jsx", + "flow" + ] +}); +``` + +### Plugins + + - `jsx` + - `flow` + - `doExpressions` + - `objectRestSpread` + - `decorators` (Based on an outdated version of the Decorators proposal. Will be removed in a future version of `Babylon`) + - `classProperties` + - `exportExtensions` + - `asyncGenerators` + - `functionBind` + - `functionSent` + - `dynamicImport` diff --git a/node_modules/babylon/bin/babylon.js b/node_modules/babylon/bin/babylon.js new file mode 100755 index 00000000..449ddfed --- /dev/null +++ b/node_modules/babylon/bin/babylon.js @@ -0,0 +1,16 @@ +#!/usr/bin/env node +/* eslint no-var: 0 */ + +var babylon = require(".."); +var fs = require("fs"); + +var filename = process.argv[2]; +if (!filename) { + console.error("no filename specified"); + process.exit(0); +} + +var file = fs.readFileSync(filename, "utf8"); +var ast = babylon.parse(file); + +console.log(JSON.stringify(ast, null, " ")); diff --git a/node_modules/babylon/bin/generate-identifier-regex.js b/node_modules/babylon/bin/generate-identifier-regex.js new file mode 100644 index 00000000..9b0ae7d6 --- /dev/null +++ b/node_modules/babylon/bin/generate-identifier-regex.js @@ -0,0 +1,62 @@ +"use strict"; + +// Which Unicode version should be used? +const version = "9.0.0"; + +const start = require("unicode-" + version + "/Binary_Property/ID_Start/code-points.js") + .filter(function(ch) { return ch > 0x7f; }); +let last = -1; +const cont = [0x200c, 0x200d].concat( + require("unicode-" + version + "/Binary_Property/ID_Continue/code-points.js") + .filter(function(ch) { + return ch > 0x7f && search(start, ch, last + 1) == -1; + }) + ); + +function search(arr, ch, starting) { + for (let i = starting; arr[i] <= ch && i < arr.length; last = i++) + if (arr[i] === ch) + return i; + return -1; +} + +function pad(str, width) { + while (str.length < width) str = "0" + str; + return str; +} + +function esc(code) { + const hex = code.toString(16); + if (hex.length <= 2) return "\\x" + pad(hex, 2); + else return "\\u" + pad(hex, 4); +} + +function generate(chars) { + const astral = []; + let re = ""; + for (let i = 0, at = 0x10000; i < chars.length; i++) { + const from = chars[i]; + let to = from; + while (i < chars.length - 1 && chars[i + 1] == to + 1) { + i++; + to++; + } + if (to <= 0xffff) { + if (from == to) re += esc(from); + else if (from + 1 == to) re += esc(from) + esc(to); + else re += esc(from) + "-" + esc(to); + } else { + astral.push(from - at, to - from); + at = to; + } + } + return { nonASCII: re, astral: astral }; +} + +const startData = generate(start); +const contData = generate(cont); + +console.log("let nonASCIIidentifierStartChars = \"" + startData.nonASCII + "\";"); +console.log("let nonASCIIidentifierChars = \"" + contData.nonASCII + "\";"); +console.log("const astralIdentifierStartCodes = " + JSON.stringify(startData.astral) + ";"); +console.log("const astralIdentifierCodes = " + JSON.stringify(contData.astral) + ";"); diff --git a/node_modules/babylon/lib/index.js b/node_modules/babylon/lib/index.js new file mode 100644 index 00000000..f64e4b11 --- /dev/null +++ b/node_modules/babylon/lib/index.js @@ -0,0 +1,7096 @@ +'use strict'; + +Object.defineProperty(exports, '__esModule', { value: true }); + +/* eslint max-len: 0 */ + +// This is a trick taken from Esprima. It turns out that, on +// non-Chrome browsers, to check whether a string is in a set, a +// predicate containing a big ugly `switch` statement is faster than +// a regular expression, and on Chrome the two are about on par. +// This function uses `eval` (non-lexical) to produce such a +// predicate from a space-separated string of words. +// +// It starts by sorting the words by length. + +function makePredicate(words) { + words = words.split(" "); + return function (str) { + return words.indexOf(str) >= 0; + }; +} + +// Reserved word lists for various dialects of the language + +var reservedWords = { + 6: makePredicate("enum await"), + strict: makePredicate("implements interface let package private protected public static yield"), + strictBind: makePredicate("eval arguments") +}; + +// And the keywords + +var isKeyword = makePredicate("break case catch continue debugger default do else finally for function if return switch throw try var while with null true false instanceof typeof void delete new in this let const class extends export import yield super"); + +// ## Character categories + +// Big ugly regular expressions that match characters in the +// whitespace, identifier, and identifier-start categories. These +// are only applied when a character is found to actually have a +// code point above 128. +// Generated by `bin/generate-identifier-regex.js`. + +var nonASCIIidentifierStartChars = "\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0-\u08B4\u08B6-\u08BD\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C60\u0C61\u0C80\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D54-\u0D56\u0D5F-\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1C80-\u1C88\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2118-\u211D\u2124\u2126\u2128\u212A-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309B-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FD5\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AE\uA7B0-\uA7B7\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA8FD\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC"; +var nonASCIIidentifierChars = "\u200C\u200D\xB7\u0300-\u036F\u0387\u0483-\u0487\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u0610-\u061A\u064B-\u0669\u0670\u06D6-\u06DC\u06DF-\u06E4\u06E7\u06E8\u06EA-\u06ED\u06F0-\u06F9\u0711\u0730-\u074A\u07A6-\u07B0\u07C0-\u07C9\u07EB-\u07F3\u0816-\u0819\u081B-\u0823\u0825-\u0827\u0829-\u082D\u0859-\u085B\u08D4-\u08E1\u08E3-\u0903\u093A-\u093C\u093E-\u094F\u0951-\u0957\u0962\u0963\u0966-\u096F\u0981-\u0983\u09BC\u09BE-\u09C4\u09C7\u09C8\u09CB-\u09CD\u09D7\u09E2\u09E3\u09E6-\u09EF\u0A01-\u0A03\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A66-\u0A71\u0A75\u0A81-\u0A83\u0ABC\u0ABE-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AE2\u0AE3\u0AE6-\u0AEF\u0B01-\u0B03\u0B3C\u0B3E-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B62\u0B63\u0B66-\u0B6F\u0B82\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD7\u0BE6-\u0BEF\u0C00-\u0C03\u0C3E-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C62\u0C63\u0C66-\u0C6F\u0C81-\u0C83\u0CBC\u0CBE-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CE2\u0CE3\u0CE6-\u0CEF\u0D01-\u0D03\u0D3E-\u0D44\u0D46-\u0D48\u0D4A-\u0D4D\u0D57\u0D62\u0D63\u0D66-\u0D6F\u0D82\u0D83\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DE6-\u0DEF\u0DF2\u0DF3\u0E31\u0E34-\u0E3A\u0E47-\u0E4E\u0E50-\u0E59\u0EB1\u0EB4-\u0EB9\u0EBB\u0EBC\u0EC8-\u0ECD\u0ED0-\u0ED9\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E\u0F3F\u0F71-\u0F84\u0F86\u0F87\u0F8D-\u0F97\u0F99-\u0FBC\u0FC6\u102B-\u103E\u1040-\u1049\u1056-\u1059\u105E-\u1060\u1062-\u1064\u1067-\u106D\u1071-\u1074\u1082-\u108D\u108F-\u109D\u135D-\u135F\u1369-\u1371\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17B4-\u17D3\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u18A9\u1920-\u192B\u1930-\u193B\u1946-\u194F\u19D0-\u19DA\u1A17-\u1A1B\u1A55-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AB0-\u1ABD\u1B00-\u1B04\u1B34-\u1B44\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1B82\u1BA1-\u1BAD\u1BB0-\u1BB9\u1BE6-\u1BF3\u1C24-\u1C37\u1C40-\u1C49\u1C50-\u1C59\u1CD0-\u1CD2\u1CD4-\u1CE8\u1CED\u1CF2-\u1CF4\u1CF8\u1CF9\u1DC0-\u1DF5\u1DFB-\u1DFF\u203F\u2040\u2054\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2CEF-\u2CF1\u2D7F\u2DE0-\u2DFF\u302A-\u302F\u3099\u309A\uA620-\uA629\uA66F\uA674-\uA67D\uA69E\uA69F\uA6F0\uA6F1\uA802\uA806\uA80B\uA823-\uA827\uA880\uA881\uA8B4-\uA8C5\uA8D0-\uA8D9\uA8E0-\uA8F1\uA900-\uA909\uA926-\uA92D\uA947-\uA953\uA980-\uA983\uA9B3-\uA9C0\uA9D0-\uA9D9\uA9E5\uA9F0-\uA9F9\uAA29-\uAA36\uAA43\uAA4C\uAA4D\uAA50-\uAA59\uAA7B-\uAA7D\uAAB0\uAAB2-\uAAB4\uAAB7\uAAB8\uAABE\uAABF\uAAC1\uAAEB-\uAAEF\uAAF5\uAAF6\uABE3-\uABEA\uABEC\uABED\uABF0-\uABF9\uFB1E\uFE00-\uFE0F\uFE20-\uFE2F\uFE33\uFE34\uFE4D-\uFE4F\uFF10-\uFF19\uFF3F"; + +var nonASCIIidentifierStart = new RegExp("[" + nonASCIIidentifierStartChars + "]"); +var nonASCIIidentifier = new RegExp("[" + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "]"); + +nonASCIIidentifierStartChars = nonASCIIidentifierChars = null; + +// These are a run-length and offset encoded representation of the +// >0xffff code points that are a valid part of identifiers. The +// offset starts at 0x10000, and each pair of numbers represents an +// offset to the next range, and then a size of the range. They were +// generated by `bin/generate-identifier-regex.js`. +// eslint-disable-next-line comma-spacing +var astralIdentifierStartCodes = [0, 11, 2, 25, 2, 18, 2, 1, 2, 14, 3, 13, 35, 122, 70, 52, 268, 28, 4, 48, 48, 31, 17, 26, 6, 37, 11, 29, 3, 35, 5, 7, 2, 4, 43, 157, 19, 35, 5, 35, 5, 39, 9, 51, 157, 310, 10, 21, 11, 7, 153, 5, 3, 0, 2, 43, 2, 1, 4, 0, 3, 22, 11, 22, 10, 30, 66, 18, 2, 1, 11, 21, 11, 25, 71, 55, 7, 1, 65, 0, 16, 3, 2, 2, 2, 26, 45, 28, 4, 28, 36, 7, 2, 27, 28, 53, 11, 21, 11, 18, 14, 17, 111, 72, 56, 50, 14, 50, 785, 52, 76, 44, 33, 24, 27, 35, 42, 34, 4, 0, 13, 47, 15, 3, 22, 0, 2, 0, 36, 17, 2, 24, 85, 6, 2, 0, 2, 3, 2, 14, 2, 9, 8, 46, 39, 7, 3, 1, 3, 21, 2, 6, 2, 1, 2, 4, 4, 0, 19, 0, 13, 4, 159, 52, 19, 3, 54, 47, 21, 1, 2, 0, 185, 46, 42, 3, 37, 47, 21, 0, 60, 42, 86, 25, 391, 63, 32, 0, 449, 56, 264, 8, 2, 36, 18, 0, 50, 29, 881, 921, 103, 110, 18, 195, 2749, 1070, 4050, 582, 8634, 568, 8, 30, 114, 29, 19, 47, 17, 3, 32, 20, 6, 18, 881, 68, 12, 0, 67, 12, 65, 0, 32, 6124, 20, 754, 9486, 1, 3071, 106, 6, 12, 4, 8, 8, 9, 5991, 84, 2, 70, 2, 1, 3, 0, 3, 1, 3, 3, 2, 11, 2, 0, 2, 6, 2, 64, 2, 3, 3, 7, 2, 6, 2, 27, 2, 3, 2, 4, 2, 0, 4, 6, 2, 339, 3, 24, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 7, 4149, 196, 60, 67, 1213, 3, 2, 26, 2, 1, 2, 0, 3, 0, 2, 9, 2, 3, 2, 0, 2, 0, 7, 0, 5, 0, 2, 0, 2, 0, 2, 2, 2, 1, 2, 0, 3, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 1, 2, 0, 3, 3, 2, 6, 2, 3, 2, 3, 2, 0, 2, 9, 2, 16, 6, 2, 2, 4, 2, 16, 4421, 42710, 42, 4148, 12, 221, 3, 5761, 10591, 541]; +// eslint-disable-next-line comma-spacing +var astralIdentifierCodes = [509, 0, 227, 0, 150, 4, 294, 9, 1368, 2, 2, 1, 6, 3, 41, 2, 5, 0, 166, 1, 1306, 2, 54, 14, 32, 9, 16, 3, 46, 10, 54, 9, 7, 2, 37, 13, 2, 9, 52, 0, 13, 2, 49, 13, 10, 2, 4, 9, 83, 11, 7, 0, 161, 11, 6, 9, 7, 3, 57, 0, 2, 6, 3, 1, 3, 2, 10, 0, 11, 1, 3, 6, 4, 4, 193, 17, 10, 9, 87, 19, 13, 9, 214, 6, 3, 8, 28, 1, 83, 16, 16, 9, 82, 12, 9, 9, 84, 14, 5, 9, 423, 9, 838, 7, 2, 7, 17, 9, 57, 21, 2, 13, 19882, 9, 135, 4, 60, 6, 26, 9, 1016, 45, 17, 3, 19723, 1, 5319, 4, 4, 5, 9, 7, 3, 6, 31, 3, 149, 2, 1418, 49, 513, 54, 5, 49, 9, 0, 15, 0, 23, 4, 2, 14, 1361, 6, 2, 16, 3, 6, 2, 1, 2, 4, 2214, 6, 110, 6, 6, 9, 792487, 239]; + +// This has a complexity linear to the value of the code. The +// assumption is that looking up astral identifier characters is +// rare. +function isInAstralSet(code, set) { + var pos = 0x10000; + for (var i = 0; i < set.length; i += 2) { + pos += set[i]; + if (pos > code) return false; + + pos += set[i + 1]; + if (pos >= code) return true; + } +} + +// Test whether a given character code starts an identifier. + +function isIdentifierStart(code) { + if (code < 65) return code === 36; + if (code < 91) return true; + if (code < 97) return code === 95; + if (code < 123) return true; + if (code <= 0xffff) return code >= 0xaa && nonASCIIidentifierStart.test(String.fromCharCode(code)); + return isInAstralSet(code, astralIdentifierStartCodes); +} + +// Test whether a given character is part of an identifier. + +function isIdentifierChar(code) { + if (code < 48) return code === 36; + if (code < 58) return true; + if (code < 65) return false; + if (code < 91) return true; + if (code < 97) return code === 95; + if (code < 123) return true; + if (code <= 0xffff) return code >= 0xaa && nonASCIIidentifier.test(String.fromCharCode(code)); + return isInAstralSet(code, astralIdentifierStartCodes) || isInAstralSet(code, astralIdentifierCodes); +} + +// A second optional argument can be given to further configure +var defaultOptions = { + // Source type ("script" or "module") for different semantics + sourceType: "script", + // Source filename. + sourceFilename: undefined, + // Line from which to start counting source. Useful for + // integration with other tools. + startLine: 1, + // When enabled, a return at the top level is not considered an + // error. + allowReturnOutsideFunction: false, + // When enabled, import/export statements are not constrained to + // appearing at the top of the program. + allowImportExportEverywhere: false, + // TODO + allowSuperOutsideMethod: false, + // An array of plugins to enable + plugins: [], + // TODO + strictMode: null +}; + +// Interpret and default an options object + +function getOptions(opts) { + var options = {}; + for (var key in defaultOptions) { + options[key] = opts && key in opts ? opts[key] : defaultOptions[key]; + } + return options; +} + +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { + return typeof obj; +} : function (obj) { + return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; +}; + + + + + + + + + + + +var classCallCheck = function (instance, Constructor) { + if (!(instance instanceof Constructor)) { + throw new TypeError("Cannot call a class as a function"); + } +}; + + + + + + + + + + + +var inherits = function (subClass, superClass) { + if (typeof superClass !== "function" && superClass !== null) { + throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); + } + + subClass.prototype = Object.create(superClass && superClass.prototype, { + constructor: { + value: subClass, + enumerable: false, + writable: true, + configurable: true + } + }); + if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; +}; + + + + + + + + + + + +var possibleConstructorReturn = function (self, call) { + if (!self) { + throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); + } + + return call && (typeof call === "object" || typeof call === "function") ? call : self; +}; + +// ## Token types + +// The assignment of fine-grained, information-carrying type objects +// allows the tokenizer to store the information it has about a +// token in a way that is very cheap for the parser to look up. + +// All token type variables start with an underscore, to make them +// easy to recognize. + +// The `beforeExpr` property is used to disambiguate between regular +// expressions and divisions. It is set on all token types that can +// be followed by an expression (thus, a slash after them would be a +// regular expression). +// +// `isLoop` marks a keyword as starting a loop, which is important +// to know when parsing a label, in order to allow or disallow +// continue jumps to that label. + +var beforeExpr = true; +var startsExpr = true; +var isLoop = true; +var isAssign = true; +var prefix = true; +var postfix = true; + +var TokenType = function TokenType(label) { + var conf = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + classCallCheck(this, TokenType); + + this.label = label; + this.keyword = conf.keyword; + this.beforeExpr = !!conf.beforeExpr; + this.startsExpr = !!conf.startsExpr; + this.rightAssociative = !!conf.rightAssociative; + this.isLoop = !!conf.isLoop; + this.isAssign = !!conf.isAssign; + this.prefix = !!conf.prefix; + this.postfix = !!conf.postfix; + this.binop = conf.binop || null; + this.updateContext = null; +}; + +var KeywordTokenType = function (_TokenType) { + inherits(KeywordTokenType, _TokenType); + + function KeywordTokenType(name) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + classCallCheck(this, KeywordTokenType); + + options.keyword = name; + + return possibleConstructorReturn(this, _TokenType.call(this, name, options)); + } + + return KeywordTokenType; +}(TokenType); + +var BinopTokenType = function (_TokenType2) { + inherits(BinopTokenType, _TokenType2); + + function BinopTokenType(name, prec) { + classCallCheck(this, BinopTokenType); + return possibleConstructorReturn(this, _TokenType2.call(this, name, { beforeExpr: beforeExpr, binop: prec })); + } + + return BinopTokenType; +}(TokenType); + +var types = { + num: new TokenType("num", { startsExpr: startsExpr }), + regexp: new TokenType("regexp", { startsExpr: startsExpr }), + string: new TokenType("string", { startsExpr: startsExpr }), + name: new TokenType("name", { startsExpr: startsExpr }), + eof: new TokenType("eof"), + + // Punctuation token types. + bracketL: new TokenType("[", { beforeExpr: beforeExpr, startsExpr: startsExpr }), + bracketR: new TokenType("]"), + braceL: new TokenType("{", { beforeExpr: beforeExpr, startsExpr: startsExpr }), + braceBarL: new TokenType("{|", { beforeExpr: beforeExpr, startsExpr: startsExpr }), + braceR: new TokenType("}"), + braceBarR: new TokenType("|}"), + parenL: new TokenType("(", { beforeExpr: beforeExpr, startsExpr: startsExpr }), + parenR: new TokenType(")"), + comma: new TokenType(",", { beforeExpr: beforeExpr }), + semi: new TokenType(";", { beforeExpr: beforeExpr }), + colon: new TokenType(":", { beforeExpr: beforeExpr }), + doubleColon: new TokenType("::", { beforeExpr: beforeExpr }), + dot: new TokenType("."), + question: new TokenType("?", { beforeExpr: beforeExpr }), + arrow: new TokenType("=>", { beforeExpr: beforeExpr }), + template: new TokenType("template"), + ellipsis: new TokenType("...", { beforeExpr: beforeExpr }), + backQuote: new TokenType("`", { startsExpr: startsExpr }), + dollarBraceL: new TokenType("${", { beforeExpr: beforeExpr, startsExpr: startsExpr }), + at: new TokenType("@"), + + // Operators. These carry several kinds of properties to help the + // parser use them properly (the presence of these properties is + // what categorizes them as operators). + // + // `binop`, when present, specifies that this operator is a binary + // operator, and will refer to its precedence. + // + // `prefix` and `postfix` mark the operator as a prefix or postfix + // unary operator. + // + // `isAssign` marks all of `=`, `+=`, `-=` etcetera, which act as + // binary operators with a very low precedence, that should result + // in AssignmentExpression nodes. + + eq: new TokenType("=", { beforeExpr: beforeExpr, isAssign: isAssign }), + assign: new TokenType("_=", { beforeExpr: beforeExpr, isAssign: isAssign }), + incDec: new TokenType("++/--", { prefix: prefix, postfix: postfix, startsExpr: startsExpr }), + prefix: new TokenType("prefix", { beforeExpr: beforeExpr, prefix: prefix, startsExpr: startsExpr }), + logicalOR: new BinopTokenType("||", 1), + logicalAND: new BinopTokenType("&&", 2), + bitwiseOR: new BinopTokenType("|", 3), + bitwiseXOR: new BinopTokenType("^", 4), + bitwiseAND: new BinopTokenType("&", 5), + equality: new BinopTokenType("==/!=", 6), + relational: new BinopTokenType(">", 7), + bitShift: new BinopTokenType("<>>", 8), + plusMin: new TokenType("+/-", { beforeExpr: beforeExpr, binop: 9, prefix: prefix, startsExpr: startsExpr }), + modulo: new BinopTokenType("%", 10), + star: new BinopTokenType("*", 10), + slash: new BinopTokenType("/", 10), + exponent: new TokenType("**", { beforeExpr: beforeExpr, binop: 11, rightAssociative: true }) +}; + +var keywords = { + "break": new KeywordTokenType("break"), + "case": new KeywordTokenType("case", { beforeExpr: beforeExpr }), + "catch": new KeywordTokenType("catch"), + "continue": new KeywordTokenType("continue"), + "debugger": new KeywordTokenType("debugger"), + "default": new KeywordTokenType("default", { beforeExpr: beforeExpr }), + "do": new KeywordTokenType("do", { isLoop: isLoop, beforeExpr: beforeExpr }), + "else": new KeywordTokenType("else", { beforeExpr: beforeExpr }), + "finally": new KeywordTokenType("finally"), + "for": new KeywordTokenType("for", { isLoop: isLoop }), + "function": new KeywordTokenType("function", { startsExpr: startsExpr }), + "if": new KeywordTokenType("if"), + "return": new KeywordTokenType("return", { beforeExpr: beforeExpr }), + "switch": new KeywordTokenType("switch"), + "throw": new KeywordTokenType("throw", { beforeExpr: beforeExpr }), + "try": new KeywordTokenType("try"), + "var": new KeywordTokenType("var"), + "let": new KeywordTokenType("let"), + "const": new KeywordTokenType("const"), + "while": new KeywordTokenType("while", { isLoop: isLoop }), + "with": new KeywordTokenType("with"), + "new": new KeywordTokenType("new", { beforeExpr: beforeExpr, startsExpr: startsExpr }), + "this": new KeywordTokenType("this", { startsExpr: startsExpr }), + "super": new KeywordTokenType("super", { startsExpr: startsExpr }), + "class": new KeywordTokenType("class"), + "extends": new KeywordTokenType("extends", { beforeExpr: beforeExpr }), + "export": new KeywordTokenType("export"), + "import": new KeywordTokenType("import"), + "yield": new KeywordTokenType("yield", { beforeExpr: beforeExpr, startsExpr: startsExpr }), + "null": new KeywordTokenType("null", { startsExpr: startsExpr }), + "true": new KeywordTokenType("true", { startsExpr: startsExpr }), + "false": new KeywordTokenType("false", { startsExpr: startsExpr }), + "in": new KeywordTokenType("in", { beforeExpr: beforeExpr, binop: 7 }), + "instanceof": new KeywordTokenType("instanceof", { beforeExpr: beforeExpr, binop: 7 }), + "typeof": new KeywordTokenType("typeof", { beforeExpr: beforeExpr, prefix: prefix, startsExpr: startsExpr }), + "void": new KeywordTokenType("void", { beforeExpr: beforeExpr, prefix: prefix, startsExpr: startsExpr }), + "delete": new KeywordTokenType("delete", { beforeExpr: beforeExpr, prefix: prefix, startsExpr: startsExpr }) +}; + +// Map keyword names to token types. +Object.keys(keywords).forEach(function (name) { + types["_" + name] = keywords[name]; +}); + +// Matches a whole line break (where CRLF is considered a single +// line break). Used to count lines. + +var lineBreak = /\r\n?|\n|\u2028|\u2029/; +var lineBreakG = new RegExp(lineBreak.source, "g"); + +function isNewLine(code) { + return code === 10 || code === 13 || code === 0x2028 || code === 0x2029; +} + +var nonASCIIwhitespace = /[\u1680\u180e\u2000-\u200a\u202f\u205f\u3000\ufeff]/; + +// The algorithm used to determine whether a regexp can appear at a +// given point in the program is loosely based on sweet.js' approach. +// See https://github.com/mozilla/sweet.js/wiki/design + +var TokContext = function TokContext(token, isExpr, preserveSpace, override) { + classCallCheck(this, TokContext); + + this.token = token; + this.isExpr = !!isExpr; + this.preserveSpace = !!preserveSpace; + this.override = override; +}; + +var types$1 = { + braceStatement: new TokContext("{", false), + braceExpression: new TokContext("{", true), + templateQuasi: new TokContext("${", true), + parenStatement: new TokContext("(", false), + parenExpression: new TokContext("(", true), + template: new TokContext("`", true, true, function (p) { + return p.readTmplToken(); + }), + functionExpression: new TokContext("function", true) +}; + +// Token-specific context update code + +types.parenR.updateContext = types.braceR.updateContext = function () { + if (this.state.context.length === 1) { + this.state.exprAllowed = true; + return; + } + + var out = this.state.context.pop(); + if (out === types$1.braceStatement && this.curContext() === types$1.functionExpression) { + this.state.context.pop(); + this.state.exprAllowed = false; + } else if (out === types$1.templateQuasi) { + this.state.exprAllowed = true; + } else { + this.state.exprAllowed = !out.isExpr; + } +}; + +types.name.updateContext = function (prevType) { + this.state.exprAllowed = false; + + if (prevType === types._let || prevType === types._const || prevType === types._var) { + if (lineBreak.test(this.input.slice(this.state.end))) { + this.state.exprAllowed = true; + } + } +}; + +types.braceL.updateContext = function (prevType) { + this.state.context.push(this.braceIsBlock(prevType) ? types$1.braceStatement : types$1.braceExpression); + this.state.exprAllowed = true; +}; + +types.dollarBraceL.updateContext = function () { + this.state.context.push(types$1.templateQuasi); + this.state.exprAllowed = true; +}; + +types.parenL.updateContext = function (prevType) { + var statementParens = prevType === types._if || prevType === types._for || prevType === types._with || prevType === types._while; + this.state.context.push(statementParens ? types$1.parenStatement : types$1.parenExpression); + this.state.exprAllowed = true; +}; + +types.incDec.updateContext = function () { + // tokExprAllowed stays unchanged +}; + +types._function.updateContext = function () { + if (this.curContext() !== types$1.braceStatement) { + this.state.context.push(types$1.functionExpression); + } + + this.state.exprAllowed = false; +}; + +types.backQuote.updateContext = function () { + if (this.curContext() === types$1.template) { + this.state.context.pop(); + } else { + this.state.context.push(types$1.template); + } + this.state.exprAllowed = false; +}; + +// These are used when `options.locations` is on, for the +// `startLoc` and `endLoc` properties. + +var Position = function Position(line, col) { + classCallCheck(this, Position); + + this.line = line; + this.column = col; +}; + +var SourceLocation = function SourceLocation(start, end) { + classCallCheck(this, SourceLocation); + + this.start = start; + this.end = end; +}; + +// The `getLineInfo` function is mostly useful when the +// `locations` option is off (for performance reasons) and you +// want to find the line/column position for a given character +// offset. `input` should be the code string that the offset refers +// into. + +function getLineInfo(input, offset) { + for (var line = 1, cur = 0;;) { + lineBreakG.lastIndex = cur; + var match = lineBreakG.exec(input); + if (match && match.index < offset) { + ++line; + cur = match.index + match[0].length; + } else { + return new Position(line, offset - cur); + } + } +} + +var State = function () { + function State() { + classCallCheck(this, State); + } + + State.prototype.init = function init(options, input) { + this.strict = options.strictMode === false ? false : options.sourceType === "module"; + + this.input = input; + + this.potentialArrowAt = -1; + + this.inMethod = this.inFunction = this.inGenerator = this.inAsync = this.inPropertyName = this.inType = this.noAnonFunctionType = false; + + this.labels = []; + + this.decorators = []; + + this.tokens = []; + + this.comments = []; + + this.trailingComments = []; + this.leadingComments = []; + this.commentStack = []; + + this.pos = this.lineStart = 0; + this.curLine = options.startLine; + + this.type = types.eof; + this.value = null; + this.start = this.end = this.pos; + this.startLoc = this.endLoc = this.curPosition(); + + this.lastTokEndLoc = this.lastTokStartLoc = null; + this.lastTokStart = this.lastTokEnd = this.pos; + + this.context = [types$1.braceStatement]; + this.exprAllowed = true; + + this.containsEsc = this.containsOctal = false; + this.octalPosition = null; + + this.exportedIdentifiers = []; + + return this; + }; + + // TODO + + + // TODO + + + // Used to signify the start of a potential arrow function + + + // Flags to track whether we are in a function, a generator. + + + // Labels in scope. + + + // Leading decorators. + + + // Token store. + + + // Comment store. + + + // Comment attachment store + + + // The current position of the tokenizer in the input. + + + // Properties of the current token: + // Its type + + + // For tokens that include more information than their type, the value + + + // Its start and end offset + + + // And, if locations are used, the {line, column} object + // corresponding to those offsets + + + // Position information for the previous token + + + // The context stack is used to superficially track syntactic + // context to predict whether a regular expression is allowed in a + // given position. + + + // Used to signal to callers of `readWord1` whether the word + // contained any escape sequences. This is needed because words with + // escape sequences must not be interpreted as keywords. + + + // TODO + + + // Names of exports store. `default` is stored as a name for both + // `export default foo;` and `export { foo as default };`. + + + State.prototype.curPosition = function curPosition() { + return new Position(this.curLine, this.pos - this.lineStart); + }; + + State.prototype.clone = function clone(skipArrays) { + var state = new State(); + for (var key in this) { + var val = this[key]; + + if ((!skipArrays || key === "context") && Array.isArray(val)) { + val = val.slice(); + } + + state[key] = val; + } + return state; + }; + + return State; +}(); + +// Object type used to represent tokens. Note that normally, tokens +// simply exist as properties on the parser object. This is only +// used for the onToken callback and the external tokenizer. + +var Token = function Token(state) { + classCallCheck(this, Token); + + this.type = state.type; + this.value = state.value; + this.start = state.start; + this.end = state.end; + this.loc = new SourceLocation(state.startLoc, state.endLoc); +}; + +// ## Tokenizer + +function codePointToString(code) { + // UTF-16 Decoding + if (code <= 0xFFFF) { + return String.fromCharCode(code); + } else { + return String.fromCharCode((code - 0x10000 >> 10) + 0xD800, (code - 0x10000 & 1023) + 0xDC00); + } +} + +var Tokenizer = function () { + function Tokenizer(options, input) { + classCallCheck(this, Tokenizer); + + this.state = new State(); + this.state.init(options, input); + } + + // Move to the next token + + Tokenizer.prototype.next = function next() { + if (!this.isLookahead) { + this.state.tokens.push(new Token(this.state)); + } + + this.state.lastTokEnd = this.state.end; + this.state.lastTokStart = this.state.start; + this.state.lastTokEndLoc = this.state.endLoc; + this.state.lastTokStartLoc = this.state.startLoc; + this.nextToken(); + }; + + // TODO + + Tokenizer.prototype.eat = function eat(type) { + if (this.match(type)) { + this.next(); + return true; + } else { + return false; + } + }; + + // TODO + + Tokenizer.prototype.match = function match(type) { + return this.state.type === type; + }; + + // TODO + + Tokenizer.prototype.isKeyword = function isKeyword$$1(word) { + return isKeyword(word); + }; + + // TODO + + Tokenizer.prototype.lookahead = function lookahead() { + var old = this.state; + this.state = old.clone(true); + + this.isLookahead = true; + this.next(); + this.isLookahead = false; + + var curr = this.state.clone(true); + this.state = old; + return curr; + }; + + // Toggle strict mode. Re-reads the next number or string to please + // pedantic tests (`"use strict"; 010;` should fail). + + Tokenizer.prototype.setStrict = function setStrict(strict) { + this.state.strict = strict; + if (!this.match(types.num) && !this.match(types.string)) return; + this.state.pos = this.state.start; + while (this.state.pos < this.state.lineStart) { + this.state.lineStart = this.input.lastIndexOf("\n", this.state.lineStart - 2) + 1; + --this.state.curLine; + } + this.nextToken(); + }; + + Tokenizer.prototype.curContext = function curContext() { + return this.state.context[this.state.context.length - 1]; + }; + + // Read a single token, updating the parser object's token-related + // properties. + + Tokenizer.prototype.nextToken = function nextToken() { + var curContext = this.curContext(); + if (!curContext || !curContext.preserveSpace) this.skipSpace(); + + this.state.containsOctal = false; + this.state.octalPosition = null; + this.state.start = this.state.pos; + this.state.startLoc = this.state.curPosition(); + if (this.state.pos >= this.input.length) return this.finishToken(types.eof); + + if (curContext.override) { + return curContext.override(this); + } else { + return this.readToken(this.fullCharCodeAtPos()); + } + }; + + Tokenizer.prototype.readToken = function readToken(code) { + // Identifier or keyword. '\uXXXX' sequences are allowed in + // identifiers, so '\' also dispatches to that. + if (isIdentifierStart(code) || code === 92 /* '\' */) { + return this.readWord(); + } else { + return this.getTokenFromCode(code); + } + }; + + Tokenizer.prototype.fullCharCodeAtPos = function fullCharCodeAtPos() { + var code = this.input.charCodeAt(this.state.pos); + if (code <= 0xd7ff || code >= 0xe000) return code; + + var next = this.input.charCodeAt(this.state.pos + 1); + return (code << 10) + next - 0x35fdc00; + }; + + Tokenizer.prototype.pushComment = function pushComment(block, text, start, end, startLoc, endLoc) { + var comment = { + type: block ? "CommentBlock" : "CommentLine", + value: text, + start: start, + end: end, + loc: new SourceLocation(startLoc, endLoc) + }; + + if (!this.isLookahead) { + this.state.tokens.push(comment); + this.state.comments.push(comment); + this.addComment(comment); + } + }; + + Tokenizer.prototype.skipBlockComment = function skipBlockComment() { + var startLoc = this.state.curPosition(); + var start = this.state.pos; + var end = this.input.indexOf("*/", this.state.pos += 2); + if (end === -1) this.raise(this.state.pos - 2, "Unterminated comment"); + + this.state.pos = end + 2; + lineBreakG.lastIndex = start; + var match = void 0; + while ((match = lineBreakG.exec(this.input)) && match.index < this.state.pos) { + ++this.state.curLine; + this.state.lineStart = match.index + match[0].length; + } + + this.pushComment(true, this.input.slice(start + 2, end), start, this.state.pos, startLoc, this.state.curPosition()); + }; + + Tokenizer.prototype.skipLineComment = function skipLineComment(startSkip) { + var start = this.state.pos; + var startLoc = this.state.curPosition(); + var ch = this.input.charCodeAt(this.state.pos += startSkip); + while (this.state.pos < this.input.length && ch !== 10 && ch !== 13 && ch !== 8232 && ch !== 8233) { + ++this.state.pos; + ch = this.input.charCodeAt(this.state.pos); + } + + this.pushComment(false, this.input.slice(start + startSkip, this.state.pos), start, this.state.pos, startLoc, this.state.curPosition()); + }; + + // Called at the start of the parse and after every token. Skips + // whitespace and comments, and. + + Tokenizer.prototype.skipSpace = function skipSpace() { + loop: while (this.state.pos < this.input.length) { + var ch = this.input.charCodeAt(this.state.pos); + switch (ch) { + case 32:case 160: + // ' ' + ++this.state.pos; + break; + + case 13: + if (this.input.charCodeAt(this.state.pos + 1) === 10) { + ++this.state.pos; + } + + case 10:case 8232:case 8233: + ++this.state.pos; + ++this.state.curLine; + this.state.lineStart = this.state.pos; + break; + + case 47: + // '/' + switch (this.input.charCodeAt(this.state.pos + 1)) { + case 42: + // '*' + this.skipBlockComment(); + break; + + case 47: + this.skipLineComment(2); + break; + + default: + break loop; + } + break; + + default: + if (ch > 8 && ch < 14 || ch >= 5760 && nonASCIIwhitespace.test(String.fromCharCode(ch))) { + ++this.state.pos; + } else { + break loop; + } + } + } + }; + + // Called at the end of every token. Sets `end`, `val`, and + // maintains `context` and `exprAllowed`, and skips the space after + // the token, so that the next one's `start` will point at the + // right position. + + Tokenizer.prototype.finishToken = function finishToken(type, val) { + this.state.end = this.state.pos; + this.state.endLoc = this.state.curPosition(); + var prevType = this.state.type; + this.state.type = type; + this.state.value = val; + + this.updateContext(prevType); + }; + + // ### Token reading + + // This is the function that is called to fetch the next token. It + // is somewhat obscure, because it works in character codes rather + // than characters, and because operator parsing has been inlined + // into it. + // + // All in the name of speed. + // + + + Tokenizer.prototype.readToken_dot = function readToken_dot() { + var next = this.input.charCodeAt(this.state.pos + 1); + if (next >= 48 && next <= 57) { + return this.readNumber(true); + } + + var next2 = this.input.charCodeAt(this.state.pos + 2); + if (next === 46 && next2 === 46) { + // 46 = dot '.' + this.state.pos += 3; + return this.finishToken(types.ellipsis); + } else { + ++this.state.pos; + return this.finishToken(types.dot); + } + }; + + Tokenizer.prototype.readToken_slash = function readToken_slash() { + // '/' + if (this.state.exprAllowed) { + ++this.state.pos; + return this.readRegexp(); + } + + var next = this.input.charCodeAt(this.state.pos + 1); + if (next === 61) { + return this.finishOp(types.assign, 2); + } else { + return this.finishOp(types.slash, 1); + } + }; + + Tokenizer.prototype.readToken_mult_modulo = function readToken_mult_modulo(code) { + // '%*' + var type = code === 42 ? types.star : types.modulo; + var width = 1; + var next = this.input.charCodeAt(this.state.pos + 1); + + if (next === 42) { + // '*' + width++; + next = this.input.charCodeAt(this.state.pos + 2); + type = types.exponent; + } + + if (next === 61) { + width++; + type = types.assign; + } + + return this.finishOp(type, width); + }; + + Tokenizer.prototype.readToken_pipe_amp = function readToken_pipe_amp(code) { + // '|&' + var next = this.input.charCodeAt(this.state.pos + 1); + if (next === code) return this.finishOp(code === 124 ? types.logicalOR : types.logicalAND, 2); + if (next === 61) return this.finishOp(types.assign, 2); + if (code === 124 && next === 125 && this.hasPlugin("flow")) return this.finishOp(types.braceBarR, 2); + return this.finishOp(code === 124 ? types.bitwiseOR : types.bitwiseAND, 1); + }; + + Tokenizer.prototype.readToken_caret = function readToken_caret() { + // '^' + var next = this.input.charCodeAt(this.state.pos + 1); + if (next === 61) { + return this.finishOp(types.assign, 2); + } else { + return this.finishOp(types.bitwiseXOR, 1); + } + }; + + Tokenizer.prototype.readToken_plus_min = function readToken_plus_min(code) { + // '+-' + var next = this.input.charCodeAt(this.state.pos + 1); + + if (next === code) { + if (next === 45 && this.input.charCodeAt(this.state.pos + 2) === 62 && lineBreak.test(this.input.slice(this.state.lastTokEnd, this.state.pos))) { + // A `-->` line comment + this.skipLineComment(3); + this.skipSpace(); + return this.nextToken(); + } + return this.finishOp(types.incDec, 2); + } + + if (next === 61) { + return this.finishOp(types.assign, 2); + } else { + return this.finishOp(types.plusMin, 1); + } + }; + + Tokenizer.prototype.readToken_lt_gt = function readToken_lt_gt(code) { + // '<>' + var next = this.input.charCodeAt(this.state.pos + 1); + var size = 1; + + if (next === code) { + size = code === 62 && this.input.charCodeAt(this.state.pos + 2) === 62 ? 3 : 2; + if (this.input.charCodeAt(this.state.pos + size) === 61) return this.finishOp(types.assign, size + 1); + return this.finishOp(types.bitShift, size); + } + + if (next === 33 && code === 60 && this.input.charCodeAt(this.state.pos + 2) === 45 && this.input.charCodeAt(this.state.pos + 3) === 45) { + if (this.inModule) this.unexpected(); + // ` + +```js +var compressible = require('compressible') +``` + +### compressible(type) + +Checks if the given `Content-Type` is compressible. The `type` argument is expected +to be a value MIME type or `Content-Type` string, though no validation is performed. + +The MIME is looked up in the [`mime-db`](https://www.npmjs.com/package/mime-db) and +if there is compressible information in the database entry, that is returned. Otherwise, +this module will fallback to `true` for the following types: + + * `text/*` + * `*/*+json` + * `*/*+text` + * `*/*+xml` + +If this module is not sure if a type is specifically compressible or specifically +uncompressible, `undefined` is returned. + + + +```js +compressible('text/html') // => true +compressible('image/png') // => false +``` + +## License + +[MIT](LICENSE) + +[npm-image]: https://img.shields.io/npm/v/compressible.svg +[npm-url]: https://npmjs.org/package/compressible +[node-version-image]: https://img.shields.io/node/v/compressible.svg +[node-version-url]: https://nodejs.org/en/download/ +[travis-image]: https://img.shields.io/travis/jshttp/compressible/master.svg +[travis-url]: https://travis-ci.org/jshttp/compressible +[coveralls-image]: https://img.shields.io/coveralls/jshttp/compressible/master.svg +[coveralls-url]: https://coveralls.io/r/jshttp/compressible?branch=master +[downloads-image]: https://img.shields.io/npm/dm/compressible.svg +[downloads-url]: https://npmjs.org/package/compressible diff --git a/node_modules/compressible/index.js b/node_modules/compressible/index.js new file mode 100644 index 00000000..bf14ad72 --- /dev/null +++ b/node_modules/compressible/index.js @@ -0,0 +1,58 @@ +/*! + * compressible + * Copyright(c) 2013 Jonathan Ong + * Copyright(c) 2014 Jeremiah Senkpiel + * Copyright(c) 2015 Douglas Christopher Wilson + * MIT Licensed + */ + +'use strict' + +/** + * Module dependencies. + * @private + */ + +var db = require('mime-db') + +/** + * Module variables. + * @private + */ + +var compressibleTypeRegExp = /^text\/|\+json$|\+text$|\+xml$/i +var extractTypeRegExp = /^\s*([^;\s]*)(?:;|\s|$)/ + +/** + * Module exports. + * @public + */ + +module.exports = compressible + +/** + * Checks if a type is compressible. + * + * @param {string} type + * @return {Boolean} compressible + * @public + */ + +function compressible (type) { + if (!type || typeof type !== 'string') { + return false + } + + // strip parameters + var match = extractTypeRegExp.exec(type) + var mime = match && match[1].toLowerCase() + var data = db[mime] + + // return database information + if (data && data.compressible !== undefined) { + return data.compressible + } + + // fallback to regexp or unknown + return compressibleTypeRegExp.test(mime) || undefined +} diff --git a/node_modules/compressible/package.json b/node_modules/compressible/package.json new file mode 100644 index 00000000..ccdf5e98 --- /dev/null +++ b/node_modules/compressible/package.json @@ -0,0 +1,147 @@ +{ + "_args": [ + [ + { + "raw": "compressible@~2.0.8", + "scope": null, + "escapedName": "compressible", + "name": "compressible", + "rawSpec": "~2.0.8", + "spec": ">=2.0.8 <2.1.0", + "type": "range" + }, + "/Users/ericchiu/Desktop/CIS 700/HW7/Project7-BioCrowds/node_modules/compression" + ] + ], + "_from": "compressible@>=2.0.8 <2.1.0", + "_id": "compressible@2.0.10", + "_inCache": true, + "_location": "/compressible", + "_nodeVersion": "4.7.3", + "_npmOperationalInternal": { + "host": "packages-12-west.internal.npmjs.com", + "tmp": "tmp/compressible-2.0.10.tgz_1490330888540_0.3248714415822178" + }, + "_npmUser": { + "name": "dougwilson", + "email": "doug@somethingdoug.com" + }, + "_npmVersion": "2.15.11", + "_phantomChildren": {}, + "_requested": { + "raw": "compressible@~2.0.8", + "scope": null, + "escapedName": "compressible", + "name": "compressible", + "rawSpec": "~2.0.8", + "spec": ">=2.0.8 <2.1.0", + "type": "range" + }, + "_requiredBy": [ + "/compression" + ], + "_resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.10.tgz", + "_shasum": "feda1c7f7617912732b29bf8cf26252a20b9eecd", + "_shrinkwrap": null, + "_spec": "compressible@~2.0.8", + "_where": "/Users/ericchiu/Desktop/CIS 700/HW7/Project7-BioCrowds/node_modules/compression", + "bugs": { + "url": "https://github.com/jshttp/compressible/issues" + }, + "contributors": [ + { + "name": "Douglas Christopher Wilson", + "email": "doug@somethingdoug.com" + }, + { + "name": "Jonathan Ong", + "email": "me@jongleberry.com", + "url": "http://jongleberry.com" + }, + { + "name": "Jeremiah Senkpiel", + "email": "fishrock123@rocketmail.com", + "url": "https://searchbeam.jit.su" + } + ], + "dependencies": { + "mime-db": ">= 1.27.0 < 2" + }, + "description": "Compressible Content-Type / mime checking", + "devDependencies": { + "eslint": "3.18.0", + "eslint-config-standard": "7.1.0", + "eslint-plugin-markdown": "1.0.0-beta.4", + "eslint-plugin-promise": "3.5.0", + "eslint-plugin-standard": "2.1.1", + "istanbul": "0.4.5", + "mocha": "~1.21.5" + }, + "directories": {}, + "dist": { + "shasum": "feda1c7f7617912732b29bf8cf26252a20b9eecd", + "tarball": "https://registry.npmjs.org/compressible/-/compressible-2.0.10.tgz" + }, + "engines": { + "node": ">= 0.6" + }, + "files": [ + "HISTORY.md", + "LICENSE", + "README.md", + "index.js" + ], + "gitHead": "235bc74b36aa7fe854df88ce2c68242c0a4ca938", + "homepage": "https://github.com/jshttp/compressible#readme", + "keywords": [ + "compress", + "gzip", + "mime", + "content-type" + ], + "license": "MIT", + "maintainers": [ + { + "name": "defunctzombie", + "email": "shtylman@gmail.com" + }, + { + "name": "dougwilson", + "email": "doug@somethingdoug.com" + }, + { + "name": "federomero", + "email": "federomero@gmail.com" + }, + { + "name": "fishrock123", + "email": "fishrock123@rocketmail.com" + }, + { + "name": "jongleberry", + "email": "jonathanrichardong@gmail.com" + }, + { + "name": "mscdex", + "email": "mscdex@mscdex.net" + }, + { + "name": "tjholowaychuk", + "email": "tj@vision-media.ca" + } + ], + "name": "compressible", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/jshttp/compressible.git" + }, + "scripts": { + "lint": "eslint --plugin markdown --ext js,md .", + "test": "mocha --reporter spec --bail --check-leaks test/", + "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot --check-leaks", + "test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter dot --check-leaks" + }, + "version": "2.0.10" +} diff --git a/node_modules/compression/HISTORY.md b/node_modules/compression/HISTORY.md new file mode 100644 index 00000000..663f0de0 --- /dev/null +++ b/node_modules/compression/HISTORY.md @@ -0,0 +1,251 @@ +1.6.2 / 2016-05-12 +================== + + * deps: accepts@~1.3.3 + - deps: mime-types@~2.1.11 + - deps: negotiator@0.6.1 + * deps: bytes@2.3.0 + - Drop partial bytes on all parsed units + - Fix parsing byte string that looks like hex + - perf: hoist regular expressions + * deps: compressible@~2.0.8 + - deps: mime-db@'>= 1.23.0 < 2' + +1.6.1 / 2016-01-19 +================== + + * deps: bytes@2.2.0 + * deps: compressible@~2.0.7 + - deps: mime-db@'>= 1.21.0 < 2' + * deps: accepts@~1.3.1 + - deps: mime-types@~2.1.9 + +1.6.0 / 2015-09-29 +================== + + * Skip compression when response has `Cache-Control: no-transform` + * deps: accepts@~1.3.0 + - deps: mime-types@~2.1.7 + - deps: negotiator@0.6.0 + * deps: compressible@~2.0.6 + - deps: mime-db@'>= 1.19.0 < 2' + * deps: on-headers@~1.0.1 + - perf: enable strict mode + * deps: vary@~1.1.0 + - Only accept valid field names in the `field` argument + +1.5.2 / 2015-07-30 +================== + + * deps: accepts@~1.2.12 + - deps: mime-types@~2.1.4 + * deps: compressible@~2.0.5 + - deps: mime-db@'>= 1.16.0 < 2' + * deps: vary@~1.0.1 + - Fix setting empty header from empty `field` + - perf: enable strict mode + - perf: remove argument reassignments + +1.5.1 / 2015-07-05 +================== + + * deps: accepts@~1.2.10 + - deps: mime-types@~2.1.2 + * deps: compressible@~2.0.4 + - deps: mime-db@'>= 1.14.0 < 2' + - perf: enable strict mode + +1.5.0 / 2015-06-09 +================== + + * Fix return value from `.end` and `.write` after end + * Improve detection of zero-length body without `Content-Length` + * deps: accepts@~1.2.9 + - deps: mime-types@~2.1.1 + - perf: avoid argument reassignment & argument slice + - perf: avoid negotiator recursive construction + - perf: enable strict mode + - perf: remove unnecessary bitwise operator + * deps: bytes@2.1.0 + - Slight optimizations + - Units no longer case sensitive when parsing + * deps: compressible@~2.0.3 + - Fix regex fallback to work if type exists, but is undefined + - deps: mime-db@'>= 1.13.0 < 2' + - perf: hoist regex declaration + - perf: use regex to extract mime + * perf: enable strict mode + * perf: remove flush reassignment + * perf: simplify threshold detection + +1.4.4 / 2015-05-11 +================== + + * deps: accepts@~1.2.7 + - deps: mime-types@~2.0.11 + - deps: negotiator@0.5.3 + * deps: debug@~2.2.0 + - deps: ms@0.7.1 + +1.4.3 / 2015-03-14 +================== + + * deps: accepts@~1.2.5 + - deps: mime-types@~2.0.10 + * deps: debug@~2.1.3 + - Fix high intensity foreground color for bold + - deps: ms@0.7.0 + +1.4.2 / 2015-03-11 +================== + + * Fix error when code calls `res.end(str, encoding)` + - Specific to Node.js 0.8 + * deps: debug@~2.1.2 + - deps: ms@0.7.0 + +1.4.1 / 2015-02-15 +================== + + * deps: accepts@~1.2.4 + - deps: mime-types@~2.0.9 + - deps: negotiator@0.5.1 + +1.4.0 / 2015-02-01 +================== + + * Prefer `gzip` over `deflate` on the server + - Not all clients agree on what "deflate" coding means + +1.3.1 / 2015-01-31 +================== + + * deps: accepts@~1.2.3 + - deps: mime-types@~2.0.8 + * deps: compressible@~2.0.2 + - deps: mime-db@'>= 1.1.2 < 2' + +1.3.0 / 2014-12-30 +================== + + * Export the default `filter` function for wrapping + * deps: accepts@~1.2.2 + - deps: mime-types@~2.0.7 + - deps: negotiator@0.5.0 + * deps: debug@~2.1.1 + +1.2.2 / 2014-12-10 +================== + + * Fix `.end` to only proxy to `.end` + - Fixes an issue with Node.js 0.11.14 + * deps: accepts@~1.1.4 + - deps: mime-types@~2.0.4 + +1.2.1 / 2014-11-23 +================== + + * deps: accepts@~1.1.3 + - deps: mime-types@~2.0.3 + +1.2.0 / 2014-10-16 +================== + + * deps: debug@~2.1.0 + - Implement `DEBUG_FD` env variable support + +1.1.2 / 2014-10-15 +================== + + * deps: accepts@~1.1.2 + - Fix error when media type has invalid parameter + - deps: negotiator@0.4.9 + +1.1.1 / 2014-10-12 +================== + + * deps: accepts@~1.1.1 + - deps: mime-types@~2.0.2 + - deps: negotiator@0.4.8 + * deps: compressible@~2.0.1 + - deps: mime-db@1.x + +1.1.0 / 2014-09-07 +================== + + * deps: accepts@~1.1.0 + * deps: compressible@~2.0.0 + * deps: debug@~2.0.0 + +1.0.11 / 2014-08-10 +=================== + + * deps: on-headers@~1.0.0 + * deps: vary@~1.0.0 + +1.0.10 / 2014-08-05 +=================== + + * deps: compressible@~1.1.1 + - Fix upper-case Content-Type characters prevent compression + +1.0.9 / 2014-07-20 +================== + + * Add `debug` messages + * deps: accepts@~1.0.7 + - deps: negotiator@0.4.7 + +1.0.8 / 2014-06-20 +================== + + * deps: accepts@~1.0.5 + - use `mime-types` + +1.0.7 / 2014-06-11 +================== + + * use vary module for better `Vary` behavior + * deps: accepts@1.0.3 + * deps: compressible@1.1.0 + +1.0.6 / 2014-06-03 +================== + + * fix regression when negotiation fails + +1.0.5 / 2014-06-03 +================== + + * fix listeners for delayed stream creation + - fixes regression for certain `stream.pipe(res)` situations + +1.0.4 / 2014-06-03 +================== + + * fix adding `Vary` when value stored as array + * fix back-pressure behavior + * fix length check for `res.end` + +1.0.3 / 2014-05-29 +================== + + * use `accepts` for negotiation + * use `on-headers` to handle header checking + * deps: bytes@1.0.0 + +1.0.2 / 2014-04-29 +================== + + * only version compatible with node.js 0.8 + * support headers given to `res.writeHead` + * deps: bytes@0.3.0 + * deps: negotiator@0.4.3 + +1.0.1 / 2014-03-08 +================== + + * bump negotiator + * use compressible + * use .headersSent (drops 0.8 support) + * handle identity;q=0 case diff --git a/node_modules/compression/LICENSE b/node_modules/compression/LICENSE new file mode 100644 index 00000000..386b7b69 --- /dev/null +++ b/node_modules/compression/LICENSE @@ -0,0 +1,23 @@ +(The MIT License) + +Copyright (c) 2014 Jonathan OngMiddleware to proxy requests through a specified index page, useful for Single Page Applications that utilise the HTML5 History API.
+ +[](https://travis-ci.org/bripkens/connect-history-api-fallback) +[](https://david-dm.org/bripkens/connect-history-api-fallback/master) + +[](https://nodei.co/npm/connect-history-api-fallback/) + +## Introduction + +Single Page Applications (SPA) typically only utilise one index file that is +accessible by web browsers: usually `index.html`. Navigation in the application +is then commonly handled using JavaScript with the help of the +[HTML5 History API](http://www.w3.org/html/wg/drafts/html/master/single-page.html#the-history-interface). +This results in issues when the user hits the refresh button or is directly +accessing a page other than the landing page, e.g. `/help` or `/help/online` +as the web server bypasses the index file to locate the file at this location. +As your application is a SPA, the web server will fail trying to retrieve the file and return a *404 - Not Found* +message to the user. + +This tiny middleware addresses some of the issues. Specifically, it will change +the requested location to the index you specify (default being `/index.html`) +whenever there is a request which fulfills the following criteria: + + 1. The request is a GET request + 2. which accepts `text/html`, + 3. is not a direct file request, i.e. the requested path does not contain a + `.` (DOT) character and + 4. does not match a pattern provided in options.rewrites (see options below) + +## Usage + +The middleware is available through NPM and can easily be added. + +``` +npm install --save connect-history-api-fallback +``` + +Import the library + +```javascript +var history = require('connect-history-api-fallback'); +``` + +Now you only need to add the middleware to your application like so + +```javascript +var connect = require('connect'); + +var app = connect() + .use(history()) + .listen(3000); +``` + +Of course you can also use this piece of middleware with express: + +```javascript +var express = require('express'); + +var app = express(); +app.use(history()); +``` + +## Options +You can optionally pass options to the library when obtaining the middleware + +```javascript +var middleware = history({}); +``` + +### index +Override the index (default `/index.html`) + +```javascript +history({ + index: '/default.html' +}); +``` + +### rewrites +Override the index when the request url matches a regex pattern. You can either rewrite to a static string or use a function to transform the incoming request. + +The following will rewrite a request that matches the `/\/soccer/` pattern to `/soccer.html`. +```javascript +history({ + rewrites: [ + { from: /\/soccer/, to: '/soccer.html'} + ] +}); +``` + +Alternatively functions can be used to have more control over the rewrite process. For instance, the following listing shows how requests to `/libs/jquery/jquery.1.12.0.min.js` and the like can be routed to `./bower_components/libs/jquery/jquery.1.12.0.min.js`. You can also make use of this if you have an API version in the URL path. +```javascript +history({ + rewrites: [ + { + from: /^\/libs\/.*$/, + to: function(context) { + return '/bower_components' + context.parsedUrl.pathname; + } + } + ] +}); +``` + +The function will always be called with a context object that has the following properties: + + - **parsedUrl**: Information about the URL as provided by the [URL module's](https://nodejs.org/api/url.html#url_url_parse_urlstr_parsequerystring_slashesdenotehost) `url.parse`. + - **match**: An Array of matched results as provided by `String.match(...)`. + + +### verbose +This middleware does not log any information by default. If you wish to activate logging, then you can do so via the `verbose` option or by specifying a logger function. + +```javascript +history({ + verbose: true +}); +``` + +Alternatively use your own logger + +```javascript +history({ + logger: console.log.bind(console) +}); +``` + +### htmlAcceptHeaders +Override the default `Accepts:` headers that are queried when matching HTML content requests (Default: `['text/html', '*/*']`). + +```javascript +history({ + htmlAcceptHeaders: ['text/html', 'application/xhtml+xml'] +}) +``` + +### disableDotRule +Disables the dot rule mentioned above: + +> […] is not a direct file request, i.e. the requested path does not contain a `.` (DOT) character […] + +```javascript +history({ + disableDotRule: true +}) +``` diff --git a/node_modules/connect-history-api-fallback/lib/index.js b/node_modules/connect-history-api-fallback/lib/index.js new file mode 100644 index 00000000..ae1355ff --- /dev/null +++ b/node_modules/connect-history-api-fallback/lib/index.js @@ -0,0 +1,107 @@ +'use strict'; + +var url = require('url'); + +exports = module.exports = function historyApiFallback(options) { + options = options || {}; + var logger = getLogger(options); + + return function(req, res, next) { + var headers = req.headers; + if (req.method !== 'GET') { + logger( + 'Not rewriting', + req.method, + req.url, + 'because the method is not GET.' + ); + return next(); + } else if (!headers || typeof headers.accept !== 'string') { + logger( + 'Not rewriting', + req.method, + req.url, + 'because the client did not send an HTTP accept header.' + ); + return next(); + } else if (headers.accept.indexOf('application/json') === 0) { + logger( + 'Not rewriting', + req.method, + req.url, + 'because the client prefers JSON.' + ); + return next(); + } else if (!acceptsHtml(headers.accept, options)) { + logger( + 'Not rewriting', + req.method, + req.url, + 'because the client does not accept HTML.' + ); + return next(); + } + + var parsedUrl = url.parse(req.url); + var rewriteTarget; + options.rewrites = options.rewrites || []; + for (var i = 0; i < options.rewrites.length; i++) { + var rewrite = options.rewrites[i]; + var match = parsedUrl.pathname.match(rewrite.from); + if (match !== null) { + rewriteTarget = evaluateRewriteRule(parsedUrl, match, rewrite.to); + logger('Rewriting', req.method, req.url, 'to', rewriteTarget); + req.url = rewriteTarget; + return next(); + } + } + + if (parsedUrl.pathname.indexOf('.') !== -1 && + options.disableDotRule !== true) { + logger( + 'Not rewriting', + req.method, + req.url, + 'because the path includes a dot (.) character.' + ); + return next(); + } + + rewriteTarget = options.index || '/index.html'; + logger('Rewriting', req.method, req.url, 'to', rewriteTarget); + req.url = rewriteTarget; + next(); + }; +}; + +function evaluateRewriteRule(parsedUrl, match, rule) { + if (typeof rule === 'string') { + return rule; + } else if (typeof rule !== 'function') { + throw new Error('Rewrite rule can only be of type string of function.'); + } + + return rule({ + parsedUrl: parsedUrl, + match: match + }); +} + +function acceptsHtml(header, options) { + options.htmlAcceptHeaders = options.htmlAcceptHeaders || ['text/html', '*/*']; + for (var i = 0; i < options.htmlAcceptHeaders.length; i++) { + if (header.indexOf(options.htmlAcceptHeaders[i]) !== -1) { + return true; + } + } + return false; +} + +function getLogger(options) { + if (options && options.logger) { + return options.logger; + } else if (options && options.verbose) { + return console.log.bind(console); + } + return function(){}; +} diff --git a/node_modules/connect-history-api-fallback/package.json b/node_modules/connect-history-api-fallback/package.json new file mode 100644 index 00000000..d3dd2de6 --- /dev/null +++ b/node_modules/connect-history-api-fallback/package.json @@ -0,0 +1,106 @@ +{ + "_args": [ + [ + { + "raw": "connect-history-api-fallback@^1.3.0", + "scope": null, + "escapedName": "connect-history-api-fallback", + "name": "connect-history-api-fallback", + "rawSpec": "^1.3.0", + "spec": ">=1.3.0 <2.0.0", + "type": "range" + }, + "/Users/ericchiu/Desktop/CIS 700/HW7/Project7-BioCrowds/node_modules/webpack-dev-server" + ] + ], + "_from": "connect-history-api-fallback@>=1.3.0 <2.0.0", + "_id": "connect-history-api-fallback@1.3.0", + "_inCache": true, + "_location": "/connect-history-api-fallback", + "_nodeVersion": "6.2.0", + "_npmOperationalInternal": { + "host": "packages-12-west.internal.npmjs.com", + "tmp": "tmp/connect-history-api-fallback-1.3.0.tgz_1470552836120_0.7486736204009503" + }, + "_npmUser": { + "name": "bripkens", + "email": "bripkens.dev@gmail.com" + }, + "_npmVersion": "3.8.9", + "_phantomChildren": {}, + "_requested": { + "raw": "connect-history-api-fallback@^1.3.0", + "scope": null, + "escapedName": "connect-history-api-fallback", + "name": "connect-history-api-fallback", + "rawSpec": "^1.3.0", + "spec": ">=1.3.0 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/webpack-dev-server" + ], + "_resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.3.0.tgz", + "_shasum": "e51d17f8f0ef0db90a64fdb47de3051556e9f169", + "_shrinkwrap": null, + "_spec": "connect-history-api-fallback@^1.3.0", + "_where": "/Users/ericchiu/Desktop/CIS 700/HW7/Project7-BioCrowds/node_modules/webpack-dev-server", + "author": { + "name": "Ben Ripkens", + "email": "bripkens.dev@gmail.com", + "url": "http://bripkens.de" + }, + "bugs": { + "url": "https://github.com/bripkens/connect-history-api-fallback/issues" + }, + "contributors": [ + { + "name": "Craig Myles", + "email": "cr@igmyles.com", + "url": "http://www.craigmyles.com" + } + ], + "dependencies": {}, + "description": "Provides a fallback for non-existing directories so that the HTML 5 history API can be used.", + "devDependencies": { + "eslint": "^0.18.0", + "nodeunit": "^0.9.1", + "sinon": "^1.14.1" + }, + "directories": {}, + "dist": { + "shasum": "e51d17f8f0ef0db90a64fdb47de3051556e9f169", + "tarball": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.3.0.tgz" + }, + "engines": { + "node": ">=0.8" + }, + "gitHead": "709252d1b7afbf4b29748ec9a881684603d01f97", + "homepage": "https://github.com/bripkens/connect-history-api-fallback#readme", + "keyswords": [ + "connect", + "html5", + "history api", + "fallback", + "spa" + ], + "license": "MIT", + "main": "lib/index.js", + "maintainers": [ + { + "name": "bripkens", + "email": "bripkens.dev@gmail.com" + } + ], + "name": "connect-history-api-fallback", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+ssh://git@github.com/bripkens/connect-history-api-fallback.git" + }, + "scripts": { + "test": "eslint lib/index.js test/index_test.js && nodeunit test/index_test.js" + }, + "version": "1.3.0" +} diff --git a/node_modules/connect-history-api-fallback/test/index_test.js b/node_modules/connect-history-api-fallback/test/index_test.js new file mode 100644 index 00000000..a67e34d1 --- /dev/null +++ b/node_modules/connect-history-api-fallback/test/index_test.js @@ -0,0 +1,250 @@ +'use strict'; + +var sinon = require('sinon'); +var historyApiFallback = require('../lib'); + +var tests = module.exports = {}; + +var middleware; +var req = null; +var requestedUrl; +var next; + +tests.setUp = function(done) { + middleware = historyApiFallback(); + requestedUrl = '/foo'; + req = { + method: 'GET', + url: requestedUrl, + headers: { + accept: 'text/html, */*' + } + }; + next = sinon.stub(); + + done(); +}; + + +['POST', 'PUT', 'DELETE', 'HEAD', 'OPTIONS'].forEach(function(method) { + tests['should ignore ' + method + ' requests'] = function(test) { + req.method = method; + + middleware(req, null, next); + + test.equal(req.url, requestedUrl); + test.ok(next.called); + test.done(); + }; +}); + + +tests['should ignore requests that do not accept html'] = function(test) { + req.headers.accept = 'application/json'; + + middleware(req, null, next); + + test.equal(req.url, requestedUrl); + test.ok(next.called); + test.done(); +}; + + +tests['should ignore file requests'] = function(test) { + var expected = req.url = 'js/app.js'; + + middleware(req, null, next); + + test.equal(req.url, expected); + test.ok(next.called); + test.done(); +}; + + +tests['should rewrite requests when the . rule is disabled'] = function(test) { + req.url = 'js/app.js'; + middleware = historyApiFallback({ + disableDotRule: true + }); + middleware(req, null, next); + + test.equal(req.url, '/index.html'); + test.ok(next.called); + test.done(); +}; + + +tests['should take JSON preference into account'] = function(test) { + req.headers.accept = 'application/json, text/plain, */*'; + + middleware(req, null, next); + + test.equal(req.url, requestedUrl); + test.ok(next.called); + test.done(); +}; + + +tests['should rewrite valid requests'] = function(test) { + middleware(req, null, next); + + test.equal(req.url, '/index.html'); + test.ok(next.called); + test.done(); +}; + +tests['should not fail for missing HTTP accept header'] = function(test) { + delete req.headers.accept; + + middleware(req, null, next); + + test.equal(req.url, requestedUrl); + test.ok(next.called); + test.done(); +}; + +tests['should not fail for missing headers object'] = function(test) { + delete req.headers; + + middleware(req, null, next); + + test.equal(req.url, requestedUrl); + test.ok(next.called); + test.done(); +}; + +tests['should work in verbose mode'] = function(test) { + var expected = req.url = 'js/app.js'; + middleware = historyApiFallback({ + verbose: true + }); + + middleware(req, null, next); + + test.equal(req.url, expected); + test.ok(next.called); + test.done(); +}; + +tests['should work with a custom logger'] = function(test) { + var expected = req.url = 'js/app.js'; + var logger = sinon.stub(); + middleware = historyApiFallback({ + logger: logger + }); + + middleware(req, null, next); + + test.equal(req.url, expected); + test.ok(next.called); + test.ok(logger.calledOnce); + test.done(); +}; + +tests['should rewrite requested path according to rules'] = function(test) { + req.url = '/soccer'; + middleware = historyApiFallback({ + rewrites: [ + {from: /\/soccer/, to: '/soccer.html'} + ] + }); + + middleware(req, null, next); + + test.equal(req.url, '/soccer.html'); + test.ok(next.called); + test.done(); +}; + +tests['should support functions as rewrite rule'] = function(test) { + middleware = historyApiFallback({ + rewrites: [ + { + from: /^\/libs\/(.*)$/, + to: function(context) { + return './bower_components' + context.parsedUrl.pathname; + } + } + ] + }); + + req.url = '/libs/jquery/jquery.1.12.0.min.js'; + middleware(req, null, next); + test.equal(req.url, './bower_components/libs/jquery/jquery.1.12.0.min.js'); + test.ok(next.called); + + next = sinon.stub(); + var expected = req.url = '/js/main.js'; + middleware(req, null, next); + test.equal(req.url, expected); + test.ok(next.called); + + test.done(); +}; + +tests['should test rewrite rules'] = function(test) { + req.url = '/socer'; + middleware = historyApiFallback({ + rewrites: [ + {from: /\/soccer/, to: '/soccer.html'} + ] + }); + + middleware(req, null, next); + + test.equal(req.url, '/index.html'); + test.ok(next.called); + test.done(); +}; + +tests['should support custom index file'] = function(test) { + var index = 'default.html'; + req.url = '/socer'; + middleware = historyApiFallback({ + index: index + }); + + middleware(req, null, next); + + test.equal(req.url, index); + test.ok(next.called); + test.done(); +}; + +tests['should accept html requests based on headers option'] = function(test) { + req.headers.accept = '*/*'; + middleware = historyApiFallback({ + htmlAcceptHeaders: ['text/html', 'application/xhtml+xml'] + }); + + middleware(req, null, next); + + test.equal(req.url, requestedUrl); + test.ok(next.called); + test.done(); +}; + +tests['should support custom rewrite rules'] = function(test) { + req.headers.accept = '*/*'; + var url = '/app/login/app.js'; + req.url = url; + middleware = historyApiFallback({ + rewrites: [ + { + from: /\/app\/login/, + to: function onMatch(ctx) { + if (ctx.parsedUrl.path.indexOf('.js')) { + return ctx.parsedUrl.href; + } + return '/app/login/index.html'; + } + } + ] + }); + + middleware(req, null, next); + + test.equal(req.url, url); + test.ok(next.called); + test.done(); +}; diff --git a/node_modules/console-browserify/.npmignore b/node_modules/console-browserify/.npmignore new file mode 100644 index 00000000..aa3fd4b8 --- /dev/null +++ b/node_modules/console-browserify/.npmignore @@ -0,0 +1,14 @@ +.DS_Store +.monitor +.*.swp +.nodemonignore +releases +*.log +*.err +fleet.json +public/browserify +bin/*.json +.bin +build +compile +.lock-wscript diff --git a/node_modules/console-browserify/.testem.json b/node_modules/console-browserify/.testem.json new file mode 100644 index 00000000..633c2ba8 --- /dev/null +++ b/node_modules/console-browserify/.testem.json @@ -0,0 +1,14 @@ +{ + "launchers": { + "node": { + "command": "npm test" + } + }, + "src_files": [ + "./**/*.js" + ], + "before_tests": "npm run build", + "on_exit": "rm test/static/bundle.js", + "test_page": "test/static/index.html", + "launch_in_dev": ["node", "phantomjs"] +} diff --git a/node_modules/console-browserify/.travis.yml b/node_modules/console-browserify/.travis.yml new file mode 100644 index 00000000..ed178f63 --- /dev/null +++ b/node_modules/console-browserify/.travis.yml @@ -0,0 +1,4 @@ +language: node_js +node_js: + - 0.8 + - 0.9 diff --git a/node_modules/console-browserify/LICENCE b/node_modules/console-browserify/LICENCE new file mode 100644 index 00000000..a23e08a8 --- /dev/null +++ b/node_modules/console-browserify/LICENCE @@ -0,0 +1,19 @@ +Copyright (c) 2012 Raynos. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +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. \ No newline at end of file diff --git a/node_modules/console-browserify/README.md b/node_modules/console-browserify/README.md new file mode 100644 index 00000000..572615eb --- /dev/null +++ b/node_modules/console-browserify/README.md @@ -0,0 +1,33 @@ +# console-browserify + +[![build status][1]][2] + +[![browser support][3]][4] + + +Emulate console for all the browsers + +## Example + +```js +var console = require("console-browserify") + +console.log("hello world!") +``` + +## Installation + +`npm install console-browserify` + +## Contributors + + - Raynos + +## MIT Licenced + + + + [1]: https://secure.travis-ci.org/Raynos/console-browserify.png + [2]: http://travis-ci.org/Raynos/console-browserify + [3]: http://ci.testling.com/Raynos/console-browserify.png + [4]: http://ci.testling.com/Raynos/console-browserify diff --git a/node_modules/console-browserify/index.js b/node_modules/console-browserify/index.js new file mode 100644 index 00000000..af433ce8 --- /dev/null +++ b/node_modules/console-browserify/index.js @@ -0,0 +1,86 @@ +/*global window, global*/ +var util = require("util") +var assert = require("assert") +var now = require("date-now") + +var slice = Array.prototype.slice +var console +var times = {} + +if (typeof global !== "undefined" && global.console) { + console = global.console +} else if (typeof window !== "undefined" && window.console) { + console = window.console +} else { + console = {} +} + +var functions = [ + [log, "log"], + [info, "info"], + [warn, "warn"], + [error, "error"], + [time, "time"], + [timeEnd, "timeEnd"], + [trace, "trace"], + [dir, "dir"], + [consoleAssert, "assert"] +] + +for (var i = 0; i < functions.length; i++) { + var tuple = functions[i] + var f = tuple[0] + var name = tuple[1] + + if (!console[name]) { + console[name] = f + } +} + +module.exports = console + +function log() {} + +function info() { + console.log.apply(console, arguments) +} + +function warn() { + console.log.apply(console, arguments) +} + +function error() { + console.warn.apply(console, arguments) +} + +function time(label) { + times[label] = now() +} + +function timeEnd(label) { + var time = times[label] + if (!time) { + throw new Error("No such label: " + label) + } + + var duration = now() - time + console.log(label + ": " + duration + "ms") +} + +function trace() { + var err = new Error() + err.name = "Trace" + err.message = util.format.apply(null, arguments) + console.error(err.stack) +} + +function dir(object) { + console.log(util.inspect(object) + "\n") +} + +function consoleAssert(expression) { + if (!expression) { + var arr = slice.call(arguments, 1) + assert.ok(false, util.format.apply(null, arr)) + } +} diff --git a/node_modules/console-browserify/package.json b/node_modules/console-browserify/package.json new file mode 100644 index 00000000..c653934c --- /dev/null +++ b/node_modules/console-browserify/package.json @@ -0,0 +1,122 @@ +{ + "_args": [ + [ + { + "raw": "console-browserify@^1.1.0", + "scope": null, + "escapedName": "console-browserify", + "name": "console-browserify", + "rawSpec": "^1.1.0", + "spec": ">=1.1.0 <2.0.0", + "type": "range" + }, + "/Users/ericchiu/Desktop/CIS 700/HW7/Project7-BioCrowds/node_modules/node-libs-browser" + ] + ], + "_from": "console-browserify@>=1.1.0 <2.0.0", + "_id": "console-browserify@1.1.0", + "_inCache": true, + "_location": "/console-browserify", + "_npmUser": { + "name": "raynos", + "email": "raynos2@gmail.com" + }, + "_npmVersion": "1.4.6", + "_phantomChildren": {}, + "_requested": { + "raw": "console-browserify@^1.1.0", + "scope": null, + "escapedName": "console-browserify", + "name": "console-browserify", + "rawSpec": "^1.1.0", + "spec": ">=1.1.0 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/node-libs-browser" + ], + "_resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz", + "_shasum": "f0241c45730a9fc6323b206dbf38edc741d0bb10", + "_shrinkwrap": null, + "_spec": "console-browserify@^1.1.0", + "_where": "/Users/ericchiu/Desktop/CIS 700/HW7/Project7-BioCrowds/node_modules/node-libs-browser", + "author": { + "name": "Raynos", + "email": "raynos2@gmail.com" + }, + "bugs": { + "url": "https://github.com/Raynos/console-browserify/issues", + "email": "raynos2@gmail.com" + }, + "contributors": [ + { + "name": "Raynos" + } + ], + "dependencies": { + "date-now": "^0.1.4" + }, + "description": "Emulate console for all the browsers", + "devDependencies": { + "jsonify": "0.0.0", + "run-browser": "^1.3.0", + "tap-dot": "^0.2.1", + "tap-spec": "^0.1.8", + "tape": "^2.12.3" + }, + "directories": {}, + "dist": { + "shasum": "f0241c45730a9fc6323b206dbf38edc741d0bb10", + "tarball": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz" + }, + "homepage": "https://github.com/Raynos/console-browserify", + "keywords": [], + "licenses": [ + { + "type": "MIT", + "url": "http://github.com/Raynos/console-browserify/raw/master/LICENSE" + } + ], + "main": "index", + "maintainers": [ + { + "name": "raynos", + "email": "raynos2@gmail.com" + } + ], + "name": "console-browserify", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/Raynos/console-browserify.git" + }, + "scripts": { + "browser": "run-browser test/index.js", + "build": "browserify test/index.js -o test/static/bundle.js", + "cover": "istanbul cover --report none --print detail ./test/index.js", + "dot": "node ./test/index.js | tap-dot", + "phantom": "run-browser test/index.js -b | tap-spec", + "start": "node ./index.js", + "test": "node ./test/index.js | tap-spec", + "testem": "testem", + "view-cover": "istanbul report html && google-chrome ./coverage/index.html" + }, + "testling": { + "files": "test/index.js", + "browsers": [ + "ie/8..latest", + "firefox/16..latest", + "firefox/nightly", + "chrome/22..latest", + "chrome/canary", + "opera/12..latest", + "opera/next", + "safari/5.1..latest", + "ipad/6.0..latest", + "iphone/6.0..latest", + "android-browser/4.2..latest" + ] + }, + "version": "1.1.0" +} diff --git a/node_modules/console-browserify/test/index.js b/node_modules/console-browserify/test/index.js new file mode 100644 index 00000000..26dfaad6 --- /dev/null +++ b/node_modules/console-browserify/test/index.js @@ -0,0 +1,67 @@ +var console = require("../index") +var test = require("tape") + +if (typeof window !== "undefined" && !window.JSON) { + window.JSON = require("jsonify") +} + +test("console has expected methods", function (assert) { + assert.ok(console.log) + assert.ok(console.info) + assert.ok(console.warn) + assert.ok(console.dir) + assert.ok(console.time, "time") + assert.ok(console.timeEnd, "timeEnd") + assert.ok(console.trace, "trace") + assert.ok(console.assert) + + assert.end() +}) + +test("invoke console.log", function (assert) { + console.log("test-log") + + assert.end() +}) + +test("invoke console.info", function (assert) { + console.info("test-info") + + assert.end() +}) + +test("invoke console.warn", function (assert) { + console.warn("test-warn") + + assert.end() +}) + +test("invoke console.time", function (assert) { + console.time("label") + + assert.end() +}) + +test("invoke console.trace", function (assert) { + console.trace("test-trace") + + assert.end() +}) + +test("invoke console.assert", function (assert) { + console.assert(true) + + assert.end() +}) + +test("invoke console.dir", function (assert) { + console.dir("test-dir") + + assert.end() +}) + +test("invoke console.timeEnd", function (assert) { + console.timeEnd("label") + + assert.end() +}) diff --git a/node_modules/console-browserify/test/static/index.html b/node_modules/console-browserify/test/static/index.html new file mode 100644 index 00000000..dd55012f --- /dev/null +++ b/node_modules/console-browserify/test/static/index.html @@ -0,0 +1,12 @@ + + + + +Welcome back, ' + escapeHtml(name) + '!
'); + } else { + res.write('Hello, new visitor!
'); + } + + res.write(' values + * + * @param {string} str + * @param {object} [options] + * @return {object} + * @public + */ + +function parse(str, options) { + if (typeof str !== 'string') { + throw new TypeError('argument str must be a string'); + } + + var obj = {} + var opt = options || {}; + var pairs = str.split(pairSplitRegExp); + var dec = opt.decode || decode; + + for (var i = 0; i < pairs.length; i++) { + var pair = pairs[i]; + var eq_idx = pair.indexOf('='); + + // skip things that don't look like key=value + if (eq_idx < 0) { + continue; + } + + var key = pair.substr(0, eq_idx).trim() + var val = pair.substr(++eq_idx, pair.length).trim(); + + // quoted values + if ('"' == val[0]) { + val = val.slice(1, -1); + } + + // only assign once + if (undefined == obj[key]) { + obj[key] = tryDecode(val, dec); + } + } + + return obj; +} + +/** + * Serialize data into a cookie header. + * + * Serialize the a name value pair into a cookie string suitable for + * http headers. An optional options object specified cookie parameters. + * + * serialize('foo', 'bar', { httpOnly: true }) + * => "foo=bar; httpOnly" + * + * @param {string} name + * @param {string} val + * @param {object} [options] + * @return {string} + * @public + */ + +function serialize(name, val, options) { + var opt = options || {}; + var enc = opt.encode || encode; + + if (typeof enc !== 'function') { + throw new TypeError('option encode is invalid'); + } + + if (!fieldContentRegExp.test(name)) { + throw new TypeError('argument name is invalid'); + } + + var value = enc(val); + + if (value && !fieldContentRegExp.test(value)) { + throw new TypeError('argument val is invalid'); + } + + var str = name + '=' + value; + + if (null != opt.maxAge) { + var maxAge = opt.maxAge - 0; + if (isNaN(maxAge)) throw new Error('maxAge should be a Number'); + str += '; Max-Age=' + Math.floor(maxAge); + } + + if (opt.domain) { + if (!fieldContentRegExp.test(opt.domain)) { + throw new TypeError('option domain is invalid'); + } + + str += '; Domain=' + opt.domain; + } + + if (opt.path) { + if (!fieldContentRegExp.test(opt.path)) { + throw new TypeError('option path is invalid'); + } + + str += '; Path=' + opt.path; + } + + if (opt.expires) { + if (typeof opt.expires.toUTCString !== 'function') { + throw new TypeError('option expires is invalid'); + } + + str += '; Expires=' + opt.expires.toUTCString(); + } + + if (opt.httpOnly) { + str += '; HttpOnly'; + } + + if (opt.secure) { + str += '; Secure'; + } + + if (opt.sameSite) { + var sameSite = typeof opt.sameSite === 'string' + ? opt.sameSite.toLowerCase() : opt.sameSite; + + switch (sameSite) { + case true: + str += '; SameSite=Strict'; + break; + case 'lax': + str += '; SameSite=Lax'; + break; + case 'strict': + str += '; SameSite=Strict'; + break; + default: + throw new TypeError('option sameSite is invalid'); + } + } + + return str; +} + +/** + * Try decoding a string using a decoding function. + * + * @param {string} str + * @param {function} decode + * @private + */ + +function tryDecode(str, decode) { + try { + return decode(str); + } catch (e) { + return str; + } +} diff --git a/node_modules/cookie/package.json b/node_modules/cookie/package.json new file mode 100644 index 00000000..16471401 --- /dev/null +++ b/node_modules/cookie/package.json @@ -0,0 +1,106 @@ +{ + "_args": [ + [ + { + "raw": "cookie@0.3.1", + "scope": null, + "escapedName": "cookie", + "name": "cookie", + "rawSpec": "0.3.1", + "spec": "0.3.1", + "type": "version" + }, + "/Users/ericchiu/Desktop/CIS 700/HW7/Project7-BioCrowds/node_modules/express" + ] + ], + "_from": "cookie@0.3.1", + "_id": "cookie@0.3.1", + "_inCache": true, + "_location": "/cookie", + "_npmOperationalInternal": { + "host": "packages-12-west.internal.npmjs.com", + "tmp": "tmp/cookie-0.3.1.tgz_1464323556714_0.6435900838114321" + }, + "_npmUser": { + "name": "dougwilson", + "email": "doug@somethingdoug.com" + }, + "_npmVersion": "1.4.28", + "_phantomChildren": {}, + "_requested": { + "raw": "cookie@0.3.1", + "scope": null, + "escapedName": "cookie", + "name": "cookie", + "rawSpec": "0.3.1", + "spec": "0.3.1", + "type": "version" + }, + "_requiredBy": [ + "/express" + ], + "_resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", + "_shasum": "e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb", + "_shrinkwrap": null, + "_spec": "cookie@0.3.1", + "_where": "/Users/ericchiu/Desktop/CIS 700/HW7/Project7-BioCrowds/node_modules/express", + "author": { + "name": "Roman Shtylman", + "email": "shtylman@gmail.com" + }, + "bugs": { + "url": "https://github.com/jshttp/cookie/issues" + }, + "contributors": [ + { + "name": "Douglas Christopher Wilson", + "email": "doug@somethingdoug.com" + } + ], + "dependencies": {}, + "description": "HTTP server cookie parsing and serialization", + "devDependencies": { + "istanbul": "0.4.3", + "mocha": "1.21.5" + }, + "directories": {}, + "dist": { + "shasum": "e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb", + "tarball": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz" + }, + "engines": { + "node": ">= 0.6" + }, + "files": [ + "HISTORY.md", + "LICENSE", + "README.md", + "index.js" + ], + "gitHead": "e3c77d497d66c8b8d4b677b8954c1b192a09f0b3", + "homepage": "https://github.com/jshttp/cookie", + "keywords": [ + "cookie", + "cookies" + ], + "license": "MIT", + "maintainers": [ + { + "name": "dougwilson", + "email": "doug@somethingdoug.com" + } + ], + "name": "cookie", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/jshttp/cookie.git" + }, + "scripts": { + "test": "mocha --reporter spec --bail --check-leaks test/", + "test-ci": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter spec --check-leaks test/", + "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot --check-leaks test/" + }, + "version": "0.3.1" +} diff --git a/node_modules/core-js/CHANGELOG.md b/node_modules/core-js/CHANGELOG.md new file mode 100644 index 00000000..b597d55d --- /dev/null +++ b/node_modules/core-js/CHANGELOG.md @@ -0,0 +1,561 @@ +## Changelog +##### 2.4.1 - 2016.07.18 +- fixed `script` tag for some parsers, [#204](https://github.com/zloirock/core-js/issues/204), [#216](https://github.com/zloirock/core-js/issues/216) +- removed some unused variables, [#217](https://github.com/zloirock/core-js/issues/217), [#218](https://github.com/zloirock/core-js/issues/218) +- fixed MS Edge `Reflect.construct` and `Reflect.apply` - they should not allow primitive as `argumentsList` argument + +##### 1.2.7 [LEGACY] - 2016.07.18 +- some fixes for issues like [#159](https://github.com/zloirock/core-js/issues/159), [#186](https://github.com/zloirock/core-js/issues/186), [#194](https://github.com/zloirock/core-js/issues/194), [#207](https://github.com/zloirock/core-js/issues/207) + +##### 2.4.0 - 2016.05.08 +- Added `Observable`, [stage 1 proposal](https://github.com/zenparsing/es-observable) +- Fixed behavior `Object.{getOwnPropertySymbols, getOwnPropertyDescriptor}` and `Object#propertyIsEnumerable` on `Object.prototype` +- `Reflect.construct` and `Reflect.apply` should throw an error if `argumentsList` argument is not an object, [#194](https://github.com/zloirock/core-js/issues/194) + +##### 2.3.0 - 2016.04.24 +- Added `asap` for enqueuing microtasks, [stage 0 proposal](https://github.com/rwaldron/tc39-notes/blob/master/es6/2014-09/sept-25.md#510-globalasap-for-enqueuing-a-microtask) +- Added well-known symbol `Symbol.asyncIterator` for [stage 2 async iteration proposal](https://github.com/tc39/proposal-async-iteration) +- Added well-known symbol `Symbol.observable` for [stage 1 observables proposal](https://github.com/zenparsing/es-observable) +- `String#{padStart, padEnd}` returns original string if filler is empty string, [TC39 meeting notes](https://github.com/rwaldron/tc39-notes/blob/master/es7/2016-03/march-29.md#stringprototypepadstartpadend) +- `Object.values` and `Object.entries` moved to stage 4 from 3, [TC39 meeting notes](https://github.com/rwaldron/tc39-notes/blob/master/es7/2016-03/march-29.md#objectvalues--objectentries) +- `System.global` moved to stage 2 from 1, [TC39 meeting notes](https://github.com/rwaldron/tc39-notes/blob/master/es7/2016-03/march-29.md#systemglobal) +- `Map#toJSON` and `Set#toJSON` rejected and will be removed from the next major release, [TC39 meeting notes](https://github.com/rwaldron/tc39-notes/blob/master/es7/2016-03/march-31.md#mapprototypetojsonsetprototypetojson) +- `Error.isError` withdrawn and will be removed from the next major release, [TC39 meeting notes](https://github.com/rwaldron/tc39-notes/blob/master/es7/2016-03/march-29.md#erroriserror) +- Added fallback for `Function#name` on non-extensible functions and functions with broken `toString` conversion, [#193](https://github.com/zloirock/core-js/issues/193) + +##### 2.2.2 - 2016.04.06 +- Added conversion `-0` to `+0` to `Array#{indexOf, lastIndexOf}`, [ES2016 fix](https://github.com/tc39/ecma262/pull/316) +- Added fixes for some `Math` methods in Tor Browser +- `Array.{from, of}` no longer calls prototype setters +- Added workaround over Chrome DevTools strange behavior, [#186](https://github.com/zloirock/core-js/issues/186) + +##### 2.2.1 - 2016.03.19 +- Fixed `Object.getOwnPropertyNames(window)` `2.1+` versions bug, [#181](https://github.com/zloirock/core-js/issues/181) + +##### 2.2.0 - 2016.03.15 +- Added `String#matchAll`, [proposal](https://github.com/tc39/String.prototype.matchAll) +- Added `Object#__(define|lookup)[GS]etter__`, [annex B ES2017](https://github.com/tc39/ecma262/pull/381) +- Added `@@toPrimitive` methods to `Date` and `Symbol` +- Fixed `%TypedArray%#slice` in Edge ~ 13 (throws with `@@species` and wrapped / inherited constructor) +- Some other minor fixes + +##### 2.1.5 - 2016.03.12 +- Improved support NodeJS domains in `Promise#then`, [#180](https://github.com/zloirock/core-js/issues/180) +- Added fallback for `Date#toJSON` bug in Qt Script, [#173](https://github.com/zloirock/core-js/issues/173#issuecomment-193972502) + +##### 2.1.4 - 2016.03.08 +- Added fallback for `Symbol` polyfill in Qt Script, [#173](https://github.com/zloirock/core-js/issues/173) +- Added one more fallback for IE11 `Script Access Denied` error with iframes, [#165](https://github.com/zloirock/core-js/issues/165) + +##### 2.1.3 - 2016.02.29 +- Added fallback for [`es6-promise` package bug](https://github.com/stefanpenner/es6-promise/issues/169), [#176](https://github.com/zloirock/core-js/issues/176) + +##### 2.1.2 - 2016.02.29 +- Some minor `Promise` fixes: + - Browsers `rejectionhandled` event better HTML spec complaint + - Errors in unhandled rejection handlers should not cause any problems + - Fixed typo in feature detection + +##### 2.1.1 - 2016.02.22 +- Some `Promise` improvements: + - Feature detection: + - **Added detection unhandled rejection tracking support - now it's available everywhere**, [#140](https://github.com/zloirock/core-js/issues/140) + - Added detection `@@species` pattern support for completely correct subclassing + - Removed usage `Object.setPrototypeOf` from feature detection and noisy console message about it in FF + - `Promise.all` fixed for some very specific cases + +##### 2.1.0 - 2016.02.09 +- **API**: + - ES5 polyfills are split and logic, used in other polyfills, moved to internal modules + - **All entry point works in ES3 environment like IE8- without `core-js/(library/)es5`** + - **Added all missed single entry points for ES5 polyfills** + - Separated ES5 polyfills moved to the ES6 namespace. Why? + - Mainly, for prevent duplication features in different namespaces - logic of most required ES5 polyfills changed in ES6+: + - Already added changes for: `Object` statics - should accept primitives, new whitespaces lists in `String#trim`, `parse(Int|float)`, `RegExp#toString` logic, `String#split`, etc + - Should be changed in the future: `@@species` and `ToLength` logic in `Array` methods, `Date` parsing, `Function#bind`, etc + - Should not be changed only several features like `Array.isArray` and `Date.now` + - Some ES5 polyfills required for modern engines + - All old entry points should work fine, but in the next major release API can be changed + - `Object.getOwnPropertyDescriptors` moved to the stage 3, [January TC39 meeting](https://github.com/rwaldron/tc39-notes/blob/master/es7/2016-01/2016-01-28.md#objectgetownpropertydescriptors-to-stage-3-jordan-harband-low-priority-but-super-quick) + - Added `umd` option for [custom build process](https://github.com/zloirock/core-js#custom-build-from-external-scripts), [#169](https://github.com/zloirock/core-js/issues/169) + - Returned entry points for `Array` statics, removed in `2.0`, for compatibility with `babel` `6` and for future fixes +- **Deprecated**: + - `Reflect.enumerate` deprecated and will be removed from the next major release, [January TC39 meeting](https://github.com/rwaldron/tc39-notes/blob/master/es7/2016-01/2016-01-28.md#5xix-revisit-proxy-enumerate---revisit-decision-to-exhaust-iterator) +- **New Features**: + - Added [`Reflect` metadata API](https://github.com/jonathandturner/decorators/blob/master/specs/metadata.md) as a pre-strawman feature, [#152](https://github.com/zloirock/core-js/issues/152): + - `Reflect.defineMetadata` + - `Reflect.deleteMetadata` + - `Reflect.getMetadata` + - `Reflect.getMetadataKeys` + - `Reflect.getOwnMetadata` + - `Reflect.getOwnMetadataKeys` + - `Reflect.hasMetadata` + - `Reflect.hasOwnMetadata` + - `Reflect.metadata` + - Implementation / fixes `Date#toJSON` + - Fixes for `parseInt` and `Number.parseInt` + - Fixes for `parseFloat` and `Number.parseFloat` + - Fixes for `RegExp#toString` + - Fixes for `Array#sort` + - Fixes for `Number#toFixed` + - Fixes for `Number#toPrecision` + - Additional fixes for `String#split` (`RegExp#@@split`) +- **Improvements**: + - Correct subclassing wrapped collections, `Number` and `RegExp` constructors with native class syntax + - Correct support `SharedArrayBuffer` and buffers from other realms in typed arrays wrappers + - Additional validations for `Object.{defineProperty, getOwnPropertyDescriptor}` and `Reflect.defineProperty` +- **Bug Fixes**: + - Fixed some cases `Array#lastIndexOf` with negative second argument + +##### 2.0.3 - 2016.01.11 +- Added fallback for V8 ~ Chrome 49 `Promise` subclassing bug causes unhandled rejection on feature detection, [#159](https://github.com/zloirock/core-js/issues/159) +- Added fix for very specific environments with global `window === null` + +##### 2.0.2 - 2016.01.04 +- Temporarily removed `length` validation from `Uint8Array` constructor wrapper. Reason - [bug in `ws` module](https://github.com/websockets/ws/pull/645) (-> `socket.io`) which passes to `Buffer` constructor -> `Uint8Array` float and uses [the `V8` bug](https://code.google.com/p/v8/issues/detail?id=4552) for conversion to int (by the spec should be thrown an error). [It creates problems for many people.](https://github.com/karma-runner/karma/issues/1768) I hope, it will be returned after fixing this bug in `V8`. + +##### 2.0.1 - 2015.12.31 +- forced usage `Promise.resolve` polyfill in the `library` version for correct work with wrapper +- `Object.assign` should be defined in the strict mode -> throw an error on extension non-extensible objects, [#154](https://github.com/zloirock/core-js/issues/154) + +##### 2.0.0 - 2015.12.24 +- added implementations and fixes [Typed Arrays](https://github.com/zloirock/core-js#ecmascript-6-typed-arrays)-related features + - `ArrayBuffer`, `ArrayBuffer.isView`, `ArrayBuffer#slice` + - `DataView` with all getter / setter methods + - `Int8Array`, `Uint8Array`, `Uint8ClampedArray`, `Int16Array`, `Uint16Array`, `Int32Array`, `Uint32Array`, `Float32Array` and `Float64Array` constructors + - `%TypedArray%.{for, of}`, `%TypedArray%#{copyWithin, every, fill, filter, find, findIndex, forEach, indexOf, includes, join, lastIndexOf, map, reduce, reduceRight, reverse, set, slice, some, sort, subarray, values, keys, entries, @@iterator, ...}` +- added [`System.global`](https://github.com/zloirock/core-js#ecmascript-7-proposals), [proposal](https://github.com/tc39/proposal-global), [November TC39 meeting](https://github.com/rwaldron/tc39-notes/tree/master/es7/2015-11/nov-19.md#systemglobal-jhd) +- added [`Error.isError`](https://github.com/zloirock/core-js#ecmascript-7-proposals), [proposal](https://github.com/ljharb/proposal-is-error), [November TC39 meeting](https://github.com/rwaldron/tc39-notes/tree/master/es7/2015-11/nov-19.md#jhd-erroriserror) +- added [`Math.{iaddh, isubh, imulh, umulh}`](https://github.com/zloirock/core-js#ecmascript-7-proposals), [proposal](https://gist.github.com/BrendanEich/4294d5c212a6d2254703) +- `RegExp.escape` moved from the `es7` to the non-standard `core` namespace, [July TC39 meeting](https://github.com/rwaldron/tc39-notes/blob/master/es7/2015-07/july-28.md#62-regexpescape) - too slow, but it's condition of stability, [#116](https://github.com/zloirock/core-js/issues/116) +- [`Promise`](https://github.com/zloirock/core-js#ecmascript-6-promise) + - some performance optimisations + - added basic support [`rejectionHandled` event / `onrejectionhandled` handler](https://github.com/zloirock/core-js#unhandled-rejection-tracking) to the polyfill + - removed usage `@@species` from `Promise.{all, race}`, [November TC39 meeting](https://github.com/rwaldron/tc39-notes/tree/master/es7/2015-11/nov-18.md#conclusionresolution-2) +- some improvements [collections polyfills](https://github.com/zloirock/core-js#ecmascript-6-collections) + - `O(1)` and preventing possible leaks with frozen keys, [#134](https://github.com/zloirock/core-js/issues/134) + - correct observable state object keys +- renamed `String#{padLeft, padRight}` -> [`String#{padStart, padEnd}`](https://github.com/zloirock/core-js#ecmascript-7-proposals), [proposal](https://github.com/tc39/proposal-string-pad-start-end), [November TC39 meeting](https://github.com/rwaldron/tc39-notes/tree/master/es7/2015-11/nov-17.md#conclusionresolution-2) (they want to rename it on each meeting?O_o), [#132](https://github.com/zloirock/core-js/issues/132) +- added [`String#{trimStart, trimEnd}` as aliases for `String#{trimLeft, trimRight}`](https://github.com/zloirock/core-js#ecmascript-7-proposals), [proposal](https://github.com/sebmarkbage/ecmascript-string-left-right-trim), [November TC39 meeting](https://github.com/rwaldron/tc39-notes/tree/master/es7/2015-11/nov-17.md#conclusionresolution-2) +- added [annex B HTML methods](https://github.com/zloirock/core-js#ecmascript-6-string) - ugly, but also [the part of the spec](http://www.ecma-international.org/ecma-262/6.0/#sec-string.prototype.anchor) +- added little fix for [`Date#toString`](https://github.com/zloirock/core-js#ecmascript-6-date) - `new Date(NaN).toString()` [should be `'Invalid Date'`](http://www.ecma-international.org/ecma-262/6.0/#sec-todatestring) +- added [`{keys, values, entries, @@iterator}` methods to DOM collections](https://github.com/zloirock/core-js#iterable-dom-collections) which should have [iterable interface](https://heycam.github.io/webidl/#idl-iterable) or should be [inherited from `Array`](https://heycam.github.io/webidl/#LegacyArrayClass) - `NodeList`, `DOMTokenList`, `MediaList`, `StyleSheetList`, `CSSRuleList`. +- removed Mozilla `Array` generics - [deprecated and will be removed from FF](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array#Array_generic_methods), [looks like strawman is dead](http://wiki.ecmascript.org/doku.php?id=strawman:array_statics), available [alternative shim](https://github.com/plusdude/array-generics) +- removed `core.log` module +- CommonJS API + - added entry points for [virtual methods](https://github.com/zloirock/core-js#commonjs-and-prototype-methods-without-global-namespace-pollution) + - added entry points for [stages proposals](https://github.com/zloirock/core-js#ecmascript-7-proposals) + - some other minor changes +- [custom build from external scripts](https://github.com/zloirock/core-js#custom-build-from-external-scripts) moved to the separate package for preventing problems with dependencies +- changed `$` prefix for internal modules file names because Team Foundation Server does not support it, [#129](https://github.com/zloirock/core-js/issues/129) +- additional fix for `SameValueZero` in V8 ~ Chromium 39-42 collections +- additional fix for FF27 `Array` iterator +- removed usage shortcuts for `arguments` object - old WebKit bug, [#150](https://github.com/zloirock/core-js/issues/150) +- `{Map, Set}#forEach` non-generic, [#144](https://github.com/zloirock/core-js/issues/144) +- many other improvements + +##### 1.2.6 - 2015.11.09 +* reject with `TypeError` on attempt resolve promise itself +* correct behavior with broken `Promise` subclass constructors / methods +* added `Promise`-based fallback for microtask +* fixed V8 and FF `Array#{values, @@iterator}.name` +* fixed IE7- `[1, 2].join(undefined) -> '1,2'` +* some other fixes / improvements / optimizations + +##### 1.2.5 - 2015.11.02 +* some more `Number` constructor fixes: + * fixed V8 ~ Node 0.8 bug: `Number('+0x1')` should be `NaN` + * fixed `Number(' 0b1\n')` case, should be `1` + * fixed `Number()` case, should be `0` + +##### 1.2.4 - 2015.11.01 +* fixed `Number('0b12') -> NaN` case in the shim +* fixed V8 ~ Chromium 40- bug - `Weak(Map|Set)#{delete, get, has}` should not throw errors [#124](https://github.com/zloirock/core-js/issues/124) +* some other fixes and optimizations + +##### 1.2.3 - 2015.10.23 +* fixed some problems related old V8 bug `Object('a').propertyIsEnumerable(0) // => false`, for example, `Object.assign({}, 'qwe')` from the last release +* fixed `.name` property and `Function#toString` conversion some polyfilled methods +* fixed `Math.imul` arity in Safari 8- + +##### 1.2.2 - 2015.10.18 +* improved optimisations for V8 +* fixed build process from external packages, [#120](https://github.com/zloirock/core-js/pull/120) +* one more `Object.{assign, values, entries}` fix for [**very** specific case](https://github.com/ljharb/proposal-object-values-entries/issues/5) + +##### 1.2.1 - 2015.10.02 +* replaced fix `JSON.stringify` + `Symbol` behavior from `.toJSON` method to wrapping `JSON.stringify` - little more correct, [compat-table/642](https://github.com/kangax/compat-table/pull/642) +* fixed typo which broke tasks scheduler in WebWorkers in old FF, [#114](https://github.com/zloirock/core-js/pull/114) + +##### 1.2.0 - 2015.09.27 +* added browser [`Promise` rejection hook](#unhandled-rejection-tracking), [#106](https://github.com/zloirock/core-js/issues/106) +* added correct [`IsRegExp`](http://www.ecma-international.org/ecma-262/6.0/#sec-isregexp) logic to [`String#{includes, startsWith, endsWith}`](https://github.com/zloirock/core-js/#ecmascript-6-string) and [`RegExp` constructor](https://github.com/zloirock/core-js/#ecmascript-6-regexp), `@@match` case, [example](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/match#Disabling_the_isRegExp_check) +* updated [`String#leftPad`](https://github.com/zloirock/core-js/#ecmascript-7-proposals) [with proposal](https://github.com/ljharb/proposal-string-pad-left-right/issues/6): string filler truncated from the right side +* replaced V8 [`Object.assign`](https://github.com/zloirock/core-js/#ecmascript-6-object) - its properties order not only [incorrect](https://github.com/sindresorhus/object-assign/issues/22), it is non-deterministic and it causes some problems +* fixed behavior with deleted in getters properties for `Object.{`[`assign`](https://github.com/zloirock/core-js/#ecmascript-6-object)`, `[`entries, values`](https://github.com/zloirock/core-js/#ecmascript-7-proposals)`}`, [example](http://goo.gl/iQE01c) +* fixed [`Math.sinh`](https://github.com/zloirock/core-js/#ecmascript-6-math) with very small numbers in V8 near Chromium 38 +* some other fixes and optimizations + +##### 1.1.4 - 2015.09.05 +* fixed support symbols in FF34-35 [`Object.assign`](https://github.com/zloirock/core-js/#ecmascript-6-object) +* fixed [collections iterators](https://github.com/zloirock/core-js/#ecmascript-6-iterators) in FF25-26 +* fixed non-generic WebKit [`Array.of`](https://github.com/zloirock/core-js/#ecmascript-6-array) +* some other fixes and optimizations + +##### 1.1.3 - 2015.08.29 +* fixed support Node.js domains in [`Promise`](https://github.com/zloirock/core-js/#ecmascript-6-promise), [#103](https://github.com/zloirock/core-js/issues/103) + +##### 1.1.2 - 2015.08.28 +* added `toJSON` method to [`Symbol`](https://github.com/zloirock/core-js/#ecmascript-6-symbol) polyfill and to MS Edge implementation for expected `JSON.stringify` result w/o patching this method +* replaced [`Reflect.construct`](https://github.com/zloirock/core-js/#ecmascript-6-reflect) implementations w/o correct support third argument +* fixed `global` detection with changed `document.domain` in ~IE8, [#100](https://github.com/zloirock/core-js/issues/100) + +##### 1.1.1 - 2015.08.20 +* added more correct microtask implementation for [`Promise`](#ecmascript-6-promise) + +##### 1.1.0 - 2015.08.17 +* updated [string padding](https://github.com/zloirock/core-js/#ecmascript-7-proposals) to [actual proposal](https://github.com/ljharb/proposal-string-pad-left-right) - renamed, minor internal changes: + * `String#lpad` -> `String#padLeft` + * `String#rpad` -> `String#padRight` +* added [string trim functions](#ecmascript-7-proposals) - [proposal](https://github.com/sebmarkbage/ecmascript-string-left-right-trim), defacto standard - required only for IE11- and fixed for some old engines: + * `String#trimLeft` + * `String#trimRight` +* [`String#trim`](https://github.com/zloirock/core-js/#ecmascript-6-string) fixed for some engines by es6 spec and moved from `es5` to single `es6` module +* splitted [`es6.object.statics-accept-primitives`](https://github.com/zloirock/core-js/#ecmascript-6-object) +* caps for `freeze`-family `Object` methods moved from `es5` to `es6` namespace and joined with [es6 wrappers](https://github.com/zloirock/core-js/#ecmascript-6-object) +* `es5` [namespace](https://github.com/zloirock/core-js/#commonjs) also includes modules, moved to `es6` namespace - you can use it as before +* increased `MessageChannel` priority in `$.task`, [#95](https://github.com/zloirock/core-js/issues/95) +* does not get `global.Symbol` on each getting iterator, if you wanna use alternative `Symbol` shim - add it before `core-js` +* [`Reflect.construct`](https://github.com/zloirock/core-js/#ecmascript-6-reflect) optimized and fixed for some cases +* simplified [`Reflect.enumerate`](https://github.com/zloirock/core-js/#ecmascript-6-reflect), see [this question](https://esdiscuss.org/topic/question-about-enumerate-and-property-decision-timing) +* some corrections in [`Math.acosh`](https://github.com/zloirock/core-js/#ecmascript-6-math) +* fixed [`Math.imul`](https://github.com/zloirock/core-js/#ecmascript-6-math) for old WebKit +* some fixes in string / RegExp [well-known symbols](https://github.com/zloirock/core-js/#ecmascript-6-regexp) logic +* some other fixes and optimizations + +##### 1.0.1 - 2015.07.31 +* some fixes for final MS Edge, replaced broken native `Reflect.defineProperty` +* some minor fixes and optimizations +* changed compression `client/*.min.js` options for safe `Function#name` and `Function#length`, should be fixed [#92](https://github.com/zloirock/core-js/issues/92) + +##### 1.0.0 - 2015.07.22 +* added logic for [well-known symbols](https://github.com/zloirock/core-js/#ecmascript-6-regexp): + * `Symbol.match` + * `Symbol.replace` + * `Symbol.split` + * `Symbol.search` +* actualized and optimized work with iterables: + * optimized [`Map`, `Set`, `WeakMap`, `WeakSet` constructors](https://github.com/zloirock/core-js/#ecmascript-6-collections), [`Promise.all`, `Promise.race`](https://github.com/zloirock/core-js/#ecmascript-6-promise) for default `Array Iterator` + * optimized [`Array.from`](https://github.com/zloirock/core-js/#ecmascript-6-array) for default `Array Iterator` + * added [`core.getIteratorMethod`](https://github.com/zloirock/core-js/#ecmascript-6-iterators) helper +* uses enumerable properties in shimmed instances - collections, iterators, etc for optimize performance +* added support native constructors to [`Reflect.construct`](https://github.com/zloirock/core-js/#ecmascript-6-reflect) with 2 arguments +* added support native constructors to [`Function#bind`](https://github.com/zloirock/core-js/#ecmascript-5) shim with `new` +* removed obsolete `.clear` methods native [`Weak`-collections](https://github.com/zloirock/core-js/#ecmascript-6-collections) +* maximum modularity, reduced minimal custom build size, separated into submodules: + * [`es6.reflect`](https://github.com/zloirock/core-js/#ecmascript-6-reflect) + * [`es6.regexp`](https://github.com/zloirock/core-js/#ecmascript-6-regexp) + * [`es6.math`](https://github.com/zloirock/core-js/#ecmascript-6-math) + * [`es6.number`](https://github.com/zloirock/core-js/#ecmascript-6-number) + * [`es7.object.to-array`](https://github.com/zloirock/core-js/#ecmascript-7-proposals) + * [`core.object`](https://github.com/zloirock/core-js/#object) + * [`core.string`](https://github.com/zloirock/core-js/#escaping-strings) + * [`core.iter-helpers`](https://github.com/zloirock/core-js/#ecmascript-6-iterators) + * internal modules (`$`, `$.iter`, etc) +* many other optimizations +* final cleaning non-standard features + * moved `$for` to [separate library](https://github.com/zloirock/forof). This work for syntax - `for-of` loop and comprehensions + * moved `Date#{format, formatUTC}` to [separate library](https://github.com/zloirock/dtf). Standard way for this - `ECMA-402` + * removed `Math` methods from `Number.prototype`. Slight sugar for simple `Math` methods calling + * removed `{Array#, Array, Dict}.turn` + * removed `core.global` +* uses `ToNumber` instead of `ToLength` in [`Number Iterator`](https://github.com/zloirock/core-js/#number-iterator), `Array.from(2.5)` will be `[0, 1, 2]` instead of `[0, 1]` +* fixed [#85](https://github.com/zloirock/core-js/issues/85) - invalid `Promise` unhandled rejection message in nested `setTimeout` +* fixed [#86](https://github.com/zloirock/core-js/issues/86) - support FF extensions +* fixed [#89](https://github.com/zloirock/core-js/issues/89) - behavior `Number` constructor in strange case + +##### 0.9.18 - 2015.06.17 +* removed `/` from [`RegExp.escape`](https://github.com/zloirock/core-js/#ecmascript-7-proposals) escaped characters + +##### 0.9.17 - 2015.06.14 +* updated [`RegExp.escape`](https://github.com/zloirock/core-js/#ecmascript-7-proposals) to the [latest proposal](https://github.com/benjamingr/RexExp.escape) +* fixed conflict with webpack dev server + IE buggy behavior + +##### 0.9.16 - 2015.06.11 +* more correct order resolving thenable in [`Promise`](https://github.com/zloirock/core-js/#ecmascript-6-promise) polyfill +* uses polyfill instead of [buggy V8 `Promise`](https://github.com/zloirock/core-js/issues/78) + +##### 0.9.15 - 2015.06.09 +* [collections](https://github.com/zloirock/core-js/#ecmascript-6-collections) from `library` version return wrapped native instances +* fixed collections prototype methods in `library` version +* optimized [`Math.hypot`](https://github.com/zloirock/core-js/#ecmascript-6-math) + +##### 0.9.14 - 2015.06.04 +* updated [`Promise.resolve` behavior](https://esdiscuss.org/topic/fixing-promise-resolve) +* added fallback for IE11 buggy `Object.getOwnPropertyNames` + iframe +* some other fixes + +##### 0.9.13 - 2015.05.25 +* added fallback for [`Symbol` polyfill](https://github.com/zloirock/core-js/#ecmascript-6-symbol) for old Android +* some other fixes + +##### 0.9.12 - 2015.05.24 +* different instances `core-js` should use / recognize the same symbols +* some fixes + +##### 0.9.11 - 2015.05.18 +* simplified [custom build](https://github.com/zloirock/core-js/#custom-build) + * add custom build js api + * added `grunt-cli` to `devDependencies` for `npm run grunt` +* some fixes + +##### 0.9.10 - 2015.05.16 +* wrapped `Function#toString` for correct work wrapped methods / constructors with methods similar to the [`lodash` `isNative`](https://github.com/lodash/lodash/issues/1197) +* added proto versions of methods to export object in `default` version for consistency with `library` version + +##### 0.9.9 - 2015.05.14 +* wrapped `Object#propertyIsEnumerable` for [`Symbol` polyfill](https://github.com/zloirock/core-js/#ecmascript-6-symbol) +* [added proto versions of methods to `library` for ES7 bind syntax](https://github.com/zloirock/core-js/issues/65) +* some other fixes + +##### 0.9.8 - 2015.05.12 +* fixed [`Math.hypot`](https://github.com/zloirock/core-js/#ecmascript-6-math) with negative arguments +* added `Object#toString.toString` as fallback for [`lodash` `isNative`](https://github.com/lodash/lodash/issues/1197) + +##### 0.9.7 - 2015.05.07 +* added [support DOM collections](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice#Streamlining_cross-browser_behavior) to IE8- `Array#slice` + +##### 0.9.6 - 2015.05.01 +* added [`String#lpad`, `String#rpad`](https://github.com/zloirock/core-js/#ecmascript-7-proposals) + +##### 0.9.5 - 2015.04.30 +* added cap for `Function#@@hasInstance` +* some fixes and optimizations + +##### 0.9.4 - 2015.04.27 +* fixed `RegExp` constructor + +##### 0.9.3 - 2015.04.26 +* some fixes and optimizations + +##### 0.9.2 - 2015.04.25 +* more correct [`Promise`](https://github.com/zloirock/core-js/#ecmascript-6-promise) unhandled rejection tracking and resolving / rejection priority + +##### 0.9.1 - 2015.04.25 +* fixed `__proto__`-based [`Promise`](https://github.com/zloirock/core-js/#ecmascript-6-promise) subclassing in some environments + +##### 0.9.0 - 2015.04.24 +* added correct [symbols](https://github.com/zloirock/core-js/#ecmascript-6-symbol) descriptors + * fixed behavior `Object.{assign, create, defineProperty, defineProperties, getOwnPropertyDescriptor, getOwnPropertyDescriptors}` with symbols + * added [single entry points](https://github.com/zloirock/core-js/#commonjs) for `Object.{create, defineProperty, defineProperties}` +* added [`Map#toJSON`](https://github.com/zloirock/core-js/#ecmascript-7-proposals) +* removed non-standard methods `Object#[_]` and `Function#only` - they solves syntax problems, but now in compilers available arrows and ~~in near future will be available~~ [available](http://babeljs.io/blog/2015/05/14/function-bind/) [bind syntax](https://github.com/zenparsing/es-function-bind) +* removed non-standard undocumented methods `Symbol.{pure, set}` +* some fixes and internal changes + +##### 0.8.4 - 2015.04.18 +* uses `webpack` instead of `browserify` for browser builds - more compression-friendly result + +##### 0.8.3 - 2015.04.14 +* fixed `Array` statics with single entry points + +##### 0.8.2 - 2015.04.13 +* [`Math.fround`](https://github.com/zloirock/core-js/#ecmascript-6-math) now also works in IE9- +* added [`Set#toJSON`](https://github.com/zloirock/core-js/#ecmascript-7-proposals) +* some optimizations and fixes + +##### 0.8.1 - 2015.04.03 +* fixed `Symbol.keyFor` + +##### 0.8.0 - 2015.04.02 +* changed [CommonJS API](https://github.com/zloirock/core-js/#commonjs) +* splitted and renamed some modules +* added support ES3 environment (ES5 polyfill) to **all** default versions - size increases slightly (+ ~4kb w/o gzip), many issues disappear, if you don't need it - [simply include only required namespaces / features / modules](https://github.com/zloirock/core-js/#commonjs) +* removed [abstract references](https://github.com/zenparsing/es-abstract-refs) support - proposal has been superseded =\ +* [`$for.isIterable` -> `core.isIterable`, `$for.getIterator` -> `core.getIterator`](https://github.com/zloirock/core-js/#ecmascript-6-iterators), temporary available in old namespace +* fixed iterators support in v8 `Promise.all` and `Promise.race` +* many other fixes + +##### 0.7.2 - 2015.03.09 +* some fixes + +##### 0.7.1 - 2015.03.07 +* some fixes + +##### 0.7.0 - 2015.03.06 +* rewritten and splitted into [CommonJS modules](https://github.com/zloirock/core-js/#commonjs) + +##### 0.6.1 - 2015.02.24 +* fixed support [`Object.defineProperty`](https://github.com/zloirock/core-js/#ecmascript-5) with accessors on DOM elements on IE8 + +##### 0.6.0 - 2015.02.23 +* added support safe closing iteration - calling `iterator.return` on abort iteration, if it exists +* added basic support [`Promise`](https://github.com/zloirock/core-js/#ecmascript-6-promise) unhandled rejection tracking in shim +* added [`Object.getOwnPropertyDescriptors`](https://github.com/zloirock/core-js/#ecmascript-7-proposals) +* removed `console` cap - creates too many problems +* restructuring [namespaces](https://github.com/zloirock/core-js/#custom-build) +* some fixes + +##### 0.5.4 - 2015.02.15 +* some fixes + +##### 0.5.3 - 2015.02.14 +* added [support binary and octal literals](https://github.com/zloirock/core-js/#ecmascript-6-number) to `Number` constructor +* added [`Date#toISOString`](https://github.com/zloirock/core-js/#ecmascript-5) + +##### 0.5.2 - 2015.02.10 +* some fixes + +##### 0.5.1 - 2015.02.09 +* some fixes + +##### 0.5.0 - 2015.02.08 +* systematization of modules +* splitted [`es6` module](https://github.com/zloirock/core-js/#ecmascript-6) +* splitted `console` module: `web.console` - only cap for missing methods, `core.log` - bound methods & additional features +* added [`delay` method](https://github.com/zloirock/core-js/#delay) +* some fixes + +##### 0.4.10 - 2015.01.28 +* [`Object.getOwnPropertySymbols`](https://github.com/zloirock/core-js/#ecmascript-6-symbol) polyfill returns array of wrapped keys + +##### 0.4.9 - 2015.01.27 +* FF20-24 fix + +##### 0.4.8 - 2015.01.25 +* some [collections](https://github.com/zloirock/core-js/#ecmascript-6-collections) fixes + +##### 0.4.7 - 2015.01.25 +* added support frozen objects as [collections](https://github.com/zloirock/core-js/#ecmascript-6-collections) keys + +##### 0.4.6 - 2015.01.21 +* added [`Object.getOwnPropertySymbols`](https://github.com/zloirock/core-js/#ecmascript-6-symbol) +* added [`NodeList.prototype[@@iterator]`](https://github.com/zloirock/core-js/#ecmascript-6-iterators) +* added basic `@@species` logic - getter in native constructors +* removed `Function#by` +* some fixes + +##### 0.4.5 - 2015.01.16 +* some fixes + +##### 0.4.4 - 2015.01.11 +* enabled CSP support + +##### 0.4.3 - 2015.01.10 +* added `Function` instances `name` property for IE9+ + +##### 0.4.2 - 2015.01.10 +* `Object` static methods accept primitives +* `RegExp` constructor can alter flags (IE9+) +* added `Array.prototype[Symbol.unscopables]` + +##### 0.4.1 - 2015.01.05 +* some fixes + +##### 0.4.0 - 2015.01.03 +* added [`es6.reflect`](https://github.com/zloirock/core-js/#ecmascript-6-reflect) module: + * added `Reflect.apply` + * added `Reflect.construct` + * added `Reflect.defineProperty` + * added `Reflect.deleteProperty` + * added `Reflect.enumerate` + * added `Reflect.get` + * added `Reflect.getOwnPropertyDescriptor` + * added `Reflect.getPrototypeOf` + * added `Reflect.has` + * added `Reflect.isExtensible` + * added `Reflect.preventExtensions` + * added `Reflect.set` + * added `Reflect.setPrototypeOf` +* `core-js` methods now can use external `Symbol.iterator` polyfill +* some fixes + +##### 0.3.3 - 2014.12.28 +* [console cap](https://github.com/zloirock/core-js/#console) excluded from node.js default builds + +##### 0.3.2 - 2014.12.25 +* added cap for [ES5](https://github.com/zloirock/core-js/#ecmascript-5) freeze-family methods +* fixed `console` bug + +##### 0.3.1 - 2014.12.23 +* some fixes + +##### 0.3.0 - 2014.12.23 +* Optimize [`Map` & `Set`](https://github.com/zloirock/core-js/#ecmascript-6-collections): + * use entries chain on hash table + * fast & correct iteration + * iterators moved to [`es6`](https://github.com/zloirock/core-js/#ecmascript-6) and [`es6.collections`](https://github.com/zloirock/core-js/#ecmascript-6-collections) modules + +##### 0.2.5 - 2014.12.20 +* `console` no longer shortcut for `console.log` (compatibility problems) +* some fixes + +##### 0.2.4 - 2014.12.17 +* better compliance of ES6 +* added [`Math.fround`](https://github.com/zloirock/core-js/#ecmascript-6-math) (IE10+) +* some fixes + +##### 0.2.3 - 2014.12.15 +* [Symbols](https://github.com/zloirock/core-js/#ecmascript-6-symbol): + * added option to disable addition setter to `Object.prototype` for Symbol polyfill: + * added `Symbol.useSimple` + * added `Symbol.useSetter` + * added cap for well-known Symbols: + * added `Symbol.hasInstance` + * added `Symbol.isConcatSpreadable` + * added `Symbol.match` + * added `Symbol.replace` + * added `Symbol.search` + * added `Symbol.species` + * added `Symbol.split` + * added `Symbol.toPrimitive` + * added `Symbol.unscopables` + +##### 0.2.2 - 2014.12.13 +* added [`RegExp#flags`](https://github.com/zloirock/core-js/#ecmascript-6-regexp) ([December 2014 Draft Rev 29](http://wiki.ecmascript.org/doku.php?id=harmony:specification_drafts#december_6_2014_draft_rev_29)) +* added [`String.raw`](https://github.com/zloirock/core-js/#ecmascript-6-string) + +##### 0.2.1 - 2014.12.12 +* repair converting -0 to +0 in [native collections](https://github.com/zloirock/core-js/#ecmascript-6-collections) + +##### 0.2.0 - 2014.12.06 +* added [`es7.proposals`](https://github.com/zloirock/core-js/#ecmascript-7-proposals) and [`es7.abstract-refs`](https://github.com/zenparsing/es-abstract-refs) modules +* added [`String#at`](https://github.com/zloirock/core-js/#ecmascript-7-proposals) +* added real [`String Iterator`](https://github.com/zloirock/core-js/#ecmascript-6-iterators), older versions used Array Iterator +* added abstract references support: + * added `Symbol.referenceGet` + * added `Symbol.referenceSet` + * added `Symbol.referenceDelete` + * added `Function#@@referenceGet` + * added `Map#@@referenceGet` + * added `Map#@@referenceSet` + * added `Map#@@referenceDelete` + * added `WeakMap#@@referenceGet` + * added `WeakMap#@@referenceSet` + * added `WeakMap#@@referenceDelete` + * added `Dict.{...methods}[@@referenceGet]` +* removed deprecated `.contains` methods +* some fixes + +##### 0.1.5 - 2014.12.01 +* added [`Array#copyWithin`](https://github.com/zloirock/core-js/#ecmascript-6-array) +* added [`String#codePointAt`](https://github.com/zloirock/core-js/#ecmascript-6-string) +* added [`String.fromCodePoint`](https://github.com/zloirock/core-js/#ecmascript-6-string) + +##### 0.1.4 - 2014.11.27 +* added [`Dict.mapPairs`](https://github.com/zloirock/core-js/#dict) + +##### 0.1.3 - 2014.11.20 +* [TC39 November meeting](https://github.com/rwaldron/tc39-notes/tree/master/es6/2014-11): + * [`.contains` -> `.includes`](https://github.com/rwaldron/tc39-notes/blob/master/es6/2014-11/nov-18.md#51--44-arrayprototypecontains-and-stringprototypecontains) + * `String#contains` -> [`String#includes`](https://github.com/zloirock/core-js/#ecmascript-6-string) + * `Array#contains` -> [`Array#includes`](https://github.com/zloirock/core-js/#ecmascript-7-proposals) + * `Dict.contains` -> [`Dict.includes`](https://github.com/zloirock/core-js/#dict) + * [removed `WeakMap#clear`](https://github.com/rwaldron/tc39-notes/blob/master/es6/2014-11/nov-19.md#412-should-weakmapweakset-have-a-clear-method-markm) + * [removed `WeakSet#clear`](https://github.com/rwaldron/tc39-notes/blob/master/es6/2014-11/nov-19.md#412-should-weakmapweakset-have-a-clear-method-markm) + +##### 0.1.2 - 2014.11.19 +* `Map` & `Set` bug fix + +##### 0.1.1 - 2014.11.18 +* public release \ No newline at end of file diff --git a/node_modules/core-js/Gruntfile.js b/node_modules/core-js/Gruntfile.js new file mode 100644 index 00000000..afbcd948 --- /dev/null +++ b/node_modules/core-js/Gruntfile.js @@ -0,0 +1,2 @@ +require('LiveScript'); +module.exports = require('./build/Gruntfile'); \ No newline at end of file diff --git a/node_modules/core-js/LICENSE b/node_modules/core-js/LICENSE new file mode 100644 index 00000000..c99b842d --- /dev/null +++ b/node_modules/core-js/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2014-2016 Denis Pushkarev + +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. diff --git a/node_modules/core-js/bower.json b/node_modules/core-js/bower.json new file mode 100644 index 00000000..f6eb784b --- /dev/null +++ b/node_modules/core-js/bower.json @@ -0,0 +1,47 @@ +{ + "name": "core.js", + "main": "client/core.js", + "version": "2.4.1", + "description": "Standard Library", + "keywords": [ + "ES3", + "ECMAScript 3", + "ES5", + "ECMAScript 5", + "ES6", + "ES2015", + "ECMAScript 6", + "ECMAScript 2015", + "ES7", + "ES2016", + "ECMAScript 7", + "ECMAScript 2016", + "Harmony", + "Strawman", + "Map", + "Set", + "WeakMap", + "WeakSet", + "Promise", + "Symbol", + "TypedArray", + "setImmediate", + "Dict", + "polyfill", + "shim" + ], + "authors": [ + "Denis Pushkarev
+ require('crypto').createHash('sha1').update('abc').digest('hex') == ''
+
+
+
+
diff --git a/node_modules/crypto-browserify/example/test.js b/node_modules/crypto-browserify/example/test.js
new file mode 100644
index 00000000..f1b0e4a9
--- /dev/null
+++ b/node_modules/crypto-browserify/example/test.js
@@ -0,0 +1,4 @@
+var crypto = require('crypto')
+var abc = crypto.createHash('sha1').update('abc').digest('hex')
+console.log(abc)
+//require('hello').inlineCall().call2()
diff --git a/node_modules/crypto-browserify/helpers.js b/node_modules/crypto-browserify/helpers.js
new file mode 100644
index 00000000..b9e1ed01
--- /dev/null
+++ b/node_modules/crypto-browserify/helpers.js
@@ -0,0 +1,34 @@
+var intSize = 4;
+var zeroBuffer = new Buffer(intSize); zeroBuffer.fill(0);
+var chrsz = 8;
+
+function toArray(buf, bigEndian) {
+ if ((buf.length % intSize) !== 0) {
+ var len = buf.length + (intSize - (buf.length % intSize));
+ buf = Buffer.concat([buf, zeroBuffer], len);
+ }
+
+ var arr = [];
+ var fn = bigEndian ? buf.readInt32BE : buf.readInt32LE;
+ for (var i = 0; i < buf.length; i += intSize) {
+ arr.push(fn.call(buf, i));
+ }
+ return arr;
+}
+
+function toBuffer(arr, size, bigEndian) {
+ var buf = new Buffer(size);
+ var fn = bigEndian ? buf.writeInt32BE : buf.writeInt32LE;
+ for (var i = 0; i < arr.length; i++) {
+ fn.call(buf, arr[i], i * 4, true);
+ }
+ return buf;
+}
+
+function hash(buf, fn, hashSize, bigEndian) {
+ if (!Buffer.isBuffer(buf)) buf = new Buffer(buf);
+ var arr = fn(toArray(buf, bigEndian), buf.length * chrsz);
+ return toBuffer(arr, hashSize, bigEndian);
+}
+
+module.exports = { hash: hash };
diff --git a/node_modules/crypto-browserify/index.js b/node_modules/crypto-browserify/index.js
new file mode 100644
index 00000000..3283c283
--- /dev/null
+++ b/node_modules/crypto-browserify/index.js
@@ -0,0 +1,49 @@
+var rng = require('./rng')
+
+function error () {
+ var m = [].slice.call(arguments).join(' ')
+ throw new Error([
+ m,
+ 'we accept pull requests',
+ 'http://github.com/dominictarr/crypto-browserify'
+ ].join('\n'))
+}
+
+exports.createHash = require('./create-hash')
+
+exports.createHmac = require('./create-hmac')
+
+exports.randomBytes = function(size, callback) {
+ if (callback && callback.call) {
+ try {
+ callback.call(this, undefined, new Buffer(rng(size)))
+ } catch (err) { callback(err) }
+ } else {
+ return new Buffer(rng(size))
+ }
+}
+
+function each(a, f) {
+ for(var i in a)
+ f(a[i], i)
+}
+
+exports.getHashes = function () {
+ return ['sha1', 'sha256', 'sha512', 'md5', 'rmd160']
+}
+
+var p = require('./pbkdf2')(exports)
+exports.pbkdf2 = p.pbkdf2
+exports.pbkdf2Sync = p.pbkdf2Sync
+require('browserify-aes/inject')(exports, module.exports);
+
+// the least I can do is make error messages for the rest of the node.js/crypto api.
+each(['createCredentials'
+, 'createSign'
+, 'createVerify'
+, 'createDiffieHellman'
+], function (name) {
+ exports[name] = function () {
+ error('sorry,', name, 'is not implemented yet')
+ }
+})
diff --git a/node_modules/crypto-browserify/md5.js b/node_modules/crypto-browserify/md5.js
new file mode 100644
index 00000000..92067a02
--- /dev/null
+++ b/node_modules/crypto-browserify/md5.js
@@ -0,0 +1,155 @@
+/*
+ * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
+ * Digest Algorithm, as defined in RFC 1321.
+ * Version 2.1 Copyright (C) Paul Johnston 1999 - 2002.
+ * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
+ * Distributed under the BSD License
+ * See http://pajhome.org.uk/crypt/md5 for more info.
+ */
+
+var helpers = require('./helpers');
+
+/*
+ * Calculate the MD5 of an array of little-endian words, and a bit length
+ */
+function core_md5(x, len)
+{
+ /* append padding */
+ x[len >> 5] |= 0x80 << ((len) % 32);
+ x[(((len + 64) >>> 9) << 4) + 14] = len;
+
+ var a = 1732584193;
+ var b = -271733879;
+ var c = -1732584194;
+ var d = 271733878;
+
+ for(var i = 0; i < x.length; i += 16)
+ {
+ var olda = a;
+ var oldb = b;
+ var oldc = c;
+ var oldd = d;
+
+ a = md5_ff(a, b, c, d, x[i+ 0], 7 , -680876936);
+ d = md5_ff(d, a, b, c, x[i+ 1], 12, -389564586);
+ c = md5_ff(c, d, a, b, x[i+ 2], 17, 606105819);
+ b = md5_ff(b, c, d, a, x[i+ 3], 22, -1044525330);
+ a = md5_ff(a, b, c, d, x[i+ 4], 7 , -176418897);
+ d = md5_ff(d, a, b, c, x[i+ 5], 12, 1200080426);
+ c = md5_ff(c, d, a, b, x[i+ 6], 17, -1473231341);
+ b = md5_ff(b, c, d, a, x[i+ 7], 22, -45705983);
+ a = md5_ff(a, b, c, d, x[i+ 8], 7 , 1770035416);
+ d = md5_ff(d, a, b, c, x[i+ 9], 12, -1958414417);
+ c = md5_ff(c, d, a, b, x[i+10], 17, -42063);
+ b = md5_ff(b, c, d, a, x[i+11], 22, -1990404162);
+ a = md5_ff(a, b, c, d, x[i+12], 7 , 1804603682);
+ d = md5_ff(d, a, b, c, x[i+13], 12, -40341101);
+ c = md5_ff(c, d, a, b, x[i+14], 17, -1502002290);
+ b = md5_ff(b, c, d, a, x[i+15], 22, 1236535329);
+
+ a = md5_gg(a, b, c, d, x[i+ 1], 5 , -165796510);
+ d = md5_gg(d, a, b, c, x[i+ 6], 9 , -1069501632);
+ c = md5_gg(c, d, a, b, x[i+11], 14, 643717713);
+ b = md5_gg(b, c, d, a, x[i+ 0], 20, -373897302);
+ a = md5_gg(a, b, c, d, x[i+ 5], 5 , -701558691);
+ d = md5_gg(d, a, b, c, x[i+10], 9 , 38016083);
+ c = md5_gg(c, d, a, b, x[i+15], 14, -660478335);
+ b = md5_gg(b, c, d, a, x[i+ 4], 20, -405537848);
+ a = md5_gg(a, b, c, d, x[i+ 9], 5 , 568446438);
+ d = md5_gg(d, a, b, c, x[i+14], 9 , -1019803690);
+ c = md5_gg(c, d, a, b, x[i+ 3], 14, -187363961);
+ b = md5_gg(b, c, d, a, x[i+ 8], 20, 1163531501);
+ a = md5_gg(a, b, c, d, x[i+13], 5 , -1444681467);
+ d = md5_gg(d, a, b, c, x[i+ 2], 9 , -51403784);
+ c = md5_gg(c, d, a, b, x[i+ 7], 14, 1735328473);
+ b = md5_gg(b, c, d, a, x[i+12], 20, -1926607734);
+
+ a = md5_hh(a, b, c, d, x[i+ 5], 4 , -378558);
+ d = md5_hh(d, a, b, c, x[i+ 8], 11, -2022574463);
+ c = md5_hh(c, d, a, b, x[i+11], 16, 1839030562);
+ b = md5_hh(b, c, d, a, x[i+14], 23, -35309556);
+ a = md5_hh(a, b, c, d, x[i+ 1], 4 , -1530992060);
+ d = md5_hh(d, a, b, c, x[i+ 4], 11, 1272893353);
+ c = md5_hh(c, d, a, b, x[i+ 7], 16, -155497632);
+ b = md5_hh(b, c, d, a, x[i+10], 23, -1094730640);
+ a = md5_hh(a, b, c, d, x[i+13], 4 , 681279174);
+ d = md5_hh(d, a, b, c, x[i+ 0], 11, -358537222);
+ c = md5_hh(c, d, a, b, x[i+ 3], 16, -722521979);
+ b = md5_hh(b, c, d, a, x[i+ 6], 23, 76029189);
+ a = md5_hh(a, b, c, d, x[i+ 9], 4 , -640364487);
+ d = md5_hh(d, a, b, c, x[i+12], 11, -421815835);
+ c = md5_hh(c, d, a, b, x[i+15], 16, 530742520);
+ b = md5_hh(b, c, d, a, x[i+ 2], 23, -995338651);
+
+ a = md5_ii(a, b, c, d, x[i+ 0], 6 , -198630844);
+ d = md5_ii(d, a, b, c, x[i+ 7], 10, 1126891415);
+ c = md5_ii(c, d, a, b, x[i+14], 15, -1416354905);
+ b = md5_ii(b, c, d, a, x[i+ 5], 21, -57434055);
+ a = md5_ii(a, b, c, d, x[i+12], 6 , 1700485571);
+ d = md5_ii(d, a, b, c, x[i+ 3], 10, -1894986606);
+ c = md5_ii(c, d, a, b, x[i+10], 15, -1051523);
+ b = md5_ii(b, c, d, a, x[i+ 1], 21, -2054922799);
+ a = md5_ii(a, b, c, d, x[i+ 8], 6 , 1873313359);
+ d = md5_ii(d, a, b, c, x[i+15], 10, -30611744);
+ c = md5_ii(c, d, a, b, x[i+ 6], 15, -1560198380);
+ b = md5_ii(b, c, d, a, x[i+13], 21, 1309151649);
+ a = md5_ii(a, b, c, d, x[i+ 4], 6 , -145523070);
+ d = md5_ii(d, a, b, c, x[i+11], 10, -1120210379);
+ c = md5_ii(c, d, a, b, x[i+ 2], 15, 718787259);
+ b = md5_ii(b, c, d, a, x[i+ 9], 21, -343485551);
+
+ a = safe_add(a, olda);
+ b = safe_add(b, oldb);
+ c = safe_add(c, oldc);
+ d = safe_add(d, oldd);
+ }
+ return Array(a, b, c, d);
+
+}
+
+/*
+ * These functions implement the four basic operations the algorithm uses.
+ */
+function md5_cmn(q, a, b, x, s, t)
+{
+ return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s),b);
+}
+function md5_ff(a, b, c, d, x, s, t)
+{
+ return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t);
+}
+function md5_gg(a, b, c, d, x, s, t)
+{
+ return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t);
+}
+function md5_hh(a, b, c, d, x, s, t)
+{
+ return md5_cmn(b ^ c ^ d, a, b, x, s, t);
+}
+function md5_ii(a, b, c, d, x, s, t)
+{
+ return md5_cmn(c ^ (b | (~d)), a, b, x, s, t);
+}
+
+/*
+ * Add integers, wrapping at 2^32. This uses 16-bit operations internally
+ * to work around bugs in some JS interpreters.
+ */
+function safe_add(x, y)
+{
+ var lsw = (x & 0xFFFF) + (y & 0xFFFF);
+ var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
+ return (msw << 16) | (lsw & 0xFFFF);
+}
+
+/*
+ * Bitwise rotate a 32-bit number to the left.
+ */
+function bit_rol(num, cnt)
+{
+ return (num << cnt) | (num >>> (32 - cnt));
+}
+
+module.exports = function md5(buf) {
+ return helpers.hash(buf, core_md5, 16);
+};
diff --git a/node_modules/crypto-browserify/package.json b/node_modules/crypto-browserify/package.json
new file mode 100644
index 00000000..895bd679
--- /dev/null
+++ b/node_modules/crypto-browserify/package.json
@@ -0,0 +1,103 @@
+{
+ "_args": [
+ [
+ {
+ "raw": "crypto-browserify@3.3.0",
+ "scope": null,
+ "escapedName": "crypto-browserify",
+ "name": "crypto-browserify",
+ "rawSpec": "3.3.0",
+ "spec": "3.3.0",
+ "type": "version"
+ },
+ "/Users/ericchiu/Desktop/CIS 700/HW7/Project7-BioCrowds/node_modules/node-libs-browser"
+ ]
+ ],
+ "_from": "crypto-browserify@3.3.0",
+ "_id": "crypto-browserify@3.3.0",
+ "_inCache": true,
+ "_location": "/crypto-browserify",
+ "_npmUser": {
+ "name": "dominictarr",
+ "email": "dominic.tarr@gmail.com"
+ },
+ "_npmVersion": "1.4.26",
+ "_phantomChildren": {},
+ "_requested": {
+ "raw": "crypto-browserify@3.3.0",
+ "scope": null,
+ "escapedName": "crypto-browserify",
+ "name": "crypto-browserify",
+ "rawSpec": "3.3.0",
+ "spec": "3.3.0",
+ "type": "version"
+ },
+ "_requiredBy": [
+ "/node-libs-browser"
+ ],
+ "_resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.3.0.tgz",
+ "_shasum": "b9fc75bb4a0ed61dcf1cd5dae96eb30c9c3e506c",
+ "_shrinkwrap": null,
+ "_spec": "crypto-browserify@3.3.0",
+ "_where": "/Users/ericchiu/Desktop/CIS 700/HW7/Project7-BioCrowds/node_modules/node-libs-browser",
+ "author": {
+ "name": "Dominic Tarr",
+ "email": "dominic.tarr@gmail.com",
+ "url": "dominictarr.com"
+ },
+ "browser": {
+ "crypto": false
+ },
+ "bugs": {
+ "url": "https://github.com/dominictarr/crypto-browserify/issues"
+ },
+ "dependencies": {
+ "browserify-aes": "0.4.0",
+ "pbkdf2-compat": "2.0.1",
+ "ripemd160": "0.2.0",
+ "sha.js": "2.2.6"
+ },
+ "description": "partial implementation of crypto for the browser",
+ "devDependencies": {
+ "hash-test-vectors": "~1.3.0",
+ "tape": "~2.3.2"
+ },
+ "directories": {},
+ "dist": {
+ "shasum": "b9fc75bb4a0ed61dcf1cd5dae96eb30c9c3e506c",
+ "tarball": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.3.0.tgz"
+ },
+ "engines": {
+ "node": "*"
+ },
+ "gitHead": "0f1821f6233548f632de2b5658c895fa7a8e3d3d",
+ "homepage": "https://github.com/dominictarr/crypto-browserify",
+ "license": "MIT",
+ "maintainers": [
+ {
+ "name": "dominictarr",
+ "email": "dominic.tarr@gmail.com"
+ }
+ ],
+ "name": "crypto-browserify",
+ "optionalDependencies": {},
+ "readme": "ERROR: No README data found!",
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/dominictarr/crypto-browserify.git"
+ },
+ "scripts": {
+ "test": "set -e; for t in test/*.js; do node $t; done"
+ },
+ "testling": {
+ "files": "test/*.js",
+ "browsers": [
+ "ie/latest",
+ "chrome/latest",
+ "firefox/latest",
+ "safari/latest",
+ "opera/latest"
+ ]
+ },
+ "version": "3.3.0"
+}
diff --git a/node_modules/crypto-browserify/pbkdf2.js b/node_modules/crypto-browserify/pbkdf2.js
new file mode 100644
index 00000000..88382f4f
--- /dev/null
+++ b/node_modules/crypto-browserify/pbkdf2.js
@@ -0,0 +1,12 @@
+var pbkdf2Export = require('pbkdf2-compat/pbkdf2')
+
+module.exports = function (crypto, exports) {
+ exports = exports || {}
+
+ var exported = pbkdf2Export(crypto)
+
+ exports.pbkdf2 = exported.pbkdf2
+ exports.pbkdf2Sync = exported.pbkdf2Sync
+
+ return exports
+}
diff --git a/node_modules/crypto-browserify/readme.markdown b/node_modules/crypto-browserify/readme.markdown
new file mode 100644
index 00000000..cde89668
--- /dev/null
+++ b/node_modules/crypto-browserify/readme.markdown
@@ -0,0 +1,47 @@
+# crypto-browserify
+
+A (partial) port of node's `crypto` module to the browser.
+
+[](https://travis-ci.org/dominictarr/crypto-browserify)
+
+[](http://ci.testling.com/dominictarr/crypto-browserify)
+
+The goal of this module is to reimplement node's crypto module,
+in pure javascript so that it can run in the browser.
+
+Here is the subset that is currently implemented:
+
+* createHash (sha1, sha256, sha512, md5, rmd160)
+* createHmac (sha1, sha256, sha512, md5)
+* pbkdf2
+* pbkdf2Sync
+* randomBytes
+* createCipher (aes)
+* createDecipher (aes)
+
+## TODO
+
+The highest priority unimplemented features are
+
+* createDiffieHelman
+* createSign (rsa)
+* createVerify (rsa)
+
+## contributions
+
+If you are interested in writing a feature, please implement as a new module,
+which will be incorporated into crypto-browserify as a dependency.
+
+All deps must be compatible with node's crypto
+(generate example inputs and outputs with node,
+and save base64 strings inside JSON, so that tests can run in the browser.
+see [sha.js](https://github.com/dominictarr/sha.js)
+
+Crypto is _extra serious_ so please do not hesitate to review the code,
+and post comments if you do.
+
+## License
+
+MIT
+
+
diff --git a/node_modules/crypto-browserify/rng.js b/node_modules/crypto-browserify/rng.js
new file mode 100644
index 00000000..0f140bb0
--- /dev/null
+++ b/node_modules/crypto-browserify/rng.js
@@ -0,0 +1,26 @@
+(function() {
+ var g = ('undefined' === typeof window ? global : window) || {}
+ _crypto = (
+ g.crypto || g.msCrypto || require('crypto')
+ )
+ module.exports = function(size) {
+ // Modern Browsers
+ if(_crypto.getRandomValues) {
+ var bytes = new Buffer(size); //in browserify, this is an extended Uint8Array
+ /* This will not work in older browsers.
+ * See https://developer.mozilla.org/en-US/docs/Web/API/window.crypto.getRandomValues
+ */
+
+ _crypto.getRandomValues(bytes);
+ return bytes;
+ }
+ else if (_crypto.randomBytes) {
+ return _crypto.randomBytes(size)
+ }
+ else
+ throw new Error(
+ 'secure random number generation not supported by this browser\n'+
+ 'use chrome, FireFox or Internet Explorer 11'
+ )
+ }
+}())
diff --git a/node_modules/crypto-browserify/test/aes.js b/node_modules/crypto-browserify/test/aes.js
new file mode 100644
index 00000000..090b27e6
--- /dev/null
+++ b/node_modules/crypto-browserify/test/aes.js
@@ -0,0 +1,18 @@
+var test = require('tape');
+var crypto = require('../');
+test('ciphers', function (t) {
+ crypto.listCiphers().forEach(function (cipher) {
+ t.test(cipher, function (t) {
+ t.plan(1);
+ var data = crypto.randomBytes(562);
+ var password = crypto.randomBytes(20);
+ var crypter = crypto.createCipher(cipher, password);
+ var decrypter = crypto.createDecipher(cipher, password);
+ var out = [];
+ out.push(decrypter.update(crypter.update(data)));
+ out.push(decrypter.update(crypter.final()));
+ out.push(decrypter.final());
+ t.equals(data.toString('hex'), Buffer.concat(out).toString('hex'));
+ });
+ });
+});
\ No newline at end of file
diff --git a/node_modules/crypto-browserify/test/create-hash.js b/node_modules/crypto-browserify/test/create-hash.js
new file mode 100644
index 00000000..60a5e74f
--- /dev/null
+++ b/node_modules/crypto-browserify/test/create-hash.js
@@ -0,0 +1,32 @@
+var fs = require('fs')
+var test = require('tape')
+
+var algorithms = require('../').getHashes()
+var encodings = [/*'binary',*/ 'hex', 'base64'];
+var vectors = require('hash-test-vectors')
+
+var createHash = require('../create-hash')
+
+algorithms.forEach(function (algorithm) {
+ test('test ' + algorithm + ' against test vectors', function (t) {
+
+ vectors.forEach(function (obj, i) {
+ var input = new Buffer(obj.input, 'base64')
+ var node = obj[algorithm]
+ var js = createHash(algorithm).update(input).digest('hex')
+ t.equal(js, node, algorithm + '(testVector['+i+']) == ' + node)
+ })
+
+ encodings.forEach(function (encoding) {
+ vectors.forEach(function (obj, i) {
+ var input = new Buffer(obj.input, 'base64').toString(encoding)
+ var node = obj[algorithm]
+ var js = createHash(algorithm).update(input, encoding).digest('hex')
+ t.equal(js, node, algorithm + '(testVector['+i+'], '+encoding+') == ' + node)
+ })
+ });
+
+ t.end()
+ })
+});
+
diff --git a/node_modules/crypto-browserify/test/create-hmac.js b/node_modules/crypto-browserify/test/create-hmac.js
new file mode 100644
index 00000000..9076000c
--- /dev/null
+++ b/node_modules/crypto-browserify/test/create-hmac.js
@@ -0,0 +1,24 @@
+
+var test = require('tape')
+
+var algorithms = require('../').getHashes()
+var vectors = require('hash-test-vectors/hmac')
+var createHmac = require('../create-hmac')
+
+algorithms.forEach(function (alg) {
+
+ test('hmac('+alg+')', function (t) {
+ vectors.forEach(function (input, i) {
+ var output = createHmac(alg, new Buffer(input.key, 'hex'))
+ .update(input.data, 'hex').digest()
+
+ output = input.truncate ? output.slice(0, input.truncate) : output
+ t.equal(output.toString('hex'), input[alg])
+ })
+ t.end()
+ })
+
+})
+
+
+
diff --git a/node_modules/crypto-browserify/test/pbkdf2.js b/node_modules/crypto-browserify/test/pbkdf2.js
new file mode 100644
index 00000000..fc26900f
--- /dev/null
+++ b/node_modules/crypto-browserify/test/pbkdf2.js
@@ -0,0 +1,23 @@
+
+var tape = require('tape')
+var pbkdf2Sync = require('../').pbkdf2Sync
+
+var vectors = require('hash-test-vectors/pbkdf2')
+
+tape('pbkdf2', function (t) {
+ vectors.forEach(function (input) {
+ //skip inputs that will take way too long
+ if(input.iterations > 10000) return
+
+ var key = pbkdf2Sync(input.password, input.salt, input.iterations, input.length)
+
+ if(key.toString('hex') !== input.sha1)
+ console.log(input)
+
+ t.equal(key.toString('hex'), input.sha1)
+
+
+ })
+
+ t.end()
+})
diff --git a/node_modules/crypto-browserify/test/random-bytes.js b/node_modules/crypto-browserify/test/random-bytes.js
new file mode 100644
index 00000000..417f2db8
--- /dev/null
+++ b/node_modules/crypto-browserify/test/random-bytes.js
@@ -0,0 +1,55 @@
+var test = require('tape')
+var crypto = require('../')
+
+test('get error message', function (t) {
+
+ try {
+ var b = crypto.randomBytes(10)
+ t.ok(Buffer.isBuffer(b))
+ t.end()
+ } catch (err) {
+ t.ok(/not supported/.test(err.message), '"not supported" is in error message')
+ t.end()
+ }
+
+})
+
+test('randomBytes', function (t) {
+ t.plan(5);
+ t.equal(crypto.randomBytes(10).length, 10);
+ t.ok(Buffer.isBuffer(crypto.randomBytes(10)))
+ crypto.randomBytes(10, function(ex, bytes) {
+ t.error(ex);
+ t.equal(bytes.length, 10);
+ t.ok(Buffer.isBuffer(bytes))
+ t.end();
+ });
+});
+
+test('randomBytes seem random', function (t) {
+
+ var L = 1000
+ var b = crypto.randomBytes(L)
+
+ var mean = [].reduce.call(b, function (a, b) { return a + b}, 0) / L
+
+ // test that the random numbers are plausably random.
+ // Math.random() will pass this, but this will catch
+ // terrible mistakes such as this blunder:
+ // https://github.com/dominictarr/crypto-browserify/commit/3267955e1df7edd1680e52aeede9a89506ed2464#commitcomment-7916835
+
+ // this doesn't check that the bytes are in a random *order*
+ // but it's better than nothing.
+
+ var expected = 256/2
+ var smean = Math.sqrt(mean)
+ //console.log doesn't work right on testling, *grumble grumble*
+ console.log(JSON.stringify([expected - smean, mean, expected + smean]))
+ t.ok(mean < expected + smean)
+ t.ok(mean > expected - smean)
+
+ t.end()
+
+})
+
+
diff --git a/node_modules/cycle/README.md b/node_modules/cycle/README.md
new file mode 100644
index 00000000..de9a06d0
--- /dev/null
+++ b/node_modules/cycle/README.md
@@ -0,0 +1,49 @@
+Fork of https://github.com/douglascrockford/JSON-js, maintained in npm as `cycle`.
+
+# Contributors
+
+* Douglas Crockford
+* Nuno Job
+* Justin Warkentin
+
+# JSON in JavaScript
+
+Douglas Crockford
+douglas@crockford.com
+
+2010-11-18
+
+
+JSON is a light-weight, language independent, data interchange format.
+See http://www.JSON.org/
+
+The files in this collection implement JSON encoders/decoders in JavaScript.
+
+JSON became a built-in feature of JavaScript when the ECMAScript Programming
+Language Standard - Fifth Edition was adopted by the ECMA General Assembly
+in December 2009. Most of the files in this collection are for applications
+that are expected to run in obsolete web browsers. For most purposes, json2.js
+is the best choice.
+
+
+json2.js: This file creates a JSON property in the global object, if there
+isn't already one, setting its value to an object containing a stringify
+method and a parse method. The parse method uses the eval method to do the
+parsing, guarding it with several regular expressions to defend against
+accidental code execution hazards. On current browsers, this file does nothing,
+prefering the built-in JSON object.
+
+json.js: This file does everything that json2.js does. It also adds a
+toJSONString method and a parseJSON method to Object.prototype. Use of this
+file is not recommended.
+
+json_parse.js: This file contains an alternative JSON parse function that
+uses recursive descent instead of eval.
+
+json_parse_state.js: This files contains an alternative JSON parse function that
+uses a state machine instead of eval.
+
+cycle.js: This file contains two functions, JSON.decycle and JSON.retrocycle,
+which make it possible to encode cyclical structures and dags in JSON, and to
+then recover them. JSONPath is used to represent the links.
+http://GOESSNER.net/articles/JsonPath/
diff --git a/node_modules/cycle/cycle.js b/node_modules/cycle/cycle.js
new file mode 100644
index 00000000..2e776ad9
--- /dev/null
+++ b/node_modules/cycle/cycle.js
@@ -0,0 +1,170 @@
+/*
+ cycle.js
+ 2013-02-19
+
+ Public Domain.
+
+ NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
+
+ This code should be minified before deployment.
+ See http://javascript.crockford.com/jsmin.html
+
+ USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
+ NOT CONTROL.
+*/
+
+/*jslint evil: true, regexp: true */
+
+/*members $ref, apply, call, decycle, hasOwnProperty, length, prototype, push,
+ retrocycle, stringify, test, toString
+*/
+
+var cycle = exports;
+
+cycle.decycle = function decycle(object) {
+ 'use strict';
+
+// Make a deep copy of an object or array, assuring that there is at most
+// one instance of each object or array in the resulting structure. The
+// duplicate references (which might be forming cycles) are replaced with
+// an object of the form
+// {$ref: PATH}
+// where the PATH is a JSONPath string that locates the first occurance.
+// So,
+// var a = [];
+// a[0] = a;
+// return JSON.stringify(JSON.decycle(a));
+// produces the string '[{"$ref":"$"}]'.
+
+// JSONPath is used to locate the unique object. $ indicates the top level of
+// the object or array. [NUMBER] or [STRING] indicates a child member or
+// property.
+
+ var objects = [], // Keep a reference to each unique object or array
+ paths = []; // Keep the path to each unique object or array
+
+ return (function derez(value, path) {
+
+// The derez recurses through the object, producing the deep copy.
+
+ var i, // The loop counter
+ name, // Property name
+ nu; // The new object or array
+
+// typeof null === 'object', so go on if this value is really an object but not
+// one of the weird builtin objects.
+
+ if (typeof value === 'object' && value !== null &&
+ !(value instanceof Boolean) &&
+ !(value instanceof Date) &&
+ !(value instanceof Number) &&
+ !(value instanceof RegExp) &&
+ !(value instanceof String)) {
+
+// If the value is an object or array, look to see if we have already
+// encountered it. If so, return a $ref/path object. This is a hard way,
+// linear search that will get slower as the number of unique objects grows.
+
+ for (i = 0; i < objects.length; i += 1) {
+ if (objects[i] === value) {
+ return {$ref: paths[i]};
+ }
+ }
+
+// Otherwise, accumulate the unique value and its path.
+
+ objects.push(value);
+ paths.push(path);
+
+// If it is an array, replicate the array.
+
+ if (Object.prototype.toString.apply(value) === '[object Array]') {
+ nu = [];
+ for (i = 0; i < value.length; i += 1) {
+ nu[i] = derez(value[i], path + '[' + i + ']');
+ }
+ } else {
+
+// If it is an object, replicate the object.
+
+ nu = {};
+ for (name in value) {
+ if (Object.prototype.hasOwnProperty.call(value, name)) {
+ nu[name] = derez(value[name],
+ path + '[' + JSON.stringify(name) + ']');
+ }
+ }
+ }
+ return nu;
+ }
+ return value;
+ }(object, '$'));
+};
+
+
+cycle.retrocycle = function retrocycle($) {
+ 'use strict';
+
+// Restore an object that was reduced by decycle. Members whose values are
+// objects of the form
+// {$ref: PATH}
+// are replaced with references to the value found by the PATH. This will
+// restore cycles. The object will be mutated.
+
+// The eval function is used to locate the values described by a PATH. The
+// root object is kept in a $ variable. A regular expression is used to
+// assure that the PATH is extremely well formed. The regexp contains nested
+// * quantifiers. That has been known to have extremely bad performance
+// problems on some browsers for very long strings. A PATH is expected to be
+// reasonably short. A PATH is allowed to belong to a very restricted subset of
+// Goessner's JSONPath.
+
+// So,
+// var s = '[{"$ref":"$"}]';
+// return JSON.retrocycle(JSON.parse(s));
+// produces an array containing a single element which is the array itself.
+
+ var px =
+ /^\$(?:\[(?:\d+|\"(?:[^\\\"\u0000-\u001f]|\\([\\\"\/bfnrt]|u[0-9a-zA-Z]{4}))*\")\])*$/;
+
+ (function rez(value) {
+
+// The rez function walks recursively through the object looking for $ref
+// properties. When it finds one that has a value that is a path, then it
+// replaces the $ref object with a reference to the value that is found by
+// the path.
+
+ var i, item, name, path;
+
+ if (value && typeof value === 'object') {
+ if (Object.prototype.toString.apply(value) === '[object Array]') {
+ for (i = 0; i < value.length; i += 1) {
+ item = value[i];
+ if (item && typeof item === 'object') {
+ path = item.$ref;
+ if (typeof path === 'string' && px.test(path)) {
+ value[i] = eval(path);
+ } else {
+ rez(item);
+ }
+ }
+ }
+ } else {
+ for (name in value) {
+ if (typeof value[name] === 'object') {
+ item = value[name];
+ if (item) {
+ path = item.$ref;
+ if (typeof path === 'string' && px.test(path)) {
+ value[name] = eval(path);
+ } else {
+ rez(item);
+ }
+ }
+ }
+ }
+ }
+ }
+ }($));
+ return $;
+};
diff --git a/node_modules/cycle/package.json b/node_modules/cycle/package.json
new file mode 100644
index 00000000..e44eec97
--- /dev/null
+++ b/node_modules/cycle/package.json
@@ -0,0 +1,81 @@
+{
+ "_args": [
+ [
+ {
+ "raw": "cycle@1.0.x",
+ "scope": null,
+ "escapedName": "cycle",
+ "name": "cycle",
+ "rawSpec": "1.0.x",
+ "spec": ">=1.0.0 <1.1.0",
+ "type": "range"
+ },
+ "/Users/ericchiu/Desktop/CIS 700/HW7/Project7-BioCrowds/node_modules/winston"
+ ]
+ ],
+ "_from": "cycle@>=1.0.0 <1.1.0",
+ "_id": "cycle@1.0.3",
+ "_inCache": true,
+ "_location": "/cycle",
+ "_npmUser": {
+ "name": "dscape",
+ "email": "nunojobpinto@gmail.com"
+ },
+ "_npmVersion": "1.2.32",
+ "_phantomChildren": {},
+ "_requested": {
+ "raw": "cycle@1.0.x",
+ "scope": null,
+ "escapedName": "cycle",
+ "name": "cycle",
+ "rawSpec": "1.0.x",
+ "spec": ">=1.0.0 <1.1.0",
+ "type": "range"
+ },
+ "_requiredBy": [
+ "/winston"
+ ],
+ "_resolved": "https://registry.npmjs.org/cycle/-/cycle-1.0.3.tgz",
+ "_shasum": "21e80b2be8580f98b468f379430662b046c34ad2",
+ "_shrinkwrap": null,
+ "_spec": "cycle@1.0.x",
+ "_where": "/Users/ericchiu/Desktop/CIS 700/HW7/Project7-BioCrowds/node_modules/winston",
+ "author": "",
+ "bugs": {
+ "url": "http://github.com/douglascrockford/JSON-js/issues"
+ },
+ "dependencies": {},
+ "description": "decycle your json",
+ "devDependencies": {},
+ "directories": {},
+ "dist": {
+ "shasum": "21e80b2be8580f98b468f379430662b046c34ad2",
+ "tarball": "https://registry.npmjs.org/cycle/-/cycle-1.0.3.tgz"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ },
+ "homepage": "https://github.com/douglascrockford/JSON-js",
+ "keywords": [
+ "json",
+ "cycle",
+ "stringify",
+ "parse"
+ ],
+ "main": "./cycle.js",
+ "maintainers": [
+ {
+ "name": "dscape",
+ "email": "nunojobpinto@gmail.com"
+ }
+ ],
+ "name": "cycle",
+ "optionalDependencies": {},
+ "readme": "Fork of https://github.com/douglascrockford/JSON-js, maintained in npm as `cycle`.\n\n# Contributors\n\n* Douglas Crockford\n* Nuno Job\n* Justin Warkentin\n\n# JSON in JavaScript\n\nDouglas Crockford\ndouglas@crockford.com\n\n2010-11-18\n\n\nJSON is a light-weight, language independent, data interchange format.\nSee http://www.JSON.org/\n\nThe files in this collection implement JSON encoders/decoders in JavaScript.\n\nJSON became a built-in feature of JavaScript when the ECMAScript Programming\nLanguage Standard - Fifth Edition was adopted by the ECMA General Assembly\nin December 2009. Most of the files in this collection are for applications\nthat are expected to run in obsolete web browsers. For most purposes, json2.js\nis the best choice.\n\n\njson2.js: This file creates a JSON property in the global object, if there\nisn't already one, setting its value to an object containing a stringify\nmethod and a parse method. The parse method uses the eval method to do the\nparsing, guarding it with several regular expressions to defend against\naccidental code execution hazards. On current browsers, this file does nothing,\nprefering the built-in JSON object.\n\njson.js: This file does everything that json2.js does. It also adds a\ntoJSONString method and a parseJSON method to Object.prototype. Use of this\nfile is not recommended.\n\njson_parse.js: This file contains an alternative JSON parse function that\nuses recursive descent instead of eval.\n\njson_parse_state.js: This files contains an alternative JSON parse function that\nuses a state machine instead of eval.\n\ncycle.js: This file contains two functions, JSON.decycle and JSON.retrocycle,\nwhich make it possible to encode cyclical structures and dags in JSON, and to\nthen recover them. JSONPath is used to represent the links.\nhttp://GOESSNER.net/articles/JsonPath/\n",
+ "readmeFilename": "README.md",
+ "repository": {
+ "type": "git",
+ "url": "git+ssh://git@github.com/dscape/cycle.git"
+ },
+ "version": "1.0.3"
+}
diff --git a/node_modules/dat-gui/.npmignore b/node_modules/dat-gui/.npmignore
new file mode 100644
index 00000000..546f53c9
--- /dev/null
+++ b/node_modules/dat-gui/.npmignore
@@ -0,0 +1,2 @@
+/node_modules/
+/dat-gui/
\ No newline at end of file
diff --git a/node_modules/dat-gui/index.js b/node_modules/dat-gui/index.js
new file mode 100644
index 00000000..2f273a14
--- /dev/null
+++ b/node_modules/dat-gui/index.js
@@ -0,0 +1,2 @@
+module.exports = require('./vendor/dat.gui')
+module.exports.color = require('./vendor/dat.color')
\ No newline at end of file
diff --git a/node_modules/dat-gui/package.json b/node_modules/dat-gui/package.json
new file mode 100644
index 00000000..36466133
--- /dev/null
+++ b/node_modules/dat-gui/package.json
@@ -0,0 +1,79 @@
+{
+ "_args": [
+ [
+ {
+ "raw": "dat-gui@^0.5.0",
+ "scope": null,
+ "escapedName": "dat-gui",
+ "name": "dat-gui",
+ "rawSpec": "^0.5.0",
+ "spec": ">=0.5.0 <0.6.0",
+ "type": "range"
+ },
+ "/Users/ericchiu/Desktop/CIS 700/HW7/Project7-BioCrowds"
+ ]
+ ],
+ "_from": "dat-gui@>=0.5.0 <0.6.0",
+ "_id": "dat-gui@0.5.0",
+ "_inCache": true,
+ "_location": "/dat-gui",
+ "_npmUser": {
+ "name": "shama",
+ "email": "kyle@dontkry.com"
+ },
+ "_npmVersion": "1.2.32",
+ "_phantomChildren": {},
+ "_requested": {
+ "raw": "dat-gui@^0.5.0",
+ "scope": null,
+ "escapedName": "dat-gui",
+ "name": "dat-gui",
+ "rawSpec": "^0.5.0",
+ "spec": ">=0.5.0 <0.6.0",
+ "type": "range"
+ },
+ "_requiredBy": [
+ "/"
+ ],
+ "_resolved": "https://registry.npmjs.org/dat-gui/-/dat-gui-0.5.0.tgz",
+ "_shasum": "1212da836109747d0ac220bad7b07c17daa03583",
+ "_shrinkwrap": null,
+ "_spec": "dat-gui@^0.5.0",
+ "_where": "/Users/ericchiu/Desktop/CIS 700/HW7/Project7-BioCrowds",
+ "author": {
+ "name": "Data Arts Team, Google Creative Lab"
+ },
+ "dependencies": {},
+ "description": "Browserified dat-gui library",
+ "devDependencies": {},
+ "directories": {},
+ "dist": {
+ "shasum": "1212da836109747d0ac220bad7b07c17daa03583",
+ "tarball": "https://registry.npmjs.org/dat-gui/-/dat-gui-0.5.0.tgz"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ },
+ "homepage": "https://code.google.com/p/dat-gui/",
+ "licenses": [
+ {
+ "type": "Apache-2.0",
+ "url": "http://www.apache.org/licenses/LICENSE-2.0"
+ }
+ ],
+ "maintainers": [
+ {
+ "name": "shama",
+ "email": "kyle@dontkry.com"
+ }
+ ],
+ "name": "dat-gui",
+ "optionalDependencies": {},
+ "readme": "=dat.GUI=\nA lightweight graphical user interface for changing variables in JavaScript. \n\nGet started with dat.GUI by reading the tutorial at [http://workshop.chromeexperiments.com/examples/gui].\n\n----\n\n==Packaged Builds==\nThe easiest way to use dat.GUI in your code is by using the built source at {{{build/dat.gui.min.js}}}. These built JavaScript files bundle all the necessary dependencies to run dat.GUI.\n\nIn your {{{head}}} tag, include the following code:\n{{{\n\n}}}\n\n----\n\n==Using dat.GUI with require.js==\nInternally, dat.GUI uses [http://requirejs.org/ require.js] to handle dependency management. If you're making changes to the source and want to see the effects of your changes without building, use require js.\n\nIn your {{{head}}} tag, include the following code:\n{{{\n\n}}}\n\nThen, in {{{path/to/main.js}}}:\n{{{\nrequire([\n 'path/to/gui/module/GUI'\n], function(GUI) {\n\n // No namespace necessary \n var gui = new GUI();\n\n});\n}}}\n\n----\n\n==Directory Contents==\n * build: Concatenated source code.\n * src: Modular code in [http://requirejs.org/ require.js] format. Also includes css, [http://sass-lang.com/ scss], and html, some of which is included during build.\n * tests: [https://github.com/jquery/qunit QUnit] test suite.\n * utils: [http://nodejs.org/ node.js] utility scripts for compiling source.\n\n----\n\n==Building your own dat.GUI==\n\nIn the terminal, enter the following:\n\n{{{\n$ cd utils\n$ node build_gui.js\n}}}\n\nThis will create a namespaced, unminified build of dat.GUI at {{{build/dat.gui.js}}}\n\n_To export minified source using Closure Compiler, open {{{utils/build_gui.js}}} and set the {{{minify}}} parameter to {{{true}}}._\n\n----\n\n==Change log==\n\n===0.5===\n * Moved to requirejs for dependency management.\n * Changed global namespace from *DAT* to *dat* (lowercase).\n * Added support for color controllers. See [http://workshop.chromeexperiments.com/examples/gui/#4--Color-Controllers Color Controllers].\n * Added support for folders. See [http://workshop.chromeexperiments.com/examples/gui/#3--Folders Folders].\n * Added support for saving named presets. See [http://workshop.chromeexperiments.com/examples/gui/examples/gui/#6--Presets Presets].\n * Removed `height` parameter from GUI constructor. Scrollbar automatically induced when window is too short.\n * `dat.GUI.autoPlace` parameter removed. Use `new dat.GUI( { autoPlace: false } )`. See [http://workshop.chromeexperiments.com/examples/gui/#9--Custom-Placement Custom Placement].\n * `gui.autoListen` and `gui.listenAll()` removed. See [http://workshop.chromeexperiments.com/examples/gui/#11--Updating-the-Display-Manually Updating The Display Manually].\n * `dat.GUI.load` removed. See [http://workshop.chromeexperiments.com/examples/gui/#5--Saving-Values Saving Values].\n * Made Controller code completely agnostic of GUI. Controllers can easily be created independent of a GUI panel.\n\n\n===0.4===\n\n * Migrated from GitHub to Google Code.\n\n----\n\n==Thanks==\nThe following libraries / open-source projects were used in the development of dat.GUI:\n * [http://requirejs.org/ require.js]\n * [http://sass-lang.com/ Sass]\n * [http://nodejs.org/ node.js]\n * [https://github.com/jquery/qunit QUnit] / [http://jquery.com/ jquery]",
+ "readmeFilename": "readme.wiki",
+ "repository": {
+ "type": "git",
+ "url": "https://code.google.com/p/dat-gui/"
+ },
+ "version": "0.5.0"
+}
diff --git a/node_modules/dat-gui/readme.wiki b/node_modules/dat-gui/readme.wiki
new file mode 100644
index 00000000..a6631064
--- /dev/null
+++ b/node_modules/dat-gui/readme.wiki
@@ -0,0 +1,89 @@
+=dat.GUI=
+A lightweight graphical user interface for changing variables in JavaScript.
+
+Get started with dat.GUI by reading the tutorial at [http://workshop.chromeexperiments.com/examples/gui].
+
+----
+
+==Packaged Builds==
+The easiest way to use dat.GUI in your code is by using the built source at {{{build/dat.gui.min.js}}}. These built JavaScript files bundle all the necessary dependencies to run dat.GUI.
+
+In your {{{head}}} tag, include the following code:
+{{{
+
+}}}
+
+----
+
+==Using dat.GUI with require.js==
+Internally, dat.GUI uses [http://requirejs.org/ require.js] to handle dependency management. If you're making changes to the source and want to see the effects of your changes without building, use require js.
+
+In your {{{head}}} tag, include the following code:
+{{{
+
+}}}
+
+Then, in {{{path/to/main.js}}}:
+{{{
+require([
+ 'path/to/gui/module/GUI'
+], function(GUI) {
+
+ // No namespace necessary
+ var gui = new GUI();
+
+});
+}}}
+
+----
+
+==Directory Contents==
+ * build: Concatenated source code.
+ * src: Modular code in [http://requirejs.org/ require.js] format. Also includes css, [http://sass-lang.com/ scss], and html, some of which is included during build.
+ * tests: [https://github.com/jquery/qunit QUnit] test suite.
+ * utils: [http://nodejs.org/ node.js] utility scripts for compiling source.
+
+----
+
+==Building your own dat.GUI==
+
+In the terminal, enter the following:
+
+{{{
+$ cd utils
+$ node build_gui.js
+}}}
+
+This will create a namespaced, unminified build of dat.GUI at {{{build/dat.gui.js}}}
+
+_To export minified source using Closure Compiler, open {{{utils/build_gui.js}}} and set the {{{minify}}} parameter to {{{true}}}._
+
+----
+
+==Change log==
+
+===0.5===
+ * Moved to requirejs for dependency management.
+ * Changed global namespace from *DAT* to *dat* (lowercase).
+ * Added support for color controllers. See [http://workshop.chromeexperiments.com/examples/gui/#4--Color-Controllers Color Controllers].
+ * Added support for folders. See [http://workshop.chromeexperiments.com/examples/gui/#3--Folders Folders].
+ * Added support for saving named presets. See [http://workshop.chromeexperiments.com/examples/gui/examples/gui/#6--Presets Presets].
+ * Removed `height` parameter from GUI constructor. Scrollbar automatically induced when window is too short.
+ * `dat.GUI.autoPlace` parameter removed. Use `new dat.GUI( { autoPlace: false } )`. See [http://workshop.chromeexperiments.com/examples/gui/#9--Custom-Placement Custom Placement].
+ * `gui.autoListen` and `gui.listenAll()` removed. See [http://workshop.chromeexperiments.com/examples/gui/#11--Updating-the-Display-Manually Updating The Display Manually].
+ * `dat.GUI.load` removed. See [http://workshop.chromeexperiments.com/examples/gui/#5--Saving-Values Saving Values].
+ * Made Controller code completely agnostic of GUI. Controllers can easily be created independent of a GUI panel.
+
+
+===0.4===
+
+ * Migrated from GitHub to Google Code.
+
+----
+
+==Thanks==
+The following libraries / open-source projects were used in the development of dat.GUI:
+ * [http://requirejs.org/ require.js]
+ * [http://sass-lang.com/ Sass]
+ * [http://nodejs.org/ node.js]
+ * [https://github.com/jquery/qunit QUnit] / [http://jquery.com/ jquery]
\ No newline at end of file
diff --git a/node_modules/dat-gui/vendor/dat.color.js b/node_modules/dat-gui/vendor/dat.color.js
new file mode 100644
index 00000000..57351e8f
--- /dev/null
+++ b/node_modules/dat-gui/vendor/dat.color.js
@@ -0,0 +1,755 @@
+/**
+ * dat-gui JavaScript Controller Library
+ * http://code.google.com/p/dat-gui
+ *
+ * Copyright 2011 Data Arts Team, Google Creative Lab
+ *
+ * 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
+ */
+
+/** @namespace */
+var dat = module.exports = dat || {};
+
+/** @namespace */
+dat.color = dat.color || {};
+
+/** @namespace */
+dat.utils = dat.utils || {};
+
+dat.utils.common = (function () {
+
+ var ARR_EACH = Array.prototype.forEach;
+ var ARR_SLICE = Array.prototype.slice;
+
+ /**
+ * Band-aid methods for things that should be a lot easier in JavaScript.
+ * Implementation and structure inspired by underscore.js
+ * http://documentcloud.github.com/underscore/
+ */
+
+ return {
+
+ BREAK: {},
+
+ extend: function(target) {
+
+ this.each(ARR_SLICE.call(arguments, 1), function(obj) {
+
+ for (var key in obj)
+ if (!this.isUndefined(obj[key]))
+ target[key] = obj[key];
+
+ }, this);
+
+ return target;
+
+ },
+
+ defaults: function(target) {
+
+ this.each(ARR_SLICE.call(arguments, 1), function(obj) {
+
+ for (var key in obj)
+ if (this.isUndefined(target[key]))
+ target[key] = obj[key];
+
+ }, this);
+
+ return target;
+
+ },
+
+ compose: function() {
+ var toCall = ARR_SLICE.call(arguments);
+ return function() {
+ var args = ARR_SLICE.call(arguments);
+ for (var i = toCall.length -1; i >= 0; i--) {
+ args = [toCall[i].apply(this, args)];
+ }
+ return args[0];
+ }
+ },
+
+ each: function(obj, itr, scope) {
+
+
+ if (ARR_EACH && obj.forEach === ARR_EACH) {
+
+ obj.forEach(itr, scope);
+
+ } else if (obj.length === obj.length + 0) { // Is number but not NaN
+
+ for (var key = 0, l = obj.length; key < l; key++)
+ if (key in obj && itr.call(scope, obj[key], key) === this.BREAK)
+ return;
+
+ } else {
+
+ for (var key in obj)
+ if (itr.call(scope, obj[key], key) === this.BREAK)
+ return;
+
+ }
+
+ },
+
+ defer: function(fnc) {
+ setTimeout(fnc, 0);
+ },
+
+ toArray: function(obj) {
+ if (obj.toArray) return obj.toArray();
+ return ARR_SLICE.call(obj);
+ },
+
+ isUndefined: function(obj) {
+ return obj === undefined;
+ },
+
+ isNull: function(obj) {
+ return obj === null;
+ },
+
+ isNaN: function(obj) {
+ return obj !== obj;
+ },
+
+ isArray: Array.isArray || function(obj) {
+ return obj.constructor === Array;
+ },
+
+ isObject: function(obj) {
+ return obj === Object(obj);
+ },
+
+ isNumber: function(obj) {
+ return obj === obj+0;
+ },
+
+ isString: function(obj) {
+ return obj === obj+'';
+ },
+
+ isBoolean: function(obj) {
+ return obj === false || obj === true;
+ },
+
+ isFunction: function(obj) {
+ return Object.prototype.toString.call(obj) === '[object Function]';
+ }
+
+ };
+
+})();
+
+
+dat.color.toString = (function (common) {
+
+ return function(color) {
+
+ if (color.a == 1 || common.isUndefined(color.a)) {
+
+ var s = color.hex.toString(16);
+ while (s.length < 6) {
+ s = '0' + s;
+ }
+
+ return '#' + s;
+
+ } else {
+
+ return 'rgba(' + Math.round(color.r) + ',' + Math.round(color.g) + ',' + Math.round(color.b) + ',' + color.a + ')';
+
+ }
+
+ }
+
+})(dat.utils.common);
+
+
+dat.Color = dat.color.Color = (function (interpret, math, toString, common) {
+
+ var Color = function() {
+
+ this.__state = interpret.apply(this, arguments);
+
+ if (this.__state === false) {
+ throw 'Failed to interpret color arguments';
+ }
+
+ this.__state.a = this.__state.a || 1;
+
+
+ };
+
+ Color.COMPONENTS = ['r','g','b','h','s','v','hex','a'];
+
+ common.extend(Color.prototype, {
+
+ toString: function() {
+ return toString(this);
+ },
+
+ toOriginal: function() {
+ return this.__state.conversion.write(this);
+ }
+
+ });
+
+ defineRGBComponent(Color.prototype, 'r', 2);
+ defineRGBComponent(Color.prototype, 'g', 1);
+ defineRGBComponent(Color.prototype, 'b', 0);
+
+ defineHSVComponent(Color.prototype, 'h');
+ defineHSVComponent(Color.prototype, 's');
+ defineHSVComponent(Color.prototype, 'v');
+
+ Object.defineProperty(Color.prototype, 'a', {
+
+ get: function() {
+ return this.__state.a;
+ },
+
+ set: function(v) {
+ this.__state.a = v;
+ }
+
+ });
+
+ Object.defineProperty(Color.prototype, 'hex', {
+
+ get: function() {
+
+ if (!this.__state.space !== 'HEX') {
+ this.__state.hex = math.rgb_to_hex(this.r, this.g, this.b);
+ }
+
+ return this.__state.hex;
+
+ },
+
+ set: function(v) {
+
+ this.__state.space = 'HEX';
+ this.__state.hex = v;
+
+ }
+
+ });
+
+ function defineRGBComponent(target, component, componentHexIndex) {
+
+ Object.defineProperty(target, component, {
+
+ get: function() {
+
+ if (this.__state.space === 'RGB') {
+ return this.__state[component];
+ }
+
+ recalculateRGB(this, component, componentHexIndex);
+
+ return this.__state[component];
+
+ },
+
+ set: function(v) {
+
+ if (this.__state.space !== 'RGB') {
+ recalculateRGB(this, component, componentHexIndex);
+ this.__state.space = 'RGB';
+ }
+
+ this.__state[component] = v;
+
+ }
+
+ });
+
+ }
+
+ function defineHSVComponent(target, component) {
+
+ Object.defineProperty(target, component, {
+
+ get: function() {
+
+ if (this.__state.space === 'HSV')
+ return this.__state[component];
+
+ recalculateHSV(this);
+
+ return this.__state[component];
+
+ },
+
+ set: function(v) {
+
+ if (this.__state.space !== 'HSV') {
+ recalculateHSV(this);
+ this.__state.space = 'HSV';
+ }
+
+ this.__state[component] = v;
+
+ }
+
+ });
+
+ }
+
+ function recalculateRGB(color, component, componentHexIndex) {
+
+ if (color.__state.space === 'HEX') {
+
+ color.__state[component] = math.component_from_hex(color.__state.hex, componentHexIndex);
+
+ } else if (color.__state.space === 'HSV') {
+
+ common.extend(color.__state, math.hsv_to_rgb(color.__state.h, color.__state.s, color.__state.v));
+
+ } else {
+
+ throw 'Corrupted color state';
+
+ }
+
+ }
+
+ function recalculateHSV(color) {
+
+ var result = math.rgb_to_hsv(color.r, color.g, color.b);
+
+ common.extend(color.__state,
+ {
+ s: result.s,
+ v: result.v
+ }
+ );
+
+ if (!common.isNaN(result.h)) {
+ color.__state.h = result.h;
+ } else if (common.isUndefined(color.__state.h)) {
+ color.__state.h = 0;
+ }
+
+ }
+
+ return Color;
+
+})(dat.color.interpret = (function (toString, common) {
+
+ var result, toReturn;
+
+ var interpret = function() {
+
+ toReturn = false;
+
+ var original = arguments.length > 1 ? common.toArray(arguments) : arguments[0];
+
+ common.each(INTERPRETATIONS, function(family) {
+
+ if (family.litmus(original)) {
+
+ common.each(family.conversions, function(conversion, conversionName) {
+
+ result = conversion.read(original);
+
+ if (toReturn === false && result !== false) {
+ toReturn = result;
+ result.conversionName = conversionName;
+ result.conversion = conversion;
+ return common.BREAK;
+
+ }
+
+ });
+
+ return common.BREAK;
+
+ }
+
+ });
+
+ return toReturn;
+
+ };
+
+ var INTERPRETATIONS = [
+
+ // Strings
+ {
+
+ litmus: common.isString,
+
+ conversions: {
+
+ THREE_CHAR_HEX: {
+
+ read: function(original) {
+
+ var test = original.match(/^#([A-F0-9])([A-F0-9])([A-F0-9])$/i);
+ if (test === null) return false;
+
+ return {
+ space: 'HEX',
+ hex: parseInt(
+ '0x' +
+ test[1].toString() + test[1].toString() +
+ test[2].toString() + test[2].toString() +
+ test[3].toString() + test[3].toString())
+ };
+
+ },
+
+ write: toString
+
+ },
+
+ SIX_CHAR_HEX: {
+
+ read: function(original) {
+
+ var test = original.match(/^#([A-F0-9]{6})$/i);
+ if (test === null) return false;
+
+ return {
+ space: 'HEX',
+ hex: parseInt('0x' + test[1].toString())
+ };
+
+ },
+
+ write: toString
+
+ },
+
+ CSS_RGB: {
+
+ read: function(original) {
+
+ var test = original.match(/^rgb\(\s*(.+)\s*,\s*(.+)\s*,\s*(.+)\s*\)/);
+ if (test === null) return false;
+
+ return {
+ space: 'RGB',
+ r: parseFloat(test[1]),
+ g: parseFloat(test[2]),
+ b: parseFloat(test[3])
+ };
+
+ },
+
+ write: toString
+
+ },
+
+ CSS_RGBA: {
+
+ read: function(original) {
+
+ var test = original.match(/^rgba\(\s*(.+)\s*,\s*(.+)\s*,\s*(.+)\s*\,\s*(.+)\s*\)/);
+ if (test === null) return false;
+
+ return {
+ space: 'RGB',
+ r: parseFloat(test[1]),
+ g: parseFloat(test[2]),
+ b: parseFloat(test[3]),
+ a: parseFloat(test[4])
+ };
+
+ },
+
+ write: toString
+
+ }
+
+ }
+
+ },
+
+ // Numbers
+ {
+
+ litmus: common.isNumber,
+
+ conversions: {
+
+ HEX: {
+ read: function(original) {
+ return {
+ space: 'HEX',
+ hex: original,
+ conversionName: 'HEX'
+ }
+ },
+
+ write: function(color) {
+ return color.hex;
+ }
+ }
+
+ }
+
+ },
+
+ // Arrays
+ {
+
+ litmus: common.isArray,
+
+ conversions: {
+
+ RGB_ARRAY: {
+ read: function(original) {
+ if (original.length != 3) return false;
+ return {
+ space: 'RGB',
+ r: original[0],
+ g: original[1],
+ b: original[2]
+ };
+ },
+
+ write: function(color) {
+ return [color.r, color.g, color.b];
+ }
+
+ },
+
+ RGBA_ARRAY: {
+ read: function(original) {
+ if (original.length != 4) return false;
+ return {
+ space: 'RGB',
+ r: original[0],
+ g: original[1],
+ b: original[2],
+ a: original[3]
+ };
+ },
+
+ write: function(color) {
+ return [color.r, color.g, color.b, color.a];
+ }
+
+ }
+
+ }
+
+ },
+
+ // Objects
+ {
+
+ litmus: common.isObject,
+
+ conversions: {
+
+ RGBA_OBJ: {
+ read: function(original) {
+ if (common.isNumber(original.r) &&
+ common.isNumber(original.g) &&
+ common.isNumber(original.b) &&
+ common.isNumber(original.a)) {
+ return {
+ space: 'RGB',
+ r: original.r,
+ g: original.g,
+ b: original.b,
+ a: original.a
+ }
+ }
+ return false;
+ },
+
+ write: function(color) {
+ return {
+ r: color.r,
+ g: color.g,
+ b: color.b,
+ a: color.a
+ }
+ }
+ },
+
+ RGB_OBJ: {
+ read: function(original) {
+ if (common.isNumber(original.r) &&
+ common.isNumber(original.g) &&
+ common.isNumber(original.b)) {
+ return {
+ space: 'RGB',
+ r: original.r,
+ g: original.g,
+ b: original.b
+ }
+ }
+ return false;
+ },
+
+ write: function(color) {
+ return {
+ r: color.r,
+ g: color.g,
+ b: color.b
+ }
+ }
+ },
+
+ HSVA_OBJ: {
+ read: function(original) {
+ if (common.isNumber(original.h) &&
+ common.isNumber(original.s) &&
+ common.isNumber(original.v) &&
+ common.isNumber(original.a)) {
+ return {
+ space: 'HSV',
+ h: original.h,
+ s: original.s,
+ v: original.v,
+ a: original.a
+ }
+ }
+ return false;
+ },
+
+ write: function(color) {
+ return {
+ h: color.h,
+ s: color.s,
+ v: color.v,
+ a: color.a
+ }
+ }
+ },
+
+ HSV_OBJ: {
+ read: function(original) {
+ if (common.isNumber(original.h) &&
+ common.isNumber(original.s) &&
+ common.isNumber(original.v)) {
+ return {
+ space: 'HSV',
+ h: original.h,
+ s: original.s,
+ v: original.v
+ }
+ }
+ return false;
+ },
+
+ write: function(color) {
+ return {
+ h: color.h,
+ s: color.s,
+ v: color.v
+ }
+ }
+
+ }
+
+ }
+
+ }
+
+
+ ];
+
+ return interpret;
+
+
+})(dat.color.toString,
+dat.utils.common),
+dat.color.math = (function () {
+
+ var tmpComponent;
+
+ return {
+
+ hsv_to_rgb: function(h, s, v) {
+
+ var hi = Math.floor(h / 60) % 6;
+
+ var f = h / 60 - Math.floor(h / 60);
+ var p = v * (1.0 - s);
+ var q = v * (1.0 - (f * s));
+ var t = v * (1.0 - ((1.0 - f) * s));
+ var c = [
+ [v, t, p],
+ [q, v, p],
+ [p, v, t],
+ [p, q, v],
+ [t, p, v],
+ [v, p, q]
+ ][hi];
+
+ return {
+ r: c[0] * 255,
+ g: c[1] * 255,
+ b: c[2] * 255
+ };
+
+ },
+
+ rgb_to_hsv: function(r, g, b) {
+
+ var min = Math.min(r, g, b),
+ max = Math.max(r, g, b),
+ delta = max - min,
+ h, s;
+
+ if (max != 0) {
+ s = delta / max;
+ } else {
+ return {
+ h: NaN,
+ s: 0,
+ v: 0
+ };
+ }
+
+ if (r == max) {
+ h = (g - b) / delta;
+ } else if (g == max) {
+ h = 2 + (b - r) / delta;
+ } else {
+ h = 4 + (r - g) / delta;
+ }
+ h /= 6;
+ if (h < 0) {
+ h += 1;
+ }
+
+ return {
+ h: h * 360,
+ s: s,
+ v: max / 255
+ };
+ },
+
+ rgb_to_hex: function(r, g, b) {
+ var hex = this.hex_with_component(0, 2, r);
+ hex = this.hex_with_component(hex, 1, g);
+ hex = this.hex_with_component(hex, 0, b);
+ return hex;
+ },
+
+ component_from_hex: function(hex, componentIndex) {
+ return (hex >> (componentIndex * 8)) & 0xFF;
+ },
+
+ hex_with_component: function(hex, componentIndex, value) {
+ return value << (tmpComponent = componentIndex * 8) | (hex & ~ (0xFF << tmpComponent));
+ }
+
+ }
+
+})(),
+dat.color.toString,
+dat.utils.common);
\ No newline at end of file
diff --git a/node_modules/dat-gui/vendor/dat.gui.js b/node_modules/dat-gui/vendor/dat.gui.js
new file mode 100644
index 00000000..36f16f1d
--- /dev/null
+++ b/node_modules/dat-gui/vendor/dat.gui.js
@@ -0,0 +1,3660 @@
+/**
+ * dat-gui JavaScript Controller Library
+ * http://code.google.com/p/dat-gui
+ *
+ * Copyright 2011 Data Arts Team, Google Creative Lab
+ *
+ * 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
+ */
+
+/** @namespace */
+var dat = module.exports = dat || {};
+
+/** @namespace */
+dat.gui = dat.gui || {};
+
+/** @namespace */
+dat.utils = dat.utils || {};
+
+/** @namespace */
+dat.controllers = dat.controllers || {};
+
+/** @namespace */
+dat.dom = dat.dom || {};
+
+/** @namespace */
+dat.color = dat.color || {};
+
+dat.utils.css = (function () {
+ return {
+ load: function (url, doc) {
+ doc = doc || document;
+ var link = doc.createElement('link');
+ link.type = 'text/css';
+ link.rel = 'stylesheet';
+ link.href = url;
+ doc.getElementsByTagName('head')[0].appendChild(link);
+ },
+ inject: function(css, doc) {
+ doc = doc || document;
+ var injected = document.createElement('style');
+ injected.type = 'text/css';
+ injected.innerHTML = css;
+ doc.getElementsByTagName('head')[0].appendChild(injected);
+ }
+ }
+})();
+
+
+dat.utils.common = (function () {
+
+ var ARR_EACH = Array.prototype.forEach;
+ var ARR_SLICE = Array.prototype.slice;
+
+ /**
+ * Band-aid methods for things that should be a lot easier in JavaScript.
+ * Implementation and structure inspired by underscore.js
+ * http://documentcloud.github.com/underscore/
+ */
+
+ return {
+
+ BREAK: {},
+
+ extend: function(target) {
+
+ this.each(ARR_SLICE.call(arguments, 1), function(obj) {
+
+ for (var key in obj)
+ if (!this.isUndefined(obj[key]))
+ target[key] = obj[key];
+
+ }, this);
+
+ return target;
+
+ },
+
+ defaults: function(target) {
+
+ this.each(ARR_SLICE.call(arguments, 1), function(obj) {
+
+ for (var key in obj)
+ if (this.isUndefined(target[key]))
+ target[key] = obj[key];
+
+ }, this);
+
+ return target;
+
+ },
+
+ compose: function() {
+ var toCall = ARR_SLICE.call(arguments);
+ return function() {
+ var args = ARR_SLICE.call(arguments);
+ for (var i = toCall.length -1; i >= 0; i--) {
+ args = [toCall[i].apply(this, args)];
+ }
+ return args[0];
+ }
+ },
+
+ each: function(obj, itr, scope) {
+
+
+ if (ARR_EACH && obj.forEach === ARR_EACH) {
+
+ obj.forEach(itr, scope);
+
+ } else if (obj.length === obj.length + 0) { // Is number but not NaN
+
+ for (var key = 0, l = obj.length; key < l; key++)
+ if (key in obj && itr.call(scope, obj[key], key) === this.BREAK)
+ return;
+
+ } else {
+
+ for (var key in obj)
+ if (itr.call(scope, obj[key], key) === this.BREAK)
+ return;
+
+ }
+
+ },
+
+ defer: function(fnc) {
+ setTimeout(fnc, 0);
+ },
+
+ toArray: function(obj) {
+ if (obj.toArray) return obj.toArray();
+ return ARR_SLICE.call(obj);
+ },
+
+ isUndefined: function(obj) {
+ return obj === undefined;
+ },
+
+ isNull: function(obj) {
+ return obj === null;
+ },
+
+ isNaN: function(obj) {
+ return obj !== obj;
+ },
+
+ isArray: Array.isArray || function(obj) {
+ return obj.constructor === Array;
+ },
+
+ isObject: function(obj) {
+ return obj === Object(obj);
+ },
+
+ isNumber: function(obj) {
+ return obj === obj+0;
+ },
+
+ isString: function(obj) {
+ return obj === obj+'';
+ },
+
+ isBoolean: function(obj) {
+ return obj === false || obj === true;
+ },
+
+ isFunction: function(obj) {
+ return Object.prototype.toString.call(obj) === '[object Function]';
+ }
+
+ };
+
+})();
+
+
+dat.controllers.Controller = (function (common) {
+
+ /**
+ * @class An "abstract" class that represents a given property of an object.
+ *
+ * @param {Object} object The object to be manipulated
+ * @param {string} property The name of the property to be manipulated
+ *
+ * @member dat.controllers
+ */
+ var Controller = function(object, property) {
+
+ this.initialValue = object[property];
+
+ /**
+ * Those who extend this class will put their DOM elements in here.
+ * @type {DOMElement}
+ */
+ this.domElement = document.createElement('div');
+
+ /**
+ * The object to manipulate
+ * @type {Object}
+ */
+ this.object = object;
+
+ /**
+ * The name of the property to manipulate
+ * @type {String}
+ */
+ this.property = property;
+
+ /**
+ * The function to be called on change.
+ * @type {Function}
+ * @ignore
+ */
+ this.__onChange = undefined;
+
+ /**
+ * The function to be called on finishing change.
+ * @type {Function}
+ * @ignore
+ */
+ this.__onFinishChange = undefined;
+
+ };
+
+ common.extend(
+
+ Controller.prototype,
+
+ /** @lends dat.controllers.Controller.prototype */
+ {
+
+ /**
+ * Specify that a function fire every time someone changes the value with
+ * this Controller.
+ *
+ * @param {Function} fnc This function will be called whenever the value
+ * is modified via this Controller.
+ * @returns {dat.controllers.Controller} this
+ */
+ onChange: function(fnc) {
+ this.__onChange = fnc;
+ return this;
+ },
+
+ /**
+ * Specify that a function fire every time someone "finishes" changing
+ * the value wih this Controller. Useful for values that change
+ * incrementally like numbers or strings.
+ *
+ * @param {Function} fnc This function will be called whenever
+ * someone "finishes" changing the value via this Controller.
+ * @returns {dat.controllers.Controller} this
+ */
+ onFinishChange: function(fnc) {
+ this.__onFinishChange = fnc;
+ return this;
+ },
+
+ /**
+ * Change the value of object[property]
+ *
+ * @param {Object} newValue The new value of object[property]
+ */
+ setValue: function(newValue) {
+ this.object[this.property] = newValue;
+ if (this.__onChange) {
+ this.__onChange.call(this, newValue);
+ }
+ this.updateDisplay();
+ return this;
+ },
+
+ /**
+ * Gets the value of object[property]
+ *
+ * @returns {Object} The current value of object[property]
+ */
+ getValue: function() {
+ return this.object[this.property];
+ },
+
+ /**
+ * Refreshes the visual display of a Controller in order to keep sync
+ * with the object's current value.
+ * @returns {dat.controllers.Controller} this
+ */
+ updateDisplay: function() {
+ return this;
+ },
+
+ /**
+ * @returns {Boolean} true if the value has deviated from initialValue
+ */
+ isModified: function() {
+ return this.initialValue !== this.getValue()
+ }
+
+ }
+
+ );
+
+ return Controller;
+
+
+})(dat.utils.common);
+
+
+dat.dom.dom = (function (common) {
+
+ var EVENT_MAP = {
+ 'HTMLEvents': ['change'],
+ 'MouseEvents': ['click','mousemove','mousedown','mouseup', 'mouseover'],
+ 'KeyboardEvents': ['keydown']
+ };
+
+ var EVENT_MAP_INV = {};
+ common.each(EVENT_MAP, function(v, k) {
+ common.each(v, function(e) {
+ EVENT_MAP_INV[e] = k;
+ });
+ });
+
+ var CSS_VALUE_PIXELS = /(\d+(\.\d+)?)px/;
+
+ function cssValueToPixels(val) {
+
+ if (val === '0' || common.isUndefined(val)) return 0;
+
+ var match = val.match(CSS_VALUE_PIXELS);
+
+ if (!common.isNull(match)) {
+ return parseFloat(match[1]);
+ }
+
+ // TODO ...ems? %?
+
+ return 0;
+
+ }
+
+ /**
+ * @namespace
+ * @member dat.dom
+ */
+ var dom = {
+
+ /**
+ *
+ * @param elem
+ * @param selectable
+ */
+ makeSelectable: function(elem, selectable) {
+
+ if (elem === undefined || elem.style === undefined) return;
+
+ elem.onselectstart = selectable ? function() {
+ return false;
+ } : function() {
+ };
+
+ elem.style.MozUserSelect = selectable ? 'auto' : 'none';
+ elem.style.KhtmlUserSelect = selectable ? 'auto' : 'none';
+ elem.unselectable = selectable ? 'on' : 'off';
+
+ },
+
+ /**
+ *
+ * @param elem
+ * @param horizontal
+ * @param vertical
+ */
+ makeFullscreen: function(elem, horizontal, vertical) {
+
+ if (common.isUndefined(horizontal)) horizontal = true;
+ if (common.isUndefined(vertical)) vertical = true;
+
+ elem.style.position = 'absolute';
+
+ if (horizontal) {
+ elem.style.left = 0;
+ elem.style.right = 0;
+ }
+ if (vertical) {
+ elem.style.top = 0;
+ elem.style.bottom = 0;
+ }
+
+ },
+
+ /**
+ *
+ * @param elem
+ * @param eventType
+ * @param params
+ */
+ fakeEvent: function(elem, eventType, params, aux) {
+ params = params || {};
+ var className = EVENT_MAP_INV[eventType];
+ if (!className) {
+ throw new Error('Event type ' + eventType + ' not supported.');
+ }
+ var evt = document.createEvent(className);
+ switch (className) {
+ case 'MouseEvents':
+ var clientX = params.x || params.clientX || 0;
+ var clientY = params.y || params.clientY || 0;
+ evt.initMouseEvent(eventType, params.bubbles || false,
+ params.cancelable || true, window, params.clickCount || 1,
+ 0, //screen X
+ 0, //screen Y
+ clientX, //client X
+ clientY, //client Y
+ false, false, false, false, 0, null);
+ break;
+ case 'KeyboardEvents':
+ var init = evt.initKeyboardEvent || evt.initKeyEvent; // webkit || moz
+ common.defaults(params, {
+ cancelable: true,
+ ctrlKey: false,
+ altKey: false,
+ shiftKey: false,
+ metaKey: false,
+ keyCode: undefined,
+ charCode: undefined
+ });
+ init(eventType, params.bubbles || false,
+ params.cancelable, window,
+ params.ctrlKey, params.altKey,
+ params.shiftKey, params.metaKey,
+ params.keyCode, params.charCode);
+ break;
+ default:
+ evt.initEvent(eventType, params.bubbles || false,
+ params.cancelable || true);
+ break;
+ }
+ common.defaults(evt, aux);
+ elem.dispatchEvent(evt);
+ },
+
+ /**
+ *
+ * @param elem
+ * @param event
+ * @param func
+ * @param bool
+ */
+ bind: function(elem, event, func, bool) {
+ bool = bool || false;
+ if (elem.addEventListener)
+ elem.addEventListener(event, func, bool);
+ else if (elem.attachEvent)
+ elem.attachEvent('on' + event, func);
+ return dom;
+ },
+
+ /**
+ *
+ * @param elem
+ * @param event
+ * @param func
+ * @param bool
+ */
+ unbind: function(elem, event, func, bool) {
+ bool = bool || false;
+ if (elem.removeEventListener)
+ elem.removeEventListener(event, func, bool);
+ else if (elem.detachEvent)
+ elem.detachEvent('on' + event, func);
+ return dom;
+ },
+
+ /**
+ *
+ * @param elem
+ * @param className
+ */
+ addClass: function(elem, className) {
+ if (elem.className === undefined) {
+ elem.className = className;
+ } else if (elem.className !== className) {
+ var classes = elem.className.split(/ +/);
+ if (classes.indexOf(className) == -1) {
+ classes.push(className);
+ elem.className = classes.join(' ').replace(/^\s+/, '').replace(/\s+$/, '');
+ }
+ }
+ return dom;
+ },
+
+ /**
+ *
+ * @param elem
+ * @param className
+ */
+ removeClass: function(elem, className) {
+ if (className) {
+ if (elem.className === undefined) {
+ // elem.className = className;
+ } else if (elem.className === className) {
+ elem.removeAttribute('class');
+ } else {
+ var classes = elem.className.split(/ +/);
+ var index = classes.indexOf(className);
+ if (index != -1) {
+ classes.splice(index, 1);
+ elem.className = classes.join(' ');
+ }
+ }
+ } else {
+ elem.className = undefined;
+ }
+ return dom;
+ },
+
+ hasClass: function(elem, className) {
+ return new RegExp('(?:^|\\s+)' + className + '(?:\\s+|$)').test(elem.className) || false;
+ },
+
+ /**
+ *
+ * @param elem
+ */
+ getWidth: function(elem) {
+
+ var style = getComputedStyle(elem);
+
+ return cssValueToPixels(style['border-left-width']) +
+ cssValueToPixels(style['border-right-width']) +
+ cssValueToPixels(style['padding-left']) +
+ cssValueToPixels(style['padding-right']) +
+ cssValueToPixels(style['width']);
+ },
+
+ /**
+ *
+ * @param elem
+ */
+ getHeight: function(elem) {
+
+ var style = getComputedStyle(elem);
+
+ return cssValueToPixels(style['border-top-width']) +
+ cssValueToPixels(style['border-bottom-width']) +
+ cssValueToPixels(style['padding-top']) +
+ cssValueToPixels(style['padding-bottom']) +
+ cssValueToPixels(style['height']);
+ },
+
+ /**
+ *
+ * @param elem
+ */
+ getOffset: function(elem) {
+ var offset = {left: 0, top:0};
+ if (elem.offsetParent) {
+ do {
+ offset.left += elem.offsetLeft;
+ offset.top += elem.offsetTop;
+ } while (elem = elem.offsetParent);
+ }
+ return offset;
+ },
+
+ // http://stackoverflow.com/posts/2684561/revisions
+ /**
+ *
+ * @param elem
+ */
+ isActive: function(elem) {
+ return elem === document.activeElement && ( elem.type || elem.href );
+ }
+
+ };
+
+ return dom;
+
+})(dat.utils.common);
+
+
+dat.controllers.OptionController = (function (Controller, dom, common) {
+
+ /**
+ * @class Provides a select input to alter the property of an object, using a
+ * list of accepted values.
+ *
+ * @extends dat.controllers.Controller
+ *
+ * @param {Object} object The object to be manipulated
+ * @param {string} property The name of the property to be manipulated
+ * @param {Object|string[]} options A map of labels to acceptable values, or
+ * a list of acceptable string values.
+ *
+ * @member dat.controllers
+ */
+ var OptionController = function(object, property, options) {
+
+ OptionController.superclass.call(this, object, property);
+
+ var _this = this;
+
+ /**
+ * The drop down menu
+ * @ignore
+ */
+ this.__select = document.createElement('select');
+
+ if (common.isArray(options)) {
+ var map = {};
+ common.each(options, function(element) {
+ map[element] = element;
+ });
+ options = map;
+ }
+
+ common.each(options, function(value, key) {
+
+ var opt = document.createElement('option');
+ opt.innerHTML = key;
+ opt.setAttribute('value', value);
+ _this.__select.appendChild(opt);
+
+ });
+
+ // Acknowledge original value
+ this.updateDisplay();
+
+ dom.bind(this.__select, 'change', function() {
+ var desiredValue = this.options[this.selectedIndex].value;
+ _this.setValue(desiredValue);
+ });
+
+ this.domElement.appendChild(this.__select);
+
+ };
+
+ OptionController.superclass = Controller;
+
+ common.extend(
+
+ OptionController.prototype,
+ Controller.prototype,
+
+ {
+
+ setValue: function(v) {
+ var toReturn = OptionController.superclass.prototype.setValue.call(this, v);
+ if (this.__onFinishChange) {
+ this.__onFinishChange.call(this, this.getValue());
+ }
+ return toReturn;
+ },
+
+ updateDisplay: function() {
+ this.__select.value = this.getValue();
+ return OptionController.superclass.prototype.updateDisplay.call(this);
+ }
+
+ }
+
+ );
+
+ return OptionController;
+
+})(dat.controllers.Controller,
+dat.dom.dom,
+dat.utils.common);
+
+
+dat.controllers.NumberController = (function (Controller, common) {
+
+ /**
+ * @class Represents a given property of an object that is a number.
+ *
+ * @extends dat.controllers.Controller
+ *
+ * @param {Object} object The object to be manipulated
+ * @param {string} property The name of the property to be manipulated
+ * @param {Object} [params] Optional parameters
+ * @param {Number} [params.min] Minimum allowed value
+ * @param {Number} [params.max] Maximum allowed value
+ * @param {Number} [params.step] Increment by which to change value
+ *
+ * @member dat.controllers
+ */
+ var NumberController = function(object, property, params) {
+
+ NumberController.superclass.call(this, object, property);
+
+ params = params || {};
+
+ this.__min = params.min;
+ this.__max = params.max;
+ this.__step = params.step;
+
+ if (common.isUndefined(this.__step)) {
+
+ if (this.initialValue == 0) {
+ this.__impliedStep = 1; // What are we, psychics?
+ } else {
+ // Hey Doug, check this out.
+ this.__impliedStep = Math.pow(10, Math.floor(Math.log(this.initialValue)/Math.LN10))/10;
+ }
+
+ } else {
+
+ this.__impliedStep = this.__step;
+
+ }
+
+ this.__precision = numDecimals(this.__impliedStep);
+
+
+ };
+
+ NumberController.superclass = Controller;
+
+ common.extend(
+
+ NumberController.prototype,
+ Controller.prototype,
+
+ /** @lends dat.controllers.NumberController.prototype */
+ {
+
+ setValue: function(v) {
+
+ if (this.__min !== undefined && v < this.__min) {
+ v = this.__min;
+ } else if (this.__max !== undefined && v > this.__max) {
+ v = this.__max;
+ }
+
+ if (this.__step !== undefined && v % this.__step != 0) {
+ v = Math.round(v / this.__step) * this.__step;
+ }
+
+ return NumberController.superclass.prototype.setValue.call(this, v);
+
+ },
+
+ /**
+ * Specify a minimum value for object[property].
+ *
+ * @param {Number} minValue The minimum value for
+ * object[property]
+ * @returns {dat.controllers.NumberController} this
+ */
+ min: function(v) {
+ this.__min = v;
+ return this;
+ },
+
+ /**
+ * Specify a maximum value for object[property].
+ *
+ * @param {Number} maxValue The maximum value for
+ * object[property]
+ * @returns {dat.controllers.NumberController} this
+ */
+ max: function(v) {
+ this.__max = v;
+ return this;
+ },
+
+ /**
+ * Specify a step value that dat.controllers.NumberController
+ * increments by.
+ *
+ * @param {Number} stepValue The step value for
+ * dat.controllers.NumberController
+ * @default if minimum and maximum specified increment is 1% of the
+ * difference otherwise stepValue is 1
+ * @returns {dat.controllers.NumberController} this
+ */
+ step: function(v) {
+ this.__step = v;
+ return this;
+ }
+
+ }
+
+ );
+
+ function numDecimals(x) {
+ x = x.toString();
+ if (x.indexOf('.') > -1) {
+ return x.length - x.indexOf('.') - 1;
+ } else {
+ return 0;
+ }
+ }
+
+ return NumberController;
+
+})(dat.controllers.Controller,
+dat.utils.common);
+
+
+dat.controllers.NumberControllerBox = (function (NumberController, dom, common) {
+
+ /**
+ * @class Represents a given property of an object that is a number and
+ * provides an input element with which to manipulate it.
+ *
+ * @extends dat.controllers.Controller
+ * @extends dat.controllers.NumberController
+ *
+ * @param {Object} object The object to be manipulated
+ * @param {string} property The name of the property to be manipulated
+ * @param {Object} [params] Optional parameters
+ * @param {Number} [params.min] Minimum allowed value
+ * @param {Number} [params.max] Maximum allowed value
+ * @param {Number} [params.step] Increment by which to change value
+ *
+ * @member dat.controllers
+ */
+ var NumberControllerBox = function(object, property, params) {
+
+ this.__truncationSuspended = false;
+
+ NumberControllerBox.superclass.call(this, object, property, params);
+
+ var _this = this;
+
+ /**
+ * {Number} Previous mouse y position
+ * @ignore
+ */
+ var prev_y;
+
+ this.__input = document.createElement('input');
+ this.__input.setAttribute('type', 'text');
+
+ // Makes it so manually specified values are not truncated.
+
+ dom.bind(this.__input, 'change', onChange);
+ dom.bind(this.__input, 'blur', onBlur);
+ dom.bind(this.__input, 'mousedown', onMouseDown);
+ dom.bind(this.__input, 'keydown', function(e) {
+
+ // When pressing entire, you can be as precise as you want.
+ if (e.keyCode === 13) {
+ _this.__truncationSuspended = true;
+ this.blur();
+ _this.__truncationSuspended = false;
+ }
+
+ });
+
+ function onChange() {
+ var attempted = parseFloat(_this.__input.value);
+ if (!common.isNaN(attempted)) _this.setValue(attempted);
+ }
+
+ function onBlur() {
+ onChange();
+ if (_this.__onFinishChange) {
+ _this.__onFinishChange.call(_this, _this.getValue());
+ }
+ }
+
+ function onMouseDown(e) {
+ dom.bind(window, 'mousemove', onMouseDrag);
+ dom.bind(window, 'mouseup', onMouseUp);
+ prev_y = e.clientY;
+ }
+
+ function onMouseDrag(e) {
+
+ var diff = prev_y - e.clientY;
+ _this.setValue(_this.getValue() + diff * _this.__impliedStep);
+
+ prev_y = e.clientY;
+
+ }
+
+ function onMouseUp() {
+ dom.unbind(window, 'mousemove', onMouseDrag);
+ dom.unbind(window, 'mouseup', onMouseUp);
+ }
+
+ this.updateDisplay();
+
+ this.domElement.appendChild(this.__input);
+
+ };
+
+ NumberControllerBox.superclass = NumberController;
+
+ common.extend(
+
+ NumberControllerBox.prototype,
+ NumberController.prototype,
+
+ {
+
+ updateDisplay: function() {
+
+ this.__input.value = this.__truncationSuspended ? this.getValue() : roundToDecimal(this.getValue(), this.__precision);
+ return NumberControllerBox.superclass.prototype.updateDisplay.call(this);
+ }
+
+ }
+
+ );
+
+ function roundToDecimal(value, decimals) {
+ var tenTo = Math.pow(10, decimals);
+ return Math.round(value * tenTo) / tenTo;
+ }
+
+ return NumberControllerBox;
+
+})(dat.controllers.NumberController,
+dat.dom.dom,
+dat.utils.common);
+
+
+dat.controllers.NumberControllerSlider = (function (NumberController, dom, css, common, styleSheet) {
+
+ /**
+ * @class Represents a given property of an object that is a number, contains
+ * a minimum and maximum, and provides a slider element with which to
+ * manipulate it. It should be noted that the slider element is made up of
+ * <div> tags, not the html5
+ * <slider> element.
+ *
+ * @extends dat.controllers.Controller
+ * @extends dat.controllers.NumberController
+ *
+ * @param {Object} object The object to be manipulated
+ * @param {string} property The name of the property to be manipulated
+ * @param {Number} minValue Minimum allowed value
+ * @param {Number} maxValue Maximum allowed value
+ * @param {Number} stepValue Increment by which to change value
+ *
+ * @member dat.controllers
+ */
+ var NumberControllerSlider = function(object, property, min, max, step) {
+
+ NumberControllerSlider.superclass.call(this, object, property, { min: min, max: max, step: step });
+
+ var _this = this;
+
+ this.__background = document.createElement('div');
+ this.__foreground = document.createElement('div');
+
+
+
+ dom.bind(this.__background, 'mousedown', onMouseDown);
+
+ dom.addClass(this.__background, 'slider');
+ dom.addClass(this.__foreground, 'slider-fg');
+
+ function onMouseDown(e) {
+
+ dom.bind(window, 'mousemove', onMouseDrag);
+ dom.bind(window, 'mouseup', onMouseUp);
+
+ onMouseDrag(e);
+ }
+
+ function onMouseDrag(e) {
+
+ e.preventDefault();
+
+ var offset = dom.getOffset(_this.__background);
+ var width = dom.getWidth(_this.__background);
+
+ _this.setValue(
+ map(e.clientX, offset.left, offset.left + width, _this.__min, _this.__max)
+ );
+
+ return false;
+
+ }
+
+ function onMouseUp() {
+ dom.unbind(window, 'mousemove', onMouseDrag);
+ dom.unbind(window, 'mouseup', onMouseUp);
+ if (_this.__onFinishChange) {
+ _this.__onFinishChange.call(_this, _this.getValue());
+ }
+ }
+
+ this.updateDisplay();
+
+ this.__background.appendChild(this.__foreground);
+ this.domElement.appendChild(this.__background);
+
+ };
+
+ NumberControllerSlider.superclass = NumberController;
+
+ /**
+ * Injects default stylesheet for slider elements.
+ */
+ NumberControllerSlider.useDefaultStyles = function() {
+ css.inject(styleSheet);
+ };
+
+ common.extend(
+
+ NumberControllerSlider.prototype,
+ NumberController.prototype,
+
+ {
+
+ updateDisplay: function() {
+ var pct = (this.getValue() - this.__min)/(this.__max - this.__min);
+ this.__foreground.style.width = pct*100+'%';
+ return NumberControllerSlider.superclass.prototype.updateDisplay.call(this);
+ }
+
+ }
+
+
+
+ );
+
+ function map(v, i1, i2, o1, o2) {
+ return o1 + (o2 - o1) * ((v - i1) / (i2 - i1));
+ }
+
+ return NumberControllerSlider;
+
+})(dat.controllers.NumberController,
+dat.dom.dom,
+dat.utils.css,
+dat.utils.common,
+".slider {\n box-shadow: inset 0 2px 4px rgba(0,0,0,0.15);\n height: 1em;\n border-radius: 1em;\n background-color: #eee;\n padding: 0 0.5em;\n overflow: hidden;\n}\n\n.slider-fg {\n padding: 1px 0 2px 0;\n background-color: #aaa;\n height: 1em;\n margin-left: -0.5em;\n padding-right: 0.5em;\n border-radius: 1em 0 0 1em;\n}\n\n.slider-fg:after {\n display: inline-block;\n border-radius: 1em;\n background-color: #fff;\n border: 1px solid #aaa;\n content: '';\n float: right;\n margin-right: -1em;\n margin-top: -1px;\n height: 0.9em;\n width: 0.9em;\n}");
+
+
+dat.controllers.FunctionController = (function (Controller, dom, common) {
+
+ /**
+ * @class Provides a GUI interface to fire a specified method, a property of an object.
+ *
+ * @extends dat.controllers.Controller
+ *
+ * @param {Object} object The object to be manipulated
+ * @param {string} property The name of the property to be manipulated
+ *
+ * @member dat.controllers
+ */
+ var FunctionController = function(object, property, text) {
+
+ FunctionController.superclass.call(this, object, property);
+
+ var _this = this;
+
+ this.__button = document.createElement('div');
+ this.__button.innerHTML = text === undefined ? 'Fire' : text;
+ dom.bind(this.__button, 'click', function(e) {
+ e.preventDefault();
+ _this.fire();
+ return false;
+ });
+
+ dom.addClass(this.__button, 'button');
+
+ this.domElement.appendChild(this.__button);
+
+
+ };
+
+ FunctionController.superclass = Controller;
+
+ common.extend(
+
+ FunctionController.prototype,
+ Controller.prototype,
+ {
+
+ fire: function() {
+ if (this.__onChange) {
+ this.__onChange.call(this);
+ }
+ if (this.__onFinishChange) {
+ this.__onFinishChange.call(this, this.getValue());
+ }
+ this.getValue().call(this.object);
+ }
+ }
+
+ );
+
+ return FunctionController;
+
+})(dat.controllers.Controller,
+dat.dom.dom,
+dat.utils.common);
+
+
+dat.controllers.BooleanController = (function (Controller, dom, common) {
+
+ /**
+ * @class Provides a checkbox input to alter the boolean property of an object.
+ * @extends dat.controllers.Controller
+ *
+ * @param {Object} object The object to be manipulated
+ * @param {string} property The name of the property to be manipulated
+ *
+ * @member dat.controllers
+ */
+ var BooleanController = function(object, property) {
+
+ BooleanController.superclass.call(this, object, property);
+
+ var _this = this;
+ this.__prev = this.getValue();
+
+ this.__checkbox = document.createElement('input');
+ this.__checkbox.setAttribute('type', 'checkbox');
+
+
+ dom.bind(this.__checkbox, 'change', onChange, false);
+
+ this.domElement.appendChild(this.__checkbox);
+
+ // Match original value
+ this.updateDisplay();
+
+ function onChange() {
+ _this.setValue(!_this.__prev);
+ }
+
+ };
+
+ BooleanController.superclass = Controller;
+
+ common.extend(
+
+ BooleanController.prototype,
+ Controller.prototype,
+
+ {
+
+ setValue: function(v) {
+ var toReturn = BooleanController.superclass.prototype.setValue.call(this, v);
+ if (this.__onFinishChange) {
+ this.__onFinishChange.call(this, this.getValue());
+ }
+ this.__prev = this.getValue();
+ return toReturn;
+ },
+
+ updateDisplay: function() {
+
+ if (this.getValue() === true) {
+ this.__checkbox.setAttribute('checked', 'checked');
+ this.__checkbox.checked = true;
+ } else {
+ this.__checkbox.checked = false;
+ }
+
+ return BooleanController.superclass.prototype.updateDisplay.call(this);
+
+ }
+
+
+ }
+
+ );
+
+ return BooleanController;
+
+})(dat.controllers.Controller,
+dat.dom.dom,
+dat.utils.common);
+
+
+dat.color.toString = (function (common) {
+
+ return function(color) {
+
+ if (color.a == 1 || common.isUndefined(color.a)) {
+
+ var s = color.hex.toString(16);
+ while (s.length < 6) {
+ s = '0' + s;
+ }
+
+ return '#' + s;
+
+ } else {
+
+ return 'rgba(' + Math.round(color.r) + ',' + Math.round(color.g) + ',' + Math.round(color.b) + ',' + color.a + ')';
+
+ }
+
+ }
+
+})(dat.utils.common);
+
+
+dat.color.interpret = (function (toString, common) {
+
+ var result, toReturn;
+
+ var interpret = function() {
+
+ toReturn = false;
+
+ var original = arguments.length > 1 ? common.toArray(arguments) : arguments[0];
+
+ common.each(INTERPRETATIONS, function(family) {
+
+ if (family.litmus(original)) {
+
+ common.each(family.conversions, function(conversion, conversionName) {
+
+ result = conversion.read(original);
+
+ if (toReturn === false && result !== false) {
+ toReturn = result;
+ result.conversionName = conversionName;
+ result.conversion = conversion;
+ return common.BREAK;
+
+ }
+
+ });
+
+ return common.BREAK;
+
+ }
+
+ });
+
+ return toReturn;
+
+ };
+
+ var INTERPRETATIONS = [
+
+ // Strings
+ {
+
+ litmus: common.isString,
+
+ conversions: {
+
+ THREE_CHAR_HEX: {
+
+ read: function(original) {
+
+ var test = original.match(/^#([A-F0-9])([A-F0-9])([A-F0-9])$/i);
+ if (test === null) return false;
+
+ return {
+ space: 'HEX',
+ hex: parseInt(
+ '0x' +
+ test[1].toString() + test[1].toString() +
+ test[2].toString() + test[2].toString() +
+ test[3].toString() + test[3].toString())
+ };
+
+ },
+
+ write: toString
+
+ },
+
+ SIX_CHAR_HEX: {
+
+ read: function(original) {
+
+ var test = original.match(/^#([A-F0-9]{6})$/i);
+ if (test === null) return false;
+
+ return {
+ space: 'HEX',
+ hex: parseInt('0x' + test[1].toString())
+ };
+
+ },
+
+ write: toString
+
+ },
+
+ CSS_RGB: {
+
+ read: function(original) {
+
+ var test = original.match(/^rgb\(\s*(.+)\s*,\s*(.+)\s*,\s*(.+)\s*\)/);
+ if (test === null) return false;
+
+ return {
+ space: 'RGB',
+ r: parseFloat(test[1]),
+ g: parseFloat(test[2]),
+ b: parseFloat(test[3])
+ };
+
+ },
+
+ write: toString
+
+ },
+
+ CSS_RGBA: {
+
+ read: function(original) {
+
+ var test = original.match(/^rgba\(\s*(.+)\s*,\s*(.+)\s*,\s*(.+)\s*\,\s*(.+)\s*\)/);
+ if (test === null) return false;
+
+ return {
+ space: 'RGB',
+ r: parseFloat(test[1]),
+ g: parseFloat(test[2]),
+ b: parseFloat(test[3]),
+ a: parseFloat(test[4])
+ };
+
+ },
+
+ write: toString
+
+ }
+
+ }
+
+ },
+
+ // Numbers
+ {
+
+ litmus: common.isNumber,
+
+ conversions: {
+
+ HEX: {
+ read: function(original) {
+ return {
+ space: 'HEX',
+ hex: original,
+ conversionName: 'HEX'
+ }
+ },
+
+ write: function(color) {
+ return color.hex;
+ }
+ }
+
+ }
+
+ },
+
+ // Arrays
+ {
+
+ litmus: common.isArray,
+
+ conversions: {
+
+ RGB_ARRAY: {
+ read: function(original) {
+ if (original.length != 3) return false;
+ return {
+ space: 'RGB',
+ r: original[0],
+ g: original[1],
+ b: original[2]
+ };
+ },
+
+ write: function(color) {
+ return [color.r, color.g, color.b];
+ }
+
+ },
+
+ RGBA_ARRAY: {
+ read: function(original) {
+ if (original.length != 4) return false;
+ return {
+ space: 'RGB',
+ r: original[0],
+ g: original[1],
+ b: original[2],
+ a: original[3]
+ };
+ },
+
+ write: function(color) {
+ return [color.r, color.g, color.b, color.a];
+ }
+
+ }
+
+ }
+
+ },
+
+ // Objects
+ {
+
+ litmus: common.isObject,
+
+ conversions: {
+
+ RGBA_OBJ: {
+ read: function(original) {
+ if (common.isNumber(original.r) &&
+ common.isNumber(original.g) &&
+ common.isNumber(original.b) &&
+ common.isNumber(original.a)) {
+ return {
+ space: 'RGB',
+ r: original.r,
+ g: original.g,
+ b: original.b,
+ a: original.a
+ }
+ }
+ return false;
+ },
+
+ write: function(color) {
+ return {
+ r: color.r,
+ g: color.g,
+ b: color.b,
+ a: color.a
+ }
+ }
+ },
+
+ RGB_OBJ: {
+ read: function(original) {
+ if (common.isNumber(original.r) &&
+ common.isNumber(original.g) &&
+ common.isNumber(original.b)) {
+ return {
+ space: 'RGB',
+ r: original.r,
+ g: original.g,
+ b: original.b
+ }
+ }
+ return false;
+ },
+
+ write: function(color) {
+ return {
+ r: color.r,
+ g: color.g,
+ b: color.b
+ }
+ }
+ },
+
+ HSVA_OBJ: {
+ read: function(original) {
+ if (common.isNumber(original.h) &&
+ common.isNumber(original.s) &&
+ common.isNumber(original.v) &&
+ common.isNumber(original.a)) {
+ return {
+ space: 'HSV',
+ h: original.h,
+ s: original.s,
+ v: original.v,
+ a: original.a
+ }
+ }
+ return false;
+ },
+
+ write: function(color) {
+ return {
+ h: color.h,
+ s: color.s,
+ v: color.v,
+ a: color.a
+ }
+ }
+ },
+
+ HSV_OBJ: {
+ read: function(original) {
+ if (common.isNumber(original.h) &&
+ common.isNumber(original.s) &&
+ common.isNumber(original.v)) {
+ return {
+ space: 'HSV',
+ h: original.h,
+ s: original.s,
+ v: original.v
+ }
+ }
+ return false;
+ },
+
+ write: function(color) {
+ return {
+ h: color.h,
+ s: color.s,
+ v: color.v
+ }
+ }
+
+ }
+
+ }
+
+ }
+
+
+ ];
+
+ return interpret;
+
+
+})(dat.color.toString,
+dat.utils.common);
+
+
+dat.GUI = dat.gui.GUI = (function (css, saveDialogueContents, styleSheet, controllerFactory, Controller, BooleanController, FunctionController, NumberControllerBox, NumberControllerSlider, OptionController, ColorController, requestAnimationFrame, CenteredDiv, dom, common) {
+
+ css.inject(styleSheet);
+
+ /** Outer-most className for GUI's */
+ var CSS_NAMESPACE = 'dg';
+
+ var HIDE_KEY_CODE = 72;
+
+ /** The only value shared between the JS and SCSS. Use caution. */
+ var CLOSE_BUTTON_HEIGHT = 20;
+
+ var DEFAULT_DEFAULT_PRESET_NAME = 'Default';
+
+ var SUPPORTS_LOCAL_STORAGE = (function() {
+ try {
+ return 'localStorage' in window && window['localStorage'] !== null;
+ } catch (e) {
+ return false;
+ }
+ })();
+
+ var SAVE_DIALOGUE;
+
+ /** Have we yet to create an autoPlace GUI? */
+ var auto_place_virgin = true;
+
+ /** Fixed position div that auto place GUI's go inside */
+ var auto_place_container;
+
+ /** Are we hiding the GUI's ? */
+ var hide = false;
+
+ /** GUI's which should be hidden */
+ var hideable_guis = [];
+
+ /**
+ * A lightweight controller library for JavaScript. It allows you to easily
+ * manipulate variables and fire functions on the fly.
+ * @class
+ *
+ * @member dat.gui
+ *
+ * @param {Object} [params]
+ * @param {String} [params.name] The name of this GUI.
+ * @param {Object} [params.load] JSON object representing the saved state of
+ * this GUI.
+ * @param {Boolean} [params.auto=true]
+ * @param {dat.gui.GUI} [params.parent] The GUI I'm nested in.
+ * @param {Boolean} [params.closed] If true, starts closed
+ */
+ var GUI = function(params) {
+
+ var _this = this;
+
+ /**
+ * Outermost DOM Element
+ * @type DOMElement
+ */
+ this.domElement = document.createElement('div');
+ this.__ul = document.createElement('ul');
+ this.domElement.appendChild(this.__ul);
+
+ dom.addClass(this.domElement, CSS_NAMESPACE);
+
+ /**
+ * Nested GUI's by name
+ * @ignore
+ */
+ this.__folders = {};
+
+ this.__controllers = [];
+
+ /**
+ * List of objects I'm remembering for save, only used in top level GUI
+ * @ignore
+ */
+ this.__rememberedObjects = [];
+
+ /**
+ * Maps the index of remembered objects to a map of controllers, only used
+ * in top level GUI.
+ *
+ * @private
+ * @ignore
+ *
+ * @example
+ * [
+ * {
+ * propertyName: Controller,
+ * anotherPropertyName: Controller
+ * },
+ * {
+ * propertyName: Controller
+ * }
+ * ]
+ */
+ this.__rememberedObjectIndecesToControllers = [];
+
+ this.__listening = [];
+
+ params = params || {};
+
+ // Default parameters
+ params = common.defaults(params, {
+ autoPlace: true,
+ width: GUI.DEFAULT_WIDTH
+ });
+
+ params = common.defaults(params, {
+ resizable: params.autoPlace,
+ hideable: params.autoPlace
+ });
+
+
+ if (!common.isUndefined(params.load)) {
+
+ // Explicit preset
+ if (params.preset) params.load.preset = params.preset;
+
+ } else {
+
+ params.load = { preset: DEFAULT_DEFAULT_PRESET_NAME };
+
+ }
+
+ if (common.isUndefined(params.parent) && params.hideable) {
+ hideable_guis.push(this);
+ }
+
+ // Only root level GUI's are resizable.
+ params.resizable = common.isUndefined(params.parent) && params.resizable;
+
+
+ if (params.autoPlace && common.isUndefined(params.scrollable)) {
+ params.scrollable = true;
+ }
+// params.scrollable = common.isUndefined(params.parent) && params.scrollable === true;
+
+ // Not part of params because I don't want people passing this in via
+ // constructor. Should be a 'remembered' value.
+ var use_local_storage =
+ SUPPORTS_LOCAL_STORAGE &&
+ localStorage.getItem(getLocalStorageHash(this, 'isLocal')) === 'true';
+
+ Object.defineProperties(this,
+
+ /** @lends dat.gui.GUI.prototype */
+ {
+
+ /**
+ * The parent GUI
+ * @type dat.gui.GUI
+ */
+ parent: {
+ get: function() {
+ return params.parent;
+ }
+ },
+
+ scrollable: {
+ get: function() {
+ return params.scrollable;
+ }
+ },
+
+ /**
+ * Handles GUI's element placement for you
+ * @type Boolean
+ */
+ autoPlace: {
+ get: function() {
+ return params.autoPlace;
+ }
+ },
+
+ /**
+ * The identifier for a set of saved values
+ * @type String
+ */
+ preset: {
+
+ get: function() {
+ if (_this.parent) {
+ return _this.getRoot().preset;
+ } else {
+ return params.load.preset;
+ }
+ },
+
+ set: function(v) {
+ if (_this.parent) {
+ _this.getRoot().preset = v;
+ } else {
+ params.load.preset = v;
+ }
+ setPresetSelectIndex(this);
+ _this.revert();
+ }
+
+ },
+
+ /**
+ * The width of GUI element
+ * @type Number
+ */
+ width: {
+ get: function() {
+ return params.width;
+ },
+ set: function(v) {
+ params.width = v;
+ setWidth(_this, v);
+ }
+ },
+
+ /**
+ * The name of GUI. Used for folders. i.e
+ * a folder's name
+ * @type String
+ */
+ name: {
+ get: function() {
+ return params.name;
+ },
+ set: function(v) {
+ // TODO Check for collisions among sibling folders
+ params.name = v;
+ if (title_row_name) {
+ title_row_name.innerHTML = params.name;
+ }
+ }
+ },
+
+ /**
+ * Whether the GUI is collapsed or not
+ * @type Boolean
+ */
+ closed: {
+ get: function() {
+ return params.closed;
+ },
+ set: function(v) {
+ params.closed = v;
+ if (params.closed) {
+ dom.addClass(_this.__ul, GUI.CLASS_CLOSED);
+ } else {
+ dom.removeClass(_this.__ul, GUI.CLASS_CLOSED);
+ }
+ // For browsers that aren't going to respect the CSS transition,
+ // Lets just check our height against the window height right off
+ // the bat.
+ this.onResize();
+
+ if (_this.__closeButton) {
+ _this.__closeButton.innerHTML = v ? GUI.TEXT_OPEN : GUI.TEXT_CLOSED;
+ }
+ }
+ },
+
+ /**
+ * Contains all presets
+ * @type Object
+ */
+ load: {
+ get: function() {
+ return params.load;
+ }
+ },
+
+ /**
+ * Determines whether or not to use localStorage as the means for
+ * remembering
+ * @type Boolean
+ */
+ useLocalStorage: {
+
+ get: function() {
+ return use_local_storage;
+ },
+ set: function(bool) {
+ if (SUPPORTS_LOCAL_STORAGE) {
+ use_local_storage = bool;
+ if (bool) {
+ dom.bind(window, 'unload', saveToLocalStorage);
+ } else {
+ dom.unbind(window, 'unload', saveToLocalStorage);
+ }
+ localStorage.setItem(getLocalStorageHash(_this, 'isLocal'), bool);
+ }
+ }
+
+ }
+
+ });
+
+ // Are we a root level GUI?
+ if (common.isUndefined(params.parent)) {
+
+ params.closed = false;
+
+ dom.addClass(this.domElement, GUI.CLASS_MAIN);
+ dom.makeSelectable(this.domElement, false);
+
+ // Are we supposed to be loading locally?
+ if (SUPPORTS_LOCAL_STORAGE) {
+
+ if (use_local_storage) {
+
+ _this.useLocalStorage = true;
+
+ var saved_gui = localStorage.getItem(getLocalStorageHash(this, 'gui'));
+
+ if (saved_gui) {
+ params.load = JSON.parse(saved_gui);
+ }
+
+ }
+
+ }
+
+ this.__closeButton = document.createElement('div');
+ this.__closeButton.innerHTML = GUI.TEXT_CLOSED;
+ dom.addClass(this.__closeButton, GUI.CLASS_CLOSE_BUTTON);
+ this.domElement.appendChild(this.__closeButton);
+
+ dom.bind(this.__closeButton, 'click', function() {
+
+ _this.closed = !_this.closed;
+
+
+ });
+
+
+ // Oh, you're a nested GUI!
+ } else {
+
+ if (params.closed === undefined) {
+ params.closed = true;
+ }
+
+ var title_row_name = document.createTextNode(params.name);
+ dom.addClass(title_row_name, 'controller-name');
+
+ var title_row = addRow(_this, title_row_name);
+
+ var on_click_title = function(e) {
+ e.preventDefault();
+ _this.closed = !_this.closed;
+ return false;
+ };
+
+ dom.addClass(this.__ul, GUI.CLASS_CLOSED);
+
+ dom.addClass(title_row, 'title');
+ dom.bind(title_row, 'click', on_click_title);
+
+ if (!params.closed) {
+ this.closed = false;
+ }
+
+ }
+
+ if (params.autoPlace) {
+
+ if (common.isUndefined(params.parent)) {
+
+ if (auto_place_virgin) {
+ auto_place_container = document.createElement('div');
+ dom.addClass(auto_place_container, CSS_NAMESPACE);
+ dom.addClass(auto_place_container, GUI.CLASS_AUTO_PLACE_CONTAINER);
+ document.body.appendChild(auto_place_container);
+ auto_place_virgin = false;
+ }
+
+ // Put it in the dom for you.
+ auto_place_container.appendChild(this.domElement);
+
+ // Apply the auto styles
+ dom.addClass(this.domElement, GUI.CLASS_AUTO_PLACE);
+
+ }
+
+
+ // Make it not elastic.
+ if (!this.parent) setWidth(_this, params.width);
+
+ }
+
+ dom.bind(window, 'resize', function() { _this.onResize() });
+ dom.bind(this.__ul, 'webkitTransitionEnd', function() { _this.onResize(); });
+ dom.bind(this.__ul, 'transitionend', function() { _this.onResize() });
+ dom.bind(this.__ul, 'oTransitionEnd', function() { _this.onResize() });
+ this.onResize();
+
+
+ if (params.resizable) {
+ addResizeHandle(this);
+ }
+
+ function saveToLocalStorage() {
+ localStorage.setItem(getLocalStorageHash(_this, 'gui'), JSON.stringify(_this.getSaveObject()));
+ }
+
+ var root = _this.getRoot();
+ function resetWidth() {
+ var root = _this.getRoot();
+ root.width += 1;
+ common.defer(function() {
+ root.width -= 1;
+ });
+ }
+
+ if (!params.parent) {
+ resetWidth();
+ }
+
+ };
+
+ GUI.toggleHide = function() {
+
+ hide = !hide;
+ common.each(hideable_guis, function(gui) {
+ gui.domElement.style.zIndex = hide ? -999 : 999;
+ gui.domElement.style.opacity = hide ? 0 : 1;
+ });
+ };
+
+ GUI.CLASS_AUTO_PLACE = 'a';
+ GUI.CLASS_AUTO_PLACE_CONTAINER = 'ac';
+ GUI.CLASS_MAIN = 'main';
+ GUI.CLASS_CONTROLLER_ROW = 'cr';
+ GUI.CLASS_TOO_TALL = 'taller-than-window';
+ GUI.CLASS_CLOSED = 'closed';
+ GUI.CLASS_CLOSE_BUTTON = 'close-button';
+ GUI.CLASS_DRAG = 'drag';
+
+ GUI.DEFAULT_WIDTH = 245;
+ GUI.TEXT_CLOSED = 'Close Controls';
+ GUI.TEXT_OPEN = 'Open Controls';
+
+ dom.bind(window, 'keydown', function(e) {
+
+ if (document.activeElement.type !== 'text' &&
+ (e.which === HIDE_KEY_CODE || e.keyCode == HIDE_KEY_CODE)) {
+ GUI.toggleHide();
+ }
+
+ }, false);
+
+ common.extend(
+
+ GUI.prototype,
+
+ /** @lends dat.gui.GUI */
+ {
+
+ /**
+ * @param object
+ * @param property
+ * @returns {dat.controllers.Controller} The new controller that was added.
+ * @instance
+ */
+ add: function(object, property) {
+
+ return add(
+ this,
+ object,
+ property,
+ {
+ factoryArgs: Array.prototype.slice.call(arguments, 2)
+ }
+ );
+
+ },
+
+ /**
+ * @param object
+ * @param property
+ * @returns {dat.controllers.ColorController} The new controller that was added.
+ * @instance
+ */
+ addColor: function(object, property) {
+
+ return add(
+ this,
+ object,
+ property,
+ {
+ color: true
+ }
+ );
+
+ },
+
+ /**
+ * @param controller
+ * @instance
+ */
+ remove: function(controller) {
+
+ // TODO listening?
+ this.__ul.removeChild(controller.__li);
+ this.__controllers.slice(this.__controllers.indexOf(controller), 1);
+ var _this = this;
+ common.defer(function() {
+ _this.onResize();
+ });
+
+ },
+
+ destroy: function() {
+
+ if (this.autoPlace) {
+ auto_place_container.removeChild(this.domElement);
+ }
+
+ },
+
+ /**
+ * @param name
+ * @returns {dat.gui.GUI} The new folder.
+ * @throws {Error} if this GUI already has a folder by the specified
+ * name
+ * @instance
+ */
+ addFolder: function(name) {
+
+ // We have to prevent collisions on names in order to have a key
+ // by which to remember saved values
+ if (this.__folders[name] !== undefined) {
+ throw new Error('You already have a folder in this GUI by the' +
+ ' name "' + name + '"');
+ }
+
+ var new_gui_params = { name: name, parent: this };
+
+ // We need to pass down the autoPlace trait so that we can
+ // attach event listeners to open/close folder actions to
+ // ensure that a scrollbar appears if the window is too short.
+ new_gui_params.autoPlace = this.autoPlace;
+
+ // Do we have saved appearance data for this folder?
+
+ if (this.load && // Anything loaded?
+ this.load.folders && // Was my parent a dead-end?
+ this.load.folders[name]) { // Did daddy remember me?
+
+ // Start me closed if I was closed
+ new_gui_params.closed = this.load.folders[name].closed;
+
+ // Pass down the loaded data
+ new_gui_params.load = this.load.folders[name];
+
+ }
+
+ var gui = new GUI(new_gui_params);
+ this.__folders[name] = gui;
+
+ var li = addRow(this, gui.domElement);
+ dom.addClass(li, 'folder');
+ return gui;
+
+ },
+
+ open: function() {
+ this.closed = false;
+ },
+
+ close: function() {
+ this.closed = true;
+ },
+
+ onResize: function() {
+
+ var root = this.getRoot();
+
+ if (root.scrollable) {
+
+ var top = dom.getOffset(root.__ul).top;
+ var h = 0;
+
+ common.each(root.__ul.childNodes, function(node) {
+ if (! (root.autoPlace && node === root.__save_row))
+ h += dom.getHeight(node);
+ });
+
+ if (window.innerHeight - top - CLOSE_BUTTON_HEIGHT < h) {
+ dom.addClass(root.domElement, GUI.CLASS_TOO_TALL);
+ root.__ul.style.height = window.innerHeight - top - CLOSE_BUTTON_HEIGHT + 'px';
+ } else {
+ dom.removeClass(root.domElement, GUI.CLASS_TOO_TALL);
+ root.__ul.style.height = 'auto';
+ }
+
+ }
+
+ if (root.__resize_handle) {
+ common.defer(function() {
+ root.__resize_handle.style.height = root.__ul.offsetHeight + 'px';
+ });
+ }
+
+ if (root.__closeButton) {
+ root.__closeButton.style.width = root.width + 'px';
+ }
+
+ },
+
+ /**
+ * Mark objects for saving. The order of these objects cannot change as
+ * the GUI grows. When remembering new objects, append them to the end
+ * of the list.
+ *
+ * @param {Object...} objects
+ * @throws {Error} if not called on a top level GUI.
+ * @instance
+ */
+ remember: function() {
+
+ if (common.isUndefined(SAVE_DIALOGUE)) {
+ SAVE_DIALOGUE = new CenteredDiv();
+ SAVE_DIALOGUE.domElement.innerHTML = saveDialogueContents;
+ }
+
+ if (this.parent) {
+ throw new Error("You can only call remember on a top level GUI.");
+ }
+
+ var _this = this;
+
+ common.each(Array.prototype.slice.call(arguments), function(object) {
+ if (_this.__rememberedObjects.length == 0) {
+ addSaveMenu(_this);
+ }
+ if (_this.__rememberedObjects.indexOf(object) == -1) {
+ _this.__rememberedObjects.push(object);
+ }
+ });
+
+ if (this.autoPlace) {
+ // Set save row width
+ setWidth(this, this.width);
+ }
+
+ },
+
+ /**
+ * @returns {dat.gui.GUI} the topmost parent GUI of a nested GUI.
+ * @instance
+ */
+ getRoot: function() {
+ var gui = this;
+ while (gui.parent) {
+ gui = gui.parent;
+ }
+ return gui;
+ },
+
+ /**
+ * @returns {Object} a JSON object representing the current state of
+ * this GUI as well as its remembered properties.
+ * @instance
+ */
+ getSaveObject: function() {
+
+ var toReturn = this.load;
+
+ toReturn.closed = this.closed;
+
+ // Am I remembering any values?
+ if (this.__rememberedObjects.length > 0) {
+
+ toReturn.preset = this.preset;
+
+ if (!toReturn.remembered) {
+ toReturn.remembered = {};
+ }
+
+ toReturn.remembered[this.preset] = getCurrentPreset(this);
+
+ }
+
+ toReturn.folders = {};
+ common.each(this.__folders, function(element, key) {
+ toReturn.folders[key] = element.getSaveObject();
+ });
+
+ return toReturn;
+
+ },
+
+ save: function() {
+
+ if (!this.load.remembered) {
+ this.load.remembered = {};
+ }
+
+ this.load.remembered[this.preset] = getCurrentPreset(this);
+ markPresetModified(this, false);
+
+ },
+
+ saveAs: function(presetName) {
+
+ if (!this.load.remembered) {
+
+ // Retain default values upon first save
+ this.load.remembered = {};
+ this.load.remembered[DEFAULT_DEFAULT_PRESET_NAME] = getCurrentPreset(this, true);
+
+ }
+
+ this.load.remembered[presetName] = getCurrentPreset(this);
+ this.preset = presetName;
+ addPresetOption(this, presetName, true);
+
+ },
+
+ revert: function(gui) {
+
+ common.each(this.__controllers, function(controller) {
+ // Make revert work on Default.
+ if (!this.getRoot().load.remembered) {
+ controller.setValue(controller.initialValue);
+ } else {
+ recallSavedValue(gui || this.getRoot(), controller);
+ }
+ }, this);
+
+ common.each(this.__folders, function(folder) {
+ folder.revert(folder);
+ });
+
+ if (!gui) {
+ markPresetModified(this.getRoot(), false);
+ }
+
+
+ },
+
+ listen: function(controller) {
+
+ var init = this.__listening.length == 0;
+ this.__listening.push(controller);
+ if (init) updateDisplays(this.__listening);
+
+ }
+
+ }
+
+ );
+
+ function add(gui, object, property, params) {
+
+ if (object[property] === undefined) {
+ throw new Error("Object " + object + " has no property \"" + property + "\"");
+ }
+
+ var controller;
+
+ if (params.color) {
+
+ controller = new ColorController(object, property);
+
+ } else {
+
+ var factoryArgs = [object,property].concat(params.factoryArgs);
+ controller = controllerFactory.apply(gui, factoryArgs);
+
+ }
+
+ if (params.before instanceof Controller) {
+ params.before = params.before.__li;
+ }
+
+ recallSavedValue(gui, controller);
+
+ dom.addClass(controller.domElement, 'c');
+
+ var name = document.createElement('span');
+ dom.addClass(name, 'property-name');
+ name.innerHTML = controller.property;
+
+ var container = document.createElement('div');
+ container.appendChild(name);
+ container.appendChild(controller.domElement);
+
+ var li = addRow(gui, container, params.before);
+
+ dom.addClass(li, GUI.CLASS_CONTROLLER_ROW);
+ dom.addClass(li, typeof controller.getValue());
+
+ augmentController(gui, li, controller);
+
+ gui.__controllers.push(controller);
+
+ return controller;
+
+ }
+
+ /**
+ * Add a row to the end of the GUI or before another row.
+ *
+ * @param gui
+ * @param [dom] If specified, inserts the dom content in the new row
+ * @param [liBefore] If specified, places the new row before another row
+ */
+ function addRow(gui, dom, liBefore) {
+ var li = document.createElement('li');
+ if (dom) li.appendChild(dom);
+ if (liBefore) {
+ gui.__ul.insertBefore(li, params.before);
+ } else {
+ gui.__ul.appendChild(li);
+ }
+ gui.onResize();
+ return li;
+ }
+
+ function augmentController(gui, li, controller) {
+
+ controller.__li = li;
+ controller.__gui = gui;
+
+ common.extend(controller, {
+
+ options: function(options) {
+
+ if (arguments.length > 1) {
+ controller.remove();
+
+ return add(
+ gui,
+ controller.object,
+ controller.property,
+ {
+ before: controller.__li.nextElementSibling,
+ factoryArgs: [common.toArray(arguments)]
+ }
+ );
+
+ }
+
+ if (common.isArray(options) || common.isObject(options)) {
+ controller.remove();
+
+ return add(
+ gui,
+ controller.object,
+ controller.property,
+ {
+ before: controller.__li.nextElementSibling,
+ factoryArgs: [options]
+ }
+ );
+
+ }
+
+ },
+
+ name: function(v) {
+ controller.__li.firstElementChild.firstElementChild.innerHTML = v;
+ return controller;
+ },
+
+ listen: function() {
+ controller.__gui.listen(controller);
+ return controller;
+ },
+
+ remove: function() {
+ controller.__gui.remove(controller);
+ return controller;
+ }
+
+ });
+
+ // All sliders should be accompanied by a box.
+ if (controller instanceof NumberControllerSlider) {
+
+ var box = new NumberControllerBox(controller.object, controller.property,
+ { min: controller.__min, max: controller.__max, step: controller.__step });
+
+ common.each(['updateDisplay', 'onChange', 'onFinishChange'], function(method) {
+ var pc = controller[method];
+ var pb = box[method];
+ controller[method] = box[method] = function() {
+ var args = Array.prototype.slice.call(arguments);
+ pc.apply(controller, args);
+ return pb.apply(box, args);
+ }
+ });
+
+ dom.addClass(li, 'has-slider');
+ controller.domElement.insertBefore(box.domElement, controller.domElement.firstElementChild);
+
+ }
+ else if (controller instanceof NumberControllerBox) {
+
+ var r = function(returned) {
+
+ // Have we defined both boundaries?
+ if (common.isNumber(controller.__min) && common.isNumber(controller.__max)) {
+
+ // Well, then lets just replace this with a slider.
+ controller.remove();
+ return add(
+ gui,
+ controller.object,
+ controller.property,
+ {
+ before: controller.__li.nextElementSibling,
+ factoryArgs: [controller.__min, controller.__max, controller.__step]
+ });
+
+ }
+
+ return returned;
+
+ };
+
+ controller.min = common.compose(r, controller.min);
+ controller.max = common.compose(r, controller.max);
+
+ }
+ else if (controller instanceof BooleanController) {
+
+ dom.bind(li, 'click', function() {
+ dom.fakeEvent(controller.__checkbox, 'click');
+ });
+
+ dom.bind(controller.__checkbox, 'click', function(e) {
+ e.stopPropagation(); // Prevents double-toggle
+ })
+
+ }
+ else if (controller instanceof FunctionController) {
+
+ dom.bind(li, 'click', function() {
+ dom.fakeEvent(controller.__button, 'click');
+ });
+
+ dom.bind(li, 'mouseover', function() {
+ dom.addClass(controller.__button, 'hover');
+ });
+
+ dom.bind(li, 'mouseout', function() {
+ dom.removeClass(controller.__button, 'hover');
+ });
+
+ }
+ else if (controller instanceof ColorController) {
+
+ dom.addClass(li, 'color');
+ controller.updateDisplay = common.compose(function(r) {
+ li.style.borderLeftColor = controller.__color.toString();
+ return r;
+ }, controller.updateDisplay);
+
+ controller.updateDisplay();
+
+ }
+
+ controller.setValue = common.compose(function(r) {
+ if (gui.getRoot().__preset_select && controller.isModified()) {
+ markPresetModified(gui.getRoot(), true);
+ }
+ return r;
+ }, controller.setValue);
+
+ }
+
+ function recallSavedValue(gui, controller) {
+
+ // Find the topmost GUI, that's where remembered objects live.
+ var root = gui.getRoot();
+
+ // Does the object we're controlling match anything we've been told to
+ // remember?
+ var matched_index = root.__rememberedObjects.indexOf(controller.object);
+
+ // Why yes, it does!
+ if (matched_index != -1) {
+
+ // Let me fetch a map of controllers for thcommon.isObject.
+ var controller_map =
+ root.__rememberedObjectIndecesToControllers[matched_index];
+
+ // Ohp, I believe this is the first controller we've created for this
+ // object. Lets make the map fresh.
+ if (controller_map === undefined) {
+ controller_map = {};
+ root.__rememberedObjectIndecesToControllers[matched_index] =
+ controller_map;
+ }
+
+ // Keep track of this controller
+ controller_map[controller.property] = controller;
+
+ // Okay, now have we saved any values for this controller?
+ if (root.load && root.load.remembered) {
+
+ var preset_map = root.load.remembered;
+
+ // Which preset are we trying to load?
+ var preset;
+
+ if (preset_map[gui.preset]) {
+
+ preset = preset_map[gui.preset];
+
+ } else if (preset_map[DEFAULT_DEFAULT_PRESET_NAME]) {
+
+ // Uhh, you can have the default instead?
+ preset = preset_map[DEFAULT_DEFAULT_PRESET_NAME];
+
+ } else {
+
+ // Nada.
+
+ return;
+
+ }
+
+
+ // Did the loaded object remember thcommon.isObject?
+ if (preset[matched_index] &&
+
+ // Did we remember this particular property?
+ preset[matched_index][controller.property] !== undefined) {
+
+ // We did remember something for this guy ...
+ var value = preset[matched_index][controller.property];
+
+ // And that's what it is.
+ controller.initialValue = value;
+ controller.setValue(value);
+
+ }
+
+ }
+
+ }
+
+ }
+
+ function getLocalStorageHash(gui, key) {
+ // TODO how does this deal with multiple GUI's?
+ return document.location.href + '.' + key;
+
+ }
+
+ function addSaveMenu(gui) {
+
+ var div = gui.__save_row = document.createElement('li');
+
+ dom.addClass(gui.domElement, 'has-save');
+
+ gui.__ul.insertBefore(div, gui.__ul.firstChild);
+
+ dom.addClass(div, 'save-row');
+
+ var gears = document.createElement('span');
+ gears.innerHTML = ' ';
+ dom.addClass(gears, 'button gears');
+
+ // TODO replace with FunctionController
+ var button = document.createElement('span');
+ button.innerHTML = 'Save';
+ dom.addClass(button, 'button');
+ dom.addClass(button, 'save');
+
+ var button2 = document.createElement('span');
+ button2.innerHTML = 'New';
+ dom.addClass(button2, 'button');
+ dom.addClass(button2, 'save-as');
+
+ var button3 = document.createElement('span');
+ button3.innerHTML = 'Revert';
+ dom.addClass(button3, 'button');
+ dom.addClass(button3, 'revert');
+
+ var select = gui.__preset_select = document.createElement('select');
+
+ if (gui.load && gui.load.remembered) {
+
+ common.each(gui.load.remembered, function(value, key) {
+ addPresetOption(gui, key, key == gui.preset);
+ });
+
+ } else {
+ addPresetOption(gui, DEFAULT_DEFAULT_PRESET_NAME, false);
+ }
+
+ dom.bind(select, 'change', function() {
+
+
+ for (var index = 0; index < gui.__preset_select.length; index++) {
+ gui.__preset_select[index].innerHTML = gui.__preset_select[index].value;
+ }
+
+ gui.preset = this.value;
+
+ });
+
+ div.appendChild(select);
+ div.appendChild(gears);
+ div.appendChild(button);
+ div.appendChild(button2);
+ div.appendChild(button3);
+
+ if (SUPPORTS_LOCAL_STORAGE) {
+
+ var saveLocally = document.getElementById('dg-save-locally');
+ var explain = document.getElementById('dg-local-explain');
+
+ saveLocally.style.display = 'block';
+
+ var localStorageCheckBox = document.getElementById('dg-local-storage');
+
+ if (localStorage.getItem(getLocalStorageHash(gui, 'isLocal')) === 'true') {
+ localStorageCheckBox.setAttribute('checked', 'checked');
+ }
+
+ function showHideExplain() {
+ explain.style.display = gui.useLocalStorage ? 'block' : 'none';
+ }
+
+ showHideExplain();
+
+ // TODO: Use a boolean controller, fool!
+ dom.bind(localStorageCheckBox, 'change', function() {
+ gui.useLocalStorage = !gui.useLocalStorage;
+ showHideExplain();
+ });
+
+ }
+
+ var newConstructorTextArea = document.getElementById('dg-new-constructor');
+
+ dom.bind(newConstructorTextArea, 'keydown', function(e) {
+ if (e.metaKey && (e.which === 67 || e.keyCode == 67)) {
+ SAVE_DIALOGUE.hide();
+ }
+ });
+
+ dom.bind(gears, 'click', function() {
+ newConstructorTextArea.innerHTML = JSON.stringify(gui.getSaveObject(), undefined, 2);
+ SAVE_DIALOGUE.show();
+ newConstructorTextArea.focus();
+ newConstructorTextArea.select();
+ });
+
+ dom.bind(button, 'click', function() {
+ gui.save();
+ });
+
+ dom.bind(button2, 'click', function() {
+ var presetName = prompt('Enter a new preset name.');
+ if (presetName) gui.saveAs(presetName);
+ });
+
+ dom.bind(button3, 'click', function() {
+ gui.revert();
+ });
+
+// div.appendChild(button2);
+
+ }
+
+ function addResizeHandle(gui) {
+
+ gui.__resize_handle = document.createElement('div');
+
+ common.extend(gui.__resize_handle.style, {
+
+ width: '6px',
+ marginLeft: '-3px',
+ height: '200px',
+ cursor: 'ew-resize',
+ position: 'absolute'
+// border: '1px solid blue'
+
+ });
+
+ var pmouseX;
+
+ dom.bind(gui.__resize_handle, 'mousedown', dragStart);
+ dom.bind(gui.__closeButton, 'mousedown', dragStart);
+
+ gui.domElement.insertBefore(gui.__resize_handle, gui.domElement.firstElementChild);
+
+ function dragStart(e) {
+
+ e.preventDefault();
+
+ pmouseX = e.clientX;
+
+ dom.addClass(gui.__closeButton, GUI.CLASS_DRAG);
+ dom.bind(window, 'mousemove', drag);
+ dom.bind(window, 'mouseup', dragStop);
+
+ return false;
+
+ }
+
+ function drag(e) {
+
+ e.preventDefault();
+
+ gui.width += pmouseX - e.clientX;
+ gui.onResize();
+ pmouseX = e.clientX;
+
+ return false;
+
+ }
+
+ function dragStop() {
+
+ dom.removeClass(gui.__closeButton, GUI.CLASS_DRAG);
+ dom.unbind(window, 'mousemove', drag);
+ dom.unbind(window, 'mouseup', dragStop);
+
+ }
+
+ }
+
+ function setWidth(gui, w) {
+ gui.domElement.style.width = w + 'px';
+ // Auto placed save-rows are position fixed, so we have to
+ // set the width manually if we want it to bleed to the edge
+ if (gui.__save_row && gui.autoPlace) {
+ gui.__save_row.style.width = w + 'px';
+ }if (gui.__closeButton) {
+ gui.__closeButton.style.width = w + 'px';
+ }
+ }
+
+ function getCurrentPreset(gui, useInitialValues) {
+
+ var toReturn = {};
+
+ // For each object I'm remembering
+ common.each(gui.__rememberedObjects, function(val, index) {
+
+ var saved_values = {};
+
+ // The controllers I've made for thcommon.isObject by property
+ var controller_map =
+ gui.__rememberedObjectIndecesToControllers[index];
+
+ // Remember each value for each property
+ common.each(controller_map, function(controller, property) {
+ saved_values[property] = useInitialValues ? controller.initialValue : controller.getValue();
+ });
+
+ // Save the values for thcommon.isObject
+ toReturn[index] = saved_values;
+
+ });
+
+ return toReturn;
+
+ }
+
+ function addPresetOption(gui, name, setSelected) {
+ var opt = document.createElement('option');
+ opt.innerHTML = name;
+ opt.value = name;
+ gui.__preset_select.appendChild(opt);
+ if (setSelected) {
+ gui.__preset_select.selectedIndex = gui.__preset_select.length - 1;
+ }
+ }
+
+ function setPresetSelectIndex(gui) {
+ for (var index = 0; index < gui.__preset_select.length; index++) {
+ if (gui.__preset_select[index].value == gui.preset) {
+ gui.__preset_select.selectedIndex = index;
+ }
+ }
+ }
+
+ function markPresetModified(gui, modified) {
+ var opt = gui.__preset_select[gui.__preset_select.selectedIndex];
+// console.log('mark', modified, opt);
+ if (modified) {
+ opt.innerHTML = opt.value + "*";
+ } else {
+ opt.innerHTML = opt.value;
+ }
+ }
+
+ function updateDisplays(controllerArray) {
+
+
+ if (controllerArray.length != 0) {
+
+ requestAnimationFrame(function() {
+ updateDisplays(controllerArray);
+ });
+
+ }
+
+ common.each(controllerArray, function(c) {
+ c.updateDisplay();
+ });
+
+ }
+
+ return GUI;
+
+})(dat.utils.css,
+"GUI's constructor:\n\n \n\n localStorage on exit.\n\n localStorage will\n override those passed to dat.GUI's constructor. This makes it\n easier to work incrementally, but localStorage is fragile,\n and your friends may not see the same values you do.\n \n +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. ++ + diff --git a/node_modules/domain-browser/README.md b/node_modules/domain-browser/README.md new file mode 100644 index 00000000..43502eff --- /dev/null +++ b/node_modules/domain-browser/README.md @@ -0,0 +1,111 @@ + + +
npm install --save domain-browserrequire('domain-browser')npm install --save domain-browserrequire('domain-browser')//wzrd.in/bundle/domain-browser@1.1.7ender add domain-browserrequire('domain-browser')HISTORY.md file.
+
+
+
+
+
+
+CONTRIBUTING.md file.
+
+
+
+
+
+
+Location ' + escapeHtml(url) + ' not found
' + + // send a 404 + res.statusCode = 404 + res.setHeader('Content-Type', 'text/html; charset=UTF-8') + res.setHeader('Content-Length', String(Buffer.byteLength(body, 'utf-8'))) + res.end(body, 'utf-8') +}) +``` + +### Encode a URL for use in a header field + +```js +var encodeUrl = require('encodeurl') +var escapeHtml = require('escape-html') +var url = require('url') + +http.createServer(function onRequest (req, res) { + // parse inbound url + var href = url.parse(req) + + // set new host for redirect + href.host = 'localhost' + href.protocol = 'https:' + href.slashes = true + + // create location header + var location = encodeUrl(url.format(href)) + + // create html message + var body = 'Redirecting to new site: ' + escapeHtml(location) + '
' + + // send a 301 + res.statusCode = 301 + res.setHeader('Content-Type', 'text/html; charset=UTF-8') + res.setHeader('Content-Length', String(Buffer.byteLength(body, 'utf-8'))) + res.setHeader('Location', location) + res.end(body, 'utf-8') +}) +``` + +## Testing + +```sh +$ npm test +$ npm run lint +``` + +## References + +- [RFC 3986: Uniform Resource Identifier (URI): Generic Syntax][rfc-3986] +- [WHATWG URL Living Standard][whatwg-url] + +[rfc-3986]: https://tools.ietf.org/html/rfc3986 +[whatwg-url]: https://url.spec.whatwg.org/ + +## License + +[MIT](LICENSE) + +[npm-image]: https://img.shields.io/npm/v/encodeurl.svg +[npm-url]: https://npmjs.org/package/encodeurl +[node-version-image]: https://img.shields.io/node/v/encodeurl.svg +[node-version-url]: https://nodejs.org/en/download +[travis-image]: https://img.shields.io/travis/pillarjs/encodeurl.svg +[travis-url]: https://travis-ci.org/pillarjs/encodeurl +[coveralls-image]: https://img.shields.io/coveralls/pillarjs/encodeurl.svg +[coveralls-url]: https://coveralls.io/r/pillarjs/encodeurl?branch=master +[downloads-image]: https://img.shields.io/npm/dm/encodeurl.svg +[downloads-url]: https://npmjs.org/package/encodeurl diff --git a/node_modules/encodeurl/index.js b/node_modules/encodeurl/index.js new file mode 100644 index 00000000..ae77cc94 --- /dev/null +++ b/node_modules/encodeurl/index.js @@ -0,0 +1,60 @@ +/*! + * encodeurl + * Copyright(c) 2016 Douglas Christopher Wilson + * MIT Licensed + */ + +'use strict' + +/** + * Module exports. + * @public + */ + +module.exports = encodeUrl + +/** + * RegExp to match non-URL code points, *after* encoding (i.e. not including "%") + * and including invalid escape sequences. + * @private + */ + +var ENCODE_CHARS_REGEXP = /(?:[^\x21\x25\x26-\x3B\x3D\x3F-\x5B\x5D\x5F\x61-\x7A\x7E]|%(?:[^0-9A-Fa-f]|[0-9A-Fa-f][^0-9A-Fa-f]))+/g + +/** + * RegExp to match unmatched surrogate pair. + * @private + */ + +var UNMATCHED_SURROGATE_PAIR_REGEXP = /(^|[^\uD800-\uDBFF])[\uDC00-\uDFFF]|[\uD800-\uDBFF]([^\uDC00-\uDFFF]|$)/g + +/** + * String to replace unmatched surrogate pair with. + * @private + */ + +var UNMATCHED_SURROGATE_PAIR_REPLACE = '$1\uFFFD$2' + +/** + * Encode a URL to a percent-encoded form, excluding already-encoded sequences. + * + * This function will take an already-encoded URL and encode all the non-URL + * code points. This function will not encode the "%" character unless it is + * not part of a valid sequence (`%20` will be left as-is, but `%foo` will + * be encoded as `%25foo`). + * + * This encode is meant to be "safe" and does not throw errors. It will try as + * hard as it can to properly encode the given URL, including replacing any raw, + * unpaired surrogate pairs with the Unicode replacement character prior to + * encoding. + * + * @param {string} url + * @return {string} + * @public + */ + +function encodeUrl (url) { + return String(url) + .replace(UNMATCHED_SURROGATE_PAIR_REGEXP, UNMATCHED_SURROGATE_PAIR_REPLACE) + .replace(ENCODE_CHARS_REGEXP, encodeURI) +} diff --git a/node_modules/encodeurl/package.json b/node_modules/encodeurl/package.json new file mode 100644 index 00000000..8c46f188 --- /dev/null +++ b/node_modules/encodeurl/package.json @@ -0,0 +1,112 @@ +{ + "_args": [ + [ + { + "raw": "encodeurl@~1.0.1", + "scope": null, + "escapedName": "encodeurl", + "name": "encodeurl", + "rawSpec": "~1.0.1", + "spec": ">=1.0.1 <1.1.0", + "type": "range" + }, + "/Users/ericchiu/Desktop/CIS 700/HW7/Project7-BioCrowds/node_modules/express" + ] + ], + "_from": "encodeurl@>=1.0.1 <1.1.0", + "_id": "encodeurl@1.0.1", + "_inCache": true, + "_location": "/encodeurl", + "_nodeVersion": "4.4.3", + "_npmOperationalInternal": { + "host": "packages-12-west.internal.npmjs.com", + "tmp": "tmp/encodeurl-1.0.1.tgz_1465519736251_0.09314409433864057" + }, + "_npmUser": { + "name": "dougwilson", + "email": "doug@somethingdoug.com" + }, + "_npmVersion": "2.15.1", + "_phantomChildren": {}, + "_requested": { + "raw": "encodeurl@~1.0.1", + "scope": null, + "escapedName": "encodeurl", + "name": "encodeurl", + "rawSpec": "~1.0.1", + "spec": ">=1.0.1 <1.1.0", + "type": "range" + }, + "_requiredBy": [ + "/express", + "/finalhandler", + "/send", + "/serve-static" + ], + "_resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.1.tgz", + "_shasum": "79e3d58655346909fe6f0f45a5de68103b294d20", + "_shrinkwrap": null, + "_spec": "encodeurl@~1.0.1", + "_where": "/Users/ericchiu/Desktop/CIS 700/HW7/Project7-BioCrowds/node_modules/express", + "bugs": { + "url": "https://github.com/pillarjs/encodeurl/issues" + }, + "contributors": [ + { + "name": "Douglas Christopher Wilson", + "email": "doug@somethingdoug.com" + } + ], + "dependencies": {}, + "description": "Encode a URL to a percent-encoded form, excluding already-encoded sequences", + "devDependencies": { + "eslint": "2.11.1", + "eslint-config-standard": "5.3.1", + "eslint-plugin-promise": "1.3.2", + "eslint-plugin-standard": "1.3.2", + "istanbul": "0.4.3", + "mocha": "2.5.3" + }, + "directories": {}, + "dist": { + "shasum": "79e3d58655346909fe6f0f45a5de68103b294d20", + "tarball": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.1.tgz" + }, + "engines": { + "node": ">= 0.8" + }, + "files": [ + "LICENSE", + "HISTORY.md", + "README.md", + "index.js" + ], + "gitHead": "39ed0c235fed4cea7d012038fd6bb0480561d226", + "homepage": "https://github.com/pillarjs/encodeurl#readme", + "keywords": [ + "encode", + "encodeurl", + "url" + ], + "license": "MIT", + "maintainers": [ + { + "name": "dougwilson", + "email": "doug@somethingdoug.com" + } + ], + "name": "encodeurl", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/pillarjs/encodeurl.git" + }, + "scripts": { + "lint": "eslint **/*.js", + "test": "mocha --reporter spec --bail --check-leaks test/", + "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot --check-leaks test/", + "test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter spec --check-leaks test/" + }, + "version": "1.0.1" +} diff --git a/node_modules/end-of-stream/.npmignore b/node_modules/end-of-stream/.npmignore new file mode 100644 index 00000000..3c3629e6 --- /dev/null +++ b/node_modules/end-of-stream/.npmignore @@ -0,0 +1 @@ +node_modules diff --git a/node_modules/end-of-stream/README.md b/node_modules/end-of-stream/README.md new file mode 100644 index 00000000..df800c1e --- /dev/null +++ b/node_modules/end-of-stream/README.md @@ -0,0 +1,47 @@ +# end-of-stream + +A node module that calls a callback when a readable/writable/duplex stream has completed or failed. + + npm install end-of-stream + +## Usage + +Simply pass a stream and a callback to the `eos`. +Both legacy streams and streams2 are supported. + +``` js +var eos = require('end-of-stream'); + +eos(readableStream, function(err) { + if (err) return console.log('stream had an error or closed early'); + console.log('stream has ended'); +}); + +eos(writableStream, function(err) { + if (err) return console.log('stream had an error or closed early'); + console.log('stream has finished'); +}); + +eos(duplexStream, function(err) { + if (err) return console.log('stream had an error or closed early'); + console.log('stream has ended and finished'); +}); + +eos(duplexStream, {readable:false}, function(err) { + if (err) return console.log('stream had an error or closed early'); + console.log('stream has ended but might still be writable'); +}); + +eos(duplexStream, {writable:false}, function(err) { + if (err) return console.log('stream had an error or closed early'); + console.log('stream has ended but might still be readable'); +}); + +eos(readableStream, {error:false}, function(err) { + // do not treat emit('error', err) as a end-of-stream +}); +``` + +## License + +MIT \ No newline at end of file diff --git a/node_modules/end-of-stream/index.js b/node_modules/end-of-stream/index.js new file mode 100644 index 00000000..9f61ed5a --- /dev/null +++ b/node_modules/end-of-stream/index.js @@ -0,0 +1,72 @@ +var once = require('once'); + +var noop = function() {}; + +var isRequest = function(stream) { + return stream.setHeader && typeof stream.abort === 'function'; +}; + +var eos = function(stream, opts, callback) { + if (typeof opts === 'function') return eos(stream, null, opts); + if (!opts) opts = {}; + + callback = once(callback || noop); + + var ws = stream._writableState; + var rs = stream._readableState; + var readable = opts.readable || (opts.readable !== false && stream.readable); + var writable = opts.writable || (opts.writable !== false && stream.writable); + + var onlegacyfinish = function() { + if (!stream.writable) onfinish(); + }; + + var onfinish = function() { + writable = false; + if (!readable) callback(); + }; + + var onend = function() { + readable = false; + if (!writable) callback(); + }; + + var onclose = function() { + if (readable && !(rs && rs.ended)) return callback(new Error('premature close')); + if (writable && !(ws && ws.ended)) return callback(new Error('premature close')); + }; + + var onrequest = function() { + stream.req.on('finish', onfinish); + }; + + if (isRequest(stream)) { + stream.on('complete', onfinish); + stream.on('abort', onclose); + if (stream.req) onrequest(); + else stream.on('request', onrequest); + } else if (writable && !ws) { // legacy streams + stream.on('end', onlegacyfinish); + stream.on('close', onlegacyfinish); + } + + stream.on('end', onend); + stream.on('finish', onfinish); + if (opts.error !== false) stream.on('error', callback); + stream.on('close', onclose); + + return function() { + stream.removeListener('complete', onfinish); + stream.removeListener('abort', onclose); + stream.removeListener('request', onrequest); + if (stream.req) stream.req.removeListener('finish', onfinish); + stream.removeListener('end', onlegacyfinish); + stream.removeListener('close', onlegacyfinish); + stream.removeListener('finish', onfinish); + stream.removeListener('end', onend); + stream.removeListener('error', callback); + stream.removeListener('close', onclose); + }; +}; + +module.exports = eos; \ No newline at end of file diff --git a/node_modules/end-of-stream/package.json b/node_modules/end-of-stream/package.json new file mode 100644 index 00000000..edb404d0 --- /dev/null +++ b/node_modules/end-of-stream/package.json @@ -0,0 +1,89 @@ +{ + "_args": [ + [ + { + "raw": "end-of-stream@1.0.0", + "scope": null, + "escapedName": "end-of-stream", + "name": "end-of-stream", + "rawSpec": "1.0.0", + "spec": "1.0.0", + "type": "version" + }, + "/Users/ericchiu/Desktop/CIS 700/HW7/Project7-BioCrowds/node_modules/duplexify" + ] + ], + "_from": "end-of-stream@1.0.0", + "_id": "end-of-stream@1.0.0", + "_inCache": true, + "_location": "/end-of-stream", + "_npmUser": { + "name": "mafintosh", + "email": "mathiasbuus@gmail.com" + }, + "_npmVersion": "1.4.9", + "_phantomChildren": {}, + "_requested": { + "raw": "end-of-stream@1.0.0", + "scope": null, + "escapedName": "end-of-stream", + "name": "end-of-stream", + "rawSpec": "1.0.0", + "spec": "1.0.0", + "type": "version" + }, + "_requiredBy": [ + "/duplexify" + ], + "_resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.0.0.tgz", + "_shasum": "d4596e702734a93e40e9af864319eabd99ff2f0e", + "_shrinkwrap": null, + "_spec": "end-of-stream@1.0.0", + "_where": "/Users/ericchiu/Desktop/CIS 700/HW7/Project7-BioCrowds/node_modules/duplexify", + "author": { + "name": "Mathias Buus", + "email": "mathiasbuus@gmail.com" + }, + "bugs": { + "url": "https://github.com/mafintosh/end-of-stream/issues" + }, + "dependencies": { + "once": "~1.3.0" + }, + "description": "Call a callback when a readable/writable/duplex stream has completed or failed.", + "devDependencies": {}, + "directories": {}, + "dist": { + "shasum": "d4596e702734a93e40e9af864319eabd99ff2f0e", + "tarball": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.0.0.tgz" + }, + "homepage": "https://github.com/mafintosh/end-of-stream", + "keywords": [ + "stream", + "streams", + "callback", + "finish", + "close", + "end", + "wait" + ], + "license": "MIT", + "main": "index.js", + "maintainers": [ + { + "name": "mafintosh", + "email": "mathiasbuus@gmail.com" + } + ], + "name": "end-of-stream", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/mafintosh/end-of-stream.git" + }, + "scripts": { + "test": "node test.js" + }, + "version": "1.0.0" +} diff --git a/node_modules/end-of-stream/test.js b/node_modules/end-of-stream/test.js new file mode 100644 index 00000000..d4d126fe --- /dev/null +++ b/node_modules/end-of-stream/test.js @@ -0,0 +1,62 @@ +var assert = require('assert'); +var eos = require('./index'); + +var expected = 6; +var fs = require('fs'); +var net = require('net'); + +var ws = fs.createWriteStream('/dev/null'); +eos(ws, function(err) { + expected--; + assert(!!err); + if (!expected) process.exit(0); +}); +ws.close(); + +var rs = fs.createReadStream('/dev/random'); +eos(rs, function(err) { + expected--; + assert(!!err); + if (!expected) process.exit(0); +}); +rs.close(); + +var rs = fs.createReadStream(__filename); +eos(rs, function(err) { + expected--; + assert(!err); + if (!expected) process.exit(0); +}); +rs.pipe(fs.createWriteStream('/dev/null')); + +var rs = fs.createReadStream(__filename); +eos(rs, function(err) { + throw new Error('no go') +})(); +rs.pipe(fs.createWriteStream('/dev/null')); + +var socket = net.connect(50000); +eos(socket, function(err) { + expected--; + assert(!!err); + if (!expected) process.exit(0); +}); + +var server = net.createServer(function(socket) { + eos(socket, function() { + expected--; + if (!expected) process.exit(0); + }); + socket.destroy(); +}).listen(30000, function() { + var socket = net.connect(30000); + eos(socket, function() { + expected--; + if (!expected) process.exit(0); + }); +}); + +setTimeout(function() { + assert(expected === 0); + process.exit(0); +}, 1000); diff --git a/node_modules/enhanced-resolve/README.md b/node_modules/enhanced-resolve/README.md new file mode 100644 index 00000000..d3f79310 --- /dev/null +++ b/node_modules/enhanced-resolve/README.md @@ -0,0 +1,28 @@ +# enhanced-resolve + +Offers a async require.resolve function. It's highly configurable. + +[documentation](https://github.com/webpack/docs/wiki) + + +## Features + +* plugin system +* provide a custom filesystem +* sync and async node.js filesystems included + + +## Tests + +``` javascript +npm test +``` + +[](http://travis-ci.org/webpack/enhanced-resolve) + + +## License + +Copyright (c) 2012-2013 Tobias Koppers + +MIT (http://www.opensource.org/licenses/mit-license.php) \ No newline at end of file diff --git a/node_modules/enhanced-resolve/lib/CachedInputFileSystem.js b/node_modules/enhanced-resolve/lib/CachedInputFileSystem.js new file mode 100644 index 00000000..132f9653 --- /dev/null +++ b/node_modules/enhanced-resolve/lib/CachedInputFileSystem.js @@ -0,0 +1,152 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ +function Storage(duration) { + this.duration = duration; + this.running = {}; + this.data = {}; + this.levels = []; + if(duration > 0) { + this.levels.push([], [], [], [], [], [], [], [], []); + for(var i = 8000; i < duration; i+=500) + this.levels.push([]); + } + this.count = 0; + this.interval = null; + this.needTickCheck = false; + this.nextTick = null; + this.passive = true; +} + +Storage.prototype.ensureTick = function() { + if(!this.interval && this.duration > 0 && !this.nextTick) + this.interval = setInterval(this.tick.bind(this), Math.floor(this.duration / this.levels.length)); +}; + +Storage.prototype.finished = function(name) { + var args = Array.prototype.slice.call(arguments, 1); + var callbacks = this.running[name]; + delete this.running[name]; + if(this.duration > 0) { + this.count++; + this.data[name] = args; + this.levels[0].push(name); + this.ensureTick(); + } + for(var i = 0; i < callbacks.length; i++) { + callbacks[i].apply(null, args); + } +}; + +Storage.prototype.provide = function(name, provider, callback) { + var running = this.running[name]; + if(running) { + running.push(callback); + return; + } + if(this.duration > 0) { + this.checkTicks(); + var data = this.data[name]; + if(data) { + return callback.apply(null, data); + } + } + this.running[name] = running = [callback]; + provider(name, this.finished.bind(this, name)); +}; + +Storage.prototype.tick = function() { + var decay = this.levels.pop(); + for(var i = decay.length - 1; i >= 0; i--) { + delete this.data[decay[i]]; + } + this.count -= decay.length; + decay.length = 0; + this.levels.unshift(decay); + if(this.count == 0) { + clearInterval(this.interval); + this.interval = null; + this.nextTick = null; + return true; + } else if(this.nextTick) { + this.nextTick += Math.floor(this.duration / this.levels.length); + var time = new Date().getTime(); + if(this.nextTick > time) { + this.nextTick = null; + this.interval = setInterval(this.tick.bind(this), Math.floor(this.duration / this.levels.length)); + return true; + } + } else if(this.passive) { + clearInterval(this.interval); + this.interval = null; + this.nextTick = new Date().getTime() + Math.floor(this.duration / this.levels.length); + } else { + this.passive = true; + } +}; + +Storage.prototype.checkTicks = function() { + this.passive = false; + if(this.nextTick) { + while(!this.tick()); + } +}; + +Storage.prototype.purge = function(what) { + if(!what) { + this.count = 0; + clearInterval(this.interval); + this.nextTick = null; + this.data = {}; + this.levels.forEach(function(level) { + level.length = 0; + }); + } else if(typeof what === "string") { + Object.keys(this.data).forEach(function(key) { + if(key.indexOf(what) === 0) + delete this.data[key]; + }, this); + } else { + for(var i = what.length - 1; i >= 0; i--) { + this.purge(what[i]); + } + } +}; + + +function CachedInputFileSystem(fileSystem, duration) { + this.fileSystem = fileSystem; + this._statStorage = new Storage(duration); + this._readdirStorage = new Storage(duration); + this._readFileStorage = new Storage(duration); + this._readlinkStorage = new Storage(duration); +} +module.exports = CachedInputFileSystem; + +CachedInputFileSystem.prototype.isSync = function() { + return this.fileSystem.isSync(); +}; + +CachedInputFileSystem.prototype.stat = function(path, callback) { + this._statStorage.provide(path, this.fileSystem.stat.bind(this.fileSystem), callback); +}; + +CachedInputFileSystem.prototype.readdir = function(path, callback) { + this._readdirStorage.provide(path, this.fileSystem.readdir.bind(this.fileSystem), callback); +}; + +CachedInputFileSystem.prototype.readFile = function(path, callback) { + this._readFileStorage.provide(path, this.fileSystem.readFile.bind(this.fileSystem), callback); +}; + +CachedInputFileSystem.prototype.readlink = function(path, callback) { + this._readlinkStorage.provide(path, this.fileSystem.readlink.bind(this.fileSystem), callback); +}; + +CachedInputFileSystem.prototype.purge = function(what) { + this._statStorage.purge(what); + this._readdirStorage.purge(what); + this._readFileStorage.purge(what); + this._readlinkStorage.purge(what); +}; \ No newline at end of file diff --git a/node_modules/enhanced-resolve/lib/DirectoryDefaultFilePlugin.js b/node_modules/enhanced-resolve/lib/DirectoryDefaultFilePlugin.js new file mode 100644 index 00000000..f4514ff3 --- /dev/null +++ b/node_modules/enhanced-resolve/lib/DirectoryDefaultFilePlugin.js @@ -0,0 +1,42 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ +var createInnerCallback = require("./createInnerCallback"); + +function DirectoryDefaultFilePlugin(files) { + this.files = files; +} +module.exports = DirectoryDefaultFilePlugin; + +DirectoryDefaultFilePlugin.prototype.apply = function(resolver) { + var files = this.files; + resolver.plugin("directory", function(request, callback) { + var fs = this.fileSystem; + var topLevelCallback = callback; + var directory = this.join(request.path, request.request); + fs.stat(directory, function(err, stat) { + if(err || !stat) { + if(callback.log) callback.log(directory + " doesn't exist (directory default file)"); + return callback(); + } + if(!stat.isDirectory()) { + if(callback.log) callback.log(directory + " is not a directory (directory default file)"); + return callback(); + } + this.forEachBail(files, function(file, callback) { + this.doResolve("file", { + path: directory, + query: request.query, + request: file + }, createInnerCallback(function(err, result) { + if(!err && result) return callback(result); + return callback(); + }, topLevelCallback, "directory default file " + file)); + }.bind(this), function(result) { + if(!result) return callback(); + return callback(null, result); + }); + }.bind(this)); + }); +}; \ No newline at end of file diff --git a/node_modules/enhanced-resolve/lib/DirectoryDescriptionFileFieldAliasPlugin.js b/node_modules/enhanced-resolve/lib/DirectoryDescriptionFileFieldAliasPlugin.js new file mode 100644 index 00000000..e9a44f2c --- /dev/null +++ b/node_modules/enhanced-resolve/lib/DirectoryDescriptionFileFieldAliasPlugin.js @@ -0,0 +1,126 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ +var createInnerCallback = require("./createInnerCallback"); + +function DirectoryDescriptionFileFieldAliasPlugin(filename, field) { + this.filename = filename; + this.field = field; +} +module.exports = DirectoryDescriptionFileFieldAliasPlugin; + +function findDescriptionFileField(resolver, directory, filename, field, callback) { + (function findDescriptionFile() { + var descriptionFilePath = resolver.join(directory, filename); + resolver.fileSystem.readFile(descriptionFilePath, function(err, content) { + if(err) { + directory = cdUp(directory); + if(!directory) { + return callback(); + } else { + return findDescriptionFile(); + } + } + try { + content = JSON.parse(content); + } catch(e) { + if(callback.log) + callback.log(descriptionFilePath + " (directory description file): " + e); + else + e.message = descriptionFilePath + " (directory description file): " + e; + return callback(e); + } + var fieldData; + if(Array.isArray(field)) { + var current = content; + for(var j = 0; j < field.length; j++) { + if(current === null || typeof current !== "object") { + current = null; + break; + } + current = current[field[j]]; + } + if(typeof current === "object") { + fieldData = current; + } + } else { + if(typeof content[field] === "object") { + fieldData = content[field]; + } + } + if(!fieldData) return callback(); + callback(null, fieldData, directory); + }); + }()); +} + +function cdUp(directory) { + if(directory === "/") return null; + var i = directory.lastIndexOf("/"), + j = directory.lastIndexOf("\\"); + var p = i < 0 ? j : j < 0 ? i : i < j ? j : i; + if(p < 0) return null; + return directory.substr(0, p || 1); +} + +DirectoryDescriptionFileFieldAliasPlugin.prototype.apply = function(resolver) { + var filename = this.filename; + var field = this.field; + resolver.plugin("module", function(request, callback) { + var directory = request.path; + var moduleName = request.request; + findDescriptionFileField(this, directory, filename, field, function(err, fieldData, directory) { + if(err) return callback(err); + if(!fieldData) return callback(); + var data = fieldData[moduleName]; + if(data === moduleName) return callback(); + if(data === false) return callback(null, { + path: false, + resolved: true + }); + if(!data) return callback(); + var newRequest = this.parse(data); + var obj = { + path: directory, + request: newRequest.path, + query: newRequest.query, + directory: newRequest.directory + }; + var newCallback = createInnerCallback(callback, callback, "aliased from directory description file " + this.join(directory, filename) + " with mapping " + JSON.stringify(moduleName)); + if(newRequest.module) return this.doResolve("module", obj, newCallback); + if(newRequest.directory) return this.doResolve("directory", obj, newCallback); + return this.doResolve(["file", "directory"], obj, newCallback); + }.bind(this)); + }); + resolver.plugin("result", function(request, callback) { + var directory = cdUp(request.path); + var requestPath = request.path; + findDescriptionFileField(this, directory, filename, field, function(err, fieldData, directory) { + if(err) return callback(err); + if(!fieldData) return callback(); + var relative = requestPath.substr(directory.length+1).replace(/\\/g, "/"); + if(typeof fieldData[relative] !== "undefined") + var data = fieldData[relative]; + else if(typeof fieldData["./" + relative] !== "undefined") + var data = fieldData["./" + relative]; + if(data === relative || data === "./" + relative) return callback(); + if(data === false) return callback(null, { + path: false, + resolved: true + }); + if(!data) return callback(); + var newRequest = this.parse(data); + var obj = { + path: directory, + request: newRequest.path, + query: newRequest.query, + directory: newRequest.directory + }; + var newCallback = createInnerCallback(callback, callback, "aliased from directory description file " + this.join(directory, filename) + " with mapping " + JSON.stringify(relative)); + if(newRequest.module) return this.doResolve("module", obj, newCallback); + if(newRequest.directory) return this.doResolve("directory", obj, newCallback); + return this.doResolve(["file", "directory"], obj, newCallback); + }.bind(this)); + }); +}; diff --git a/node_modules/enhanced-resolve/lib/DirectoryDescriptionFilePlugin.js b/node_modules/enhanced-resolve/lib/DirectoryDescriptionFilePlugin.js new file mode 100644 index 00000000..2cbc8c68 --- /dev/null +++ b/node_modules/enhanced-resolve/lib/DirectoryDescriptionFilePlugin.js @@ -0,0 +1,74 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ +var createInnerCallback = require("./createInnerCallback"); + +function DirectoryDescriptionFilePlugin(filename, fields) { + this.filename = filename; + this.fields = fields; +} +module.exports = DirectoryDescriptionFilePlugin; + +DirectoryDescriptionFilePlugin.prototype.apply = function(resolver) { + var filename = this.filename; + var fields = this.fields; + resolver.plugin("directory", function(request, callback) { + var fs = this.fileSystem; + var directory = this.join(request.path, request.request); + var descriptionFilePath = this.join(directory, filename); + fs.readFile(descriptionFilePath, function(err, content) { + if(err) { + if(callback.log) + callback.log(descriptionFilePath + " doesn't exist (directory description file)"); + return callback(); + } + content = content.toString("utf-8"); + try { + content = JSON.parse(content); + } catch(e) { + if(callback.log) + callback.log(descriptionFilePath + " (directory description file): " + e); + else + e.message = descriptionFilePath + " (directory description file): " + e; + return callback(e); + } + var mainModules = []; + for(var i = 0; i < fields.length; i++) { + if(Array.isArray(fields[i])) { + var current = content; + for(var j = 0; j < fields[i].length; j++) { + if(current === null || typeof current !== "object") { + current = null; + break; + } + var field = fields[i][j]; + current = current[field]; + } + if(typeof current === "string") { + mainModules.push(current); + continue; + } + } else { + var field = fields[i]; + if(typeof content[field] === "string") { + mainModules.push(content[field]); + continue; + } + } + } + (function next() { + if(mainModules.length == 0) return callback(); + var mainModule = mainModules.shift(); + return this.doResolve(["file", "directory"], { + path: directory, + query: request.query, + request: mainModule + }, createInnerCallback(function(err, result) { + if(!err && result) return callback(null, result); + return next.call(this); + }.bind(this), callback, "use " + mainModule + " from " + filename)); + }.call(this)) + }.bind(this)); + }); +}; \ No newline at end of file diff --git a/node_modules/enhanced-resolve/lib/DirectoryResultPlugin.js b/node_modules/enhanced-resolve/lib/DirectoryResultPlugin.js new file mode 100644 index 00000000..7ad57306 --- /dev/null +++ b/node_modules/enhanced-resolve/lib/DirectoryResultPlugin.js @@ -0,0 +1,31 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ +function DirectoryResultPlugin(files) { + this.files = files; +} +module.exports = DirectoryResultPlugin; + +DirectoryResultPlugin.prototype.apply = function(resolver) { + var files = this.files; + resolver.plugin("directory", function(request, callback) { + var fs = this.fileSystem; + var directory = this.join(request.path, request.request); + fs.stat(directory, function(err, stat) { + if(!err && stat && stat.isDirectory()) { + return this.doResolve("result", { + path: directory, + query: request.query, + directory: true, + resolved: true + }, callback); + } + if(callback.log) { + if(err) callback.log(directory + " doesn't exist"); + else callback.log(directory + " is not a directory"); + } + return callback(); + }.bind(this)); + }); +}; \ No newline at end of file diff --git a/node_modules/enhanced-resolve/lib/FileAppendPlugin.js b/node_modules/enhanced-resolve/lib/FileAppendPlugin.js new file mode 100644 index 00000000..1be582a4 --- /dev/null +++ b/node_modules/enhanced-resolve/lib/FileAppendPlugin.js @@ -0,0 +1,40 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ +function FileAppendPlugin(appendings) { + this.appendings = appendings; +} +module.exports = FileAppendPlugin; + +FileAppendPlugin.prototype.apply = function(resolver) { + var appendings = this.appendings; + resolver.plugin("file", function(request, callback) { + var fs = this.fileSystem; + var addr = this.join(request.path, request.request); + var addrs = appendings.map(function(a) { return addr + a }); + var log = callback.log; + var missing = callback.missing; + this.forEachBail(addrs, function(addr, callback) { + fs.stat(addr, function(err, stat) { + if(!err && stat && stat.isFile()) + return callback(addr); + if(missing && err) + missing.push(addr); + if(log) { + if(err) log(addr + " doesn't exist"); + else log(addr + " is not a file"); + } + return callback(); + }); + }, function(validAddr) { + if(!validAddr) return callback(); + return this.doResolve("result", { + path: validAddr, + query: request.query, + file: true, + resolved: true + }, callback); + }.bind(this)); + }); +}; \ No newline at end of file diff --git a/node_modules/enhanced-resolve/lib/ModuleAliasPlugin.js b/node_modules/enhanced-resolve/lib/ModuleAliasPlugin.js new file mode 100644 index 00000000..eaa69267 --- /dev/null +++ b/node_modules/enhanced-resolve/lib/ModuleAliasPlugin.js @@ -0,0 +1,44 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ +var createInnerCallback = require("./createInnerCallback"); + +function ModuleAliasPlugin(aliasMap) { + this.aliasMap = aliasMap; +} +module.exports = ModuleAliasPlugin; + +ModuleAliasPlugin.prototype.apply = function(resolver) { + var aliasMap = this.aliasMap; + resolver.plugin("module", function(request, callback) { + var fs = this.fileSystem; + var keys = Object.keys(aliasMap); + var i = 0; + (function next() { + for(;i < keys.length; i++) { + var aliasName = keys[i]; + var onlyModule = /\$$/.test(aliasName); + if(onlyModule) aliasName = aliasName.substr(0, aliasName.length-1); + if((!onlyModule && request.request.indexOf(aliasName + "/") === 0) || request.request === aliasName) { + var aliasValue = aliasMap[keys[i]]; + if(request.request.indexOf(aliasValue + "/") !== 0 && request.request != aliasValue) { + var newRequestStr = aliasValue + request.request.substr(aliasName.length); + var newRequest = this.parse(newRequestStr); + var obj = { + path: request.path, + request: newRequest.path, + query: newRequest.query, + directory: newRequest.directory + }; + var newCallback = createInnerCallback(callback, callback, "aliased with mapping " + JSON.stringify(aliasName) + ": " + JSON.stringify(aliasValue) + " to " + newRequestStr); + if(newRequest.module) return this.doResolve("module", obj, newCallback); + if(newRequest.directory) return this.doResolve("directory", obj, newCallback); + return this.doResolve(["file", "directory"], obj, newCallback); + } + } + } + return callback(); + }.call(this)); + }); +}; diff --git a/node_modules/enhanced-resolve/lib/ModuleAsDirectoryPlugin.js b/node_modules/enhanced-resolve/lib/ModuleAsDirectoryPlugin.js new file mode 100644 index 00000000..e058fcf9 --- /dev/null +++ b/node_modules/enhanced-resolve/lib/ModuleAsDirectoryPlugin.js @@ -0,0 +1,43 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ +function ModuleAsDirectoryPlugin(moduleType) { + this.moduleType = moduleType; +} +module.exports = ModuleAsDirectoryPlugin; + +ModuleAsDirectoryPlugin.prototype.apply = function(resolver) { + resolver.plugin("module-" + this.moduleType, function(request, callback) { + var fs = this.fileSystem; + var i = request.request.indexOf("/"), + j = request.request.indexOf("\\"); + var p = i < 0 ? j : j < 0 ? i : i < j ? i : j; + var moduleName, remainingRequest; + if(p < 0) { + moduleName = request.request; + remainingRequest = ""; + } else { + moduleName = request.request.substr(0, p); + remainingRequest = request.request.substr(p+1); + } + var modulePath = this.join(request.path, moduleName); + fs.stat(modulePath, function(err, stat) { + if(err || !stat) { + if(callback.missing) + callback.missing.push(modulePath); + if(callback.log) callback.log(modulePath + " doesn't exist (module as directory)"); + return callback(); + } + if(stat.isDirectory()) { + return this.doResolve(request.directory ? "directory" : ["file", "directory"], { + path: modulePath, + request: remainingRequest, + query: request.query + }, callback, true); + } + if(callback.log) callback.log(modulePath + " is not a directory (module as directory)"); + return callback(); + }.bind(this)); + }); +}; diff --git a/node_modules/enhanced-resolve/lib/ModuleAsFilePlugin.js b/node_modules/enhanced-resolve/lib/ModuleAsFilePlugin.js new file mode 100644 index 00000000..7d6fadba --- /dev/null +++ b/node_modules/enhanced-resolve/lib/ModuleAsFilePlugin.js @@ -0,0 +1,18 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ +function ModuleAsFilePlugin(moduleType) { + this.moduleType = moduleType; +} +module.exports = ModuleAsFilePlugin; + +ModuleAsFilePlugin.prototype.apply = function(resolver) { + resolver.plugin("module-" + this.moduleType, function(request, callback) { + var fs = this.fileSystem; + var i = request.request.indexOf("/"), + j = request.request.indexOf("\\"); + if(i >= 0 || j >= 0 || request.directory) return callback(); + return this.doResolve("file", request, callback, true); + }); +}; diff --git a/node_modules/enhanced-resolve/lib/ModuleTemplatesPlugin.js b/node_modules/enhanced-resolve/lib/ModuleTemplatesPlugin.js new file mode 100644 index 00000000..2962ee27 --- /dev/null +++ b/node_modules/enhanced-resolve/lib/ModuleTemplatesPlugin.js @@ -0,0 +1,45 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ +var createInnerCallback = require("./createInnerCallback"); + +function ModuleTemplatesPlugin(moduleType, templates, targetModuleType) { + this.moduleType = moduleType; + this.targetModuleType = targetModuleType; + this.templates = templates; +} +module.exports = ModuleTemplatesPlugin; + +ModuleTemplatesPlugin.prototype.apply = function(resolver) { + var templates = this.templates; + var targetModuleType = this.targetModuleType; + resolver.plugin("module-" + this.moduleType, function(request, callback) { + var fs = this.fileSystem; + var topLevelCallback = callback; + var i = request.request.indexOf("/"), + j = request.request.indexOf("\\"); + var p = i < 0 ? j : j < 0 ? i : i < j ? i : j; + var moduleName, remainingRequest; + if(p < 0) { + moduleName = request.request; + remainingRequest = ""; + } else { + moduleName = request.request.substr(0, p); + remainingRequest = request.request.substr(p); + } + this.forEachBail(templates, function(template, callback) { + var moduleFinalName = template.replace(/\*/g, moduleName); + this.applyPluginsParallelBailResult("module-" + targetModuleType, { + path: request.path, + request: moduleFinalName + remainingRequest, + query: request.query, + directory: request.directory + }, createInnerCallback(function(err, result) { + if(err) return callback(err); + if(!result) return callback(); + return callback(null, result); + }, topLevelCallback, "module variation " + moduleFinalName)); + }.bind(this), callback); + }); +}; diff --git a/node_modules/enhanced-resolve/lib/ModulesInDirectoriesPlugin.js b/node_modules/enhanced-resolve/lib/ModulesInDirectoriesPlugin.js new file mode 100644 index 00000000..3b801c01 --- /dev/null +++ b/node_modules/enhanced-resolve/lib/ModulesInDirectoriesPlugin.js @@ -0,0 +1,58 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ +var createInnerCallback = require("./createInnerCallback"); +var popPathSeqment = require("./popPathSeqment"); + +function ModulesInDirectoriesPlugin(moduleType, directories) { + this.moduleType = moduleType; + this.directories = directories; +} +module.exports = ModulesInDirectoriesPlugin; + +ModulesInDirectoriesPlugin.prototype.apply = function(resolver) { + var moduleType = this.moduleType; + var directories = this.directories; + resolver.plugin("module", function(request, callback) { + var fs = this.fileSystem; + var paths = [request.path]; + var addr = [request.path]; + var pathSeqment = popPathSeqment(addr); + var topLevelCallback = callback; + while(pathSeqment) { + paths.push(addr[0]); + pathSeqment = popPathSeqment(addr); + } + var addrs = paths.map(function(p) { + return directories.map(function(d) { + return this.join(p, d); + }, this); + }, this).reduce(function(array, p) { + array.push.apply(array, p); + return array; + }, []); + this.forEachBail(addrs, function(addr, callback) { + fs.stat(addr, function(err, stat) { + if(!err && stat && stat.isDirectory()) { + this.applyPluginsParallelBailResult("module-" + moduleType, { + path: addr, + request: request.request, + query: request.query, + directory: request.directory + }, createInnerCallback(function(err, result) { + if(err) return callback(err); + if(!result) return callback(); + return callback(null, result); + }, topLevelCallback, "looking for modules in " + addr)); + return; + } + return callback(); + }.bind(this)); + }.bind(this), function(err, result) { + if(err) return callback(err); + if(!result) return callback(); + return callback(null, result); + }); + }); +}; diff --git a/node_modules/enhanced-resolve/lib/ModulesInRootPlugin.js b/node_modules/enhanced-resolve/lib/ModulesInRootPlugin.js new file mode 100644 index 00000000..2b2ab6ae --- /dev/null +++ b/node_modules/enhanced-resolve/lib/ModulesInRootPlugin.js @@ -0,0 +1,28 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ +var createInnerCallback = require("./createInnerCallback"); + +function ModulesInRootPlugin(moduleType, path) { + this.moduleType = moduleType; + this.path = path; +} +module.exports = ModulesInRootPlugin; + +ModulesInRootPlugin.prototype.apply = function(resolver) { + var moduleType = this.moduleType; + var path = this.path; + resolver.plugin("module", function(request, callback) { + this.applyPluginsParallelBailResult("module-" + moduleType, { + path: path, + request: request.request, + query: request.query, + directory: request.directory + }, createInnerCallback(function innerCallback(err, result) { + if(err) return callback(err); + if(!result) return callback(); + return callback(null, result); + }, callback, "looking for modules in " + path)); + }); +}; diff --git a/node_modules/enhanced-resolve/lib/NodeJsInputFileSystem.js b/node_modules/enhanced-resolve/lib/NodeJsInputFileSystem.js new file mode 100644 index 00000000..588095d8 --- /dev/null +++ b/node_modules/enhanced-resolve/lib/NodeJsInputFileSystem.js @@ -0,0 +1,23 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ +var fs = require("graceful-fs"); + +function NodeJsInputFileSystem() {} +module.exports = NodeJsInputFileSystem; + +NodeJsInputFileSystem.prototype.isSync = function() { + return false; +}; + +NodeJsInputFileSystem.prototype.stat = fs.stat.bind(fs); +NodeJsInputFileSystem.prototype.readdir = function readdir(path, callback) { + fs.readdir(path, function (err, files) { + callback(err, files && files.map(function (file) { + return file.normalize ? file.normalize("NFC") : file; + })); + }); +}; +NodeJsInputFileSystem.prototype.readFile = fs.readFile.bind(fs); +NodeJsInputFileSystem.prototype.readlink = fs.readlink.bind(fs); \ No newline at end of file diff --git a/node_modules/enhanced-resolve/lib/Resolver.js b/node_modules/enhanced-resolve/lib/Resolver.js new file mode 100644 index 00000000..62e57d92 --- /dev/null +++ b/node_modules/enhanced-resolve/lib/Resolver.js @@ -0,0 +1,200 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ +var Tapable = require("tapable"); +var createInnerCallback = require("./createInnerCallback"); + +function Resolver(fileSystem) { + Tapable.call(this); + this.fileSystem = fileSystem; +} +module.exports = Resolver; + +Resolver.prototype = Object.create(Tapable.prototype); + +Resolver.prototype.resolveSync = function resolveSync(context, request) { + var err, result, sync = false; + this.resolve(context, request, function(e, r) { + err = e; + result = r; + sync = true; + }); + if(!sync) throw new Error("Cannot 'resolveSync' because the fileSystem is not sync. Use 'resolve'!"); + if(err) throw err; + return result; +}; + +Resolver.prototype.resolve = function resolve(context, request, callback) { + if(typeof request === "string") request = this.parse(request); + this.applyPlugins("resolve", context, request); + var obj = { + path: context, + request: request.path, + query: request.query, + directory: request.directory + }; + function onResolved(err, result) { + if(err) return callback(err); + return callback(null, result.path === false ? false : result.path + (result.query || "")); + } + onResolved.log = callback.log; + onResolved.missing = callback.missing; + if(request.module) return this.doResolve("module", obj, onResolved); + if(request.directory) return this.doResolve("directory", obj, onResolved); + return this.doResolve(["file", "directory"], obj, onResolved); +}; + +Resolver.prototype.doResolve = function doResolve(types, request, callback, noError) { + if(!Array.isArray(types)) types = [types]; + var stackLine = types.join(" or ") + ": (" + request.path + ") " + + (request.request || "") + (request.query || "") + + (request.directory ? " directory" : "") + + (request.module ? " module" : ""); + var newStack = [stackLine]; + if(callback.stack) { + newStack = callback.stack.concat(newStack); + if(callback.stack.indexOf(stackLine) >= 0) { + // Prevent recursion + var recursionError = new Error("Recursion in resolving\nStack:\n " + newStack.join("\n ")); + recursionError.recursion = true; + if(callback.log) callback.log("abort resolving because of recursion"); + return callback(recursionError); + } + } + this.applyPlugins("resolve-step", types, request); + var localMissing = []; + var missing = callback.missing ? { + push: function(item) { + callback.missing.push(item); + localMissing.push(item); + } + } : localMissing; + var log = []; + function writeLog(msg) { + log.push(msg); + } + function logAsString() { + return log.join("\n"); + } + var currentRequestString = request.request ? request.request + " in " + request.path : request.path; + if(types.length == 1 && !noError) { + // If only one type, we can pass the error. + return this.applyPluginsParallelBailResult(types[0], request, createInnerCallback(function innerCallback(err, result) { + if(callback.log) { + for(var i = 0; i < log.length; i++) + callback.log(log[i]); + } + if(err) return callback(err); + if(result) return callback(null, result); + if(types[0] === "result") return callback(null, request); + var error = new Error("Cannot resolve " + types[0] + " '" + request.request + "' in " + request.path); + error.details = logAsString(); + error.missing = localMissing; + return callback(error); + }, { + log: writeLog, + missing: missing, + stack: newStack + }, "resolve " + types[0] + " " + currentRequestString)); + } + // For multiple type we list the errors in the details although some of them are not important + this.forEachBail(types, function(type, callback) { + this.applyPluginsParallelBailResult(type, request, createInnerCallback(function(err, result) { + if(!err && result) return callback(result); + if (err) { + (err.message || "").split("\n").forEach(function(line) { + log.push(" " + line); + }); + } + callback(); + }, { + log: writeLog, + missing: missing, + stack: newStack + }, "resolve " + type)); + }.bind(this), function(result) { + if(callback.log) { + callback.log("resolve '" + types.join("' or '") + "' " + currentRequestString); + for(var i = 0; i < log.length; i++) + callback.log(" " + log[i]); + } + if(noError && !result) return callback(); + if(result) return callback(null, result); + var error = new Error("Cannot resolve '" + types.join("' or '") + "' " + currentRequestString); + error.details = logAsString(); + error.missing = localMissing; + return callback(error); + }); +}; + +Resolver.prototype.parse = function parse(identifier) { + if(identifier === "") return null; + var part = { + path: null, + query: null, + module: false, + directory: false, + file: false + }; + var idxQuery = identifier.indexOf("?"); + if(idxQuery == 0) { + part.query = identifier; + } else if(idxQuery > 0) { + part.path = identifier.slice(0, idxQuery); + part.query = identifier.slice(idxQuery); + } else { + part.path = identifier; + } + if(part.path) { + part.module = this.isModule(part.path); + if(part.directory = this.isDirectory(part.path)) { + part.path = part.path.substr(0, part.path.length - 1); + } + } + return part; +}; + +var notModuleRegExp = /^\.$|^\.[\\\/]|^\.\.$|^\.\.[\/\\]|^\/|^[A-Z]:[\\\/]/i; +Resolver.prototype.isModule = function isModule(path) { + return !notModuleRegExp.test(path); +}; + +var directoryRegExp = /[\/\\]$/i; +Resolver.prototype.isDirectory = function isDirectory(path) { + return directoryRegExp.test(path); +}; + +Resolver.prototype.join = require("memory-fs/lib/join"); + +Resolver.prototype.normalize = require("memory-fs/lib/normalize"); + +Resolver.prototype.forEachBail = function(array, iterator, callback) { + if(array.length == 0) return callback(); + var currentPos = array.length; + var currentError, currentResult; + var done = []; + for(var i = 0; i < array.length; i++) { + var itCb = (function(i) { + return function() { + if(i >= currentPos) return; // ignore + var args = Array.prototype.slice.call(arguments); + done.push(i); + if(args.length > 0) { + currentPos = i + 1; + done = done.filter(function(item) { + return item <= i; + }); + currentResult = args; + } + if(done.length == currentPos) { + callback.apply(null, currentResult); + currentPos = 0; + } + }; + }(i)); + iterator(array[i], itCb); + if(currentPos == 0) break; + } +}; + diff --git a/node_modules/enhanced-resolve/lib/ResultSymlinkPlugin.js b/node_modules/enhanced-resolve/lib/ResultSymlinkPlugin.js new file mode 100644 index 00000000..9d4fac2a --- /dev/null +++ b/node_modules/enhanced-resolve/lib/ResultSymlinkPlugin.js @@ -0,0 +1,49 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ +var popPathSeqment = require("./popPathSeqment"); + +function ResultSymlinkPlugin(appendings) { +} +module.exports = ResultSymlinkPlugin; + +ResultSymlinkPlugin.prototype.apply = function(resolver) { + resolver.plugin("result", function pluginMethod(request, callback) { + var fs = this.fileSystem; + var paths = [request.path]; + var pathSeqments = []; + var addr = [request.path]; + var pathSeqment = popPathSeqment(addr); + while(pathSeqment) { + pathSeqments.push(pathSeqment); + paths.push(addr[0]); + pathSeqment = popPathSeqment(addr); + } + pathSeqments.push(paths[paths.length-1]); + var log = callback.log; + var missing = callback.missing; + var containsSymlink = false; + this.forEachBail(paths.map(function(_, i) { return i; }), function(idx, callback) { + fs.readlink(paths[idx], function(err, result) { + if(!err && result) { + pathSeqments[idx] = result; + containsSymlink = true; + // Shortcut when absolute symlink found + if(/^(\/|[a-zA-z]:($|\\))/.test(result)) + return callback(null, idx); + } + callback(); + }); + }, function(err, idx) { + if(!containsSymlink) return callback(); + var resultSeqments = typeof idx === "number" ? pathSeqments.slice(0, idx+1) : pathSeqments.slice(); + var result = resultSeqments.reverse().reduce(function(a, b) { + return this.join(a, b); + }.bind(this)); + log("resolved symlink to " + result); + request.path = result; + pluginMethod.call(this, request, callback); + }.bind(this)); + }); +}; \ No newline at end of file diff --git a/node_modules/enhanced-resolve/lib/SyncNodeJsInputFileSystem.js b/node_modules/enhanced-resolve/lib/SyncNodeJsInputFileSystem.js new file mode 100644 index 00000000..9fc036a7 --- /dev/null +++ b/node_modules/enhanced-resolve/lib/SyncNodeJsInputFileSystem.js @@ -0,0 +1,34 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ +var fs = require("graceful-fs"); + +function SyncNodeJsInputFileSystem() {} +module.exports = SyncNodeJsInputFileSystem; + +SyncNodeJsInputFileSystem.prototype.isSync = function() { + return true; +}; + +function asAsync(fn, context) { + return function() { + var args = Array.prototype.slice.call(arguments); + var callback = args.pop(); + try { + callback(null, fn.apply(context, args)); + } catch(e) { + callback(e); + } + }; +} + +SyncNodeJsInputFileSystem.prototype.stat = asAsync(fs.statSync, fs); +SyncNodeJsInputFileSystem.prototype.readdir = asAsync(function readdirSync(path) { + var files = fs.readdirSync(path); + return files && files.map(function (file) { + return file.normalize ? file.normalize("NFC") : file; + }); +}, fs); +SyncNodeJsInputFileSystem.prototype.readFile = asAsync(fs.readFileSync, fs); +SyncNodeJsInputFileSystem.prototype.readlink = asAsync(fs.readlinkSync, fs); \ No newline at end of file diff --git a/node_modules/enhanced-resolve/lib/UnsafeCachePlugin.js b/node_modules/enhanced-resolve/lib/UnsafeCachePlugin.js new file mode 100644 index 00000000..8806b1ca --- /dev/null +++ b/node_modules/enhanced-resolve/lib/UnsafeCachePlugin.js @@ -0,0 +1,32 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ +function UnsafeCachePlugin(regExps, cache) { + this.regExps = regExps || [/./]; + if(this.regExps === true) this.regExps = [/./]; + else if(!Array.isArray(this.regExps)) this.regExps = [this.regExps]; + this.cache = cache || {}; +} +module.exports = UnsafeCachePlugin; + +UnsafeCachePlugin.prototype.apply = function(resolver) { + var oldResolve = resolver.resolve; + var regExps = this.regExps; + var cache = this.cache; + resolver.resolve = function resolve(context, request, callback) { + var id = context + "->" + request; + if(cache[id]) { + // From cache + return callback(null, cache[id]); + } + oldResolve.call(resolver, context, request, function(err, result) { + if(err) return callback(err); + var doCache = regExps.some(function(regExp) { + return regExp.test(result.path); + }); + if(!doCache) return callback(null, result); + callback(null, cache[id] = result); + }); + }; +}; diff --git a/node_modules/enhanced-resolve/lib/createInnerCallback.js b/node_modules/enhanced-resolve/lib/createInnerCallback.js new file mode 100644 index 00000000..66fc772a --- /dev/null +++ b/node_modules/enhanced-resolve/lib/createInnerCallback.js @@ -0,0 +1,30 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ +module.exports = function createInnerCallback(callback, options, message) { + var log = options.log; + if(!log) { + if(options.stack !== callback.stack) { + function callbackWrapper() { + return callback.apply(this, arguments); + } + callbackWrapper.stack = options.stack; + callbackWrapper.missing = options.missing; + } + return callback; + } + function loggingCallbackWrapper() { + log(message); + for(var i = 0; i < theLog.length; i++) + log(" " + theLog[i]); + return callback.apply(this, arguments); + } + var theLog = []; + loggingCallbackWrapper.log = function writeLog(msg) { + theLog.push(msg); + }; + loggingCallbackWrapper.stack = options.stack; + loggingCallbackWrapper.missing = options.missing; + return loggingCallbackWrapper; +} \ No newline at end of file diff --git a/node_modules/enhanced-resolve/lib/node.js b/node_modules/enhanced-resolve/lib/node.js new file mode 100644 index 00000000..22c65905 --- /dev/null +++ b/node_modules/enhanced-resolve/lib/node.js @@ -0,0 +1,103 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ +var Resolver = require("./Resolver"); +var NodeJsInputFileSystem = require("./NodeJsInputFileSystem"); +var SyncNodeJsInputFileSystem = require("./SyncNodeJsInputFileSystem"); +var CachedInputFileSystem = require("./CachedInputFileSystem"); +var ModulesInDirectoriesPlugin = require("./ModulesInDirectoriesPlugin"); +var ModuleTemplatesPlugin = require("./ModuleTemplatesPlugin"); +var ModuleAsFilePlugin = require("./ModuleAsFilePlugin"); +var ModuleAsDirectoryPlugin = require("./ModuleAsDirectoryPlugin"); +var DirectoryDefaultFilePlugin = require("./DirectoryDefaultFilePlugin"); +var DirectoryDescriptionFilePlugin = require("./DirectoryDescriptionFilePlugin"); +var FileAppendPlugin = require("./FileAppendPlugin"); +var ResultSymlinkPlugin = require("./ResultSymlinkPlugin"); +var DirectoryResultPlugin = require("./DirectoryResultPlugin"); + +var commonPlugins = [ + new ModulesInDirectoriesPlugin("node", ["node_modules"]), + new ModuleAsFilePlugin("node"), + new ModuleAsDirectoryPlugin("node"), + new DirectoryDescriptionFilePlugin("package.json", ["main"]), + new DirectoryDefaultFilePlugin(["index"]), + new FileAppendPlugin(["", ".js", ".node"]), + new ResultSymlinkPlugin() +]; + +var commonContextPlugins = [ + new ModulesInDirectoriesPlugin("node", ["node_modules"]), + new ModuleAsFilePlugin("node"), + new ModuleAsDirectoryPlugin("node"), + new DirectoryResultPlugin(), + new ResultSymlinkPlugin() +]; + +var commonLoaderPlugins = [ + new ModulesInDirectoriesPlugin("loader-module", ["node_loaders", "node_modules"]), + new ModuleTemplatesPlugin("loader-module", ["*-loader", "*"], "node"), + new ModuleAsFilePlugin("node"), + new ModuleAsDirectoryPlugin("node"), + new DirectoryDescriptionFilePlugin("package.json", ["loader", "main"]), + new DirectoryDefaultFilePlugin(["index"]), + new FileAppendPlugin([".loader.js", "", ".js"]), + new ResultSymlinkPlugin() +]; + +var asyncFileSystem = new CachedInputFileSystem(new NodeJsInputFileSystem(), 4000); +var syncFileSystem = new CachedInputFileSystem(new SyncNodeJsInputFileSystem(), 4000); + + +var asyncResolver = new Resolver(asyncFileSystem); +asyncResolver.apply.apply(asyncResolver, commonPlugins); +module.exports = function resolve(context, request, callback) { + asyncResolver.resolve(context, request, callback); +}; + +var syncResolver = new Resolver(syncFileSystem); +syncResolver.apply.apply(syncResolver, commonPlugins); +module.exports.sync = function resolveSync(context, request) { + return syncResolver.resolveSync(context, request); +}; + + +var asyncContextResolver = new Resolver(asyncFileSystem); +asyncContextResolver.apply.apply(asyncContextResolver, commonContextPlugins); +module.exports.context = function resolveContext(context, request, callback) { + asyncContextResolver.resolve(context, request, callback); +}; + +var syncContextResolver = new Resolver(syncFileSystem); +syncContextResolver.apply.apply(syncContextResolver, commonContextPlugins); +module.exports.context.sync = function resolveSync(context, request) { + return syncContextResolver.resolveSync(context, request); +}; + + +var asyncLoaderResolver = new Resolver(asyncFileSystem); +asyncLoaderResolver.apply.apply(asyncLoaderResolver, commonLoaderPlugins); +module.exports.loader = function resolveContext(context, request, callback) { + asyncLoaderResolver.resolve(context, request, callback); +}; + +var syncLoaderResolver = new Resolver(syncFileSystem); +syncLoaderResolver.apply.apply(syncLoaderResolver, commonLoaderPlugins); +module.exports.loader.sync = function resolveSync(context, request) { + return syncLoaderResolver.resolveSync(context, request); +}; + +// Export Resolver, FileSystems and Plugins +module.exports.Resolver = Resolver; +module.exports.NodeJsInputFileSystem = NodeJsInputFileSystem; +module.exports.SyncNodeJsInputFileSystem = SyncNodeJsInputFileSystem; +module.exports.CachedInputFileSystem = CachedInputFileSystem; +module.exports.ModulesInDirectoriesPlugin = ModulesInDirectoriesPlugin; +module.exports.ModuleAsDirectoryPlugin = ModuleAsDirectoryPlugin; +module.exports.DirectoryDefaultFilePlugin = DirectoryDefaultFilePlugin; +module.exports.DirectoryDescriptionFilePlugin = DirectoryDescriptionFilePlugin; +module.exports.FileAppendPlugin = FileAppendPlugin; +module.exports.DirectoryResultPlugin = DirectoryResultPlugin; +module.exports.ResultSymlinkPlugin = ResultSymlinkPlugin; +module.exports.ModuleAsFilePlugin = ModuleAsFilePlugin; +module.exports.ModuleTemplatesPlugin = ModuleTemplatesPlugin; diff --git a/node_modules/enhanced-resolve/lib/popPathSeqment.js b/node_modules/enhanced-resolve/lib/popPathSeqment.js new file mode 100644 index 00000000..7eea05c2 --- /dev/null +++ b/node_modules/enhanced-resolve/lib/popPathSeqment.js @@ -0,0 +1,13 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ +module.exports = function popPathSeqment(pathInArray) { + var i = pathInArray[0].lastIndexOf("/"), + j = pathInArray[0].lastIndexOf("\\"); + var p = i < 0 ? j : j < 0 ? i : i < j ? j : i; + if(p < 0) return null; + var s = pathInArray[0].substr(p+1); + pathInArray[0] = pathInArray[0].substr(0, p || 1); + return s; +}; diff --git a/node_modules/enhanced-resolve/node_modules/memory-fs/.gitattributes b/node_modules/enhanced-resolve/node_modules/memory-fs/.gitattributes new file mode 100644 index 00000000..412eeda7 --- /dev/null +++ b/node_modules/enhanced-resolve/node_modules/memory-fs/.gitattributes @@ -0,0 +1,22 @@ +# Auto detect text files and perform LF normalization +* text=auto + +# Custom for Visual Studio +*.cs diff=csharp +*.sln merge=union +*.csproj merge=union +*.vbproj merge=union +*.fsproj merge=union +*.dbproj merge=union + +# Standard to msysgit +*.doc diff=astextplain +*.DOC diff=astextplain +*.docx diff=astextplain +*.DOCX diff=astextplain +*.dot diff=astextplain +*.DOT diff=astextplain +*.pdf diff=astextplain +*.PDF diff=astextplain +*.rtf diff=astextplain +*.RTF diff=astextplain diff --git a/node_modules/enhanced-resolve/node_modules/memory-fs/.npmignore b/node_modules/enhanced-resolve/node_modules/memory-fs/.npmignore new file mode 100644 index 00000000..d2b38602 --- /dev/null +++ b/node_modules/enhanced-resolve/node_modules/memory-fs/.npmignore @@ -0,0 +1,65 @@ +# Logs +logs +*.log + +# Runtime data +pids +*.pid +*.seed + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Compiled binary addons (http://nodejs.org/api/addons.html) +build/Release + +# Dependency directory +# Deployed apps should consider commenting this line out: +# see https://npmjs.org/doc/faq.html#Should-I-check-my-node_modules-folder-into-git +node_modules + +# ========================= +# Operating System Files +# ========================= + +# OSX +# ========================= + +.DS_Store +.AppleDouble +.LSOverride + +# Icon must ends with two \r. +Icon + +# Thumbnails +._* + +# Files that might appear on external disk +.Spotlight-V100 +.Trashes + +# Windows +# ========================= + +# Windows image file caches +Thumbs.db +ehthumbs.db + +# Folder config file +Desktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msm +*.msp diff --git a/node_modules/enhanced-resolve/node_modules/memory-fs/.travis.yml b/node_modules/enhanced-resolve/node_modules/memory-fs/.travis.yml new file mode 100644 index 00000000..1416d607 --- /dev/null +++ b/node_modules/enhanced-resolve/node_modules/memory-fs/.travis.yml @@ -0,0 +1,4 @@ +language: node_js +node_js: + - "0.10" + - "0.11" \ No newline at end of file diff --git a/node_modules/enhanced-resolve/node_modules/memory-fs/README.md b/node_modules/enhanced-resolve/node_modules/memory-fs/README.md new file mode 100644 index 00000000..450ef484 --- /dev/null +++ b/node_modules/enhanced-resolve/node_modules/memory-fs/README.md @@ -0,0 +1,29 @@ +# memory-fs + +A simple in-memory filesystem. Holds data in a javascript object. + +``` javascript +var MemoryFileSystem = require("memory-fs"); +var fs = new MemoryFileSystem(); // Optionally pass a javascript object + +fs.mkdirpSync("/a/test/dir"); +fs.writeFileSync("/a/test/dir/file.txt", "Hello World"); +fs.readFileSync("/a/test/dir/file.txt"); // returns Buffer("Hello World") + +// Async variantes too +fs.unlink("/a/test/dir/file.txt", function(err) { + // ... +}); + +fs.readdirSync("/a/test"); // returns ["dir"] +fs.statSync("/a/test/dir").isDirectory(); // returns true +fs.rmdirSync("/a/test/dir"); + +fs.mkdirpSync("C:\\use\\windows\\style\\paths"); +``` + +## License + +Copyright (c) 2012-2014 Tobias Koppers + +MIT (http://www.opensource.org/licenses/mit-license.php) diff --git a/node_modules/enhanced-resolve/node_modules/memory-fs/lib/MemoryFileSystem.js b/node_modules/enhanced-resolve/node_modules/memory-fs/lib/MemoryFileSystem.js new file mode 100644 index 00000000..118b3d23 --- /dev/null +++ b/node_modules/enhanced-resolve/node_modules/memory-fs/lib/MemoryFileSystem.js @@ -0,0 +1,225 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +var normalize = require("./normalize"); + +function MemoryFileSystem(data) { + this.data = data || {}; +} +module.exports = MemoryFileSystem; + +function isDir(item) { + if(typeof item !== "object") return false; + return item[""] === true; +} + +function isFile(item) { + if(typeof item !== "object") return false; + return !item[""]; +} + +function pathToArray(path) { + path = normalize(path); + var nix = /^\//.test(path); + if(!nix) { + if(!/^[A-Za-z]:/.test(path)) throw new Error("Invalid path '" + path + "'"); + path = path.replace(/[\\\/]+/g, "\\"); // multi slashs + path = path.split(/[\\\/]/); + path[0] = path[0].toUpperCase(); + } else { + path = path.replace(/\/+/g, "/"); // multi slashs + path = path.substr(1).split("/"); + } + if(!path[path.length-1]) path.pop(); + return path; +} + +function trueFn() { return true; } +function falseFn() { return false; } + +MemoryFileSystem.prototype.statSync = function(_path) { + var path = pathToArray(_path); + var current = this.data; + for(var i = 0; i < path.length - 1; i++) { + if(!isDir(current[path[i]])) + throw new Error("Path doesn't exist '" + _path + "'"); + current = current[path[i]]; + } + if(_path === "/" || isDir(current[path[i]])) { + return { + isFile: falseFn, + isDirectory: trueFn, + isBlockDevice: falseFn, + isCharacterDevice: falseFn, + isSymbolicLink: falseFn, + isFIFO: falseFn, + isSocket: falseFn + }; + } else if(isFile(current[path[i]])) { + return { + isFile: trueFn, + isDirectory: falseFn, + isBlockDevice: falseFn, + isCharacterDevice: falseFn, + isSymbolicLink: falseFn, + isFIFO: falseFn, + isSocket: falseFn + }; + } else + throw new Error("Path doesn't exist '" + _path + "'"); +}; + +MemoryFileSystem.prototype.readFileSync = function(_path, encoding) { + var path = pathToArray(_path); + var current = this.data; + for(var i = 0; i < path.length - 1; i++) { + if(!isDir(current[path[i]])) + throw new Error("Path doesn't exist '" + _path + "'"); + current = current[path[i]]; + } + if(!isFile(current[path[i]])) { + if(isDir(current[path[i]])) + throw new Error("Cannot readFile on directory '" + _path + "'"); + else + throw new Error("Path doesn't exist '" + _path + "'"); + } + current = current[path[i]]; + return encoding ? current.toString(encoding) : current; +}; + +MemoryFileSystem.prototype.readdirSync = function(_path) { + if(_path === "/") return Object.keys(this.data).filter(Boolean); + var path = pathToArray(_path); + var current = this.data; + for(var i = 0; i < path.length - 1; i++) { + if(!isDir(current[path[i]])) + throw new Error("Path doesn't exist '" + _path + "'"); + current = current[path[i]]; + } + if(!isDir(current[path[i]])) { + if(isFile(current[path[i]])) + throw new Error("Cannot readdir on file '" + _path + "'"); + else + throw new Error("Path doesn't exist '" + _path + "'"); + } + return Object.keys(current[path[i]]).filter(Boolean); +}; + +MemoryFileSystem.prototype.mkdirpSync = function(_path) { + var path = pathToArray(_path); + if(path.length === 0) return; + var current = this.data; + for(var i = 0; i < path.length; i++) { + if(isFile(current[path[i]])) + throw new Error("Path is a file '" + _path + "'"); + else if(!isDir(current[path[i]])) + current[path[i]] = {"":true}; + current = current[path[i]]; + } + return; +}; + +MemoryFileSystem.prototype.mkdirSync = function(_path) { + var path = pathToArray(_path); + if(path.length === 0) return; + var current = this.data; + for(var i = 0; i < path.length - 1; i++) { + if(!isDir(current[path[i]])) + throw new Error("Path doesn't exist '" + _path + "'"); + current = current[path[i]]; + } + if(isDir(current[path[i]])) + throw new new Error("Directory already exist '" + _path + "'"); + else if(isFile(current[path[i]])) + throw new Error("Cannot mkdir on file '" + _path + "'"); + current[path[i]] = {"":true}; + return; +}; + +MemoryFileSystem.prototype._remove = function(_path, name, testFn) { + var path = pathToArray(_path); + if(path.length === 0) throw new Error("Path cannot be removed '" + _path + "'"); + var current = this.data; + for(var i = 0; i < path.length - 1; i++) { + if(!isDir(current[path[i]])) + throw new Error("Path doesn't exist '" + _path + "'"); + current = current[path[i]]; + } + if(!testFn(current[path[i]])) + throw new Error("'" + name + "' doesn't exist '" + _path + "'"); + delete current[path[i]]; + return; +}; + +MemoryFileSystem.prototype.rmdirSync = function(_path) { + return this._remove(_path, "Directory", isDir); +}; + +MemoryFileSystem.prototype.unlinkSync = function(_path) { + return this._remove(_path, "File", isFile); +}; + +MemoryFileSystem.prototype.readlinkSync = function(_path) { + throw new Error("Path is not a link '" + _path + "'"); +}; + +MemoryFileSystem.prototype.writeFileSync = function(_path, content, encoding) { + if(!content && !encoding) throw new Error("No content"); + var path = pathToArray(_path); + if(path.length === 0) throw new Error("Path is not a file '" + _path + "'"); + var current = this.data; + for(var i = 0; i < path.length - 1; i++) { + if(!isDir(current[path[i]])) + throw new Error("Path doesn't exist '" + _path + "'"); + current = current[path[i]]; + } + if(isDir(current[path[i]])) + throw new Error("Cannot writeFile on directory '" + _path + "'"); + current[path[i]] = encoding || typeof content === "string" ? new Buffer(content, encoding) : content; + return; +}; + +MemoryFileSystem.prototype.join = require("./join"); + +MemoryFileSystem.prototype.normalize = normalize; + +// async functions + +["stat", "readdir", "mkdirp", "mkdir", "rmdir", "unlink", "readlink"].forEach(function(fn) { + MemoryFileSystem.prototype[fn] = function(path, callback) { + try { + var result = this[fn + "Sync"](path); + } catch(e) { + return callback(e); + } + return callback(null, result); + }; +}); + +MemoryFileSystem.prototype.readFile = function(path, optArg, callback) { + if(!callback) { + callback = optArg; + optArg = undefined; + } + try { + var result = this.readFileSync(path, optArg); + } catch(e) { + return callback(e); + } + return callback(null, result); +}; + +MemoryFileSystem.prototype.writeFile = function (path, content, encoding, callback) { + if(!callback) { + callback = encoding; + encoding = undefined; + } + try { + this.writeFileSync(path, content, encoding); + } catch(e) { + return callback(e); + } + return callback(); +}; diff --git a/node_modules/enhanced-resolve/node_modules/memory-fs/lib/join.js b/node_modules/enhanced-resolve/node_modules/memory-fs/lib/join.js new file mode 100644 index 00000000..255e1755 --- /dev/null +++ b/node_modules/enhanced-resolve/node_modules/memory-fs/lib/join.js @@ -0,0 +1,14 @@ +var normalize = require("./normalize"); + +var absoluteWinRegExp = /^[A-Z]:([\\\/]|$)/i; +var absoluteNixRegExp = /^\//i; + +module.exports = function join(path, request) { + if(request == "") return normalize(path); + if(absoluteWinRegExp.test(request)) return normalize(request.replace(/\//g, "\\")); + if(absoluteNixRegExp.test(request)) return normalize(request); + if(path == "/") return normalize(path + request); + if(absoluteWinRegExp.test(path)) return normalize(path + "\\" + request.replace(/\//g, "\\")); + if(absoluteNixRegExp.test(path)) return normalize(path + "/" + request); + return normalize(path + "/" + request); +}; \ No newline at end of file diff --git a/node_modules/enhanced-resolve/node_modules/memory-fs/lib/normalize.js b/node_modules/enhanced-resolve/node_modules/memory-fs/lib/normalize.js new file mode 100644 index 00000000..04726d04 --- /dev/null +++ b/node_modules/enhanced-resolve/node_modules/memory-fs/lib/normalize.js @@ -0,0 +1,38 @@ +var doubleSlashWinRegExp = /\\+/g; +var doubleSlashNixRegExp = /\/+/g; +var currentDirectoryWinMiddleRegExp = /\\(\.\\)+/; +var currentDirectoryWinEndRegExp = /\\\.$/; +var parentDirectoryWinMiddleRegExp = /\\+[^\\]+\\+\.\.\\/; +var parentDirectoryWinEndRegExp1 = /([A-Z]:\\)\\*[^\\]+\\+\.\.$/i; +var parentDirectoryWinEndRegExp2 = /\\+[^\\]+\\+\.\.$/; +var currentDirectoryNixMiddleRegExp = /\/+(\.\/)+/; +var currentDirectoryNixEndRegExp1 = /^\/+\.$/; +var currentDirectoryNixEndRegExp2 = /\/+\.$/; +var parentDirectoryNixMiddleRegExp = /(^|\/[^\/]+)\/+\.\.\/+/; +var parentDirectoryNixEndRegExp1 = /^\/[^\/]+\/+\.\.$/; +var parentDirectoryNixEndRegExp2 = /\/+[^\/]+\/+\.\.$/; +var parentDirectoryNixEndRegExp3 = /^\/+\.\.$/; + +// RegExp magic :) + +module.exports = function normalize(path) { + while(currentDirectoryWinMiddleRegExp.test(path)) + path = path.replace(currentDirectoryWinMiddleRegExp, "\\"); + path = path.replace(currentDirectoryWinEndRegExp, ""); + while(parentDirectoryWinMiddleRegExp.test(path)) + path = path.replace(parentDirectoryWinMiddleRegExp, "\\"); + path = path.replace(parentDirectoryWinEndRegExp1, "$1"); + path = path.replace(parentDirectoryWinEndRegExp2, ""); + + while(currentDirectoryNixMiddleRegExp.test(path)) + path = path.replace(currentDirectoryNixMiddleRegExp, "/"); + path = path.replace(currentDirectoryNixEndRegExp1, "/"); + path = path.replace(currentDirectoryNixEndRegExp2, ""); + while(parentDirectoryNixMiddleRegExp.test(path)) + path = path.replace(parentDirectoryNixMiddleRegExp, "/"); + path = path.replace(parentDirectoryNixEndRegExp1, "/"); + path = path.replace(parentDirectoryNixEndRegExp2, ""); + path = path.replace(parentDirectoryNixEndRegExp3, "/"); + + return path.replace(doubleSlashWinRegExp, "\\").replace(doubleSlashNixRegExp, "/"); +}; \ No newline at end of file diff --git a/node_modules/enhanced-resolve/node_modules/memory-fs/package.json b/node_modules/enhanced-resolve/node_modules/memory-fs/package.json new file mode 100644 index 00000000..fae346df --- /dev/null +++ b/node_modules/enhanced-resolve/node_modules/memory-fs/package.json @@ -0,0 +1,89 @@ +{ + "_args": [ + [ + { + "raw": "memory-fs@^0.2.0", + "scope": null, + "escapedName": "memory-fs", + "name": "memory-fs", + "rawSpec": "^0.2.0", + "spec": ">=0.2.0 <0.3.0", + "type": "range" + }, + "/Users/ericchiu/Desktop/CIS 700/HW7/Project7-BioCrowds/node_modules/enhanced-resolve" + ] + ], + "_from": "memory-fs@>=0.2.0 <0.3.0", + "_id": "memory-fs@0.2.0", + "_inCache": true, + "_location": "/enhanced-resolve/memory-fs", + "_npmUser": { + "name": "sokra", + "email": "tobias.koppers@googlemail.com" + }, + "_npmVersion": "1.4.28", + "_phantomChildren": {}, + "_requested": { + "raw": "memory-fs@^0.2.0", + "scope": null, + "escapedName": "memory-fs", + "name": "memory-fs", + "rawSpec": "^0.2.0", + "spec": ">=0.2.0 <0.3.0", + "type": "range" + }, + "_requiredBy": [ + "/enhanced-resolve" + ], + "_resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.2.0.tgz", + "_shasum": "f2bb25368bc121e391c2520de92969caee0a0290", + "_shrinkwrap": null, + "_spec": "memory-fs@^0.2.0", + "_where": "/Users/ericchiu/Desktop/CIS 700/HW7/Project7-BioCrowds/node_modules/enhanced-resolve", + "author": { + "name": "Tobias Koppers @sokra" + }, + "bugs": { + "url": "https://github.com/webpack/memory-fs/issues" + }, + "dependencies": {}, + "description": "A simple in-memory filesystem. Holds data in a javascript object.", + "devDependencies": { + "istanbul": "^0.2.13", + "mocha": "^1.20.1", + "should": "^4.0.4" + }, + "directories": { + "test": "test" + }, + "dist": { + "shasum": "f2bb25368bc121e391c2520de92969caee0a0290", + "tarball": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.2.0.tgz" + }, + "gitHead": "b90785340f2adf4eed77c59bdda7742a51d16e5e", + "homepage": "https://github.com/webpack/memory-fs", + "keywords": [ + "fs", + "memory" + ], + "license": "MIT", + "main": "lib/MemoryFileSystem.js", + "maintainers": [ + { + "name": "sokra", + "email": "tobias.koppers@googlemail.com" + } + ], + "name": "memory-fs", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/webpack/memory-fs.git" + }, + "scripts": { + "cover": "istanbul cover node_modules/mocha/bin/_mocha -- -R spec", + "test": "mocha -R spec" + }, + "version": "0.2.0" +} diff --git a/node_modules/enhanced-resolve/node_modules/memory-fs/test/MemoryFileSystem.js b/node_modules/enhanced-resolve/node_modules/memory-fs/test/MemoryFileSystem.js new file mode 100644 index 00000000..49446181 --- /dev/null +++ b/node_modules/enhanced-resolve/node_modules/memory-fs/test/MemoryFileSystem.js @@ -0,0 +1,362 @@ +var should = require("should"); +var MemoryFileSystem = require("../lib/MemoryFileSystem"); + +describe("directory", function() { + it("should have a empty root directory as startup", function(done) { + var fs = new MemoryFileSystem(); + fs.readdirSync("/").should.be.eql([]); + var stat = fs.statSync("/"); + stat.isFile().should.be.eql(false); + stat.isDirectory().should.be.eql(true); + fs.readdir("/", function(err, files) { + if(err) throw err; + files.should.be.eql([]); + done(); + }); + }); + it("should make and remove directories (linux style)", function() { + var fs = new MemoryFileSystem(); + fs.mkdirSync("/test"); + fs.mkdirSync("/test//sub/"); + fs.mkdirpSync("/test/sub2"); + fs.mkdirSync("/root\\dir"); + fs.mkdirpSync("/"); + fs.mkdirSync("/"); + fs.readdirSync("/").should.be.eql(["test", "root\\dir"]); + fs.readdirSync("/test/").should.be.eql(["sub", "sub2"]); + fs.rmdirSync("/test/sub//"); + fs.readdirSync("//test").should.be.eql(["sub2"]); + fs.rmdirSync("/test/sub2"); + fs.rmdirSync("/test"); + (function() { + fs.readdirSync("/test"); + }).should.throw(); + fs.readdirSync("/").should.be.eql(["root\\dir"]); + fs.mkdirpSync("/a/depth/sub/dir"); + var stat = fs.statSync("/a/depth/sub"); + stat.isFile().should.be.eql(false); + stat.isDirectory().should.be.eql(true); + }); + it("should make and remove directories (windows style)", function() { + var fs = new MemoryFileSystem(); + fs.mkdirSync("C:\\"); + fs.mkdirSync("C:\\test"); + fs.mkdirSync("C:\\test\\\\sub/"); + fs.mkdirpSync("c:\\test/sub2"); + fs.mkdirSync("C:\\root-dir"); + fs.readdirSync("C:").should.be.eql(["test", "root-dir"]); + fs.readdirSync("C:/test/").should.be.eql(["sub", "sub2"]); + fs.rmdirSync("C:/test\\sub\\\\"); + fs.readdirSync("C:\\\\test").should.be.eql(["sub2"]); + fs.rmdirSync("C:\\test\\sub2"); + fs.rmdirSync("C:\\test"); + (function() { + fs.readdirSync("C:\\test"); + }).should.throw(); + fs.readdirSync("C:").should.be.eql(["root-dir"]); + fs.mkdirpSync("D:\\a\\depth\\sub\\dir"); + var stat = fs.statSync("D:\\a\\depth\\sub"); + stat.isFile().should.be.eql(false); + stat.isDirectory().should.be.eql(true); + fs.readdirSync("D:\\//a/depth/\\sub").should.be.eql(["dir"]); + }); +}); +describe("files", function() { + it("should make and remove files", function() { + var fs = new MemoryFileSystem(); + fs.mkdirSync("/test"); + var buf = new Buffer("Hello World", "utf-8"); + fs.writeFileSync("/test/hello-world.txt", buf); + fs.readFileSync("/test/hello-world.txt").should.be.eql(buf); + fs.readFileSync("/test/hello-world.txt", "utf-8").should.be.eql("Hello World"); + (function() { + fs.readFileSync("/test/other-file"); + }).should.throw(); + (function() { + fs.readFileSync("/test/other-file", "utf-8"); + }).should.throw(); + fs.writeFileSync("/a", "Test", "utf-8"); + fs.readFileSync("/a", "utf-8").should.be.eql("Test"); + var stat = fs.statSync("/a"); + stat.isFile().should.be.eql(true); + stat.isDirectory().should.be.eql(false); + }); +}); +describe("errors", function() { + it("should fail on invalid paths", function() { + var fs = new MemoryFileSystem(); + fs.mkdirpSync("/test/a/b/c"); + fs.mkdirpSync("/test/a/bc"); + fs.mkdirpSync("/test/abc"); + (function() { + fs.mkdirpSync("xyz"); + }).should.throw(); + (function() { + fs.readdirSync("/test/abc/a/b/c"); + }).should.throw(); + (function() { + fs.readdirSync("/abc"); + }).should.throw(); + (function() { + fs.statSync("/abc"); + }).should.throw(); + (function() { + fs.mkdirSync("/test/a/d/b/c"); + }).should.throw(); + (function() { + fs.writeFileSync("/test/a/d/b/c", "Hello"); + }).should.throw(); + (function() { + fs.readFileSync("/test/a/d/b/c"); + }).should.throw(); + (function() { + fs.readFileSync("/test/abcd"); + }).should.throw(); + (function() { + fs.mkdirSync("/test/abcd/dir"); + }).should.throw(); + (function() { + fs.unlinkSync("/test/abcd"); + }).should.throw(); + (function() { + fs.unlinkSync("/test/abcd/file"); + }).should.throw(); + (function() { + fs.statSync("/test/a/d/b/c"); + }).should.throw(); + (function() { + fs.statSync("/test/abcd"); + }).should.throw(); + fs.mkdir("/test/a/d/b/c", function(err) { + err.should.be.instanceof(Error); + }); + }); + it("should fail incorrect arguments", function() { + var fs = new MemoryFileSystem(); + (function() { + fs.writeFileSync("/test"); + }).should.throw(); + }); + it("should fail on wrong type", function() { + var fs = new MemoryFileSystem(); + fs.mkdirpSync("/test/dir"); + fs.mkdirpSync("/test/dir"); + fs.writeFileSync("/test/file", "Hello"); + (function() { + fs.writeFileSync("/test/dir", "Hello"); + }).should.throw(); + (function() { + fs.readFileSync("/test/dir"); + }).should.throw(); + (function() { + fs.writeFileSync("/", "Hello"); + }).should.throw(); + (function() { + fs.rmdirSync("/"); + }).should.throw(); + (function() { + fs.unlinkSync("/"); + }).should.throw(); + (function() { + fs.mkdirSync("/test/dir"); + }).should.throw(); + (function() { + fs.mkdirSync("/test/file"); + }).should.throw(); + (function() { + fs.mkdirpSync("/test/file"); + }).should.throw(); + (function() { + fs.readdirSync("/test/file"); + }).should.throw(); + fs.readdirSync("/test/").should.be.eql(["dir", "file"]); + }); + it("should throw on readlink", function() { + var fs = new MemoryFileSystem(); + fs.mkdirpSync("/test/dir"); + (function() { + fs.readlinkSync("/"); + }).should.throw(); + (function() { + fs.readlinkSync("/link"); + }).should.throw(); + (function() { + fs.readlinkSync("/test"); + }).should.throw(); + (function() { + fs.readlinkSync("/test/dir"); + }).should.throw(); + (function() { + fs.readlinkSync("/test/dir/link"); + }).should.throw(); + }); +}); +describe("async", function() { + it("should be able to use the async versions", function(done) { + var fs = new MemoryFileSystem(); + fs.mkdirp("/test/dir", function(err) { + if(err) throw err; + fs.writeFile("/test/dir/a", "Hello", function(err) { + if(err) throw err; + fs.writeFile("/test/dir/b", "World", "utf-8", function(err) { + if(err) throw err; + fs.readFile("/test/dir/a", "utf-8", function(err, content) { + if(err) throw err; + content.should.be.eql("Hello"); + fs.readFile("/test/dir/b", function(err, content) { + if(err) throw err; + content.should.be.eql(new Buffer("World")); + done(); + }); + }); + }); + }); + }); + }); + it("should return errors", function(done) { + var fs = new MemoryFileSystem(); + fs.readFile("/fail/file", function(err, content) { + err.should.be.instanceof(Error); + fs.writeFile("/fail/file", "", function(err) { + err.should.be.instanceof(Error); + done(); + }); + }); + }); +}); +describe("normalize", function() { + it("should normalize paths", function() { + var fs = new MemoryFileSystem(); + fs.normalize("/a/b/c").should.be.eql("/a/b/c"); + fs.normalize("/a//b/c").should.be.eql("/a/b/c"); + fs.normalize("/a//b//c").should.be.eql("/a/b/c"); + fs.normalize("//a//b//c").should.be.eql("/a/b/c"); + fs.normalize("/a/////b/c").should.be.eql("/a/b/c"); + fs.normalize("/./a/d///..////b/c").should.be.eql("/a/b/c"); + fs.normalize("/..").should.be.eql("/"); + fs.normalize("/.").should.be.eql("/"); + fs.normalize("/.git").should.be.eql("/.git"); + fs.normalize("/a/b/c/.git").should.be.eql("/a/b/c/.git"); + fs.normalize("/a/b/c/..git").should.be.eql("/a/b/c/..git"); + fs.normalize("/a/b/c/..").should.be.eql("/a/b"); + fs.normalize("/a/b/c/../..").should.be.eql("/a"); + fs.normalize("/a/b/c/../../..").should.be.eql("/"); + fs.normalize("C:\\a\\..").should.be.eql("C:\\"); + fs.normalize("C:\\a\\b\\..").should.be.eql("C:\\a"); + fs.normalize("C:\\a\\b\\\c\\..\\..").should.be.eql("C:\\a"); + fs.normalize("C:\\a\\b\\d\\..\\c\\..\\..").should.be.eql("C:\\a"); + fs.normalize("C:\\a\\b\\d\\\\.\\\\.\\c\\.\\..").should.be.eql("C:\\a\\b\\d"); + }); +}); +describe("join", function() { + it("should join paths", function() { + var fs = new MemoryFileSystem(); + fs.join("/", "a/b/c").should.be.eql("/a/b/c"); + fs.join("/a", "b/c").should.be.eql("/a/b/c"); + fs.join("/a/b", "c").should.be.eql("/a/b/c"); + fs.join("/a/", "b/c").should.be.eql("/a/b/c"); + fs.join("/a//", "b/c").should.be.eql("/a/b/c"); + fs.join("a", "b/c").should.be.eql("a/b/c"); + fs.join("a/b", "c").should.be.eql("a/b/c"); + fs.join("C:", "a/b").should.be.eql("C:\\a\\b"); + fs.join("C:\\", "a/b").should.be.eql("C:\\a\\b"); + fs.join("C:\\", "a\\b").should.be.eql("C:\\a\\b"); + }); + it("should join paths (weird cases)", function() { + var fs = new MemoryFileSystem(); + fs.join("/", "").should.be.eql("/"); + fs.join("/a/b/", "").should.be.eql("/a/b/"); + fs.join("/a/b/c", "").should.be.eql("/a/b/c"); + fs.join("C:", "").should.be.eql("C:"); + fs.join("C:\\a\\b", "").should.be.eql("C:\\a\\b"); + }); + it("should join paths (absolute request)", function() { + var fs = new MemoryFileSystem(); + fs.join("/a/b/c", "/d/e/f").should.be.eql("/d/e/f"); + fs.join("C:\\a\\b\\c", "/d/e/f").should.be.eql("/d/e/f"); + fs.join("/a/b/c", "C:\\d\\e\\f").should.be.eql("C:\\d\\e\\f"); + fs.join("C:\\a\\b\\c", "C:\\d\\e\\f").should.be.eql("C:\\d\\e\\f"); + }); +}); +describe("os", function() { + var fileSystem; + + beforeEach(function() { + fileSystem = new MemoryFileSystem({ + "": true, + a: { + "": true, + index: new Buffer("1"), // /a/index + dir: { + "": true, + index: new Buffer("2") // /a/dir/index + } + }, + "C:": { + "": true, + a: { + "": true, + index: new Buffer("3"), // C:\files\index + dir: { + "": true, + index: new Buffer("4") // C:\files\a\index + } + } + } + }); + }); + + describe("unix", function() { + it("should stat stuff", function() { + fileSystem.statSync("/a").isDirectory().should.be.eql(true); + fileSystem.statSync("/a").isFile().should.be.eql(false); + fileSystem.statSync("/a/index").isDirectory().should.be.eql(false); + fileSystem.statSync("/a/index").isFile().should.be.eql(true); + fileSystem.statSync("/a/dir").isDirectory().should.be.eql(true); + fileSystem.statSync("/a/dir").isFile().should.be.eql(false); + fileSystem.statSync("/a/dir/index").isDirectory().should.be.eql(false); + fileSystem.statSync("/a/dir/index").isFile().should.be.eql(true); + }); + it("should readdir directories", function() { + fileSystem.readdirSync("/a").should.be.eql(["index", "dir"]); + fileSystem.readdirSync("/a/dir").should.be.eql(["index"]); + }); + it("should readdir directories", function() { + fileSystem.readFileSync("/a/index", "utf-8").should.be.eql("1"); + fileSystem.readFileSync("/a/dir/index", "utf-8").should.be.eql("2"); + }); + it("should also accept multi slashs", function() { + fileSystem.statSync("/a///dir//index").isFile().should.be.eql(true); + }); + }); + + describe("windows", function() { + it("should stat stuff", function() { + fileSystem.statSync("C:\\a").isDirectory().should.be.eql(true); + fileSystem.statSync("C:\\a").isFile().should.be.eql(false); + fileSystem.statSync("C:\\a\\index").isDirectory().should.be.eql(false); + fileSystem.statSync("C:\\a\\index").isFile().should.be.eql(true); + fileSystem.statSync("C:\\a\\dir").isDirectory().should.be.eql(true); + fileSystem.statSync("C:\\a\\dir").isFile().should.be.eql(false); + fileSystem.statSync("C:\\a\\dir\\index").isDirectory().should.be.eql(false); + fileSystem.statSync("C:\\a\\dir\\index").isFile().should.be.eql(true); + }); + it("should readdir directories", function() { + fileSystem.readdirSync("C:\\a").should.be.eql(["index", "dir"]); + fileSystem.readdirSync("C:\\a\\dir").should.be.eql(["index"]); + }); + it("should readdir directories", function() { + fileSystem.readFileSync("C:\\a\\index", "utf-8").should.be.eql("3"); + fileSystem.readFileSync("C:\\a\\dir\\index", "utf-8").should.be.eql("4"); + }); + it("should also accept multi slashs", function() { + fileSystem.statSync("C:\\\\a\\\\\\dir\\\\index").isFile().should.be.eql(true); + }); + it("should also accept a normal slash", function() { + fileSystem.statSync("C:\\a\\dir/index").isFile().should.be.eql(true); + fileSystem.statSync("C:\\a\\dir\\index").isFile().should.be.eql(true); + fileSystem.statSync("C:\\a/dir/index").isFile().should.be.eql(true); + fileSystem.statSync("C:\\a/dir\\index").isFile().should.be.eql(true); + }); + }); +}); \ No newline at end of file diff --git a/node_modules/enhanced-resolve/package.json b/node_modules/enhanced-resolve/package.json new file mode 100644 index 00000000..9ead8999 --- /dev/null +++ b/node_modules/enhanced-resolve/package.json @@ -0,0 +1,99 @@ +{ + "_args": [ + [ + { + "raw": "enhanced-resolve@~0.9.0", + "scope": null, + "escapedName": "enhanced-resolve", + "name": "enhanced-resolve", + "rawSpec": "~0.9.0", + "spec": ">=0.9.0 <0.10.0", + "type": "range" + }, + "/Users/ericchiu/Desktop/CIS 700/HW7/Project7-BioCrowds/node_modules/webpack" + ] + ], + "_from": "enhanced-resolve@>=0.9.0 <0.10.0", + "_id": "enhanced-resolve@0.9.1", + "_inCache": true, + "_location": "/enhanced-resolve", + "_nodeVersion": "4.0.0", + "_npmUser": { + "name": "sokra", + "email": "tobias.koppers@googlemail.com" + }, + "_npmVersion": "3.3.3", + "_phantomChildren": {}, + "_requested": { + "raw": "enhanced-resolve@~0.9.0", + "scope": null, + "escapedName": "enhanced-resolve", + "name": "enhanced-resolve", + "rawSpec": "~0.9.0", + "spec": ">=0.9.0 <0.10.0", + "type": "range" + }, + "_requiredBy": [ + "/webpack" + ], + "_resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-0.9.1.tgz", + "_shasum": "4d6e689b3725f86090927ccc86cd9f1635b89e2e", + "_shrinkwrap": null, + "_spec": "enhanced-resolve@~0.9.0", + "_where": "/Users/ericchiu/Desktop/CIS 700/HW7/Project7-BioCrowds/node_modules/webpack", + "author": { + "name": "Tobias Koppers @sokra" + }, + "bugs": { + "url": "https://github.com/webpack/enhanced-resolve/issues" + }, + "dependencies": { + "graceful-fs": "^4.1.2", + "memory-fs": "^0.2.0", + "tapable": "^0.1.8" + }, + "description": "Offers a async require.resolve function. It's highly configurable.", + "devDependencies": { + "istanbul": "^0.3.5", + "mocha": "^2.1.0", + "should": "^4.6.0" + }, + "directories": {}, + "dist": { + "shasum": "4d6e689b3725f86090927ccc86cd9f1635b89e2e", + "tarball": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-0.9.1.tgz" + }, + "engines": { + "node": ">=0.6" + }, + "files": [ + "lib" + ], + "gitHead": "1d14a6debbe4054f84d7d7f870ca0a1cb963f75b", + "homepage": "http://github.com/webpack/enhanced-resolve", + "licenses": [ + { + "type": "MIT", + "url": "http://www.opensource.org/licenses/mit-license.php" + } + ], + "main": "lib/node.js", + "maintainers": [ + { + "name": "sokra", + "email": "tobias.koppers@googlemail.com" + } + ], + "name": "enhanced-resolve", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/webpack/enhanced-resolve.git" + }, + "scripts": { + "cover": "istanbul cover node_modules/mocha/bin/_mocha -- -R spec", + "test": "mocha --reporter spec" + }, + "version": "0.9.1" +} diff --git a/node_modules/errno/.jshintrc b/node_modules/errno/.jshintrc new file mode 100644 index 00000000..c8ef3ca4 --- /dev/null +++ b/node_modules/errno/.jshintrc @@ -0,0 +1,59 @@ +{ + "predef": [ ] + , "bitwise": false + , "camelcase": false + , "curly": false + , "eqeqeq": false + , "forin": false + , "immed": false + , "latedef": false + , "noarg": true + , "noempty": true + , "nonew": true + , "plusplus": false + , "quotmark": true + , "regexp": false + , "undef": true + , "unused": true + , "strict": false + , "trailing": true + , "maxlen": 120 + , "asi": true + , "boss": true + , "debug": true + , "eqnull": true + , "esnext": true + , "evil": true + , "expr": true + , "funcscope": false + , "globalstrict": false + , "iterator": false + , "lastsemic": true + , "laxbreak": true + , "laxcomma": true + , "loopfunc": true + , "multistr": false + , "onecase": false + , "proto": false + , "regexdash": false + , "scripturl": true + , "smarttabs": false + , "shadow": false + , "sub": true + , "supernew": false + , "validthis": true + , "browser": true + , "couch": false + , "devel": false + , "dojo": false + , "mootools": false + , "node": true + , "nonstandard": true + , "prototypejs": false + , "rhino": false + , "worker": true + , "wsh": false + , "nomen": false + , "onevar": false + , "passfail": false +} \ No newline at end of file diff --git a/node_modules/errno/.npmignore b/node_modules/errno/.npmignore new file mode 100644 index 00000000..b512c09d --- /dev/null +++ b/node_modules/errno/.npmignore @@ -0,0 +1 @@ +node_modules \ No newline at end of file diff --git a/node_modules/errno/README.md b/node_modules/errno/README.md new file mode 100644 index 00000000..2c1f8a52 --- /dev/null +++ b/node_modules/errno/README.md @@ -0,0 +1,141 @@ +# node-errno + +Better [libuv](https://github.com/libuv/libuv)/[Node.js](https://nodejs.org)/[io.js](https://iojs.org) error handling & reporting. Available in npm as *errno*. + +* [errno exposed](#errnoexposed) +* [Custom errors](#customerrors) + + +## errno exposed + +Ever find yourself needing more details about Node.js errors? Me too, so *node-errno* contains the errno mappings direct from libuv so you can use them in your code. + +**By errno:** + +```js +require('errno').errno[3] +// → { +// "errno": 3, +// "code": "EACCES", +// "description": "permission denied" +// } +``` + +**By code:** + +```js +require('errno').code.ENOTEMPTY +// → { +// "errno": 53, +// "code": "ENOTEMPTY", +// "description": "directory not empty" +// } +``` + +**Make your errors more descriptive:** + +```js +var errno = require('errno') + +function errmsg(err) { + var str = 'Error: ' + // if it's a libuv error then get the description from errno + if (errno.errno[err.errno]) + str += errno.errno[err.errno].description + else + str += err.message + + // if it's a `fs` error then it'll have a 'path' property + if (err.path) + str += ' [' + err.path + ']' + + return str +} + +var fs = require('fs') + +fs.readFile('thisisnotarealfile.txt', function (err, data) { + if (err) + console.log(errmsg(err)) +}) +``` + +**Use as a command line tool:** + +``` +~ $ errno 53 +{ + "errno": 53, + "code": "ENOTEMPTY", + "description": "directory not empty" +} +~ $ errno EROFS +{ + "errno": 56, + "code": "EROFS", + "description": "read-only file system" +} +~ $ errno foo +No such errno/code: "foo" +``` + +Supply no arguments for the full list. Error codes are processed case-insensitive. + +You will need to install with `npm install errno -g` if you want the `errno` command to be available without supplying a full path to the node_modules installation. + + +## Custom errors + +Use `errno.custom.createError()` to create custom `Error` objects to throw around in your Node.js library. Create error heirachies so `instanceof` becomes a useful tool in tracking errors. Call-stack is correctly captured at the time you create an instance of the error object, plus a `cause` property will make available the original error object if you pass one in to the constructor. + +```js +var create = require('errno').custom.createError +var MyError = create('MyError') // inherits from Error +var SpecificError = create('SpecificError', MyError) // inherits from MyError +var OtherError = create('OtherError', MyError) + +// use them! +if (condition) throw new SpecificError('Eeek! Something bad happened') + +if (err) return callback(new OtherError(err)) +``` + +Also available is a `errno.custom.FilesystemError` with in-built access to errno properties: + +```js +fs.readFile('foo', function (err, data) { + if (err) return callback(new errno.custom.FilesystemError(err)) + // do something else +}) +``` + +The resulting error object passed through the callback will have the following properties: `code`, `errno`, `path` and `message` will contain a descriptive human-readable message. + +## Contributors + +* [bahamas10](https://github.com/bahamas10) (Dave Eddy) - Added CLI +* [ralphtheninja](https://github.com/ralphtheninja) (Lars-Magnus Skog) + +## Copyright & Licence + +*Copyright (c) 2012-2015 [Rod Vagg](https://github.com/rvagg) ([@rvagg](https://twitter.com/rvagg))* + +Made available under the MIT licence: + +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. \ No newline at end of file diff --git a/node_modules/errno/build.js b/node_modules/errno/build.js new file mode 100755 index 00000000..fce89260 --- /dev/null +++ b/node_modules/errno/build.js @@ -0,0 +1,43 @@ +#!/usr/bin/env node + +var request = require('request') + , fs = require('fs') + + , uvheadloc = 'https://raw.github.com/joyent/libuv/master/include/uv.h' + , defreg = /^\s*XX\(\s*([\-\d]+),\s*([A-Z]+),\s*"([^"]*)"\s*\)\s*\\?$/ + + +request(uvheadloc, function (err, response) { + if (err) + throw err + + var data, out + + data = response.body + .split('\n') + .map(function (line) { return line.match(defreg) }) + .filter(function (match) { return match }) + .map(function (match) { return { + errno: parseInt(match[1], 10) + , code: match[2] + , description: match[3] + }}) + + out = 'var all = module.exports.all = ' + JSON.stringify(data, 0, 1) + '\n\n' + + out += '\nmodule.exports.errno = {\n ' + + data.map(function (e, i) { + return '\'' + e.errno + '\': all[' + i + ']' + }).join('\n , ') + + '\n}\n\n' + + out += '\nmodule.exports.code = {\n ' + + data.map(function (e, i) { + return '\'' + e.code + '\': all[' + i + ']' + }).join('\n , ') + + '\n}\n\n' + + out += '\nmodule.exports.custom = require("./custom")(module.exports)\n' + + fs.writeFile('errno.js', out) +}) \ No newline at end of file diff --git a/node_modules/errno/cli.js b/node_modules/errno/cli.js new file mode 100755 index 00000000..f841771b --- /dev/null +++ b/node_modules/errno/cli.js @@ -0,0 +1,20 @@ +#!/usr/bin/env node + +var errno = require('./') + , arg = process.argv[2] + , data, code + +if (arg === undefined) + return console.log(JSON.stringify(errno.code, null, 2)) + +if ((code = +arg) == arg) + data = errno.errno[code] +else + data = errno.code[arg] || errno.code[arg.toUpperCase()] + +if (data) + console.log(JSON.stringify(data, null, 2)) +else { + console.error('No such errno/code: "' + arg + '"') + process.exit(1) +} \ No newline at end of file diff --git a/node_modules/errno/custom.js b/node_modules/errno/custom.js new file mode 100644 index 00000000..7be16c1e --- /dev/null +++ b/node_modules/errno/custom.js @@ -0,0 +1,55 @@ +var prr = require('prr') + +function init (type, message, cause) { + prr(this, { + type : type + , name : type + // can be passed just a 'cause' + , cause : typeof message != 'string' ? message : cause + , message : !!message && typeof message != 'string' ? message.message : message + + }, 'ewr') +} + +// generic prototype, not intended to be actually used - helpful for `instanceof` +function CustomError (message, cause) { + Error.call(this) + if (Error.captureStackTrace) + Error.captureStackTrace(this, arguments.callee) + init.call(this, 'CustomError', message, cause) +} + +CustomError.prototype = new Error() + +function createError (errno, type, proto) { + var err = function (message, cause) { + init.call(this, type, message, cause) + //TODO: the specificity here is stupid, errno should be available everywhere + if (type == 'FilesystemError') { + this.code = this.cause.code + this.path = this.cause.path + this.errno = this.cause.errno + this.message = + (errno.errno[this.cause.errno] + ? errno.errno[this.cause.errno].description + : this.cause.message) + + (this.cause.path ? ' [' + this.cause.path + ']' : '') + } + Error.call(this) + if (Error.captureStackTrace) + Error.captureStackTrace(this, arguments.callee) + } + err.prototype = !!proto ? new proto() : new CustomError() + return err +} + +module.exports = function (errno) { + var ce = function (type, proto) { + return createError(errno, type, proto) + } + return { + CustomError : CustomError + , FilesystemError : ce('FilesystemError') + , createError : ce + } +} diff --git a/node_modules/errno/errno.js b/node_modules/errno/errno.js new file mode 100644 index 00000000..efb79d41 --- /dev/null +++ b/node_modules/errno/errno.js @@ -0,0 +1,313 @@ +var all = module.exports.all = [ + { + errno: -2, + code: 'ENOENT', + description: 'no such file or directory' + }, + { + errno: -1, + code: 'UNKNOWN', + description: 'unknown error' + }, + { + errno: 0, + code: 'OK', + description: 'success' + }, + { + errno: 1, + code: 'EOF', + description: 'end of file' + }, + { + errno: 2, + code: 'EADDRINFO', + description: 'getaddrinfo error' + }, + { + errno: 3, + code: 'EACCES', + description: 'permission denied' + }, + { + errno: 4, + code: 'EAGAIN', + description: 'resource temporarily unavailable' + }, + { + errno: 5, + code: 'EADDRINUSE', + description: 'address already in use' + }, + { + errno: 6, + code: 'EADDRNOTAVAIL', + description: 'address not available' + }, + { + errno: 7, + code: 'EAFNOSUPPORT', + description: 'address family not supported' + }, + { + errno: 8, + code: 'EALREADY', + description: 'connection already in progress' + }, + { + errno: 9, + code: 'EBADF', + description: 'bad file descriptor' + }, + { + errno: 10, + code: 'EBUSY', + description: 'resource busy or locked' + }, + { + errno: 11, + code: 'ECONNABORTED', + description: 'software caused connection abort' + }, + { + errno: 12, + code: 'ECONNREFUSED', + description: 'connection refused' + }, + { + errno: 13, + code: 'ECONNRESET', + description: 'connection reset by peer' + }, + { + errno: 14, + code: 'EDESTADDRREQ', + description: 'destination address required' + }, + { + errno: 15, + code: 'EFAULT', + description: 'bad address in system call argument' + }, + { + errno: 16, + code: 'EHOSTUNREACH', + description: 'host is unreachable' + }, + { + errno: 17, + code: 'EINTR', + description: 'interrupted system call' + }, + { + errno: 18, + code: 'EINVAL', + description: 'invalid argument' + }, + { + errno: 19, + code: 'EISCONN', + description: 'socket is already connected' + }, + { + errno: 20, + code: 'EMFILE', + description: 'too many open files' + }, + { + errno: 21, + code: 'EMSGSIZE', + description: 'message too long' + }, + { + errno: 22, + code: 'ENETDOWN', + description: 'network is down' + }, + { + errno: 23, + code: 'ENETUNREACH', + description: 'network is unreachable' + }, + { + errno: 24, + code: 'ENFILE', + description: 'file table overflow' + }, + { + errno: 25, + code: 'ENOBUFS', + description: 'no buffer space available' + }, + { + errno: 26, + code: 'ENOMEM', + description: 'not enough memory' + }, + { + errno: 27, + code: 'ENOTDIR', + description: 'not a directory' + }, + { + errno: 28, + code: 'EISDIR', + description: 'illegal operation on a directory' + }, + { + errno: 29, + code: 'ENONET', + description: 'machine is not on the network' + }, + { + errno: 31, + code: 'ENOTCONN', + description: 'socket is not connected' + }, + { + errno: 32, + code: 'ENOTSOCK', + description: 'socket operation on non-socket' + }, + { + errno: 33, + code: 'ENOTSUP', + description: 'operation not supported on socket' + }, + { + errno: 34, + code: 'ENOENT', + description: 'no such file or directory' + }, + { + errno: 35, + code: 'ENOSYS', + description: 'function not implemented' + }, + { + errno: 36, + code: 'EPIPE', + description: 'broken pipe' + }, + { + errno: 37, + code: 'EPROTO', + description: 'protocol error' + }, + { + errno: 38, + code: 'EPROTONOSUPPORT', + description: 'protocol not supported' + }, + { + errno: 39, + code: 'EPROTOTYPE', + description: 'protocol wrong type for socket' + }, + { + errno: 40, + code: 'ETIMEDOUT', + description: 'connection timed out' + }, + { + errno: 41, + code: 'ECHARSET', + description: 'invalid Unicode character' + }, + { + errno: 42, + code: 'EAIFAMNOSUPPORT', + description: 'address family for hostname not supported' + }, + { + errno: 44, + code: 'EAISERVICE', + description: 'servname not supported for ai_socktype' + }, + { + errno: 45, + code: 'EAISOCKTYPE', + description: 'ai_socktype not supported' + }, + { + errno: 46, + code: 'ESHUTDOWN', + description: 'cannot send after transport endpoint shutdown' + }, + { + errno: 47, + code: 'EEXIST', + description: 'file already exists' + }, + { + errno: 48, + code: 'ESRCH', + description: 'no such process' + }, + { + errno: 49, + code: 'ENAMETOOLONG', + description: 'name too long' + }, + { + errno: 50, + code: 'EPERM', + description: 'operation not permitted' + }, + { + errno: 51, + code: 'ELOOP', + description: 'too many symbolic links encountered' + }, + { + errno: 52, + code: 'EXDEV', + description: 'cross-device link not permitted' + }, + { + errno: 53, + code: 'ENOTEMPTY', + description: 'directory not empty' + }, + { + errno: 54, + code: 'ENOSPC', + description: 'no space left on device' + }, + { + errno: 55, + code: 'EIO', + description: 'i/o error' + }, + { + errno: 56, + code: 'EROFS', + description: 'read-only file system' + }, + { + errno: 57, + code: 'ENODEV', + description: 'no such device' + }, + { + errno: 58, + code: 'ESPIPE', + description: 'invalid seek' + }, + { + errno: 59, + code: 'ECANCELED', + description: 'operation canceled' + } +] + +module.exports.errno = {} +module.exports.code = {} + +all.forEach(function (error) { + module.exports.errno[error.errno] = error + module.exports.code[error.code] = error +}) + +module.exports.custom = require('./custom')(module.exports) +module.exports.create = module.exports.custom.createError diff --git a/node_modules/errno/package.json b/node_modules/errno/package.json new file mode 100644 index 00000000..148fb418 --- /dev/null +++ b/node_modules/errno/package.json @@ -0,0 +1,92 @@ +{ + "_args": [ + [ + { + "raw": "errno@^0.1.3", + "scope": null, + "escapedName": "errno", + "name": "errno", + "rawSpec": "^0.1.3", + "spec": ">=0.1.3 <0.2.0", + "type": "range" + }, + "/Users/ericchiu/Desktop/CIS 700/HW7/Project7-BioCrowds/node_modules/memory-fs" + ] + ], + "_from": "errno@>=0.1.3 <0.2.0", + "_id": "errno@0.1.4", + "_inCache": true, + "_location": "/errno", + "_nodeVersion": "3.0.0", + "_npmUser": { + "name": "rvagg", + "email": "rod@vagg.org" + }, + "_npmVersion": "2.13.3", + "_phantomChildren": {}, + "_requested": { + "raw": "errno@^0.1.3", + "scope": null, + "escapedName": "errno", + "name": "errno", + "rawSpec": "^0.1.3", + "spec": ">=0.1.3 <0.2.0", + "type": "range" + }, + "_requiredBy": [ + "/memory-fs", + "/webpack-dev-middleware/memory-fs" + ], + "_resolved": "https://registry.npmjs.org/errno/-/errno-0.1.4.tgz", + "_shasum": "b896e23a9e5e8ba33871fc996abd3635fc9a1c7d", + "_shrinkwrap": null, + "_spec": "errno@^0.1.3", + "_where": "/Users/ericchiu/Desktop/CIS 700/HW7/Project7-BioCrowds/node_modules/memory-fs", + "authors": [ + "Rod Vagg @rvaggsome html
'); + * + * @param {string|number|boolean|object|Buffer} body + * @public + */ + +res.send = function send(body) { + var chunk = body; + var encoding; + var len; + var req = this.req; + var type; + + // settings + var app = this.app; + + // allow status / body + if (arguments.length === 2) { + // res.send(body, status) backwards compat + if (typeof arguments[0] !== 'number' && typeof arguments[1] === 'number') { + deprecate('res.send(body, status): Use res.status(status).send(body) instead'); + this.statusCode = arguments[1]; + } else { + deprecate('res.send(status, body): Use res.status(status).send(body) instead'); + this.statusCode = arguments[0]; + chunk = arguments[1]; + } + } + + // disambiguate res.send(status) and res.send(status, num) + if (typeof chunk === 'number' && arguments.length === 1) { + // res.send(status) will set status message as text string + if (!this.get('Content-Type')) { + this.type('txt'); + } + + deprecate('res.send(status): Use res.sendStatus(status) instead'); + this.statusCode = chunk; + chunk = statuses[chunk] + } + + switch (typeof chunk) { + // string defaulting to html + case 'string': + if (!this.get('Content-Type')) { + this.type('html'); + } + break; + case 'boolean': + case 'number': + case 'object': + if (chunk === null) { + chunk = ''; + } else if (Buffer.isBuffer(chunk)) { + if (!this.get('Content-Type')) { + this.type('bin'); + } + } else { + return this.json(chunk); + } + break; + } + + // write strings in utf-8 + if (typeof chunk === 'string') { + encoding = 'utf8'; + type = this.get('Content-Type'); + + // reflect this in content-type + if (typeof type === 'string') { + this.set('Content-Type', setCharset(type, 'utf-8')); + } + } + + // populate Content-Length + if (chunk !== undefined) { + if (!Buffer.isBuffer(chunk)) { + // convert chunk to Buffer; saves later double conversions + chunk = new Buffer(chunk, encoding); + encoding = undefined; + } + + len = chunk.length; + this.set('Content-Length', len); + } + + // populate ETag + var etag; + var generateETag = len !== undefined && app.get('etag fn'); + if (typeof generateETag === 'function' && !this.get('ETag')) { + if ((etag = generateETag(chunk, encoding))) { + this.set('ETag', etag); + } + } + + // freshness + if (req.fresh) this.statusCode = 304; + + // strip irrelevant headers + if (204 === this.statusCode || 304 === this.statusCode) { + this.removeHeader('Content-Type'); + this.removeHeader('Content-Length'); + this.removeHeader('Transfer-Encoding'); + chunk = ''; + } + + if (req.method === 'HEAD') { + // skip body for HEAD + this.end(); + } else { + // respond + this.end(chunk, encoding); + } + + return this; +}; + +/** + * Send JSON response. + * + * Examples: + * + * res.json(null); + * res.json({ user: 'tj' }); + * + * @param {string|number|boolean|object} obj + * @public + */ + +res.json = function json(obj) { + var val = obj; + + // allow status / body + if (arguments.length === 2) { + // res.json(body, status) backwards compat + if (typeof arguments[1] === 'number') { + deprecate('res.json(obj, status): Use res.status(status).json(obj) instead'); + this.statusCode = arguments[1]; + } else { + deprecate('res.json(status, obj): Use res.status(status).json(obj) instead'); + this.statusCode = arguments[0]; + val = arguments[1]; + } + } + + // settings + var app = this.app; + var replacer = app.get('json replacer'); + var spaces = app.get('json spaces'); + var body = stringify(val, replacer, spaces); + + // content-type + if (!this.get('Content-Type')) { + this.set('Content-Type', 'application/json'); + } + + return this.send(body); +}; + +/** + * Send JSON response with JSONP callback support. + * + * Examples: + * + * res.jsonp(null); + * res.jsonp({ user: 'tj' }); + * + * @param {string|number|boolean|object} obj + * @public + */ + +res.jsonp = function jsonp(obj) { + var val = obj; + + // allow status / body + if (arguments.length === 2) { + // res.json(body, status) backwards compat + if (typeof arguments[1] === 'number') { + deprecate('res.jsonp(obj, status): Use res.status(status).json(obj) instead'); + this.statusCode = arguments[1]; + } else { + deprecate('res.jsonp(status, obj): Use res.status(status).jsonp(obj) instead'); + this.statusCode = arguments[0]; + val = arguments[1]; + } + } + + // settings + var app = this.app; + var replacer = app.get('json replacer'); + var spaces = app.get('json spaces'); + var body = stringify(val, replacer, spaces); + var callback = this.req.query[app.get('jsonp callback name')]; + + // content-type + if (!this.get('Content-Type')) { + this.set('X-Content-Type-Options', 'nosniff'); + this.set('Content-Type', 'application/json'); + } + + // fixup callback + if (Array.isArray(callback)) { + callback = callback[0]; + } + + // jsonp + if (typeof callback === 'string' && callback.length !== 0) { + this.charset = 'utf-8'; + this.set('X-Content-Type-Options', 'nosniff'); + this.set('Content-Type', 'text/javascript'); + + // restrict callback charset + callback = callback.replace(/[^\[\]\w$.]/g, ''); + + // replace chars not allowed in JavaScript that are in JSON + body = body + .replace(/\u2028/g, '\\u2028') + .replace(/\u2029/g, '\\u2029'); + + // the /**/ is a specific security mitigation for "Rosetta Flash JSONP abuse" + // the typeof check is just to reduce client error noise + body = '/**/ typeof ' + callback + ' === \'function\' && ' + callback + '(' + body + ');'; + } + + return this.send(body); +}; + +/** + * Send given HTTP status code. + * + * Sets the response status to `statusCode` and the body of the + * response to the standard description from node's http.STATUS_CODES + * or the statusCode number if no description. + * + * Examples: + * + * res.sendStatus(200); + * + * @param {number} statusCode + * @public + */ + +res.sendStatus = function sendStatus(statusCode) { + var body = statuses[statusCode] || String(statusCode) + + this.statusCode = statusCode; + this.type('txt'); + + return this.send(body); +}; + +/** + * Transfer the file at the given `path`. + * + * Automatically sets the _Content-Type_ response header field. + * The callback `callback(err)` is invoked when the transfer is complete + * or when an error occurs. Be sure to check `res.sentHeader` + * if you wish to attempt responding, as the header and some data + * may have already been transferred. + * + * Options: + * + * - `maxAge` defaulting to 0 (can be string converted by `ms`) + * - `root` root directory for relative filenames + * - `headers` object of headers to serve with file + * - `dotfiles` serve dotfiles, defaulting to false; can be `"allow"` to send them + * + * Other options are passed along to `send`. + * + * Examples: + * + * The following example illustrates how `res.sendFile()` may + * be used as an alternative for the `static()` middleware for + * dynamic situations. The code backing `res.sendFile()` is actually + * the same code, so HTTP cache support etc is identical. + * + * app.get('/user/:uid/photos/:file', function(req, res){ + * var uid = req.params.uid + * , file = req.params.file; + * + * req.user.mayViewFilesFrom(uid, function(yes){ + * if (yes) { + * res.sendFile('/uploads/' + uid + '/' + file); + * } else { + * res.send(403, 'Sorry! you cant see that.'); + * } + * }); + * }); + * + * @public + */ + +res.sendFile = function sendFile(path, options, callback) { + var done = callback; + var req = this.req; + var res = this; + var next = req.next; + var opts = options || {}; + + if (!path) { + throw new TypeError('path argument is required to res.sendFile'); + } + + // support function as second arg + if (typeof options === 'function') { + done = options; + opts = {}; + } + + if (!opts.root && !isAbsolute(path)) { + throw new TypeError('path must be absolute or specify root to res.sendFile'); + } + + // create file stream + var pathname = encodeURI(path); + var file = send(req, pathname, opts); + + // transfer + sendfile(res, file, opts, function (err) { + if (done) return done(err); + if (err && err.code === 'EISDIR') return next(); + + // next() all but write errors + if (err && err.code !== 'ECONNABORTED' && err.syscall !== 'write') { + next(err); + } + }); +}; + +/** + * Transfer the file at the given `path`. + * + * Automatically sets the _Content-Type_ response header field. + * The callback `callback(err)` is invoked when the transfer is complete + * or when an error occurs. Be sure to check `res.sentHeader` + * if you wish to attempt responding, as the header and some data + * may have already been transferred. + * + * Options: + * + * - `maxAge` defaulting to 0 (can be string converted by `ms`) + * - `root` root directory for relative filenames + * - `headers` object of headers to serve with file + * - `dotfiles` serve dotfiles, defaulting to false; can be `"allow"` to send them + * + * Other options are passed along to `send`. + * + * Examples: + * + * The following example illustrates how `res.sendfile()` may + * be used as an alternative for the `static()` middleware for + * dynamic situations. The code backing `res.sendfile()` is actually + * the same code, so HTTP cache support etc is identical. + * + * app.get('/user/:uid/photos/:file', function(req, res){ + * var uid = req.params.uid + * , file = req.params.file; + * + * req.user.mayViewFilesFrom(uid, function(yes){ + * if (yes) { + * res.sendfile('/uploads/' + uid + '/' + file); + * } else { + * res.send(403, 'Sorry! you cant see that.'); + * } + * }); + * }); + * + * @public + */ + +res.sendfile = function (path, options, callback) { + var done = callback; + var req = this.req; + var res = this; + var next = req.next; + var opts = options || {}; + + // support function as second arg + if (typeof options === 'function') { + done = options; + opts = {}; + } + + // create file stream + var file = send(req, path, opts); + + // transfer + sendfile(res, file, opts, function (err) { + if (done) return done(err); + if (err && err.code === 'EISDIR') return next(); + + // next() all but write errors + if (err && err.code !== 'ECONNABORT' && err.syscall !== 'write') { + next(err); + } + }); +}; + +res.sendfile = deprecate.function(res.sendfile, + 'res.sendfile: Use res.sendFile instead'); + +/** + * Transfer the file at the given `path` as an attachment. + * + * Optionally providing an alternate attachment `filename`, + * and optional callback `callback(err)`. The callback is invoked + * when the data transfer is complete, or when an error has + * ocurred. Be sure to check `res.headersSent` if you plan to respond. + * + * This method uses `res.sendfile()`. + * + * @public + */ + +res.download = function download(path, filename, callback) { + var done = callback; + var name = filename; + + // support function as second arg + if (typeof filename === 'function') { + done = filename; + name = null; + } + + // set Content-Disposition when file is sent + var headers = { + 'Content-Disposition': contentDisposition(name || path) + }; + + // Resolve the full path for sendFile + var fullPath = resolve(path); + + return this.sendFile(fullPath, { headers: headers }, done); +}; + +/** + * Set _Content-Type_ response header with `type` through `mime.lookup()` + * when it does not contain "/", or set the Content-Type to `type` otherwise. + * + * Examples: + * + * res.type('.html'); + * res.type('html'); + * res.type('json'); + * res.type('application/json'); + * res.type('png'); + * + * @param {String} type + * @return {ServerResponse} for chaining + * @public + */ + +res.contentType = +res.type = function contentType(type) { + var ct = type.indexOf('/') === -1 + ? mime.lookup(type) + : type; + + return this.set('Content-Type', ct); +}; + +/** + * Respond to the Acceptable formats using an `obj` + * of mime-type callbacks. + * + * This method uses `req.accepted`, an array of + * acceptable types ordered by their quality values. + * When "Accept" is not present the _first_ callback + * is invoked, otherwise the first match is used. When + * no match is performed the server responds with + * 406 "Not Acceptable". + * + * Content-Type is set for you, however if you choose + * you may alter this within the callback using `res.type()` + * or `res.set('Content-Type', ...)`. + * + * res.format({ + * 'text/plain': function(){ + * res.send('hey'); + * }, + * + * 'text/html': function(){ + * res.send('hey
'); + * }, + * + * 'appliation/json': function(){ + * res.send({ message: 'hey' }); + * } + * }); + * + * In addition to canonicalized MIME types you may + * also use extnames mapped to these types: + * + * res.format({ + * text: function(){ + * res.send('hey'); + * }, + * + * html: function(){ + * res.send('hey
'); + * }, + * + * json: function(){ + * res.send({ message: 'hey' }); + * } + * }); + * + * By default Express passes an `Error` + * with a `.status` of 406 to `next(err)` + * if a match is not made. If you provide + * a `.default` callback it will be invoked + * instead. + * + * @param {Object} obj + * @return {ServerResponse} for chaining + * @public + */ + +res.format = function(obj){ + var req = this.req; + var next = req.next; + + var fn = obj.default; + if (fn) delete obj.default; + var keys = Object.keys(obj); + + var key = keys.length > 0 + ? req.accepts(keys) + : false; + + this.vary("Accept"); + + if (key) { + this.set('Content-Type', normalizeType(key).value); + obj[key](req, this, next); + } else if (fn) { + fn(); + } else { + var err = new Error('Not Acceptable'); + err.status = err.statusCode = 406; + err.types = normalizeTypes(keys).map(function(o){ return o.value }); + next(err); + } + + return this; +}; + +/** + * Set _Content-Disposition_ header to _attachment_ with optional `filename`. + * + * @param {String} filename + * @return {ServerResponse} + * @public + */ + +res.attachment = function attachment(filename) { + if (filename) { + this.type(extname(filename)); + } + + this.set('Content-Disposition', contentDisposition(filename)); + + return this; +}; + +/** + * Append additional header `field` with value `val`. + * + * Example: + * + * res.append('Link', ['' + statuses[status] + '. Redirecting to ' + u + '
' + }, + + default: function(){ + body = ''; + } + }); + + // Respond + this.statusCode = status; + this.set('Content-Length', Buffer.byteLength(body)); + + if (this.req.method === 'HEAD') { + this.end(); + } else { + this.end(body); + } +}; + +/** + * Add `field` to Vary. If already present in the Vary set, then + * this call is simply ignored. + * + * @param {Array|String} field + * @return {ServerResponse} for chaining + * @public + */ + +res.vary = function(field){ + // checks for back-compat + if (!field || (Array.isArray(field) && !field.length)) { + deprecate('res.vary(): Provide a field name'); + return this; + } + + vary(this, field); + + return this; +}; + +/** + * Render `view` with the given `options` and optional callback `fn`. + * When a callback function is given a response will _not_ be made + * automatically, otherwise a response of _200_ and _text/html_ is given. + * + * Options: + * + * - `cache` boolean hinting to the engine it should cache + * - `filename` filename of the view being rendered + * + * @public + */ + +res.render = function render(view, options, callback) { + var app = this.req.app; + var done = callback; + var opts = options || {}; + var req = this.req; + var self = this; + + // support callback function as second arg + if (typeof options === 'function') { + done = options; + opts = {}; + } + + // merge res.locals + opts._locals = self.locals; + + // default callback to respond + done = done || function (err, str) { + if (err) return req.next(err); + self.send(str); + }; + + // render + app.render(view, opts, done); +}; + +// pipe the send file stream +function sendfile(res, file, options, callback) { + var done = false; + var streaming; + + // request aborted + function onaborted() { + if (done) return; + done = true; + + var err = new Error('Request aborted'); + err.code = 'ECONNABORTED'; + callback(err); + } + + // directory + function ondirectory() { + if (done) return; + done = true; + + var err = new Error('EISDIR, read'); + err.code = 'EISDIR'; + callback(err); + } + + // errors + function onerror(err) { + if (done) return; + done = true; + callback(err); + } + + // ended + function onend() { + if (done) return; + done = true; + callback(); + } + + // file + function onfile() { + streaming = false; + } + + // finished + function onfinish(err) { + if (err && err.code === 'ECONNRESET') return onaborted(); + if (err) return onerror(err); + if (done) return; + + setImmediate(function () { + if (streaming !== false && !done) { + onaborted(); + return; + } + + if (done) return; + done = true; + callback(); + }); + } + + // streaming + function onstream() { + streaming = true; + } + + file.on('directory', ondirectory); + file.on('end', onend); + file.on('error', onerror); + file.on('file', onfile); + file.on('stream', onstream); + onFinished(res, onfinish); + + if (options.headers) { + // set headers on successful transfer + file.on('headers', function headers(res) { + var obj = options.headers; + var keys = Object.keys(obj); + + for (var i = 0; i < keys.length; i++) { + var k = keys[i]; + res.setHeader(k, obj[k]); + } + }); + } + + // pipe + file.pipe(res); +} + +/** + * Stringify JSON, like JSON.stringify, but v8 optimized. + * @private + */ + +function stringify(value, replacer, spaces) { + // v8 checks arguments.length for optimizing simple call + // https://bugs.chromium.org/p/v8/issues/detail?id=4730 + return replacer || spaces + ? JSON.stringify(value, replacer, spaces) + : JSON.stringify(value); +} diff --git a/node_modules/express/lib/router/index.js b/node_modules/express/lib/router/index.js new file mode 100644 index 00000000..51db4c28 --- /dev/null +++ b/node_modules/express/lib/router/index.js @@ -0,0 +1,662 @@ +/*! + * express + * Copyright(c) 2009-2013 TJ Holowaychuk + * Copyright(c) 2013 Roman Shtylman + * Copyright(c) 2014-2015 Douglas Christopher Wilson + * MIT Licensed + */ + +'use strict'; + +/** + * Module dependencies. + * @private + */ + +var Route = require('./route'); +var Layer = require('./layer'); +var methods = require('methods'); +var mixin = require('utils-merge'); +var debug = require('debug')('express:router'); +var deprecate = require('depd')('express'); +var flatten = require('array-flatten'); +var parseUrl = require('parseurl'); +var setPrototypeOf = require('setprototypeof') + +/** + * Module variables. + * @private + */ + +var objectRegExp = /^\[object (\S+)\]$/; +var slice = Array.prototype.slice; +var toString = Object.prototype.toString; + +/** + * Initialize a new `Router` with the given `options`. + * + * @param {Object} options + * @return {Router} which is an callable function + * @public + */ + +var proto = module.exports = function(options) { + var opts = options || {}; + + function router(req, res, next) { + router.handle(req, res, next); + } + + // mixin Router class functions + setPrototypeOf(router, proto) + + router.params = {}; + router._params = []; + router.caseSensitive = opts.caseSensitive; + router.mergeParams = opts.mergeParams; + router.strict = opts.strict; + router.stack = []; + + return router; +}; + +/** + * Map the given param placeholder `name`(s) to the given callback. + * + * Parameter mapping is used to provide pre-conditions to routes + * which use normalized placeholders. For example a _:user_id_ parameter + * could automatically load a user's information from the database without + * any additional code, + * + * The callback uses the same signature as middleware, the only difference + * being that the value of the placeholder is passed, in this case the _id_ + * of the user. Once the `next()` function is invoked, just like middleware + * it will continue on to execute the route, or subsequent parameter functions. + * + * Just like in middleware, you must either respond to the request or call next + * to avoid stalling the request. + * + * app.param('user_id', function(req, res, next, id){ + * User.find(id, function(err, user){ + * if (err) { + * return next(err); + * } else if (!user) { + * return next(new Error('failed to load user')); + * } + * req.user = user; + * next(); + * }); + * }); + * + * @param {String} name + * @param {Function} fn + * @return {app} for chaining + * @public + */ + +proto.param = function param(name, fn) { + // param logic + if (typeof name === 'function') { + deprecate('router.param(fn): Refactor to use path params'); + this._params.push(name); + return; + } + + // apply param functions + var params = this._params; + var len = params.length; + var ret; + + if (name[0] === ':') { + deprecate('router.param(' + JSON.stringify(name) + ', fn): Use router.param(' + JSON.stringify(name.substr(1)) + ', fn) instead'); + name = name.substr(1); + } + + for (var i = 0; i < len; ++i) { + if (ret = params[i](name, fn)) { + fn = ret; + } + } + + // ensure we end up with a + // middleware function + if ('function' !== typeof fn) { + throw new Error('invalid param() call for ' + name + ', got ' + fn); + } + + (this.params[name] = this.params[name] || []).push(fn); + return this; +}; + +/** + * Dispatch a req, res into the router. + * @private + */ + +proto.handle = function handle(req, res, out) { + var self = this; + + debug('dispatching %s %s', req.method, req.url); + + var idx = 0; + var protohost = getProtohost(req.url) || '' + var removed = ''; + var slashAdded = false; + var paramcalled = {}; + + // store options for OPTIONS request + // only used if OPTIONS request + var options = []; + + // middleware and routes + var stack = self.stack; + + // manage inter-router variables + var parentParams = req.params; + var parentUrl = req.baseUrl || ''; + var done = restore(out, req, 'baseUrl', 'next', 'params'); + + // setup next layer + req.next = next; + + // for options requests, respond with a default if nothing else responds + if (req.method === 'OPTIONS') { + done = wrap(done, function(old, err) { + if (err || options.length === 0) return old(err); + sendOptionsResponse(res, options, old); + }); + } + + // setup basic req values + req.baseUrl = parentUrl; + req.originalUrl = req.originalUrl || req.url; + + next(); + + function next(err) { + var layerError = err === 'route' + ? null + : err; + + // remove added slash + if (slashAdded) { + req.url = req.url.substr(1); + slashAdded = false; + } + + // restore altered req.url + if (removed.length !== 0) { + req.baseUrl = parentUrl; + req.url = protohost + removed + req.url.substr(protohost.length); + removed = ''; + } + + // signal to exit router + if (layerError === 'router') { + setImmediate(done, null) + return + } + + // no more matching layers + if (idx >= stack.length) { + setImmediate(done, layerError); + return; + } + + // get pathname of request + var path = getPathname(req); + + if (path == null) { + return done(layerError); + } + + // find next matching layer + var layer; + var match; + var route; + + while (match !== true && idx < stack.length) { + layer = stack[idx++]; + match = matchLayer(layer, path); + route = layer.route; + + if (typeof match !== 'boolean') { + // hold on to layerError + layerError = layerError || match; + } + + if (match !== true) { + continue; + } + + if (!route) { + // process non-route handlers normally + continue; + } + + if (layerError) { + // routes do not match with a pending error + match = false; + continue; + } + + var method = req.method; + var has_method = route._handles_method(method); + + // build up automatic options response + if (!has_method && method === 'OPTIONS') { + appendMethods(options, route._options()); + } + + // don't even bother matching route + if (!has_method && method !== 'HEAD') { + match = false; + continue; + } + } + + // no match + if (match !== true) { + return done(layerError); + } + + // store route for dispatch on change + if (route) { + req.route = route; + } + + // Capture one-time layer values + req.params = self.mergeParams + ? mergeParams(layer.params, parentParams) + : layer.params; + var layerPath = layer.path; + + // this should be done for the layer + self.process_params(layer, paramcalled, req, res, function (err) { + if (err) { + return next(layerError || err); + } + + if (route) { + return layer.handle_request(req, res, next); + } + + trim_prefix(layer, layerError, layerPath, path); + }); + } + + function trim_prefix(layer, layerError, layerPath, path) { + if (layerPath.length !== 0) { + // Validate path breaks on a path separator + var c = path[layerPath.length] + if (c && c !== '/' && c !== '.') return next(layerError) + + // Trim off the part of the url that matches the route + // middleware (.use stuff) needs to have the path stripped + debug('trim prefix (%s) from url %s', layerPath, req.url); + removed = layerPath; + req.url = protohost + req.url.substr(protohost.length + removed.length); + + // Ensure leading slash + if (!protohost && req.url[0] !== '/') { + req.url = '/' + req.url; + slashAdded = true; + } + + // Setup base URL (no trailing slash) + req.baseUrl = parentUrl + (removed[removed.length - 1] === '/' + ? removed.substring(0, removed.length - 1) + : removed); + } + + debug('%s %s : %s', layer.name, layerPath, req.originalUrl); + + if (layerError) { + layer.handle_error(layerError, req, res, next); + } else { + layer.handle_request(req, res, next); + } + } +}; + +/** + * Process any parameters for the layer. + * @private + */ + +proto.process_params = function process_params(layer, called, req, res, done) { + var params = this.params; + + // captured parameters from the layer, keys and values + var keys = layer.keys; + + // fast track + if (!keys || keys.length === 0) { + return done(); + } + + var i = 0; + var name; + var paramIndex = 0; + var key; + var paramVal; + var paramCallbacks; + var paramCalled; + + // process params in order + // param callbacks can be async + function param(err) { + if (err) { + return done(err); + } + + if (i >= keys.length ) { + return done(); + } + + paramIndex = 0; + key = keys[i++]; + name = key.name; + paramVal = req.params[name]; + paramCallbacks = params[name]; + paramCalled = called[name]; + + if (paramVal === undefined || !paramCallbacks) { + return param(); + } + + // param previously called with same value or error occurred + if (paramCalled && (paramCalled.match === paramVal + || (paramCalled.error && paramCalled.error !== 'route'))) { + // restore value + req.params[name] = paramCalled.value; + + // next param + return param(paramCalled.error); + } + + called[name] = paramCalled = { + error: null, + match: paramVal, + value: paramVal + }; + + paramCallback(); + } + + // single param callbacks + function paramCallback(err) { + var fn = paramCallbacks[paramIndex++]; + + // store updated value + paramCalled.value = req.params[key.name]; + + if (err) { + // store error + paramCalled.error = err; + param(err); + return; + } + + if (!fn) return param(); + + try { + fn(req, res, paramCallback, paramVal, key.name); + } catch (e) { + paramCallback(e); + } + } + + param(); +}; + +/** + * Use the given middleware function, with optional path, defaulting to "/". + * + * Use (like `.all`) will run for any http METHOD, but it will not add + * handlers for those methods so OPTIONS requests will not consider `.use` + * functions even if they could respond. + * + * The other difference is that _route_ path is stripped and not visible + * to the handler function. The main effect of this feature is that mounted + * handlers can operate without any code changes regardless of the "prefix" + * pathname. + * + * @public + */ + +proto.use = function use(fn) { + var offset = 0; + var path = '/'; + + // default path to '/' + // disambiguate router.use([fn]) + if (typeof fn !== 'function') { + var arg = fn; + + while (Array.isArray(arg) && arg.length !== 0) { + arg = arg[0]; + } + + // first arg is the path + if (typeof arg !== 'function') { + offset = 1; + path = fn; + } + } + + var callbacks = flatten(slice.call(arguments, offset)); + + if (callbacks.length === 0) { + throw new TypeError('Router.use() requires middleware functions'); + } + + for (var i = 0; i < callbacks.length; i++) { + var fn = callbacks[i]; + + if (typeof fn !== 'function') { + throw new TypeError('Router.use() requires middleware function but got a ' + gettype(fn)); + } + + // add the middleware + debug('use %o %s', path, fn.name || '