diff options
Diffstat (limited to 'deps')
365 files changed, 5267 insertions, 10077 deletions
diff --git a/deps/npm/.npmignore b/deps/npm/.npmignore index 6c258eaa0b8..ff0cb7fc3f0 100644 --- a/deps/npm/.npmignore +++ b/deps/npm/.npmignore @@ -10,6 +10,7 @@ npm-debug.log node_modules/ronn node_modules/tap node_modules/.bin +node_modules/npm-registry-mock /npmrc /release/ diff --git a/deps/npm/LICENSE b/deps/npm/LICENSE index bdca79502be..764bb871843 100644 --- a/deps/npm/LICENSE +++ b/deps/npm/LICENSE @@ -1,7 +1,7 @@ Copyright (c) Isaac Z. Schlueter All rights reserved. -npm is released under the Artistic 2.0 License. +npm is released under the Artistic License 2.0. The text of the License follows: @@ -119,15 +119,15 @@ you do at least ONE of the following: make the Source form of the Modified Version available to others under - (i) the Original License or + (i) the Original License or - (ii) a license that permits the licensee to freely copy, - modify and redistribute the Modified Version using the same - licensing terms that apply to the copy that the licensee - received, and requires that the Source form of the Modified - Version, and of any works derived from it, be made freely - available in that license fees are prohibited but Distributor - Fees are allowed. + (ii) a license that permits the licensee to freely copy, + modify and redistribute the Modified Version using the same + licensing terms that apply to the copy that the licensee + received, and requires that the Source form of the Modified + Version, and of any works derived from it, be made freely + available in that license fees are prohibited but Distributor + Fees are allowed. Distribution of Compiled Forms of the Standard Version diff --git a/deps/npm/README.md b/deps/npm/README.md index 6769c91e476..dc4853f04b6 100644 --- a/deps/npm/README.md +++ b/deps/npm/README.md @@ -234,6 +234,6 @@ will no doubt tell you to put the output in a gist or email. ## SEE ALSO * npm(1) -* npm-faq(1) +* npm-faq(7) * npm-help(1) -* npm-index(1) +* npm-index(7) diff --git a/deps/npm/doc/api/npm.md b/deps/npm/doc/api/npm.md index e099320f480..dea8773b80b 100644 --- a/deps/npm/doc/api/npm.md +++ b/deps/npm/doc/api/npm.md @@ -4,7 +4,7 @@ npm(3) -- node package manager ## SYNOPSIS var npm = require("npm") - npm.load([configObject,] function (er, npm) { + npm.load([configObject], function (er, npm) { // use the npm object, now that it's loaded. npm.config.set(key, val) diff --git a/deps/npm/doc/api/repo.md b/deps/npm/doc/api/repo.md new file mode 100644 index 00000000000..af3c52fab64 --- /dev/null +++ b/deps/npm/doc/api/repo.md @@ -0,0 +1,19 @@ +npm-repo(3) -- Open package repository page in the browser +======================================================== + +## SYNOPSIS + + npm.commands.repo(package, callback) + +## DESCRIPTION + +This command tries to guess at the likely location of a package's +repository URL, and then tries to open it using the `--browser` +config param. + +Like other commands, the first parameter is an array. This command only +uses the first element, which is expected to be a package name with an +optional version number. + +This command will launch a browser, so this command may not be the most +friendly for programmatic use. diff --git a/deps/npm/doc/cli/npm-link.md b/deps/npm/doc/cli/npm-link.md index cfd7f3a76df..f7f5ad053aa 100644 --- a/deps/npm/doc/cli/npm-link.md +++ b/deps/npm/doc/cli/npm-link.md @@ -16,7 +16,7 @@ symbolic link from `prefix/package-name` to the current folder. Next, in some other location, `npm link package-name` will create a symlink from the local `node_modules` folder to the global symlink. -Note that `package-name` is taken from `package.json` , +Note that `package-name` is taken from `package.json`, not from directory name. When creating tarballs for `npm publish`, the linked packages are diff --git a/deps/npm/doc/cli/npm-version.md b/deps/npm/doc/cli/npm-version.md index 1cacd8d0037..18aaf747003 100644 --- a/deps/npm/doc/cli/npm-version.md +++ b/deps/npm/doc/cli/npm-version.md @@ -42,4 +42,4 @@ in your git config for this to work properly. For example: * npm-init(1) * package.json(5) -* npm-semver(7) +* semver(7) diff --git a/deps/npm/doc/cli/repo.md b/deps/npm/doc/cli/repo.md new file mode 100644 index 00000000000..5c281c28e11 --- /dev/null +++ b/deps/npm/doc/cli/repo.md @@ -0,0 +1,26 @@ +npm-repo(1) -- Open package repository page in the browser +======================================================== + +## SYNOPSIS + + npm repo <pkgname> + +## DESCRIPTION + +This command tries to guess at the likely location of a package's +repository URL, and then tries to open it using the `--browser` +config param. + +## CONFIGURATION + +### browser + +* Default: OS X: `"open"`, Windows: `"start"`, Others: `"xdg-open"` +* Type: String + +The browser that is called by the `npm repo` command to open websites. + +## SEE ALSO + +* npm-docs(1) +* npm-config(1) diff --git a/deps/npm/doc/files/package.json.md b/deps/npm/doc/files/package.json.md index 8155a3e9b6c..d58d07bf08b 100644 --- a/deps/npm/doc/files/package.json.md +++ b/deps/npm/doc/files/package.json.md @@ -68,18 +68,7 @@ Version must be parseable by [node-semver](https://github.com/isaacs/node-semver), which is bundled with npm as a dependency. (`npm install semver` to use it yourself.) -Here's how npm's semver implementation deviates from what's on semver.org: - -* Versions can start with "v" -* A numeric item separated from the main three-number version by a hyphen - will be interpreted as a "build" number, and will *increase* the version. - But, if the tag is not a number separated by a hyphen, then it's treated - as a pre-release tag, and is *less than* the version without a tag. - So, `0.1.2-7 > 0.1.2-7-beta > 0.1.2-6 > 0.1.2 > 0.1.2beta` - -This is a little bit confusing to explain, but matches what you see in practice -when people create tags in git like "v1.2.3" and then do "git describe" to generate -a patch version. +More on version numbers and ranges at semver(7). ## description @@ -335,24 +324,23 @@ configs. ## dependencies -Dependencies are specified with a simple hash of package name to version -range. The version range is EITHER a string which has one or more -space-separated descriptors, OR a range like "fromVersion - toVersion" +Dependencies are specified with a simple hash of package name to +version range. The version range is a string which has one or more +space-separated descriptors. Dependencies can also be identified with +a tarball or git URL. -**Please do not put test harnesses in your `dependencies` hash.** See -`devDependencies`, below. +**Please do not put test harnesses or transpilers in your +`dependencies` hash.** See `devDependencies`, below. -Version range descriptors may be any of the following styles, where "version" -is a semver compatible version identifier. +See semver(7) for more details about specifying version ranges. * `version` Must match `version` exactly -* `=version` Same as just `version` * `>version` Must be greater than `version` * `>=version` etc * `<version` * `<=version` -* `~version` See 'Tilde Version Ranges' below -* `1.2.x` See 'X Version Ranges' below +* `~version` "Approximately equivalent to version" See semver(7) +* `1.2.x` 1.2.0, 1.2.1, etc., but not 1.3.0 * `http://...` See 'URLs as Dependencies' below * `*` Matches any version * `""` (just an empty string) Same as `*` @@ -376,40 +364,9 @@ For example, these are all valid: } } -### Tilde Version Ranges - -A range specifier starting with a tilde `~` character is matched against -a version in the following fashion. - -* The version must be at least as high as the range. -* The version must be less than the next major revision above the range. - -For example, the following are equivalent: - -* `"~1.2.3" = ">=1.2.3 <1.3.0"` -* `"~1.2" = ">=1.2.0 <1.3.0"` -* `"~1" = ">=1.0.0 <1.1.0"` - -### X Version Ranges - -An "x" in a version range specifies that the version number must start -with the supplied digits, but any digit may be used in place of the x. - -The following are equivalent: - -* `"1.2.x" = ">=1.2.0 <1.3.0"` -* `"1.x.x" = ">=1.0.0 <2.0.0"` -* `"1.2" = "1.2.x"` -* `"1.x" = "1.x.x"` -* `"1" = "1.x.x"` - -You may not supply a comparator with a version containing an x. Any -digits after the first "x" are ignored. - ### URLs as Dependencies -Starting with npm version 0.2.14, you may specify a tarball URL in place -of a version range. +You may specify a tarball URL in place of a version range. This tarball will be downloaded and installed locally to your package at install time. @@ -436,11 +393,35 @@ the external test or documentation framework that you use. In this case, it's best to list these additional items in a `devDependencies` hash. -These things will be installed whenever the `--dev` configuration flag -is set. This flag is set automatically when doing `npm link` or when doing -`npm install` from the root of a package, and can be managed like any other npm +These things will be installed when doing `npm link` or `npm install` +from the root of a package, and can be managed like any other npm configuration param. See `npm-config(7)` for more on the topic. +For build steps that are not platform-specific, such as compiling +CoffeeScript or other languages to JavaScript, use the `prepublish` +script to do this, and make the required package a devDependency. + +For example: + +```json +{ "name": "ethopia-waza", + "description": "a delightfully fruity coffee varietal", + "version": "1.2.3", + "devDependencies": { + "coffee-script": "~1.6.3" + }, + "scripts": { + "prepublish": "coffee -o lib/ -c src/waza.coffee" + }, + "main": "lib/waza.js" +} +``` + +The `prepublish` script will be run before publishing, so that users +can consume the functionality without requiring them to compile it +themselves. In dev mode (ie, locally running `npm install`), it'll +run this script as well, so that you can test it easily. + ## bundledDependencies Array of package names that will be bundled when publishing the package. @@ -481,7 +462,7 @@ Entries in `optionalDependencies` will override entries of the same name in You can specify the version of node that your stuff works on: - { "engines" : { "node" : ">=0.1.27 <0.1.30" } } + { "engines" : { "node" : ">=0.10.3 <0.12" } } And, like with dependencies, if you don't specify the version (or if you specify "\*" as the version), then any version of node will do. @@ -576,7 +557,7 @@ overridden. ## SEE ALSO -* npm-semver(7) +* semver(7) * npm-init(1) * npm-version(1) * npm-config(1) diff --git a/deps/npm/doc/misc/npm-index.md b/deps/npm/doc/misc/npm-index.md index e6eba281f39..ba309351210 100644 --- a/deps/npm/doc/misc/npm-index.md +++ b/deps/npm/doc/misc/npm-index.md @@ -191,6 +191,10 @@ View registry info Display npm username +## repo(1) + +Open package repository page in the browser + # API Documentation ## npm(3) @@ -345,6 +349,10 @@ View registry info Display npm username +## repo(3) + +Open package repository page in the browser + # Files ## npm-folders(5) diff --git a/deps/npm/doc/misc/npm-registry.md b/deps/npm/doc/misc/npm-registry.md index 0081984f76f..514bce2f835 100644 --- a/deps/npm/doc/misc/npm-registry.md +++ b/deps/npm/doc/misc/npm-registry.md @@ -53,33 +53,8 @@ otherwise. ## Do I have to use couchdb to build a registry that npm can talk to? -No, but it's way easier. - -## I published something elsewhere, and want to tell the npm registry about it. - -That is supported, but not using the npm client. You'll have to get -your hands dirty and do some HTTP. The request looks something like -this: - - PUT /my-foreign-package - content-type:application/json - accept:application/json - authorization:Basic $base_64_encoded - - { "name":"my-foreign-package" - , "maintainers":["owner","usernames"] - , "description":"A package that is hosted elsewhere" - , "keywords":["nih","my cheese smells the best"] - , "url":"http://my-different-registry.com/blerg/my-local-package" - } - -(Keywords and description are optional, but recommended. Name, -maintainers, and url are required.) - -Then, when a user tries to install "my-foreign-package", it'll redirect -to your registry. If that doesn't resolve to a valid package entry, -then it'll fail, so please make sure that you understand the spec, and -ask for help on the <npm-@googlegroups.com> mailing list. +No, but it's way easier. Basically, yes, you do, or you have to +effectively implement the entire CouchDB API anyway. ## Is there a website or something to see package docs and such? diff --git a/deps/npm/doc/misc/npm-scripts.md b/deps/npm/doc/misc/npm-scripts.md index b3f47699aaf..02d76f1c4e5 100644 --- a/deps/npm/doc/misc/npm-scripts.md +++ b/deps/npm/doc/misc/npm-scripts.md @@ -33,7 +33,7 @@ following scripts: Run by the `npm restart` command. Note: `npm restart` will run the stop and start scripts if no `restart` script is provided. -Additionally, arbitrary scrips can be run by doing +Additionally, arbitrary scripts can be run by doing `npm run-script <stage> <pkg>`. ## NOTE: INSTALL SCRIPTS ARE AN ANTIPATTERN diff --git a/deps/npm/html/doc/README.html b/deps/npm/html/doc/README.html index 2cd2cb537da..35c732cdc98 100644 --- a/deps/npm/html/doc/README.html +++ b/deps/npm/html/doc/README.html @@ -238,9 +238,9 @@ will no doubt tell you to put the output in a gist or email.</p> <h2 id="SEE-ALSO">SEE ALSO</h2> -<ul><li><a href="cli/npm.html">npm(1)</a></li><li><a href="cli/npm-faq.html">npm-faq(1)</a></li><li><a href="cli/npm-help.html">npm-help(1)</a></li><li><a href="cli/npm-index.html">npm-index(1)</a></li></ul> +<ul><li><a href="cli/npm.html">npm(1)</a></li><li><a href="misc/npm-faq.html">npm-faq(7)</a></li><li><a href="cli/npm-help.html">npm-help(1)</a></li><li><a href="misc/npm-index.html">npm-index(7)</a></li></ul> </div> -<p id="footer"><a href="../doc/README.html">README</a> — npm@1.3.6</p> +<p id="footer"><a href="../doc/README.html">README</a> — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/api/npm-bin.html b/deps/npm/html/doc/api/npm-bin.html index 0ea3cfb7d74..beaff41d482 100644 --- a/deps/npm/html/doc/api/npm-bin.html +++ b/deps/npm/html/doc/api/npm-bin.html @@ -19,7 +19,7 @@ <p>This function should not be used programmatically. Instead, just refer to the <code>npm.bin</code> member.</p> </div> -<p id="footer">npm-bin — npm@1.3.6</p> +<p id="footer">npm-bin — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/api/npm-bugs.html b/deps/npm/html/doc/api/npm-bugs.html index 44a6ff2a5e7..43fd51b9cd4 100644 --- a/deps/npm/html/doc/api/npm-bugs.html +++ b/deps/npm/html/doc/api/npm-bugs.html @@ -25,7 +25,7 @@ optional version number.</p> <p>This command will launch a browser, so this command may not be the most friendly for programmatic use.</p> </div> -<p id="footer">npm-bugs — npm@1.3.6</p> +<p id="footer">npm-bugs — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/api/npm-commands.html b/deps/npm/html/doc/api/npm-commands.html index 6f62875665a..5cdf64ab7f0 100644 --- a/deps/npm/html/doc/api/npm-commands.html +++ b/deps/npm/html/doc/api/npm-commands.html @@ -28,7 +28,7 @@ usage, or <code>man 3 npm-<command></code> for programmatic usage.</p> <ul><li><a href="../misc/npm-index.html">npm-index(7)</a></li></ul> </div> -<p id="footer">npm-commands — npm@1.3.6</p> +<p id="footer">npm-commands — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/api/npm-config.html b/deps/npm/html/doc/api/npm-config.html index 205d44db514..62c635c13f3 100644 --- a/deps/npm/html/doc/api/npm-config.html +++ b/deps/npm/html/doc/api/npm-config.html @@ -33,7 +33,7 @@ functions instead.</p> <ul><li><a href="../api/npm.html">npm(3)</a></li></ul> </div> -<p id="footer">npm-config — npm@1.3.6</p> +<p id="footer">npm-config — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/api/npm-deprecate.html b/deps/npm/html/doc/api/npm-deprecate.html index 480b28d53a6..c6771f1cd39 100644 --- a/deps/npm/html/doc/api/npm-deprecate.html +++ b/deps/npm/html/doc/api/npm-deprecate.html @@ -32,7 +32,7 @@ install the package.</p></li></ul> <ul><li><a href="../api/npm-publish.html">npm-publish(3)</a></li><li><a href="../api/npm-unpublish.html">npm-unpublish(3)</a></li><li><a href="../misc/npm-registry.html">npm-registry(7)</a></li></ul> </div> -<p id="footer">npm-deprecate — npm@1.3.6</p> +<p id="footer">npm-deprecate — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/api/npm-docs.html b/deps/npm/html/doc/api/npm-docs.html index 7f3ba6364f8..c01154cd262 100644 --- a/deps/npm/html/doc/api/npm-docs.html +++ b/deps/npm/html/doc/api/npm-docs.html @@ -25,7 +25,7 @@ optional version number.</p> <p>This command will launch a browser, so this command may not be the most friendly for programmatic use.</p> </div> -<p id="footer">npm-docs — npm@1.3.6</p> +<p id="footer">npm-docs — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/api/npm-edit.html b/deps/npm/html/doc/api/npm-edit.html index f7aa95de933..b141e5246e2 100644 --- a/deps/npm/html/doc/api/npm-edit.html +++ b/deps/npm/html/doc/api/npm-edit.html @@ -30,7 +30,7 @@ to open. The package can optionally have a version number attached.</p> <p>Since this command opens an editor in a new process, be careful about where and how this is used.</p> </div> -<p id="footer">npm-edit — npm@1.3.6</p> +<p id="footer">npm-edit — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/api/npm-explore.html b/deps/npm/html/doc/api/npm-explore.html index 81fe236d16b..be831346be2 100644 --- a/deps/npm/html/doc/api/npm-explore.html +++ b/deps/npm/html/doc/api/npm-explore.html @@ -24,7 +24,7 @@ sure to use <code>npm rebuild <pkg></code> if you make any changes.</p> <p>The first element in the 'args' parameter must be a package name. After that is the optional command, which can be any number of strings. All of the strings will be combined into one, space-delimited command.</p> </div> -<p id="footer">npm-explore — npm@1.3.6</p> +<p id="footer">npm-explore — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/api/npm-help-search.html b/deps/npm/html/doc/api/npm-help-search.html index 7980b46bb6d..c3b27716170 100644 --- a/deps/npm/html/doc/api/npm-help-search.html +++ b/deps/npm/html/doc/api/npm-help-search.html @@ -32,7 +32,7 @@ Name of the file that matched</li></ul> <p>The silent parameter is not neccessary not used, but it may in the future.</p> </div> -<p id="footer">npm-help-search — npm@1.3.6</p> +<p id="footer">npm-help-search — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/api/npm-init.html b/deps/npm/html/doc/api/npm-init.html index 24f7f558d91..9a25ef6f8a9 100644 --- a/deps/npm/html/doc/api/npm-init.html +++ b/deps/npm/html/doc/api/npm-init.html @@ -35,7 +35,7 @@ then go ahead and use this programmatically.</p> <p><a href="../files/package.json.html">package.json(5)</a></p> </div> -<p id="footer">npm-init — npm@1.3.6</p> +<p id="footer">npm-init — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/api/npm-install.html b/deps/npm/html/doc/api/npm-install.html index f2d4bd3c03e..dd626d1d56d 100644 --- a/deps/npm/html/doc/api/npm-install.html +++ b/deps/npm/html/doc/api/npm-install.html @@ -25,7 +25,7 @@ the name of a package to be installed.</p> <p>Finally, 'callback' is a function that will be called when all packages have been installed or when an error has been encountered.</p> </div> -<p id="footer">npm-install — npm@1.3.6</p> +<p id="footer">npm-install — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/api/npm-link.html b/deps/npm/html/doc/api/npm-link.html index d49e9f6abe6..a6d3b20b99a 100644 --- a/deps/npm/html/doc/api/npm-link.html +++ b/deps/npm/html/doc/api/npm-link.html @@ -39,7 +39,7 @@ npm.commands.link('redis', cb) # link-install the package</code></pre> <p>Now, any changes to the redis package will be reflected in the package in the current working directory</p> </div> -<p id="footer">npm-link — npm@1.3.6</p> +<p id="footer">npm-link — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/api/npm-load.html b/deps/npm/html/doc/api/npm-load.html index 51cd332f8d7..d63be3050b7 100644 --- a/deps/npm/html/doc/api/npm-load.html +++ b/deps/npm/html/doc/api/npm-load.html @@ -32,7 +32,7 @@ config object.</p> <p>For a list of all the available command-line configs, see <code>npm help config</code></p> </div> -<p id="footer">npm-load — npm@1.3.6</p> +<p id="footer">npm-load — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/api/npm-ls.html b/deps/npm/html/doc/api/npm-ls.html index c159e36f162..bcebef5240b 100644 --- a/deps/npm/html/doc/api/npm-ls.html +++ b/deps/npm/html/doc/api/npm-ls.html @@ -59,7 +59,7 @@ project.</p> This means that if a submodule a same dependency as a parent module, then the dependency will only be output once.</p> </div> -<p id="footer">npm-ls — npm@1.3.6</p> +<p id="footer">npm-ls — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/api/npm-outdated.html b/deps/npm/html/doc/api/npm-outdated.html index 6a48fb7b053..41632ae2ec9 100644 --- a/deps/npm/html/doc/api/npm-outdated.html +++ b/deps/npm/html/doc/api/npm-outdated.html @@ -19,7 +19,7 @@ currently outdated.</p> <p>If the 'packages' parameter is left out, npm will check all packages.</p> </div> -<p id="footer">npm-outdated — npm@1.3.6</p> +<p id="footer">npm-outdated — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/api/npm-owner.html b/deps/npm/html/doc/api/npm-owner.html index a10a78e82cf..2327caab89a 100644 --- a/deps/npm/html/doc/api/npm-owner.html +++ b/deps/npm/html/doc/api/npm-owner.html @@ -34,7 +34,7 @@ that is not implemented at this time.</p> <ul><li><a href="../api/npm-publish.html">npm-publish(3)</a></li><li><a href="../misc/npm-registry.html">npm-registry(7)</a></li></ul> </div> -<p id="footer">npm-owner — npm@1.3.6</p> +<p id="footer">npm-owner — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/api/npm-pack.html b/deps/npm/html/doc/api/npm-pack.html index 756b736f585..796cea40e1f 100644 --- a/deps/npm/html/doc/api/npm-pack.html +++ b/deps/npm/html/doc/api/npm-pack.html @@ -25,7 +25,7 @@ overwritten the second time.</p> <p>If no arguments are supplied, then npm packs the current package folder.</p> </div> -<p id="footer">npm-pack — npm@1.3.6</p> +<p id="footer">npm-pack — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/api/npm-prefix.html b/deps/npm/html/doc/api/npm-prefix.html index b8cbc89dba4..07d73cb8a3b 100644 --- a/deps/npm/html/doc/api/npm-prefix.html +++ b/deps/npm/html/doc/api/npm-prefix.html @@ -21,7 +21,7 @@ <p>This function is not useful programmatically</p> </div> -<p id="footer">npm-prefix — npm@1.3.6</p> +<p id="footer">npm-prefix — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/api/npm-prune.html b/deps/npm/html/doc/api/npm-prune.html index 7683db720c8..5c1265baa78 100644 --- a/deps/npm/html/doc/api/npm-prune.html +++ b/deps/npm/html/doc/api/npm-prune.html @@ -23,7 +23,7 @@ <p>Extraneous packages are packages that are not listed on the parent package's dependencies list.</p> </div> -<p id="footer">npm-prune — npm@1.3.6</p> +<p id="footer">npm-prune — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/api/npm-publish.html b/deps/npm/html/doc/api/npm-publish.html index 569f70022c1..d396741be8f 100644 --- a/deps/npm/html/doc/api/npm-publish.html +++ b/deps/npm/html/doc/api/npm-publish.html @@ -32,7 +32,7 @@ the registry. Overwrites when the "force" environment variable is set <ul><li><a href="../misc/npm-registry.html">npm-registry(7)</a></li><li><a href="../cli/npm-adduser.html">npm-adduser(1)</a></li><li><a href="../api/npm-owner.html">npm-owner(3)</a></li></ul> </div> -<p id="footer">npm-publish — npm@1.3.6</p> +<p id="footer">npm-publish — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/api/npm-rebuild.html b/deps/npm/html/doc/api/npm-rebuild.html index e58abb2dc31..980e3f6277d 100644 --- a/deps/npm/html/doc/api/npm-rebuild.html +++ b/deps/npm/html/doc/api/npm-rebuild.html @@ -22,7 +22,7 @@ the new binary. If no 'packages' parameter is specify, every package wil <p>See <code>npm help build</code></p> </div> -<p id="footer">npm-rebuild — npm@1.3.6</p> +<p id="footer">npm-rebuild — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/api/npm-restart.html b/deps/npm/html/doc/api/npm-restart.html index 1f9d8972d2b..eb3024c0857 100644 --- a/deps/npm/html/doc/api/npm-restart.html +++ b/deps/npm/html/doc/api/npm-restart.html @@ -27,7 +27,7 @@ in the <code>packages</code> parameter.</p> <ul><li><a href="../api/npm-start.html">npm-start(3)</a></li><li><a href="../api/npm-stop.html">npm-stop(3)</a></li></ul> </div> -<p id="footer">npm-restart — npm@1.3.6</p> +<p id="footer">npm-restart — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/api/npm-root.html b/deps/npm/html/doc/api/npm-root.html index 047f05f4cce..0d2a79192b2 100644 --- a/deps/npm/html/doc/api/npm-root.html +++ b/deps/npm/html/doc/api/npm-root.html @@ -21,7 +21,7 @@ <p>This function is not useful programmatically.</p> </div> -<p id="footer">npm-root — npm@1.3.6</p> +<p id="footer">npm-root — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/api/npm-run-script.html b/deps/npm/html/doc/api/npm-run-script.html index e620765696b..29414e43585 100644 --- a/deps/npm/html/doc/api/npm-run-script.html +++ b/deps/npm/html/doc/api/npm-run-script.html @@ -29,7 +29,7 @@ assumed to be the command to run. All other elements are ignored.</p> <ul><li><a href="../misc/npm-scripts.html">npm-scripts(7)</a></li><li><a href="../api/npm-test.html">npm-test(3)</a></li><li><a href="../api/npm-start.html">npm-start(3)</a></li><li><a href="../api/npm-restart.html">npm-restart(3)</a></li><li><a href="../api/npm-stop.html">npm-stop(3)</a></li></ul> </div> -<p id="footer">npm-run-script — npm@1.3.6</p> +<p id="footer">npm-run-script — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/api/npm-search.html b/deps/npm/html/doc/api/npm-search.html index 9c6ae169a3b..a4c725a1f5e 100644 --- a/deps/npm/html/doc/api/npm-search.html +++ b/deps/npm/html/doc/api/npm-search.html @@ -32,7 +32,7 @@ excluded term (the "searchexclude" config). The search is case insensi and doesn't try to read your mind (it doesn't do any verb tense matching or the like).</p> </div> -<p id="footer">npm-search — npm@1.3.6</p> +<p id="footer">npm-search — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/api/npm-shrinkwrap.html b/deps/npm/html/doc/api/npm-shrinkwrap.html index ed09c298eda..261e22c8371 100644 --- a/deps/npm/html/doc/api/npm-shrinkwrap.html +++ b/deps/npm/html/doc/api/npm-shrinkwrap.html @@ -26,7 +26,7 @@ but the shrinkwrap file will still be written.</p> <p>Finally, 'callback' is a function that will be called when the shrinkwrap has been saved.</p> </div> -<p id="footer">npm-shrinkwrap — npm@1.3.6</p> +<p id="footer">npm-shrinkwrap — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/api/npm-start.html b/deps/npm/html/doc/api/npm-start.html index e2d51540ed6..ce1bab22091 100644 --- a/deps/npm/html/doc/api/npm-start.html +++ b/deps/npm/html/doc/api/npm-start.html @@ -19,7 +19,7 @@ <p>npm can run tests on multiple packages. Just specify multiple packages in the <code>packages</code> parameter.</p> </div> -<p id="footer">npm-start — npm@1.3.6</p> +<p id="footer">npm-start — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/api/npm-stop.html b/deps/npm/html/doc/api/npm-stop.html index 9c34fafa684..67cc2b19311 100644 --- a/deps/npm/html/doc/api/npm-stop.html +++ b/deps/npm/html/doc/api/npm-stop.html @@ -19,7 +19,7 @@ <p>npm can run stop on multiple packages. Just specify multiple packages in the <code>packages</code> parameter.</p> </div> -<p id="footer">npm-stop — npm@1.3.6</p> +<p id="footer">npm-stop — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/api/npm-submodule.html b/deps/npm/html/doc/api/npm-submodule.html index cea266f83f8..04cda4511f2 100644 --- a/deps/npm/html/doc/api/npm-submodule.html +++ b/deps/npm/html/doc/api/npm-submodule.html @@ -33,7 +33,7 @@ dependencies into the submodule folder.</p> <ul><li>npm help json</li><li>git help submodule</li></ul> </div> -<p id="footer">npm-submodule — npm@1.3.6</p> +<p id="footer">npm-submodule — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/api/npm-tag.html b/deps/npm/html/doc/api/npm-tag.html index 3b54b73b4eb..8a17ac58020 100644 --- a/deps/npm/html/doc/api/npm-tag.html +++ b/deps/npm/html/doc/api/npm-tag.html @@ -29,7 +29,7 @@ parameter is missing or falsey (empty), the default froom the config will be used. For more information about how to set this config, check <code>man 3 npm-config</code> for programmatic usage or <code>man npm-config</code> for cli usage.</p> </div> -<p id="footer">npm-tag — npm@1.3.6</p> +<p id="footer">npm-tag — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/api/npm-test.html b/deps/npm/html/doc/api/npm-test.html index c0bcbe9683e..76cd956ede3 100644 --- a/deps/npm/html/doc/api/npm-test.html +++ b/deps/npm/html/doc/api/npm-test.html @@ -22,7 +22,7 @@ true.</p> <p>npm can run tests on multiple packages. Just specify multiple packages in the <code>packages</code> parameter.</p> </div> -<p id="footer">npm-test — npm@1.3.6</p> +<p id="footer">npm-test — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/api/npm-uninstall.html b/deps/npm/html/doc/api/npm-uninstall.html index 74d52c1c981..15c562fea3d 100644 --- a/deps/npm/html/doc/api/npm-uninstall.html +++ b/deps/npm/html/doc/api/npm-uninstall.html @@ -22,7 +22,7 @@ the name of a package to be uninstalled.</p> <p>Finally, 'callback' is a function that will be called when all packages have been uninstalled or when an error has been encountered.</p> </div> -<p id="footer">npm-uninstall — npm@1.3.6</p> +<p id="footer">npm-uninstall — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/api/npm-unpublish.html b/deps/npm/html/doc/api/npm-unpublish.html index c58e93871da..86747aa3a4b 100644 --- a/deps/npm/html/doc/api/npm-unpublish.html +++ b/deps/npm/html/doc/api/npm-unpublish.html @@ -26,7 +26,7 @@ is what is meant.</p> <p>If no version is specified, or if all versions are removed then the root package entry is removed from the registry entirely.</p> </div> -<p id="footer">npm-unpublish — npm@1.3.6</p> +<p id="footer">npm-unpublish — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/api/npm-update.html b/deps/npm/html/doc/api/npm-update.html index 34285840abc..3e7226923ee 100644 --- a/deps/npm/html/doc/api/npm-update.html +++ b/deps/npm/html/doc/api/npm-update.html @@ -18,7 +18,7 @@ <p>The 'packages' argument is an array of packages to update. The 'callback' parameter will be called when done or when an error occurs.</p> </div> -<p id="footer">npm-update — npm@1.3.6</p> +<p id="footer">npm-update — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/api/npm-version.html b/deps/npm/html/doc/api/npm-version.html index d5369e670cd..80b6a548452 100644 --- a/deps/npm/html/doc/api/npm-version.html +++ b/deps/npm/html/doc/api/npm-version.html @@ -24,7 +24,7 @@ fail if the repo is not clean.</p> parameter. The difference, however, is this function will fail if it does not have exactly one element. The only element should be a version number.</p> </div> -<p id="footer">npm-version — npm@1.3.6</p> +<p id="footer">npm-version — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/api/npm-view.html b/deps/npm/html/doc/api/npm-view.html index d0c6f0b56c8..3cfffe4f3d8 100644 --- a/deps/npm/html/doc/api/npm-view.html +++ b/deps/npm/html/doc/api/npm-view.html @@ -99,7 +99,7 @@ the field name.</p> <p>corresponding to the list of fields selected.</p> </div> -<p id="footer">npm-view — npm@1.3.6</p> +<p id="footer">npm-view — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/api/npm-whoami.html b/deps/npm/html/doc/api/npm-whoami.html index 04d4bd9138c..fe7e05ab8db 100644 --- a/deps/npm/html/doc/api/npm-whoami.html +++ b/deps/npm/html/doc/api/npm-whoami.html @@ -21,7 +21,7 @@ <p>This function is not useful programmatically</p> </div> -<p id="footer">npm-whoami — npm@1.3.6</p> +<p id="footer">npm-whoami — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/api/npm.html b/deps/npm/html/doc/api/npm.html index 97e1d3c68fe..0855f9a6a36 100644 --- a/deps/npm/html/doc/api/npm.html +++ b/deps/npm/html/doc/api/npm.html @@ -11,7 +11,7 @@ <h2 id="SYNOPSIS">SYNOPSIS</h2> <pre><code>var npm = require("npm") -npm.load([configObject,] function (er, npm) { +npm.load([configObject], function (er, npm) { // use the npm object, now that it's loaded. npm.config.set(key, val) @@ -24,7 +24,7 @@ npm.load([configObject,] function (er, npm) { <h2 id="VERSION">VERSION</h2> -<p>1.3.6</p> +<p>1.3.8</p> <h2 id="DESCRIPTION">DESCRIPTION</h2> @@ -92,7 +92,7 @@ method names. Use the <code>npm.deref</code> method to find the real name.</p> <pre><code>var cmd = npm.deref("unp") // cmd === "unpublish"</code></pre> </div> -<p id="footer">npm — npm@1.3.6</p> +<p id="footer">npm — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/api/repo.html b/deps/npm/html/doc/api/repo.html new file mode 100644 index 00000000000..511d26746ad --- /dev/null +++ b/deps/npm/html/doc/api/repo.html @@ -0,0 +1,59 @@ +<!doctype html> +<html> + <title>repo</title> + <meta http-equiv="content-type" value="text/html;utf-8"> + <link rel="stylesheet" type="text/css" href="../../static/style.css"> + + <body> + <div id="wrapper"> +<h1><a href="../api/npm-repo.html">npm-repo</a></h1> <p>Open package repository page in the browser</p> + +<h2 id="SYNOPSIS">SYNOPSIS</h2> + +<pre><code>npm.commands.repo(package, callback)</code></pre> + +<h2 id="DESCRIPTION">DESCRIPTION</h2> + +<p>This command tries to guess at the likely location of a package's +repository URL, and then tries to open it using the <code>--browser</code> +config param.</p> + +<p>Like other commands, the first parameter is an array. This command only +uses the first element, which is expected to be a package name with an +optional version number.</p> + +<p>This command will launch a browser, so this command may not be the most +friendly for programmatic use.</p> +</div> +<p id="footer">repo — npm@1.3.8</p> +<script> +;(function () { +var wrapper = document.getElementById("wrapper") +var els = Array.prototype.slice.call(wrapper.getElementsByTagName("*"), 0) + .filter(function (el) { + return el.parentNode === wrapper + && el.tagName.match(/H[1-6]/) + && el.id + }) +var l = 2 + , toc = document.createElement("ul") +toc.innerHTML = els.map(function (el) { + var i = el.tagName.charAt(1) + , out = "" + while (i > l) { + out += "<ul>" + l ++ + } + while (i < l) { + out += "</ul>" + l -- + } + out += "<li><a href='#" + el.id + "'>" + + ( el.innerText || el.text || el.innerHTML) + + "</a>" + return out +}).join("\n") +toc.id = "toc" +document.body.appendChild(toc) +})() +</script> diff --git a/deps/npm/html/doc/cli/npm-adduser.html b/deps/npm/html/doc/cli/npm-adduser.html index ff58a607241..d96bc4f6b23 100644 --- a/deps/npm/html/doc/cli/npm-adduser.html +++ b/deps/npm/html/doc/cli/npm-adduser.html @@ -39,7 +39,7 @@ authorize on a new machine.</p> <ul><li><a href="../misc/npm-registry.html">npm-registry(7)</a></li><li><a href="../cli/npm-config.html">npm-config(1)</a></li><li><a href="../misc/npm-config.html">npm-config(7)</a></li><li><a href="../files/npmrc.html">npmrc(5)</a></li><li><a href="../cli/npm-owner.html">npm-owner(1)</a></li><li><a href="../cli/npm-whoami.html">npm-whoami(1)</a></li></ul> </div> -<p id="footer">npm-adduser — npm@1.3.6</p> +<p id="footer">npm-adduser — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/cli/npm-bin.html b/deps/npm/html/doc/cli/npm-bin.html index d686e65a022..707ab5e3b15 100644 --- a/deps/npm/html/doc/cli/npm-bin.html +++ b/deps/npm/html/doc/cli/npm-bin.html @@ -20,7 +20,7 @@ <ul><li><a href="../cli/npm-prefix.html">npm-prefix(1)</a></li><li><a href="../cli/npm-root.html">npm-root(1)</a></li><li><a href="../files/npm-folders.html">npm-folders(5)</a></li><li><a href="../cli/npm-config.html">npm-config(1)</a></li><li><a href="../misc/npm-config.html">npm-config(7)</a></li><li><a href="../files/npmrc.html">npmrc(5)</a></li></ul> </div> -<p id="footer">npm-bin — npm@1.3.6</p> +<p id="footer">npm-bin — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/cli/npm-bugs.html b/deps/npm/html/doc/cli/npm-bugs.html index 5635e6736b5..161b6510397 100644 --- a/deps/npm/html/doc/cli/npm-bugs.html +++ b/deps/npm/html/doc/cli/npm-bugs.html @@ -36,7 +36,7 @@ config param.</p> <ul><li><a href="../cli/npm-docs.html">npm-docs(1)</a></li><li><a href="../cli/npm-view.html">npm-view(1)</a></li><li><a href="../cli/npm-publish.html">npm-publish(1)</a></li><li><a href="../misc/npm-registry.html">npm-registry(7)</a></li><li><a href="../cli/npm-config.html">npm-config(1)</a></li><li><a href="../misc/npm-config.html">npm-config(7)</a></li><li><a href="../files/npmrc.html">npmrc(5)</a></li><li><a href="../files/package.json.html">package.json(5)</a></li></ul> </div> -<p id="footer">npm-bugs — npm@1.3.6</p> +<p id="footer">npm-bugs — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/cli/npm-build.html b/deps/npm/html/doc/cli/npm-build.html index 60b3d7d88e2..30fb7b2ffe1 100644 --- a/deps/npm/html/doc/cli/npm-build.html +++ b/deps/npm/html/doc/cli/npm-build.html @@ -25,7 +25,7 @@ A folder containing a <code>package.json</code> file in its root.</li></ul> <ul><li><a href="../cli/npm-install.html">npm-install(1)</a></li><li><a href="../cli/npm-link.html">npm-link(1)</a></li><li><a href="../misc/npm-scripts.html">npm-scripts(7)</a></li><li><a href="../files/package.json.html">package.json(5)</a></li></ul> </div> -<p id="footer">npm-build — npm@1.3.6</p> +<p id="footer">npm-build — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/cli/npm-bundle.html b/deps/npm/html/doc/cli/npm-bundle.html index d16fe378bda..18979091496 100644 --- a/deps/npm/html/doc/cli/npm-bundle.html +++ b/deps/npm/html/doc/cli/npm-bundle.html @@ -20,7 +20,7 @@ install packages into the local space.</p> <ul><li><a href="../cli/npm-install.html">npm-install(1)</a></li></ul> </div> -<p id="footer">npm-bundle — npm@1.3.6</p> +<p id="footer">npm-bundle — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/cli/npm-cache.html b/deps/npm/html/doc/cli/npm-cache.html index 7409200f020..ca5c4129b3f 100644 --- a/deps/npm/html/doc/cli/npm-cache.html +++ b/deps/npm/html/doc/cli/npm-cache.html @@ -66,7 +66,7 @@ they do not make an HTTP request to the registry.</p> <ul><li><a href="../files/npm-folders.html">npm-folders(5)</a></li><li><a href="../cli/npm-config.html">npm-config(1)</a></li><li><a href="../misc/npm-config.html">npm-config(7)</a></li><li><a href="../files/npmrc.html">npmrc(5)</a></li><li><a href="../cli/npm-install.html">npm-install(1)</a></li><li><a href="../cli/npm-publish.html">npm-publish(1)</a></li><li><a href="../cli/npm-pack.html">npm-pack(1)</a></li></ul> </div> -<p id="footer">npm-cache — npm@1.3.6</p> +<p id="footer">npm-cache — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/cli/npm-completion.html b/deps/npm/html/doc/cli/npm-completion.html index 2731771ad38..cf825227fc9 100644 --- a/deps/npm/html/doc/cli/npm-completion.html +++ b/deps/npm/html/doc/cli/npm-completion.html @@ -33,7 +33,7 @@ completions based on the arguments.</p> <ul><li><a href="../misc/npm-developers.html">npm-developers(7)</a></li><li><a href="../misc/npm-faq.html">npm-faq(7)</a></li><li><a href="../cli/npm.html">npm(1)</a></li></ul> </div> -<p id="footer">npm-completion — npm@1.3.6</p> +<p id="footer">npm-completion — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/cli/npm-config.html b/deps/npm/html/doc/cli/npm-config.html index 30654668b9f..995d0a32e2c 100644 --- a/deps/npm/html/doc/cli/npm-config.html +++ b/deps/npm/html/doc/cli/npm-config.html @@ -72,7 +72,7 @@ global config.</p> <ul><li><a href="../files/npm-folders.html">npm-folders(5)</a></li><li><a href="../misc/npm-config.html">npm-config(7)</a></li><li><a href="../files/package.json.html">package.json(5)</a></li><li><a href="../files/npmrc.html">npmrc(5)</a></li><li><a href="../cli/npm.html">npm(1)</a></li></ul> </div> -<p id="footer">npm-config — npm@1.3.6</p> +<p id="footer">npm-config — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/cli/npm-dedupe.html b/deps/npm/html/doc/cli/npm-dedupe.html index bce6939c0f6..3f8153480cd 100644 --- a/deps/npm/html/doc/cli/npm-dedupe.html +++ b/deps/npm/html/doc/cli/npm-dedupe.html @@ -57,7 +57,7 @@ registry.</p> <ul><li><a href="../cli/npm-ls.html">npm-ls(1)</a></li><li><a href="../cli/npm-update.html">npm-update(1)</a></li><li><a href="../cli/npm-install.html">npm-install(1)</a></li></ul> </div> -<p id="footer">npm-dedupe — npm@1.3.6</p> +<p id="footer">npm-dedupe — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/cli/npm-deprecate.html b/deps/npm/html/doc/cli/npm-deprecate.html index ebd76f15ea8..baf4f253846 100644 --- a/deps/npm/html/doc/cli/npm-deprecate.html +++ b/deps/npm/html/doc/cli/npm-deprecate.html @@ -31,7 +31,7 @@ something like this:</p> <ul><li><a href="../cli/npm-publish.html">npm-publish(1)</a></li><li><a href="../misc/npm-registry.html">npm-registry(7)</a></li></ul> </div> -<p id="footer">npm-deprecate — npm@1.3.6</p> +<p id="footer">npm-deprecate — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/cli/npm-docs.html b/deps/npm/html/doc/cli/npm-docs.html index 5a9bb118b73..3ec0eacb5e1 100644 --- a/deps/npm/html/doc/cli/npm-docs.html +++ b/deps/npm/html/doc/cli/npm-docs.html @@ -37,7 +37,7 @@ config param.</p> <ul><li><a href="../cli/npm-view.html">npm-view(1)</a></li><li><a href="../cli/npm-publish.html">npm-publish(1)</a></li><li><a href="../misc/npm-registry.html">npm-registry(7)</a></li><li><a href="../cli/npm-config.html">npm-config(1)</a></li><li><a href="../misc/npm-config.html">npm-config(7)</a></li><li><a href="../files/npmrc.html">npmrc(5)</a></li><li><a href="../files/package.json.html">package.json(5)</a></li></ul> </div> -<p id="footer">npm-docs — npm@1.3.6</p> +<p id="footer">npm-docs — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/cli/npm-edit.html b/deps/npm/html/doc/cli/npm-edit.html index d5087cd2223..269dc417599 100644 --- a/deps/npm/html/doc/cli/npm-edit.html +++ b/deps/npm/html/doc/cli/npm-edit.html @@ -37,7 +37,7 @@ or <code>"notepad"</code> on Windows.</li><li>Type: path</li></ul> <ul><li><a href="../files/npm-folders.html">npm-folders(5)</a></li><li><a href="../cli/npm-explore.html">npm-explore(1)</a></li><li><a href="../cli/npm-install.html">npm-install(1)</a></li><li><a href="../cli/npm-config.html">npm-config(1)</a></li><li><a href="../misc/npm-config.html">npm-config(7)</a></li><li><a href="../files/npmrc.html">npmrc(5)</a></li></ul> </div> -<p id="footer">npm-edit — npm@1.3.6</p> +<p id="footer">npm-edit — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/cli/npm-explore.html b/deps/npm/html/doc/cli/npm-explore.html index 962563b1ba5..07dddc64208 100644 --- a/deps/npm/html/doc/cli/npm-explore.html +++ b/deps/npm/html/doc/cli/npm-explore.html @@ -40,7 +40,7 @@ Windows</li><li>Type: path</li></ul> <ul><li><a href="../cli/npm-submodule.html">npm-submodule(1)</a></li><li><a href="../files/npm-folders.html">npm-folders(5)</a></li><li><a href="../cli/npm-edit.html">npm-edit(1)</a></li><li><a href="../cli/npm-rebuild.html">npm-rebuild(1)</a></li><li><a href="../cli/npm-build.html">npm-build(1)</a></li><li><a href="../cli/npm-install.html">npm-install(1)</a></li></ul> </div> -<p id="footer">npm-explore — npm@1.3.6</p> +<p id="footer">npm-explore — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/cli/npm-help-search.html b/deps/npm/html/doc/cli/npm-help-search.html index c7fd2b29626..8edf7e70f61 100644 --- a/deps/npm/html/doc/cli/npm-help-search.html +++ b/deps/npm/html/doc/cli/npm-help-search.html @@ -38,7 +38,7 @@ where the terms were found in the documentation.</p> <ul><li><a href="../cli/npm.html">npm(1)</a></li><li><a href="../misc/npm-faq.html">npm-faq(7)</a></li><li><a href="../cli/npm-help.html">npm-help(1)</a></li></ul> </div> -<p id="footer">npm-help-search — npm@1.3.6</p> +<p id="footer">npm-help-search — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/cli/npm-help.html b/deps/npm/html/doc/cli/npm-help.html index a65658ebb1c..6b52ba30067 100644 --- a/deps/npm/html/doc/cli/npm-help.html +++ b/deps/npm/html/doc/cli/npm-help.html @@ -36,7 +36,7 @@ matches are equivalent to specifying a topic name.</p> <ul><li><a href="../cli/npm.html">npm(1)</a></li><li><a href="../../doc/README.html">README</a></li><li><a href="../misc/npm-faq.html">npm-faq(7)</a></li><li><a href="../files/npm-folders.html">npm-folders(5)</a></li><li><a href="../cli/npm-config.html">npm-config(1)</a></li><li><a href="../misc/npm-config.html">npm-config(7)</a></li><li><a href="../files/npmrc.html">npmrc(5)</a></li><li><a href="../files/package.json.html">package.json(5)</a></li><li><a href="../cli/npm-help-search.html">npm-help-search(1)</a></li><li><a href="../misc/npm-index.html">npm-index(7)</a></li></ul> </div> -<p id="footer">npm-help — npm@1.3.6</p> +<p id="footer">npm-help — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/cli/npm-init.html b/deps/npm/html/doc/cli/npm-init.html index 8f2c007cde0..737a6c9b663 100644 --- a/deps/npm/html/doc/cli/npm-init.html +++ b/deps/npm/html/doc/cli/npm-init.html @@ -29,7 +29,7 @@ without a really good reason to do so.</p> <ul><li><a href="https://github.com/isaacs/init-package-json">https://github.com/isaacs/init-package-json</a></li><li><a href="../files/package.json.html">package.json(5)</a></li><li><a href="../cli/npm-version.html">npm-version(1)</a></li></ul> </div> -<p id="footer">npm-init — npm@1.3.6</p> +<p id="footer">npm-init — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/cli/npm-install.html b/deps/npm/html/doc/cli/npm-install.html index 0213babe3bf..7097e4b31bf 100644 --- a/deps/npm/html/doc/cli/npm-install.html +++ b/deps/npm/html/doc/cli/npm-install.html @@ -141,7 +141,7 @@ affects a real use-case, it will be investigated.</p> <ul><li><a href="../files/npm-folders.html">npm-folders(5)</a></li><li><a href="../cli/npm-update.html">npm-update(1)</a></li><li><a href="../cli/npm-link.html">npm-link(1)</a></li><li><a href="../cli/npm-rebuild.html">npm-rebuild(1)</a></li><li><a href="../misc/npm-scripts.html">npm-scripts(7)</a></li><li><a href="../cli/npm-build.html">npm-build(1)</a></li><li><a href="../cli/npm-config.html">npm-config(1)</a></li><li><a href="../misc/npm-config.html">npm-config(7)</a></li><li><a href="../files/npmrc.html">npmrc(5)</a></li><li><a href="../misc/npm-registry.html">npm-registry(7)</a></li><li><a href="../files/npm-folders.html">npm-folders(5)</a></li><li><a href="../cli/npm-tag.html">npm-tag(1)</a></li><li><a href="../cli/npm-rm.html">npm-rm(1)</a></li><li><a href="../cli/npm-shrinkwrap.html">npm-shrinkwrap(1)</a></li></ul> </div> -<p id="footer">npm-install — npm@1.3.6</p> +<p id="footer">npm-install — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/cli/npm-link.html b/deps/npm/html/doc/cli/npm-link.html index 86eb8d1219a..846f7417f9a 100644 --- a/deps/npm/html/doc/cli/npm-link.html +++ b/deps/npm/html/doc/cli/npm-link.html @@ -23,7 +23,7 @@ symbolic link from <code>prefix/package-name</code> to the current folder.</p> <p>Next, in some other location, <code>npm link package-name</code> will create a symlink from the local <code>node_modules</code> folder to the global symlink.</p> -<p>Note that <code>package-name</code> is taken from <code>package.json</code> , +<p>Note that <code>package-name</code> is taken from <code>package.json</code>, not from directory name.</p> <p>When creating tarballs for <code>npm publish</code>, the linked packages are @@ -61,7 +61,7 @@ installation target into your project's <code>node_modules</code> folder.</p <ul><li><a href="../misc/npm-developers.html">npm-developers(7)</a></li><li><a href="../misc/npm-faq.html">npm-faq(7)</a></li><li><a href="../files/package.json.html">package.json(5)</a></li><li><a href="../cli/npm-install.html">npm-install(1)</a></li><li><a href="../files/npm-folders.html">npm-folders(5)</a></li><li><a href="../cli/npm-config.html">npm-config(1)</a></li><li><a href="../misc/npm-config.html">npm-config(7)</a></li><li><a href="../files/npmrc.html">npmrc(5)</a></li></ul> </div> -<p id="footer">npm-link — npm@1.3.6</p> +<p id="footer">npm-link — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/cli/npm-ls.html b/deps/npm/html/doc/cli/npm-ls.html index 108261ae155..a442de67b94 100644 --- a/deps/npm/html/doc/cli/npm-ls.html +++ b/deps/npm/html/doc/cli/npm-ls.html @@ -25,7 +25,7 @@ limit the results to only the paths to the packages named. Note that nested packages will <em>also</em> show the paths to the specified packages. For example, running <code>npm ls promzard</code> in npm's source tree will show:</p> -<pre><code>npm@1.3.6 /path/to/npm +<pre><code>npm@1.3.8 /path/to/npm └─┬ init-package-json@0.0.4 └── promzard@0.1.5</code></pre> @@ -68,7 +68,7 @@ project.</p> <ul><li><a href="../cli/npm-config.html">npm-config(1)</a></li><li><a href="../misc/npm-config.html">npm-config(7)</a></li><li><a href="../files/npmrc.html">npmrc(5)</a></li><li><a href="../files/npm-folders.html">npm-folders(5)</a></li><li><a href="../cli/npm-install.html">npm-install(1)</a></li><li><a href="../cli/npm-link.html">npm-link(1)</a></li><li><a href="../cli/npm-prune.html">npm-prune(1)</a></li><li><a href="../cli/npm-outdated.html">npm-outdated(1)</a></li><li><a href="../cli/npm-update.html">npm-update(1)</a></li></ul> </div> -<p id="footer">npm-ls — npm@1.3.6</p> +<p id="footer">npm-ls — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/cli/npm-outdated.html b/deps/npm/html/doc/cli/npm-outdated.html index 2bb3d81b363..5f536194e4d 100644 --- a/deps/npm/html/doc/cli/npm-outdated.html +++ b/deps/npm/html/doc/cli/npm-outdated.html @@ -21,7 +21,7 @@ packages are currently outdated.</p> <ul><li><a href="../cli/npm-update.html">npm-update(1)</a></li><li><a href="../misc/npm-registry.html">npm-registry(7)</a></li><li><a href="../files/npm-folders.html">npm-folders(5)</a></li></ul> </div> -<p id="footer">npm-outdated — npm@1.3.6</p> +<p id="footer">npm-outdated — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/cli/npm-owner.html b/deps/npm/html/doc/cli/npm-owner.html index 8cf0b1ca896..20252050d0b 100644 --- a/deps/npm/html/doc/cli/npm-owner.html +++ b/deps/npm/html/doc/cli/npm-owner.html @@ -34,7 +34,7 @@ that is not implemented at this time.</p> <ul><li><a href="../cli/npm-publish.html">npm-publish(1)</a></li><li><a href="../misc/npm-registry.html">npm-registry(7)</a></li><li><a href="../cli/npm-adduser.html">npm-adduser(1)</a></li><li><a href="../misc/npm-disputes.html">npm-disputes(7)</a></li></ul> </div> -<p id="footer">npm-owner — npm@1.3.6</p> +<p id="footer">npm-owner — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/cli/npm-pack.html b/deps/npm/html/doc/cli/npm-pack.html index 40568ce7696..a82989a18ff 100644 --- a/deps/npm/html/doc/cli/npm-pack.html +++ b/deps/npm/html/doc/cli/npm-pack.html @@ -29,7 +29,7 @@ overwritten the second time.</p> <ul><li><a href="../cli/npm-cache.html">npm-cache(1)</a></li><li><a href="../cli/npm-publish.html">npm-publish(1)</a></li><li><a href="../cli/npm-config.html">npm-config(1)</a></li><li><a href="../misc/npm-config.html">npm-config(7)</a></li><li><a href="../files/npmrc.html">npmrc(5)</a></li></ul> </div> -<p id="footer">npm-pack — npm@1.3.6</p> +<p id="footer">npm-pack — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/cli/npm-prefix.html b/deps/npm/html/doc/cli/npm-prefix.html index fb843d72eac..092c2a77e90 100644 --- a/deps/npm/html/doc/cli/npm-prefix.html +++ b/deps/npm/html/doc/cli/npm-prefix.html @@ -20,7 +20,7 @@ <ul><li><a href="../cli/npm-root.html">npm-root(1)</a></li><li><a href="../cli/npm-bin.html">npm-bin(1)</a></li><li><a href="../files/npm-folders.html">npm-folders(5)</a></li><li><a href="../cli/npm-config.html">npm-config(1)</a></li><li><a href="../misc/npm-config.html">npm-config(7)</a></li><li><a href="../files/npmrc.html">npmrc(5)</a></li></ul> </div> -<p id="footer">npm-prefix — npm@1.3.6</p> +<p id="footer">npm-prefix — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/cli/npm-prune.html b/deps/npm/html/doc/cli/npm-prune.html index 13364802c6e..b88b8a6d961 100644 --- a/deps/npm/html/doc/cli/npm-prune.html +++ b/deps/npm/html/doc/cli/npm-prune.html @@ -25,7 +25,7 @@ package's dependencies list.</p> <ul><li><a href="../cli/npm-rm.html">npm-rm(1)</a></li><li><a href="../files/npm-folders.html">npm-folders(5)</a></li><li><a href="../cli/npm-ls.html">npm-ls(1)</a></li></ul> </div> -<p id="footer">npm-prune — npm@1.3.6</p> +<p id="footer">npm-prune — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/cli/npm-publish.html b/deps/npm/html/doc/cli/npm-publish.html index 20f21f346d3..644d5a8380a 100644 --- a/deps/npm/html/doc/cli/npm-publish.html +++ b/deps/npm/html/doc/cli/npm-publish.html @@ -29,7 +29,7 @@ the registry. Overwrites when the "--force" flag is set.</p> <ul><li><a href="../misc/npm-registry.html">npm-registry(7)</a></li><li><a href="../cli/npm-adduser.html">npm-adduser(1)</a></li><li><a href="../cli/npm-owner.html">npm-owner(1)</a></li><li><a href="../cli/npm-deprecate.html">npm-deprecate(1)</a></li><li><a href="../cli/npm-tag.html">npm-tag(1)</a></li></ul> </div> -<p id="footer">npm-publish — npm@1.3.6</p> +<p id="footer">npm-publish — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/cli/npm-rebuild.html b/deps/npm/html/doc/cli/npm-rebuild.html index 7c2ecc5dd52..162ec21b695 100644 --- a/deps/npm/html/doc/cli/npm-rebuild.html +++ b/deps/npm/html/doc/cli/npm-rebuild.html @@ -25,7 +25,7 @@ the new binary.</p> <ul><li><a href="../cli/npm-build.html">npm-build(1)</a></li><li><a href="../cli/npm-install.html">npm-install(1)</a></li></ul> </div> -<p id="footer">npm-rebuild — npm@1.3.6</p> +<p id="footer">npm-rebuild — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/cli/npm-restart.html b/deps/npm/html/doc/cli/npm-restart.html index cf379d9ee10..4f3a7dec583 100644 --- a/deps/npm/html/doc/cli/npm-restart.html +++ b/deps/npm/html/doc/cli/npm-restart.html @@ -24,7 +24,7 @@ the "start" script.</p> <ul><li><a href="../cli/npm-run-script.html">npm-run-script(1)</a></li><li><a href="../misc/npm-scripts.html">npm-scripts(7)</a></li><li><a href="../cli/npm-test.html">npm-test(1)</a></li><li><a href="../cli/npm-start.html">npm-start(1)</a></li><li><a href="../cli/npm-stop.html">npm-stop(1)</a></li></ul> </div> -<p id="footer">npm-restart — npm@1.3.6</p> +<p id="footer">npm-restart — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/cli/npm-rm.html b/deps/npm/html/doc/cli/npm-rm.html index be0da522b19..fe365ee0251 100644 --- a/deps/npm/html/doc/cli/npm-rm.html +++ b/deps/npm/html/doc/cli/npm-rm.html @@ -22,7 +22,7 @@ on its behalf.</p> <ul><li><a href="../cli/npm-prune.html">npm-prune(1)</a></li><li><a href="../cli/npm-install.html">npm-install(1)</a></li><li><a href="../files/npm-folders.html">npm-folders(5)</a></li><li><a href="../cli/npm-config.html">npm-config(1)</a></li><li><a href="../misc/npm-config.html">npm-config(7)</a></li><li><a href="../files/npmrc.html">npmrc(5)</a></li></ul> </div> -<p id="footer">npm-rm — npm@1.3.6</p> +<p id="footer">npm-rm — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/cli/npm-root.html b/deps/npm/html/doc/cli/npm-root.html index 7d74933c477..e463159e1e1 100644 --- a/deps/npm/html/doc/cli/npm-root.html +++ b/deps/npm/html/doc/cli/npm-root.html @@ -20,7 +20,7 @@ <ul><li><a href="../cli/npm-prefix.html">npm-prefix(1)</a></li><li><a href="../cli/npm-bin.html">npm-bin(1)</a></li><li><a href="../files/npm-folders.html">npm-folders(5)</a></li><li><a href="../cli/npm-config.html">npm-config(1)</a></li><li><a href="../misc/npm-config.html">npm-config(7)</a></li><li><a href="../files/npmrc.html">npmrc(5)</a></li></ul> </div> -<p id="footer">npm-root — npm@1.3.6</p> +<p id="footer">npm-root — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/cli/npm-run-script.html b/deps/npm/html/doc/cli/npm-run-script.html index 3a74e0e1400..ef19c11d4e3 100644 --- a/deps/npm/html/doc/cli/npm-run-script.html +++ b/deps/npm/html/doc/cli/npm-run-script.html @@ -23,7 +23,7 @@ called directly, as well.</p> <ul><li><a href="../misc/npm-scripts.html">npm-scripts(7)</a></li><li><a href="../cli/npm-test.html">npm-test(1)</a></li><li><a href="../cli/npm-start.html">npm-start(1)</a></li><li><a href="../cli/npm-restart.html">npm-restart(1)</a></li><li><a href="../cli/npm-stop.html">npm-stop(1)</a></li></ul> </div> -<p id="footer">npm-run-script — npm@1.3.6</p> +<p id="footer">npm-run-script — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/cli/npm-search.html b/deps/npm/html/doc/cli/npm-search.html index f44f74fec06..7d8d5320f32 100644 --- a/deps/npm/html/doc/cli/npm-search.html +++ b/deps/npm/html/doc/cli/npm-search.html @@ -24,7 +24,7 @@ expression characters must be escaped or quoted in most shells.)</p> <ul><li><a href="../misc/npm-registry.html">npm-registry(7)</a></li><li><a href="../cli/npm-config.html">npm-config(1)</a></li><li><a href="../misc/npm-config.html">npm-config(7)</a></li><li><a href="../files/npmrc.html">npmrc(5)</a></li><li><a href="../cli/npm-view.html">npm-view(1)</a></li></ul> </div> -<p id="footer">npm-search — npm@1.3.6</p> +<p id="footer">npm-search — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/cli/npm-shrinkwrap.html b/deps/npm/html/doc/cli/npm-shrinkwrap.html index 4089a9daf97..48236f3fbd4 100644 --- a/deps/npm/html/doc/cli/npm-shrinkwrap.html +++ b/deps/npm/html/doc/cli/npm-shrinkwrap.html @@ -183,7 +183,7 @@ contents rather than versions.</p> <ul><li><a href="../cli/npm-install.html">npm-install(1)</a></li><li><a href="../files/package.json.html">package.json(5)</a></li><li><a href="../cli/npm-ls.html">npm-ls(1)</a></li></ul> </div> -<p id="footer">npm-shrinkwrap — npm@1.3.6</p> +<p id="footer">npm-shrinkwrap — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/cli/npm-star.html b/deps/npm/html/doc/cli/npm-star.html index 5ed45d31dc4..e4561fd0c2d 100644 --- a/deps/npm/html/doc/cli/npm-star.html +++ b/deps/npm/html/doc/cli/npm-star.html @@ -26,7 +26,7 @@ a vaguely positive way to show that you care.</p> <ul><li><a href="../cli/npm-view.html">npm-view(1)</a></li><li><a href="../cli/npm-whoami.html">npm-whoami(1)</a></li><li><a href="../cli/npm-adduser.html">npm-adduser(1)</a></li></ul> </div> -<p id="footer">npm-star — npm@1.3.6</p> +<p id="footer">npm-star — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/cli/npm-stars.html b/deps/npm/html/doc/cli/npm-stars.html index 72d68037d0d..854a35453ce 100644 --- a/deps/npm/html/doc/cli/npm-stars.html +++ b/deps/npm/html/doc/cli/npm-stars.html @@ -25,7 +25,7 @@ you will most certainly enjoy this command.</p> <ul><li><a href="../cli/npm-star.html">npm-star(1)</a></li><li><a href="../cli/npm-view.html">npm-view(1)</a></li><li><a href="../cli/npm-whoami.html">npm-whoami(1)</a></li><li><a href="../cli/npm-adduser.html">npm-adduser(1)</a></li></ul> </div> -<p id="footer">npm-stars — npm@1.3.6</p> +<p id="footer">npm-stars — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/cli/npm-start.html b/deps/npm/html/doc/cli/npm-start.html index 37f90396240..eb54a6a96bd 100644 --- a/deps/npm/html/doc/cli/npm-start.html +++ b/deps/npm/html/doc/cli/npm-start.html @@ -20,7 +20,7 @@ <ul><li><a href="../cli/npm-run-script.html">npm-run-script(1)</a></li><li><a href="../misc/npm-scripts.html">npm-scripts(7)</a></li><li><a href="../cli/npm-test.html">npm-test(1)</a></li><li><a href="../cli/npm-restart.html">npm-restart(1)</a></li><li><a href="../cli/npm-stop.html">npm-stop(1)</a></li></ul> </div> -<p id="footer">npm-start — npm@1.3.6</p> +<p id="footer">npm-start — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/cli/npm-stop.html b/deps/npm/html/doc/cli/npm-stop.html index 8ab1518d438..bbb196ccdb0 100644 --- a/deps/npm/html/doc/cli/npm-stop.html +++ b/deps/npm/html/doc/cli/npm-stop.html @@ -20,7 +20,7 @@ <ul><li><a href="../cli/npm-run-script.html">npm-run-script(1)</a></li><li><a href="../misc/npm-scripts.html">npm-scripts(7)</a></li><li><a href="../cli/npm-test.html">npm-test(1)</a></li><li><a href="../cli/npm-start.html">npm-start(1)</a></li><li><a href="../cli/npm-restart.html">npm-restart(1)</a></li></ul> </div> -<p id="footer">npm-stop — npm@1.3.6</p> +<p id="footer">npm-stop — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/cli/npm-submodule.html b/deps/npm/html/doc/cli/npm-submodule.html index f53682e091d..3612b6bc07a 100644 --- a/deps/npm/html/doc/cli/npm-submodule.html +++ b/deps/npm/html/doc/cli/npm-submodule.html @@ -33,7 +33,7 @@ dependencies into the submodule folder.</p> <ul><li><a href="../files/package.json.html">package.json(5)</a></li><li>git help submodule</li></ul> </div> -<p id="footer">npm-submodule — npm@1.3.6</p> +<p id="footer">npm-submodule — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/cli/npm-tag.html b/deps/npm/html/doc/cli/npm-tag.html index 859ad7fa7eb..28c3e8467b7 100644 --- a/deps/npm/html/doc/cli/npm-tag.html +++ b/deps/npm/html/doc/cli/npm-tag.html @@ -21,7 +21,7 @@ <ul><li><a href="../cli/npm-publish.html">npm-publish(1)</a></li><li><a href="../misc/npm-registry.html">npm-registry(7)</a></li><li><a href="../cli/npm-config.html">npm-config(1)</a></li><li><a href="../misc/npm-config.html">npm-config(7)</a></li><li><a href="../files/npmrc.html">npmrc(5)</a></li></ul> </div> -<p id="footer">npm-tag — npm@1.3.6</p> +<p id="footer">npm-tag — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/cli/npm-test.html b/deps/npm/html/doc/cli/npm-test.html index c6f621d1ae5..518ed64c639 100644 --- a/deps/npm/html/doc/cli/npm-test.html +++ b/deps/npm/html/doc/cli/npm-test.html @@ -23,7 +23,7 @@ true.</p> <ul><li><a href="../cli/npm-run-script.html">npm-run-script(1)</a></li><li><a href="../misc/npm-scripts.html">npm-scripts(7)</a></li><li><a href="../cli/npm-start.html">npm-start(1)</a></li><li><a href="../cli/npm-restart.html">npm-restart(1)</a></li><li><a href="../cli/npm-stop.html">npm-stop(1)</a></li></ul> </div> -<p id="footer">npm-test — npm@1.3.6</p> +<p id="footer">npm-test — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/cli/npm-uninstall.html b/deps/npm/html/doc/cli/npm-uninstall.html index 3fb5e03c657..e9dfea542db 100644 --- a/deps/npm/html/doc/cli/npm-uninstall.html +++ b/deps/npm/html/doc/cli/npm-uninstall.html @@ -22,7 +22,7 @@ on its behalf.</p> <ul><li><a href="../cli/npm-prune.html">npm-prune(1)</a></li><li><a href="../cli/npm-install.html">npm-install(1)</a></li><li><a href="../files/npm-folders.html">npm-folders(5)</a></li><li><a href="../cli/npm-config.html">npm-config(1)</a></li><li><a href="../misc/npm-config.html">npm-config(7)</a></li><li><a href="../files/npmrc.html">npmrc(5)</a></li></ul> </div> -<p id="footer">npm-uninstall — npm@1.3.6</p> +<p id="footer">npm-uninstall — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/cli/npm-unpublish.html b/deps/npm/html/doc/cli/npm-unpublish.html index 0648227e070..6398796d6a7 100644 --- a/deps/npm/html/doc/cli/npm-unpublish.html +++ b/deps/npm/html/doc/cli/npm-unpublish.html @@ -34,7 +34,7 @@ the root package entry is removed from the registry entirely.</p> <ul><li><a href="../cli/npm-deprecate.html">npm-deprecate(1)</a></li><li><a href="../cli/npm-publish.html">npm-publish(1)</a></li><li><a href="../misc/npm-registry.html">npm-registry(7)</a></li><li><a href="../cli/npm-adduser.html">npm-adduser(1)</a></li><li><a href="../cli/npm-owner.html">npm-owner(1)</a></li></ul> </div> -<p id="footer">npm-unpublish — npm@1.3.6</p> +<p id="footer">npm-unpublish — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/cli/npm-update.html b/deps/npm/html/doc/cli/npm-update.html index c9195e6c1a6..f9f4fabf742 100644 --- a/deps/npm/html/doc/cli/npm-update.html +++ b/deps/npm/html/doc/cli/npm-update.html @@ -26,7 +26,7 @@ If no package name is specified, all packages in the specified location (global <ul><li><a href="../cli/npm-install.html">npm-install(1)</a></li><li><a href="../cli/npm-outdated.html">npm-outdated(1)</a></li><li><a href="../misc/npm-registry.html">npm-registry(7)</a></li><li><a href="../files/npm-folders.html">npm-folders(5)</a></li><li><a href="../cli/npm-ls.html">npm-ls(1)</a></li></ul> </div> -<p id="footer">npm-update — npm@1.3.6</p> +<p id="footer">npm-update — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/cli/npm-version.html b/deps/npm/html/doc/cli/npm-version.html index 79c38a286b9..b63a6375d96 100644 --- a/deps/npm/html/doc/cli/npm-version.html +++ b/deps/npm/html/doc/cli/npm-version.html @@ -47,9 +47,9 @@ Enter passphrase:</code></pre> <h2 id="SEE-ALSO">SEE ALSO</h2> -<ul><li><a href="../cli/npm-init.html">npm-init(1)</a></li><li><a href="../files/package.json.html">package.json(5)</a></li><li><a href="../misc/npm-semver.html">npm-semver(7)</a></li></ul> +<ul><li><a href="../cli/npm-init.html">npm-init(1)</a></li><li><a href="../files/package.json.html">package.json(5)</a></li><li><a href="../misc/semver.html">semver(7)</a></li></ul> </div> -<p id="footer">npm-version — npm@1.3.6</p> +<p id="footer">npm-version — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/cli/npm-view.html b/deps/npm/html/doc/cli/npm-view.html index ea9733ce4e4..2a5116c2cdb 100644 --- a/deps/npm/html/doc/cli/npm-view.html +++ b/deps/npm/html/doc/cli/npm-view.html @@ -90,7 +90,7 @@ the field name.</p> <ul><li><a href="../cli/npm-search.html">npm-search(1)</a></li><li><a href="../misc/npm-registry.html">npm-registry(7)</a></li><li><a href="../cli/npm-config.html">npm-config(1)</a></li><li><a href="../misc/npm-config.html">npm-config(7)</a></li><li><a href="../files/npmrc.html">npmrc(5)</a></li><li><a href="../cli/npm-docs.html">npm-docs(1)</a></li></ul> </div> -<p id="footer">npm-view — npm@1.3.6</p> +<p id="footer">npm-view — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/cli/npm-whoami.html b/deps/npm/html/doc/cli/npm-whoami.html index f6d547a47f0..11595fa1c5f 100644 --- a/deps/npm/html/doc/cli/npm-whoami.html +++ b/deps/npm/html/doc/cli/npm-whoami.html @@ -20,7 +20,7 @@ <ul><li><a href="../cli/npm-config.html">npm-config(1)</a></li><li><a href="../misc/npm-config.html">npm-config(7)</a></li><li><a href="../files/npmrc.html">npmrc(5)</a></li><li><a href="../cli/npm-adduser.html">npm-adduser(1)</a></li></ul> </div> -<p id="footer">npm-whoami — npm@1.3.6</p> +<p id="footer">npm-whoami — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/cli/npm.html b/deps/npm/html/doc/cli/npm.html index 115d40deda2..0bdc68e5c2c 100644 --- a/deps/npm/html/doc/cli/npm.html +++ b/deps/npm/html/doc/cli/npm.html @@ -14,7 +14,7 @@ <h2 id="VERSION">VERSION</h2> -<p>1.3.6</p> +<p>1.3.8</p> <h2 id="DESCRIPTION">DESCRIPTION</h2> @@ -135,7 +135,7 @@ will no doubt tell you to put the output in a gist or email.</p> <ul><li><a href="../cli/npm-help.html">npm-help(1)</a></li><li><a href="../misc/npm-faq.html">npm-faq(7)</a></li><li><a href="../../doc/README.html">README</a></li><li><a href="../files/package.json.html">package.json(5)</a></li><li><a href="../cli/npm-install.html">npm-install(1)</a></li><li><a href="../cli/npm-config.html">npm-config(1)</a></li><li><a href="../misc/npm-config.html">npm-config(7)</a></li><li><a href="../files/npmrc.html">npmrc(5)</a></li><li><a href="../misc/npm-index.html">npm-index(7)</a></li><li><a href="../api/npm.html">npm(3)</a></li></ul> </div> -<p id="footer">npm — npm@1.3.6</p> +<p id="footer">npm — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/cli/repo.html b/deps/npm/html/doc/cli/repo.html new file mode 100644 index 00000000000..8df68e46d37 --- /dev/null +++ b/deps/npm/html/doc/cli/repo.html @@ -0,0 +1,64 @@ +<!doctype html> +<html> + <title>repo</title> + <meta http-equiv="content-type" value="text/html;utf-8"> + <link rel="stylesheet" type="text/css" href="../../static/style.css"> + + <body> + <div id="wrapper"> +<h1><a href="../cli/npm-repo.html">npm-repo</a></h1> <p>Open package repository page in the browser</p> + +<h2 id="SYNOPSIS">SYNOPSIS</h2> + +<pre><code>npm repo <pkgname></code></pre> + +<h2 id="DESCRIPTION">DESCRIPTION</h2> + +<p>This command tries to guess at the likely location of a package's +repository URL, and then tries to open it using the <code>--browser</code> +config param.</p> + +<h2 id="CONFIGURATION">CONFIGURATION</h2> + +<h3 id="browser">browser</h3> + +<ul><li>Default: OS X: <code>"open"</code>, Windows: <code>"start"</code>, Others: <code>"xdg-open"</code></li><li>Type: String</li></ul> + +<p>The browser that is called by the <code>npm repo</code> command to open websites.</p> + +<h2 id="SEE-ALSO">SEE ALSO</h2> + +<ul><li><a href="../cli/npm-docs.html">npm-docs(1)</a></li><li><a href="../cli/npm-config.html">npm-config(1)</a></li></ul> +</div> +<p id="footer">repo — npm@1.3.8</p> +<script> +;(function () { +var wrapper = document.getElementById("wrapper") +var els = Array.prototype.slice.call(wrapper.getElementsByTagName("*"), 0) + .filter(function (el) { + return el.parentNode === wrapper + && el.tagName.match(/H[1-6]/) + && el.id + }) +var l = 2 + , toc = document.createElement("ul") +toc.innerHTML = els.map(function (el) { + var i = el.tagName.charAt(1) + , out = "" + while (i > l) { + out += "<ul>" + l ++ + } + while (i < l) { + out += "</ul>" + l -- + } + out += "<li><a href='#" + el.id + "'>" + + ( el.innerText || el.text || el.innerHTML) + + "</a>" + return out +}).join("\n") +toc.id = "toc" +document.body.appendChild(toc) +})() +</script> diff --git a/deps/npm/html/doc/files/npm-folders.html b/deps/npm/html/doc/files/npm-folders.html index 0d49c4e74c0..b23f6b88573 100644 --- a/deps/npm/html/doc/files/npm-folders.html +++ b/deps/npm/html/doc/files/npm-folders.html @@ -205,7 +205,7 @@ cannot be found elsewhere. See <code><a href="../files/package.json.html">packa <ul><li><a href="../misc/npm-faq.html">npm-faq(7)</a></li><li><a href="../files/package.json.html">package.json(5)</a></li><li><a href="../cli/npm-install.html">npm-install(1)</a></li><li><a href="../cli/npm-pack.html">npm-pack(1)</a></li><li><a href="../cli/npm-cache.html">npm-cache(1)</a></li><li><a href="../cli/npm-config.html">npm-config(1)</a></li><li><a href="../files/npmrc.html">npmrc(5)</a></li><li><a href="../misc/npm-config.html">npm-config(7)</a></li><li><a href="../cli/npm-publish.html">npm-publish(1)</a></li></ul> </div> -<p id="footer">npm-folders — npm@1.3.6</p> +<p id="footer">npm-folders — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/files/npm-global.html b/deps/npm/html/doc/files/npm-global.html index 0d49c4e74c0..b23f6b88573 100644 --- a/deps/npm/html/doc/files/npm-global.html +++ b/deps/npm/html/doc/files/npm-global.html @@ -205,7 +205,7 @@ cannot be found elsewhere. See <code><a href="../files/package.json.html">packa <ul><li><a href="../misc/npm-faq.html">npm-faq(7)</a></li><li><a href="../files/package.json.html">package.json(5)</a></li><li><a href="../cli/npm-install.html">npm-install(1)</a></li><li><a href="../cli/npm-pack.html">npm-pack(1)</a></li><li><a href="../cli/npm-cache.html">npm-cache(1)</a></li><li><a href="../cli/npm-config.html">npm-config(1)</a></li><li><a href="../files/npmrc.html">npmrc(5)</a></li><li><a href="../misc/npm-config.html">npm-config(7)</a></li><li><a href="../cli/npm-publish.html">npm-publish(1)</a></li></ul> </div> -<p id="footer">npm-folders — npm@1.3.6</p> +<p id="footer">npm-folders — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/files/npm-json.html b/deps/npm/html/doc/files/npm-json.html index 5cc92407b25..32cfe95f2c7 100644 --- a/deps/npm/html/doc/files/npm-json.html +++ b/deps/npm/html/doc/files/npm-json.html @@ -58,17 +58,7 @@ changes to the version.</p> <a href="https://github.com/isaacs/node-semver">node-semver</a>, which is bundled with npm as a dependency. (<code>npm install semver</code> to use it yourself.)</p> -<p>Here's how npm's semver implementation deviates from what's on semver.org:</p> - -<ul><li>Versions can start with "v"</li><li>A numeric item separated from the main three-number version by a hyphen -will be interpreted as a "build" number, and will <em>increase</em> the version. -But, if the tag is not a number separated by a hyphen, then it's treated -as a pre-release tag, and is <em>less than</em> the version without a tag. -So, <code>0.1.2-7 > 0.1.2-7-beta > 0.1.2-6 > 0.1.2 > 0.1.2beta</code></li></ul> - -<p>This is a little bit confusing to explain, but matches what you see in practice -when people create tags in git like "v1.2.3" and then do "git describe" to generate -a patch version.</p> +<p>More on version numbers and ranges at <a href="../misc/semver.html">semver(7)</a>.</p> <h2 id="description">description</h2> @@ -323,17 +313,17 @@ configs.</p> <h2 id="dependencies">dependencies</h2> -<p>Dependencies are specified with a simple hash of package name to version -range. The version range is EITHER a string which has one or more -space-separated descriptors, OR a range like "fromVersion - toVersion"</p> +<p>Dependencies are specified with a simple hash of package name to +version range. The version range is a string which has one or more +space-separated descriptors. Dependencies can also be identified with +a tarball or git URL.</p> -<p><strong>Please do not put test harnesses in your <code>dependencies</code> hash.</strong> See -<code>devDependencies</code>, below.</p> +<p><strong>Please do not put test harnesses or transpilers in your +<code>dependencies</code> hash.</strong> See <code>devDependencies</code>, below.</p> -<p>Version range descriptors may be any of the following styles, where "version" -is a semver compatible version identifier.</p> +<p>See <a href="../misc/semver.html">semver(7)</a> for more details about specifying version ranges.</p> -<ul><li><code>version</code> Must match <code>version</code> exactly</li><li><code>=version</code> Same as just <code>version</code></li><li><code>>version</code> Must be greater than <code>version</code></li><li><code>>=version</code> etc</li><li><code><version</code></li><li><code><=version</code></li><li><code>~version</code> See 'Tilde Version Ranges' below</li><li><code>1.2.x</code> See 'X Version Ranges' below</li><li><code>http://...</code> See 'URLs as Dependencies' below</li><li><code>*</code> Matches any version</li><li><code>""</code> (just an empty string) Same as <code>*</code></li><li><code>version1 - version2</code> Same as <code>>=version1 <=version2</code>.</li><li><code>range1 || range2</code> Passes if either range1 or range2 are satisfied.</li><li><code>git...</code> See 'Git URLs as Dependencies' below</li></ul> +<ul><li><code>version</code> Must match <code>version</code> exactly</li><li><code>>version</code> Must be greater than <code>version</code></li><li><code>>=version</code> etc</li><li><code><version</code></li><li><code><=version</code></li><li><code>~version</code> "Approximately equivalent to version" See <a href="../misc/semver.html">semver(7)</a></li><li><code>1.2.x</code> 1.2.0, 1.2.1, etc., but not 1.3.0</li><li><code>http://...</code> See 'URLs as Dependencies' below</li><li><code>*</code> Matches any version</li><li><code>""</code> (just an empty string) Same as <code>*</code></li><li><code>version1 - version2</code> Same as <code>>=version1 <=version2</code>.</li><li><code>range1 || range2</code> Passes if either range1 or range2 are satisfied.</li><li><code>git...</code> See 'Git URLs as Dependencies' below</li></ul> <p>For example, these are all valid:</p> @@ -351,33 +341,9 @@ is a semver compatible version identifier.</p> } }</code></pre> -<h3 id="Tilde-Version-Ranges">Tilde Version Ranges</h3> - -<p>A range specifier starting with a tilde <code>~</code> character is matched against -a version in the following fashion.</p> - -<ul><li>The version must be at least as high as the range.</li><li>The version must be less than the next major revision above the range.</li></ul> - -<p>For example, the following are equivalent:</p> - -<ul><li><code>"~1.2.3" = ">=1.2.3 <1.3.0"</code></li><li><code>"~1.2" = ">=1.2.0 <1.3.0"</code></li><li><code>"~1" = ">=1.0.0 <1.1.0"</code></li></ul> - -<h3 id="X-Version-Ranges">X Version Ranges</h3> - -<p>An "x" in a version range specifies that the version number must start -with the supplied digits, but any digit may be used in place of the x.</p> - -<p>The following are equivalent:</p> - -<ul><li><code>"1.2.x" = ">=1.2.0 <1.3.0"</code></li><li><code>"1.x.x" = ">=1.0.0 <2.0.0"</code></li><li><code>"1.2" = "1.2.x"</code></li><li><code>"1.x" = "1.x.x"</code></li><li><code>"1" = "1.x.x"</code></li></ul> - -<p>You may not supply a comparator with a version containing an x. Any -digits after the first "x" are ignored.</p> - <h3 id="URLs-as-Dependencies">URLs as Dependencies</h3> -<p>Starting with npm version 0.2.14, you may specify a tarball URL in place -of a version range.</p> +<p>You may specify a tarball URL in place of a version range.</p> <p>This tarball will be downloaded and installed locally to your package at install time.</p> @@ -404,11 +370,35 @@ the external test or documentation framework that you use.</p> <p>In this case, it's best to list these additional items in a <code>devDependencies</code> hash.</p> -<p>These things will be installed whenever the <code>--dev</code> configuration flag -is set. This flag is set automatically when doing <code>npm link</code> or when doing -<code>npm install</code> from the root of a package, and can be managed like any other npm +<p>These things will be installed when doing <code>npm link</code> or <code>npm install</code> +from the root of a package, and can be managed like any other npm configuration param. See <code><a href="../misc/npm-config.html">npm-config(7)</a></code> for more on the topic.</p> +<p>For build steps that are not platform-specific, such as compiling +CoffeeScript or other languages to JavaScript, use the <code>prepublish</code> +script to do this, and make the required package a devDependency.</p> + +<p>For example:</p> + +<p><code>json +{ "name": "ethopia-waza", + "description": "a delightfully fruity coffee varietal", + "version": "1.2.3", + "devDependencies": { + "coffee-script": "~1.6.3" + }, + "scripts": { + "prepublish": "coffee -o lib/ -c src/waza.coffee" + }, + "main": "lib/waza.js" +} +</code></p> + +<p>The <code>prepublish</code> script will be run before publishing, so that users +can consume the functionality without requiring them to compile it +themselves. In dev mode (ie, locally running <code>npm install</code>), it'll +run this script as well, so that you can test it easily.</p> + <h2 id="bundledDependencies">bundledDependencies</h2> <p>Array of package names that will be bundled when publishing the package.</p> @@ -449,7 +439,7 @@ if (foo) { <p>You can specify the version of node that your stuff works on:</p> -<pre><code>{ "engines" : { "node" : ">=0.1.27 <0.1.30" } }</code></pre> +<pre><code>{ "engines" : { "node" : ">=0.10.3 <0.12" } }</code></pre> <p>And, like with dependencies, if you don't specify the version (or if you specify "*" as the version), then any version of node will do.</p> @@ -544,9 +534,9 @@ overridden.</p> <h2 id="SEE-ALSO">SEE ALSO</h2> -<ul><li><a href="../misc/npm-semver.html">npm-semver(7)</a></li><li><a href="../cli/npm-init.html">npm-init(1)</a></li><li><a href="../cli/npm-version.html">npm-version(1)</a></li><li><a href="../cli/npm-config.html">npm-config(1)</a></li><li><a href="../misc/npm-config.html">npm-config(7)</a></li><li><a href="../cli/npm-help.html">npm-help(1)</a></li><li><a href="../misc/npm-faq.html">npm-faq(7)</a></li><li><a href="../cli/npm-install.html">npm-install(1)</a></li><li><a href="../cli/npm-publish.html">npm-publish(1)</a></li><li><a href="../cli/npm-rm.html">npm-rm(1)</a></li></ul> +<ul><li><a href="../misc/semver.html">semver(7)</a></li><li><a href="../cli/npm-init.html">npm-init(1)</a></li><li><a href="../cli/npm-version.html">npm-version(1)</a></li><li><a href="../cli/npm-config.html">npm-config(1)</a></li><li><a href="../misc/npm-config.html">npm-config(7)</a></li><li><a href="../cli/npm-help.html">npm-help(1)</a></li><li><a href="../misc/npm-faq.html">npm-faq(7)</a></li><li><a href="../cli/npm-install.html">npm-install(1)</a></li><li><a href="../cli/npm-publish.html">npm-publish(1)</a></li><li><a href="../cli/npm-rm.html">npm-rm(1)</a></li></ul> </div> -<p id="footer">package.json — npm@1.3.6</p> +<p id="footer">package.json — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/files/npmrc.html b/deps/npm/html/doc/files/npmrc.html index d616bf99b05..5a52f2445d7 100644 --- a/deps/npm/html/doc/files/npmrc.html +++ b/deps/npm/html/doc/files/npmrc.html @@ -59,7 +59,7 @@ manner.</p> <ul><li><a href="../files/npm-folders.html">npm-folders(5)</a></li><li><a href="../cli/npm-config.html">npm-config(1)</a></li><li><a href="../misc/npm-config.html">npm-config(7)</a></li><li><a href="../files/package.json.html">package.json(5)</a></li><li><a href="../cli/npm.html">npm(1)</a></li></ul> </div> -<p id="footer">npmrc — npm@1.3.6</p> +<p id="footer">npmrc — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/files/package.json.html b/deps/npm/html/doc/files/package.json.html index 5cc92407b25..32cfe95f2c7 100644 --- a/deps/npm/html/doc/files/package.json.html +++ b/deps/npm/html/doc/files/package.json.html @@ -58,17 +58,7 @@ changes to the version.</p> <a href="https://github.com/isaacs/node-semver">node-semver</a>, which is bundled with npm as a dependency. (<code>npm install semver</code> to use it yourself.)</p> -<p>Here's how npm's semver implementation deviates from what's on semver.org:</p> - -<ul><li>Versions can start with "v"</li><li>A numeric item separated from the main three-number version by a hyphen -will be interpreted as a "build" number, and will <em>increase</em> the version. -But, if the tag is not a number separated by a hyphen, then it's treated -as a pre-release tag, and is <em>less than</em> the version without a tag. -So, <code>0.1.2-7 > 0.1.2-7-beta > 0.1.2-6 > 0.1.2 > 0.1.2beta</code></li></ul> - -<p>This is a little bit confusing to explain, but matches what you see in practice -when people create tags in git like "v1.2.3" and then do "git describe" to generate -a patch version.</p> +<p>More on version numbers and ranges at <a href="../misc/semver.html">semver(7)</a>.</p> <h2 id="description">description</h2> @@ -323,17 +313,17 @@ configs.</p> <h2 id="dependencies">dependencies</h2> -<p>Dependencies are specified with a simple hash of package name to version -range. The version range is EITHER a string which has one or more -space-separated descriptors, OR a range like "fromVersion - toVersion"</p> +<p>Dependencies are specified with a simple hash of package name to +version range. The version range is a string which has one or more +space-separated descriptors. Dependencies can also be identified with +a tarball or git URL.</p> -<p><strong>Please do not put test harnesses in your <code>dependencies</code> hash.</strong> See -<code>devDependencies</code>, below.</p> +<p><strong>Please do not put test harnesses or transpilers in your +<code>dependencies</code> hash.</strong> See <code>devDependencies</code>, below.</p> -<p>Version range descriptors may be any of the following styles, where "version" -is a semver compatible version identifier.</p> +<p>See <a href="../misc/semver.html">semver(7)</a> for more details about specifying version ranges.</p> -<ul><li><code>version</code> Must match <code>version</code> exactly</li><li><code>=version</code> Same as just <code>version</code></li><li><code>>version</code> Must be greater than <code>version</code></li><li><code>>=version</code> etc</li><li><code><version</code></li><li><code><=version</code></li><li><code>~version</code> See 'Tilde Version Ranges' below</li><li><code>1.2.x</code> See 'X Version Ranges' below</li><li><code>http://...</code> See 'URLs as Dependencies' below</li><li><code>*</code> Matches any version</li><li><code>""</code> (just an empty string) Same as <code>*</code></li><li><code>version1 - version2</code> Same as <code>>=version1 <=version2</code>.</li><li><code>range1 || range2</code> Passes if either range1 or range2 are satisfied.</li><li><code>git...</code> See 'Git URLs as Dependencies' below</li></ul> +<ul><li><code>version</code> Must match <code>version</code> exactly</li><li><code>>version</code> Must be greater than <code>version</code></li><li><code>>=version</code> etc</li><li><code><version</code></li><li><code><=version</code></li><li><code>~version</code> "Approximately equivalent to version" See <a href="../misc/semver.html">semver(7)</a></li><li><code>1.2.x</code> 1.2.0, 1.2.1, etc., but not 1.3.0</li><li><code>http://...</code> See 'URLs as Dependencies' below</li><li><code>*</code> Matches any version</li><li><code>""</code> (just an empty string) Same as <code>*</code></li><li><code>version1 - version2</code> Same as <code>>=version1 <=version2</code>.</li><li><code>range1 || range2</code> Passes if either range1 or range2 are satisfied.</li><li><code>git...</code> See 'Git URLs as Dependencies' below</li></ul> <p>For example, these are all valid:</p> @@ -351,33 +341,9 @@ is a semver compatible version identifier.</p> } }</code></pre> -<h3 id="Tilde-Version-Ranges">Tilde Version Ranges</h3> - -<p>A range specifier starting with a tilde <code>~</code> character is matched against -a version in the following fashion.</p> - -<ul><li>The version must be at least as high as the range.</li><li>The version must be less than the next major revision above the range.</li></ul> - -<p>For example, the following are equivalent:</p> - -<ul><li><code>"~1.2.3" = ">=1.2.3 <1.3.0"</code></li><li><code>"~1.2" = ">=1.2.0 <1.3.0"</code></li><li><code>"~1" = ">=1.0.0 <1.1.0"</code></li></ul> - -<h3 id="X-Version-Ranges">X Version Ranges</h3> - -<p>An "x" in a version range specifies that the version number must start -with the supplied digits, but any digit may be used in place of the x.</p> - -<p>The following are equivalent:</p> - -<ul><li><code>"1.2.x" = ">=1.2.0 <1.3.0"</code></li><li><code>"1.x.x" = ">=1.0.0 <2.0.0"</code></li><li><code>"1.2" = "1.2.x"</code></li><li><code>"1.x" = "1.x.x"</code></li><li><code>"1" = "1.x.x"</code></li></ul> - -<p>You may not supply a comparator with a version containing an x. Any -digits after the first "x" are ignored.</p> - <h3 id="URLs-as-Dependencies">URLs as Dependencies</h3> -<p>Starting with npm version 0.2.14, you may specify a tarball URL in place -of a version range.</p> +<p>You may specify a tarball URL in place of a version range.</p> <p>This tarball will be downloaded and installed locally to your package at install time.</p> @@ -404,11 +370,35 @@ the external test or documentation framework that you use.</p> <p>In this case, it's best to list these additional items in a <code>devDependencies</code> hash.</p> -<p>These things will be installed whenever the <code>--dev</code> configuration flag -is set. This flag is set automatically when doing <code>npm link</code> or when doing -<code>npm install</code> from the root of a package, and can be managed like any other npm +<p>These things will be installed when doing <code>npm link</code> or <code>npm install</code> +from the root of a package, and can be managed like any other npm configuration param. See <code><a href="../misc/npm-config.html">npm-config(7)</a></code> for more on the topic.</p> +<p>For build steps that are not platform-specific, such as compiling +CoffeeScript or other languages to JavaScript, use the <code>prepublish</code> +script to do this, and make the required package a devDependency.</p> + +<p>For example:</p> + +<p><code>json +{ "name": "ethopia-waza", + "description": "a delightfully fruity coffee varietal", + "version": "1.2.3", + "devDependencies": { + "coffee-script": "~1.6.3" + }, + "scripts": { + "prepublish": "coffee -o lib/ -c src/waza.coffee" + }, + "main": "lib/waza.js" +} +</code></p> + +<p>The <code>prepublish</code> script will be run before publishing, so that users +can consume the functionality without requiring them to compile it +themselves. In dev mode (ie, locally running <code>npm install</code>), it'll +run this script as well, so that you can test it easily.</p> + <h2 id="bundledDependencies">bundledDependencies</h2> <p>Array of package names that will be bundled when publishing the package.</p> @@ -449,7 +439,7 @@ if (foo) { <p>You can specify the version of node that your stuff works on:</p> -<pre><code>{ "engines" : { "node" : ">=0.1.27 <0.1.30" } }</code></pre> +<pre><code>{ "engines" : { "node" : ">=0.10.3 <0.12" } }</code></pre> <p>And, like with dependencies, if you don't specify the version (or if you specify "*" as the version), then any version of node will do.</p> @@ -544,9 +534,9 @@ overridden.</p> <h2 id="SEE-ALSO">SEE ALSO</h2> -<ul><li><a href="../misc/npm-semver.html">npm-semver(7)</a></li><li><a href="../cli/npm-init.html">npm-init(1)</a></li><li><a href="../cli/npm-version.html">npm-version(1)</a></li><li><a href="../cli/npm-config.html">npm-config(1)</a></li><li><a href="../misc/npm-config.html">npm-config(7)</a></li><li><a href="../cli/npm-help.html">npm-help(1)</a></li><li><a href="../misc/npm-faq.html">npm-faq(7)</a></li><li><a href="../cli/npm-install.html">npm-install(1)</a></li><li><a href="../cli/npm-publish.html">npm-publish(1)</a></li><li><a href="../cli/npm-rm.html">npm-rm(1)</a></li></ul> +<ul><li><a href="../misc/semver.html">semver(7)</a></li><li><a href="../cli/npm-init.html">npm-init(1)</a></li><li><a href="../cli/npm-version.html">npm-version(1)</a></li><li><a href="../cli/npm-config.html">npm-config(1)</a></li><li><a href="../misc/npm-config.html">npm-config(7)</a></li><li><a href="../cli/npm-help.html">npm-help(1)</a></li><li><a href="../misc/npm-faq.html">npm-faq(7)</a></li><li><a href="../cli/npm-install.html">npm-install(1)</a></li><li><a href="../cli/npm-publish.html">npm-publish(1)</a></li><li><a href="../cli/npm-rm.html">npm-rm(1)</a></li></ul> </div> -<p id="footer">package.json — npm@1.3.6</p> +<p id="footer">package.json — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/index.html b/deps/npm/html/doc/index.html index 2517c0b7c2a..c223f0e69f2 100644 --- a/deps/npm/html/doc/index.html +++ b/deps/npm/html/doc/index.html @@ -198,6 +198,10 @@ <p>Display npm username</p> +<h2 id="repo-1"><a href="cli/repo.html">repo(1)</a></h2> + +<p>Open package repository page in the browser</p> + <h1>API Documentation</h1> <h2 id="npm-3"><a href="api/npm.html">npm(3)</a></h2> @@ -352,6 +356,10 @@ <p>Display npm username</p> +<h2 id="repo-3"><a href="api/repo.html">repo(3)</a></h2> + +<p>Open package repository page in the browser</p> + <h1>Files</h1> <h2 id="npm-folders-5"><a href="files/npm-folders.html">npm-folders(5)</a></h2> @@ -408,7 +416,7 @@ <p>The semantic versioner for npm</p> </div> -<p id="footer">npm-index — npm@1.3.6</p> +<p id="footer">npm-index — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/misc/npm-coding-style.html b/deps/npm/html/doc/misc/npm-coding-style.html index 962fd735720..c2a313b8fae 100644 --- a/deps/npm/html/doc/misc/npm-coding-style.html +++ b/deps/npm/html/doc/misc/npm-coding-style.html @@ -182,7 +182,7 @@ set to anything."</p> <ul><li><a href="../misc/npm-developers.html">npm-developers(7)</a></li><li><a href="../misc/npm-faq.html">npm-faq(7)</a></li><li><a href="../cli/npm.html">npm(1)</a></li></ul> </div> -<p id="footer">npm-coding-style — npm@1.3.6</p> +<p id="footer">npm-coding-style — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/misc/npm-config.html b/deps/npm/html/doc/misc/npm-config.html index 759cb106a89..a9768df5e8a 100644 --- a/deps/npm/html/doc/misc/npm-config.html +++ b/deps/npm/html/doc/misc/npm-config.html @@ -717,7 +717,7 @@ then answer "no" to any prompt.</p> <ul><li><a href="../cli/npm-config.html">npm-config(1)</a></li><li><a href="../misc/npm-config.html">npm-config(7)</a></li><li><a href="../files/npmrc.html">npmrc(5)</a></li><li><a href="../misc/npm-scripts.html">npm-scripts(7)</a></li><li><a href="../files/npm-folders.html">npm-folders(5)</a></li><li><a href="../cli/npm.html">npm(1)</a></li></ul> </div> -<p id="footer">npm-config — npm@1.3.6</p> +<p id="footer">npm-config — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/misc/npm-developers.html b/deps/npm/html/doc/misc/npm-developers.html index 5555fc6d2df..d71adb2ee7d 100644 --- a/deps/npm/html/doc/misc/npm-developers.html +++ b/deps/npm/html/doc/misc/npm-developers.html @@ -174,7 +174,7 @@ from a fresh checkout.</p> <ul><li><a href="../misc/npm-faq.html">npm-faq(7)</a></li><li><a href="../cli/npm.html">npm(1)</a></li><li><a href="../cli/npm-init.html">npm-init(1)</a></li><li><a href="../files/package.json.html">package.json(5)</a></li><li><a href="../misc/npm-scripts.html">npm-scripts(7)</a></li><li><a href="../cli/npm-publish.html">npm-publish(1)</a></li><li><a href="../cli/npm-adduser.html">npm-adduser(1)</a></li><li><a href="../misc/npm-registry.html">npm-registry(7)</a></li></ul> </div> -<p id="footer">npm-developers — npm@1.3.6</p> +<p id="footer">npm-developers — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/misc/npm-disputes.html b/deps/npm/html/doc/misc/npm-disputes.html index 21a8989f363..b05749eea62 100644 --- a/deps/npm/html/doc/misc/npm-disputes.html +++ b/deps/npm/html/doc/misc/npm-disputes.html @@ -91,7 +91,7 @@ things into it.</li></ol> <ul><li><a href="../misc/npm-registry.html">npm-registry(7)</a></li><li><a href="../cli/npm-owner.html">npm-owner(1)</a></li></ul> </div> -<p id="footer">npm-disputes — npm@1.3.6</p> +<p id="footer">npm-disputes — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/misc/npm-faq.html b/deps/npm/html/doc/misc/npm-faq.html index ef4c6fe2614..c442758dba9 100644 --- a/deps/npm/html/doc/misc/npm-faq.html +++ b/deps/npm/html/doc/misc/npm-faq.html @@ -340,7 +340,7 @@ There is not sufficient need to impose namespace rules on everyone.</p> <ul><li><a href="../cli/npm.html">npm(1)</a></li><li><a href="../misc/npm-developers.html">npm-developers(7)</a></li><li><a href="../files/package.json.html">package.json(5)</a></li><li><a href="../cli/npm-config.html">npm-config(1)</a></li><li><a href="../misc/npm-config.html">npm-config(7)</a></li><li><a href="../files/npmrc.html">npmrc(5)</a></li><li><a href="../misc/npm-config.html">npm-config(7)</a></li><li><a href="../files/npm-folders.html">npm-folders(5)</a></li></ul> </div> -<p id="footer">npm-faq — npm@1.3.6</p> +<p id="footer">npm-faq — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/misc/npm-index.html b/deps/npm/html/doc/misc/npm-index.html index ab25fa5faf3..4b571e07f31 100644 --- a/deps/npm/html/doc/misc/npm-index.html +++ b/deps/npm/html/doc/misc/npm-index.html @@ -198,6 +198,10 @@ <p>Display npm username</p> +<h2 id="repo-1"><a href="../cli/repo.html">repo(1)</a></h2> + +<p>Open package repository page in the browser</p> + <h1>API Documentation</h1> <h2 id="npm-3"><a href="../api/npm.html">npm(3)</a></h2> @@ -352,6 +356,10 @@ <p>Display npm username</p> +<h2 id="repo-3"><a href="../api/repo.html">repo(3)</a></h2> + +<p>Open package repository page in the browser</p> + <h1>Files</h1> <h2 id="npm-folders-5"><a href="../files/npm-folders.html">npm-folders(5)</a></h2> @@ -408,7 +416,7 @@ <p>The semantic versioner for npm</p> </div> -<p id="footer">npm-index — npm@1.3.6</p> +<p id="footer">npm-index — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/misc/npm-registry.html b/deps/npm/html/doc/misc/npm-registry.html index 9c6c0c3976b..fa88e9e9d6a 100644 --- a/deps/npm/html/doc/misc/npm-registry.html +++ b/deps/npm/html/doc/misc/npm-registry.html @@ -60,33 +60,8 @@ otherwise.</p> <h2 id="Do-I-have-to-use-couchdb-to-build-a-registry-that-npm-can-talk-to">Do I have to use couchdb to build a registry that npm can talk to?</h2> -<p>No, but it's way easier.</p> - -<h2 id="I-published-something-elsewhere-and-want-to-tell-the-npm-registry-about-it">I published something elsewhere, and want to tell the npm registry about it.</h2> - -<p>That is supported, but not using the npm client. You'll have to get -your hands dirty and do some HTTP. The request looks something like -this:</p> - -<pre><code>PUT /my-foreign-package -content-type:application/json -accept:application/json -authorization:Basic $base_64_encoded - -{ "name":"my-foreign-package" -, "maintainers":["owner","usernames"] -, "description":"A package that is hosted elsewhere" -, "keywords":["nih","my cheese smells the best"] -, "url":"http://my-different-registry.com/blerg/my-local-package" -}</code></pre> - -<p>(Keywords and description are optional, but recommended. Name, -maintainers, and url are required.)</p> - -<p>Then, when a user tries to install "my-foreign-package", it'll redirect -to your registry. If that doesn't resolve to a valid package entry, -then it'll fail, so please make sure that you understand the spec, and -ask for help on the <a href="mailto:npm-@googlegroups.com">npm-@googlegroups.com</a> mailing list.</p> +<p>No, but it's way easier. Basically, yes, you do, or you have to +effectively implement the entire CouchDB API anyway.</p> <h2 id="Is-there-a-website-or-something-to-see-package-docs-and-such">Is there a website or something to see package docs and such?</h2> @@ -96,7 +71,7 @@ ask for help on the <a href="mailto:npm-@googlegroups.com">npm-@googlegroups.com <ul><li><a href="../cli/npm-config.html">npm-config(1)</a></li><li><a href="../misc/npm-config.html">npm-config(7)</a></li><li><a href="../files/npmrc.html">npmrc(5)</a></li><li><a href="../misc/npm-developers.html">npm-developers(7)</a></li><li><a href="../misc/npm-disputes.html">npm-disputes(7)</a></li></ul> </div> -<p id="footer">npm-registry — npm@1.3.6</p> +<p id="footer">npm-registry — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/misc/npm-scripts.html b/deps/npm/html/doc/misc/npm-scripts.html index d0343f9a7c6..6acb2a94b90 100644 --- a/deps/npm/html/doc/misc/npm-scripts.html +++ b/deps/npm/html/doc/misc/npm-scripts.html @@ -29,7 +29,7 @@ Run by the <code>npm start</code> command.</li><li>prerestart, restart, postrest Run by the <code>npm restart</code> command. Note: <code>npm restart</code> will run the stop and start scripts if no <code>restart</code> script is provided.</li></ul> -<p>Additionally, arbitrary scrips can be run by doing +<p>Additionally, arbitrary scripts can be run by doing <code>npm run-script <stage> <pkg></code>.</p> <h2 id="NOTE-INSTALL-SCRIPTS-ARE-AN-ANTIPATTERN">NOTE: INSTALL SCRIPTS ARE AN ANTIPATTERN</h2> @@ -223,7 +223,7 @@ the user will sudo the npm command in question.</li></ul> <ul><li><a href="../cli/npm-run-script.html">npm-run-script(1)</a></li><li><a href="../files/package.json.html">package.json(5)</a></li><li><a href="../misc/npm-developers.html">npm-developers(7)</a></li><li><a href="../cli/npm-install.html">npm-install(1)</a></li></ul> </div> -<p id="footer">npm-scripts — npm@1.3.6</p> +<p id="footer">npm-scripts — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/misc/removing-npm.html b/deps/npm/html/doc/misc/removing-npm.html index 0b0299346d0..99bc973b2f4 100644 --- a/deps/npm/html/doc/misc/removing-npm.html +++ b/deps/npm/html/doc/misc/removing-npm.html @@ -58,7 +58,7 @@ modules. To track those down, you can do the following:</p> <ul><li><a href="../../doc/README.html">README</a></li><li><a href="../cli/npm-rm.html">npm-rm(1)</a></li><li><a href="../cli/npm-prune.html">npm-prune(1)</a></li></ul> </div> -<p id="footer">removing-npm — npm@1.3.6</p> +<p id="footer">removing-npm — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/html/doc/misc/semver.html b/deps/npm/html/doc/misc/semver.html index 502c8490d4e..b51ea74022d 100644 --- a/deps/npm/html/doc/misc/semver.html +++ b/deps/npm/html/doc/misc/semver.html @@ -94,7 +94,7 @@ in descending order when passed to Array.sort().</li></ul> range.</li><li>maxSatisfying(versions, range): Return the highest version in the list that satisfies the range, or null if none of them do.</li></ul> </div> -<p id="footer">semver — npm@1.3.6</p> +<p id="footer">semver — npm@1.3.8</p> <script> ;(function () { var wrapper = document.getElementById("wrapper") diff --git a/deps/npm/lib/cache.js b/deps/npm/lib/cache.js index 3739968f6dc..a8bd6b388f7 100644 --- a/deps/npm/lib/cache.js +++ b/deps/npm/lib/cache.js @@ -1203,17 +1203,11 @@ function lockFileName (u) { return path.resolve(npm.config.get("cache"), h + "-" + c + ".lock") } -var madeCache = false var myLocks = {} function lock (u, cb) { // the cache dir needs to exist already for this. - if (madeCache) then() - else mkdir(npm.config.get("cache"), function (er) { + getCacheStat(function (er, cs) { if (er) return cb(er) - madeCache = true - then() - }) - function then () { var opts = { stale: npm.config.get("cache-lock-stale") , retries: npm.config.get("cache-lock-retries") , wait: npm.config.get("cache-lock-wait") } @@ -1223,7 +1217,7 @@ function lock (u, cb) { if (!er) myLocks[lf] = true cb(er) }) - } + }) } function unlock (u, cb) { diff --git a/deps/npm/lib/npm.js b/deps/npm/lib/npm.js index ea9759265d1..8b8ee95b08d 100644 --- a/deps/npm/lib/npm.js +++ b/deps/npm/lib/npm.js @@ -146,6 +146,7 @@ var commandCache = {} , "edit" , "explore" , "docs" + , "repo" , "bugs" , "faq" , "root" diff --git a/deps/npm/lib/outdated.js b/deps/npm/lib/outdated.js index b205922efec..b21e10d06fe 100644 --- a/deps/npm/lib/outdated.js +++ b/deps/npm/lib/outdated.js @@ -93,13 +93,16 @@ function outdated_ (args, dir, parentHas, cb) { var jsonFile = path.resolve(dir, "node_modules", pkg, "package.json") readJson(jsonFile, function (er, d) { if (er && er.code !== "ENOENT" && er.code !== "ENOTDIR") return cb(er) - cb(null, er ? [] : [[d.name, d.version]]) + cb(null, er ? [] : [[d.name, d.version, d._from]]) }) }, function (er, pvs) { if (er) return cb(er) has = Object.create(parentHas) pvs.forEach(function (pv) { - has[pv[0]] = pv[1] + has[pv[0]] = { + version: pv[1], + from: pv[2] + } }) next() @@ -129,6 +132,9 @@ function shouldUpdate (args, dir, dep, has, req, cb) { // if that's what we already have, or if it's not on the args list, // then dive into it. Otherwise, cb() with the data. + // { version: , from: } + var curr = has[dep] + function skip () { outdated_( args , path.resolve(dir, "node_modules", dep) @@ -137,7 +143,7 @@ function shouldUpdate (args, dir, dep, has, req, cb) { } function doIt (shouldHave) { - cb(null, [[ dir, dep, has[dep], shouldHave, req ]]) + cb(null, [[ dir, dep, curr.version, shouldHave, req ]]) } if (args.length && args.indexOf(dep) === -1) { @@ -147,7 +153,9 @@ function shouldUpdate (args, dir, dep, has, req, cb) { // so, we can conceivably update this. find out if we need to. cache.add(dep, req, function (er, d) { // if this fails, then it means we can't update this thing. - // it's probably a thing that isn't published. - return (er || d.version === has[dep]) ? skip() : doIt(d.version) + // it's probably a thing that isn't published. otherwise + // check that the origin hasn't changed (#1727) and that + // there is no newer version available + return (er || (d._from === curr.from && d.version === has[dep])) ? skip() : doIt(d.version) }) } diff --git a/deps/npm/lib/repo.js b/deps/npm/lib/repo.js new file mode 100644 index 00000000000..19066c82284 --- /dev/null +++ b/deps/npm/lib/repo.js @@ -0,0 +1,29 @@ + +module.exports = repo + +repo.usage = "npm repo <pkgname>" + +repo.completion = function (opts, cb) { + if (opts.conf.argv.remain.length > 2) return cb() + registry.get("/-/short", 60000, function (er, list) { + return cb(null, list || []) + }) +} + +var npm = require("./npm.js") + , registry = npm.registry + , log = require("npmlog") + , opener = require("opener") + , github = require('github-url-from-git') + +function repo (args, cb) { + if (!args.length) return cb(repo.usage) + var n = args[0].split("@").shift() + registry.get(n + "/latest", 3600, function (er, d) { + if (er) return cb(er) + var r = d.repository; + if (!r) return cb(new Error('no repository')); + var url = github(r.url); + opener(url, { command: npm.config.get("browser") }, cb) + }) +} diff --git a/deps/npm/lib/search.js b/deps/npm/lib/search.js index c758f869ad9..fdc1c8b07da 100644 --- a/deps/npm/lib/search.js +++ b/deps/npm/lib/search.js @@ -85,7 +85,7 @@ function stripData (data) { }) , url: !Object.keys(data.versions || {}).length ? data.url : null , keywords: data.keywords || [] - , version: Object.keys(data.versions)[0] || [] + , version: Object.keys(data.versions || {})[0] || [] , time: data.time && data.time.modified && (new Date(data.time.modified).toISOString() @@ -133,7 +133,6 @@ function prettify (data, args) { var tty = require("tty") , stdout = process.stdout , cols = !tty.isatty(stdout.fd) ? Infinity - : stdout._handle ? stdout._handle.getWindowSize()[0] : process.stdout.getWindowSize()[0] cols = (cols == 0) ? Infinity : cols } catch (ex) { cols = Infinity } diff --git a/deps/npm/man/man1/npm-README.1 b/deps/npm/man/man1/npm-README.1 index 811acb2b118..201c861a151 100644 --- a/deps/npm/man/man1/npm-README.1 +++ b/deps/npm/man/man1/npm-README.1 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM" "1" "July 2013" "" "" +.TH "NPM" "1" "August 2013" "" "" . .SH "NAME" \fBnpm\fR \-\- node package manager @@ -313,13 +313,13 @@ will no doubt tell you to put the output in a gist or email\. npm help npm . .IP "\(bu" 4 -npm help faq +npm help faq . .IP "\(bu" 4 npm help help . .IP "\(bu" 4 -npm help index +npm help index . .IP "" 0 diff --git a/deps/npm/man/man1/npm-adduser.1 b/deps/npm/man/man1/npm-adduser.1 index 8696248be79..11b74cf12c9 100644 --- a/deps/npm/man/man1/npm-adduser.1 +++ b/deps/npm/man/man1/npm-adduser.1 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-ADDUSER" "1" "July 2013" "" "" +.TH "NPM\-ADDUSER" "1" "August 2013" "" "" . .SH "NAME" \fBnpm-adduser\fR \-\- Add a registry user account diff --git a/deps/npm/man/man1/npm-bin.1 b/deps/npm/man/man1/npm-bin.1 index fe6886053a5..cd5611714bc 100644 --- a/deps/npm/man/man1/npm-bin.1 +++ b/deps/npm/man/man1/npm-bin.1 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-BIN" "1" "July 2013" "" "" +.TH "NPM\-BIN" "1" "August 2013" "" "" . .SH "NAME" \fBnpm-bin\fR \-\- Display npm bin folder diff --git a/deps/npm/man/man1/npm-bugs.1 b/deps/npm/man/man1/npm-bugs.1 index dc2a8375297..f7e2fb8b12c 100644 --- a/deps/npm/man/man1/npm-bugs.1 +++ b/deps/npm/man/man1/npm-bugs.1 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-BUGS" "1" "July 2013" "" "" +.TH "NPM\-BUGS" "1" "August 2013" "" "" . .SH "NAME" \fBnpm-bugs\fR \-\- Bugs for a package in a web browser maybe diff --git a/deps/npm/man/man1/npm-build.1 b/deps/npm/man/man1/npm-build.1 index 1cb520911bc..3f06d3b74e2 100644 --- a/deps/npm/man/man1/npm-build.1 +++ b/deps/npm/man/man1/npm-build.1 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-BUILD" "1" "July 2013" "" "" +.TH "NPM\-BUILD" "1" "August 2013" "" "" . .SH "NAME" \fBnpm-build\fR \-\- Build a package diff --git a/deps/npm/man/man1/npm-bundle.1 b/deps/npm/man/man1/npm-bundle.1 index 880d23f9de9..16139cb04d7 100644 --- a/deps/npm/man/man1/npm-bundle.1 +++ b/deps/npm/man/man1/npm-bundle.1 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-BUNDLE" "1" "July 2013" "" "" +.TH "NPM\-BUNDLE" "1" "August 2013" "" "" . .SH "NAME" \fBnpm-bundle\fR \-\- REMOVED diff --git a/deps/npm/man/man1/npm-cache.1 b/deps/npm/man/man1/npm-cache.1 index 1aa5c628681..a08c634411e 100644 --- a/deps/npm/man/man1/npm-cache.1 +++ b/deps/npm/man/man1/npm-cache.1 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-CACHE" "1" "July 2013" "" "" +.TH "NPM\-CACHE" "1" "August 2013" "" "" . .SH "NAME" \fBnpm-cache\fR \-\- Manipulates packages cache diff --git a/deps/npm/man/man1/npm-completion.1 b/deps/npm/man/man1/npm-completion.1 index 25e7bf10c84..0fde5aa8108 100644 --- a/deps/npm/man/man1/npm-completion.1 +++ b/deps/npm/man/man1/npm-completion.1 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-COMPLETION" "1" "July 2013" "" "" +.TH "NPM\-COMPLETION" "1" "August 2013" "" "" . .SH "NAME" \fBnpm-completion\fR \-\- Tab Completion for npm diff --git a/deps/npm/man/man1/npm-config.1 b/deps/npm/man/man1/npm-config.1 index 55a00995c19..cb0475def88 100644 --- a/deps/npm/man/man1/npm-config.1 +++ b/deps/npm/man/man1/npm-config.1 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-CONFIG" "1" "July 2013" "" "" +.TH "NPM\-CONFIG" "1" "August 2013" "" "" . .SH "NAME" \fBnpm-config\fR \-\- Manage the npm configuration files diff --git a/deps/npm/man/man1/npm-dedupe.1 b/deps/npm/man/man1/npm-dedupe.1 index 5446cbdd8b0..75effdeb16e 100644 --- a/deps/npm/man/man1/npm-dedupe.1 +++ b/deps/npm/man/man1/npm-dedupe.1 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-DEDUPE" "1" "July 2013" "" "" +.TH "NPM\-DEDUPE" "1" "August 2013" "" "" . .SH "NAME" \fBnpm-dedupe\fR \-\- Reduce duplication diff --git a/deps/npm/man/man1/npm-deprecate.1 b/deps/npm/man/man1/npm-deprecate.1 index 265e437cbc0..ccc9b661ef7 100644 --- a/deps/npm/man/man1/npm-deprecate.1 +++ b/deps/npm/man/man1/npm-deprecate.1 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-DEPRECATE" "1" "July 2013" "" "" +.TH "NPM\-DEPRECATE" "1" "August 2013" "" "" . .SH "NAME" \fBnpm-deprecate\fR \-\- Deprecate a version of a package diff --git a/deps/npm/man/man1/npm-docs.1 b/deps/npm/man/man1/npm-docs.1 index a3a9c475183..7a4213a7304 100644 --- a/deps/npm/man/man1/npm-docs.1 +++ b/deps/npm/man/man1/npm-docs.1 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-DOCS" "1" "July 2013" "" "" +.TH "NPM\-DOCS" "1" "August 2013" "" "" . .SH "NAME" \fBnpm-docs\fR \-\- Docs for a package in a web browser maybe diff --git a/deps/npm/man/man1/npm-edit.1 b/deps/npm/man/man1/npm-edit.1 index 48213a586b8..684a33ea20b 100644 --- a/deps/npm/man/man1/npm-edit.1 +++ b/deps/npm/man/man1/npm-edit.1 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-EDIT" "1" "July 2013" "" "" +.TH "NPM\-EDIT" "1" "August 2013" "" "" . .SH "NAME" \fBnpm-edit\fR \-\- Edit an installed package diff --git a/deps/npm/man/man1/npm-explore.1 b/deps/npm/man/man1/npm-explore.1 index c534f4ac693..01e8ee6bd79 100644 --- a/deps/npm/man/man1/npm-explore.1 +++ b/deps/npm/man/man1/npm-explore.1 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-EXPLORE" "1" "July 2013" "" "" +.TH "NPM\-EXPLORE" "1" "August 2013" "" "" . .SH "NAME" \fBnpm-explore\fR \-\- Browse an installed package diff --git a/deps/npm/man/man1/npm-help-search.1 b/deps/npm/man/man1/npm-help-search.1 index 098bcedead9..7c0e2a9e00e 100644 --- a/deps/npm/man/man1/npm-help-search.1 +++ b/deps/npm/man/man1/npm-help-search.1 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-HELP\-SEARCH" "1" "July 2013" "" "" +.TH "NPM\-HELP\-SEARCH" "1" "August 2013" "" "" . .SH "NAME" \fBnpm-help-search\fR \-\- Search npm help documentation diff --git a/deps/npm/man/man1/npm-help.1 b/deps/npm/man/man1/npm-help.1 index ce5f7726632..0bc63cd31d0 100644 --- a/deps/npm/man/man1/npm-help.1 +++ b/deps/npm/man/man1/npm-help.1 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-HELP" "1" "July 2013" "" "" +.TH "NPM\-HELP" "1" "August 2013" "" "" . .SH "NAME" \fBnpm-help\fR \-\- Get help on npm diff --git a/deps/npm/man/man1/npm-init.1 b/deps/npm/man/man1/npm-init.1 index 4e8b6b1a4ea..399d40a329b 100644 --- a/deps/npm/man/man1/npm-init.1 +++ b/deps/npm/man/man1/npm-init.1 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-INIT" "1" "July 2013" "" "" +.TH "NPM\-INIT" "1" "August 2013" "" "" . .SH "NAME" \fBnpm-init\fR \-\- Interactively create a package\.json file diff --git a/deps/npm/man/man1/npm-install.1 b/deps/npm/man/man1/npm-install.1 index f389c8e4089..2d5508b9aba 100644 --- a/deps/npm/man/man1/npm-install.1 +++ b/deps/npm/man/man1/npm-install.1 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-INSTALL" "1" "July 2013" "" "" +.TH "NPM\-INSTALL" "1" "August 2013" "" "" . .SH "NAME" \fBnpm-install\fR \-\- Install a package diff --git a/deps/npm/man/man1/npm-link.1 b/deps/npm/man/man1/npm-link.1 index d972d854804..b299327eed4 100644 --- a/deps/npm/man/man1/npm-link.1 +++ b/deps/npm/man/man1/npm-link.1 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-LINK" "1" "July 2013" "" "" +.TH "NPM\-LINK" "1" "August 2013" "" "" . .SH "NAME" \fBnpm-link\fR \-\- Symlink a package folder @@ -26,7 +26,7 @@ Next, in some other location, \fBnpm link package\-name\fR will create a symlink from the local \fBnode_modules\fR folder to the global symlink\. . .P -Note that \fBpackage\-name\fR is taken from \fBpackage\.json\fR , +Note that \fBpackage\-name\fR is taken from \fBpackage\.json\fR, not from directory name\. . .P diff --git a/deps/npm/man/man1/npm-ls.1 b/deps/npm/man/man1/npm-ls.1 index 50802022deb..6d5a934b44f 100644 --- a/deps/npm/man/man1/npm-ls.1 +++ b/deps/npm/man/man1/npm-ls.1 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-LS" "1" "July 2013" "" "" +.TH "NPM\-LS" "1" "August 2013" "" "" . .SH "NAME" \fBnpm-ls\fR \-\- List installed packages @@ -29,7 +29,7 @@ For example, running \fBnpm ls promzard\fR in npm\'s source tree will show: .IP "" 4 . .nf -npm@1.3.6 /path/to/npm +npm@1.3.8 /path/to/npm └─┬ init\-package\-json@0\.0\.4 └── promzard@0\.1\.5 . diff --git a/deps/npm/man/man1/npm-outdated.1 b/deps/npm/man/man1/npm-outdated.1 index 4ef2e8497a0..928408f9191 100644 --- a/deps/npm/man/man1/npm-outdated.1 +++ b/deps/npm/man/man1/npm-outdated.1 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-OUTDATED" "1" "July 2013" "" "" +.TH "NPM\-OUTDATED" "1" "August 2013" "" "" . .SH "NAME" \fBnpm-outdated\fR \-\- Check for outdated packages diff --git a/deps/npm/man/man1/npm-owner.1 b/deps/npm/man/man1/npm-owner.1 index b0ba9e809e1..a933a3afbf9 100644 --- a/deps/npm/man/man1/npm-owner.1 +++ b/deps/npm/man/man1/npm-owner.1 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-OWNER" "1" "July 2013" "" "" +.TH "NPM\-OWNER" "1" "August 2013" "" "" . .SH "NAME" \fBnpm-owner\fR \-\- Manage package owners diff --git a/deps/npm/man/man1/npm-pack.1 b/deps/npm/man/man1/npm-pack.1 index b591b9ebe33..fddfefa75a3 100644 --- a/deps/npm/man/man1/npm-pack.1 +++ b/deps/npm/man/man1/npm-pack.1 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-PACK" "1" "July 2013" "" "" +.TH "NPM\-PACK" "1" "August 2013" "" "" . .SH "NAME" \fBnpm-pack\fR \-\- Create a tarball from a package diff --git a/deps/npm/man/man1/npm-prefix.1 b/deps/npm/man/man1/npm-prefix.1 index 60897bc0b35..8b0c55f423d 100644 --- a/deps/npm/man/man1/npm-prefix.1 +++ b/deps/npm/man/man1/npm-prefix.1 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-PREFIX" "1" "July 2013" "" "" +.TH "NPM\-PREFIX" "1" "August 2013" "" "" . .SH "NAME" \fBnpm-prefix\fR \-\- Display prefix diff --git a/deps/npm/man/man1/npm-prune.1 b/deps/npm/man/man1/npm-prune.1 index e78aff934a9..867af56df4b 100644 --- a/deps/npm/man/man1/npm-prune.1 +++ b/deps/npm/man/man1/npm-prune.1 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-PRUNE" "1" "July 2013" "" "" +.TH "NPM\-PRUNE" "1" "August 2013" "" "" . .SH "NAME" \fBnpm-prune\fR \-\- Remove extraneous packages diff --git a/deps/npm/man/man1/npm-publish.1 b/deps/npm/man/man1/npm-publish.1 index 4b1d57c1612..619eeef11a9 100644 --- a/deps/npm/man/man1/npm-publish.1 +++ b/deps/npm/man/man1/npm-publish.1 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-PUBLISH" "1" "July 2013" "" "" +.TH "NPM\-PUBLISH" "1" "August 2013" "" "" . .SH "NAME" \fBnpm-publish\fR \-\- Publish a package diff --git a/deps/npm/man/man1/npm-rebuild.1 b/deps/npm/man/man1/npm-rebuild.1 index c0dc36a35dc..d1f5dd1916d 100644 --- a/deps/npm/man/man1/npm-rebuild.1 +++ b/deps/npm/man/man1/npm-rebuild.1 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-REBUILD" "1" "July 2013" "" "" +.TH "NPM\-REBUILD" "1" "August 2013" "" "" . .SH "NAME" \fBnpm-rebuild\fR \-\- Rebuild a package diff --git a/deps/npm/man/man1/npm-restart.1 b/deps/npm/man/man1/npm-restart.1 index 061c15774b4..521b68150fd 100644 --- a/deps/npm/man/man1/npm-restart.1 +++ b/deps/npm/man/man1/npm-restart.1 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-RESTART" "1" "July 2013" "" "" +.TH "NPM\-RESTART" "1" "August 2013" "" "" . .SH "NAME" \fBnpm-restart\fR \-\- Start a package diff --git a/deps/npm/man/man1/npm-rm.1 b/deps/npm/man/man1/npm-rm.1 index b19c51b1f2d..6bd7f10b8ef 100644 --- a/deps/npm/man/man1/npm-rm.1 +++ b/deps/npm/man/man1/npm-rm.1 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-RM" "1" "July 2013" "" "" +.TH "NPM\-RM" "1" "August 2013" "" "" . .SH "NAME" \fBnpm-rm\fR \-\- Remove a package diff --git a/deps/npm/man/man1/npm-root.1 b/deps/npm/man/man1/npm-root.1 index 2fbbbd6c617..90b73925b9e 100644 --- a/deps/npm/man/man1/npm-root.1 +++ b/deps/npm/man/man1/npm-root.1 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-ROOT" "1" "July 2013" "" "" +.TH "NPM\-ROOT" "1" "August 2013" "" "" . .SH "NAME" \fBnpm-root\fR \-\- Display npm root diff --git a/deps/npm/man/man1/npm-run-script.1 b/deps/npm/man/man1/npm-run-script.1 index 00de0d96798..867387cdd7c 100644 --- a/deps/npm/man/man1/npm-run-script.1 +++ b/deps/npm/man/man1/npm-run-script.1 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-RUN\-SCRIPT" "1" "July 2013" "" "" +.TH "NPM\-RUN\-SCRIPT" "1" "August 2013" "" "" . .SH "NAME" \fBnpm-run-script\fR \-\- Run arbitrary package scripts diff --git a/deps/npm/man/man1/npm-search.1 b/deps/npm/man/man1/npm-search.1 index cf82b21a889..5fbbfeecf27 100644 --- a/deps/npm/man/man1/npm-search.1 +++ b/deps/npm/man/man1/npm-search.1 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-SEARCH" "1" "July 2013" "" "" +.TH "NPM\-SEARCH" "1" "August 2013" "" "" . .SH "NAME" \fBnpm-search\fR \-\- Search for packages diff --git a/deps/npm/man/man1/npm-shrinkwrap.1 b/deps/npm/man/man1/npm-shrinkwrap.1 index 62e3aab9370..5f99316b946 100644 --- a/deps/npm/man/man1/npm-shrinkwrap.1 +++ b/deps/npm/man/man1/npm-shrinkwrap.1 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-SHRINKWRAP" "1" "July 2013" "" "" +.TH "NPM\-SHRINKWRAP" "1" "August 2013" "" "" . .SH "NAME" \fBnpm-shrinkwrap\fR \-\- Lock down dependency versions diff --git a/deps/npm/man/man1/npm-star.1 b/deps/npm/man/man1/npm-star.1 index 9fbc3000b27..08491f4052a 100644 --- a/deps/npm/man/man1/npm-star.1 +++ b/deps/npm/man/man1/npm-star.1 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-STAR" "1" "July 2013" "" "" +.TH "NPM\-STAR" "1" "August 2013" "" "" . .SH "NAME" \fBnpm-star\fR \-\- Mark your favorite packages diff --git a/deps/npm/man/man1/npm-stars.1 b/deps/npm/man/man1/npm-stars.1 index 0f23c806910..ec6d8d70b2a 100644 --- a/deps/npm/man/man1/npm-stars.1 +++ b/deps/npm/man/man1/npm-stars.1 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-STARS" "1" "July 2013" "" "" +.TH "NPM\-STARS" "1" "August 2013" "" "" . .SH "NAME" \fBnpm-stars\fR \-\- View packages marked as favorites diff --git a/deps/npm/man/man1/npm-start.1 b/deps/npm/man/man1/npm-start.1 index 70146eccf32..cf19bf17c6c 100644 --- a/deps/npm/man/man1/npm-start.1 +++ b/deps/npm/man/man1/npm-start.1 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-START" "1" "July 2013" "" "" +.TH "NPM\-START" "1" "August 2013" "" "" . .SH "NAME" \fBnpm-start\fR \-\- Start a package diff --git a/deps/npm/man/man1/npm-stop.1 b/deps/npm/man/man1/npm-stop.1 index 6886ba5d433..0bef3488744 100644 --- a/deps/npm/man/man1/npm-stop.1 +++ b/deps/npm/man/man1/npm-stop.1 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-STOP" "1" "July 2013" "" "" +.TH "NPM\-STOP" "1" "August 2013" "" "" . .SH "NAME" \fBnpm-stop\fR \-\- Stop a package diff --git a/deps/npm/man/man1/npm-submodule.1 b/deps/npm/man/man1/npm-submodule.1 index d5ad4dd4769..fec06bde8f8 100644 --- a/deps/npm/man/man1/npm-submodule.1 +++ b/deps/npm/man/man1/npm-submodule.1 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-SUBMODULE" "1" "July 2013" "" "" +.TH "NPM\-SUBMODULE" "1" "August 2013" "" "" . .SH "NAME" \fBnpm-submodule\fR \-\- Add a package as a git submodule diff --git a/deps/npm/man/man1/npm-tag.1 b/deps/npm/man/man1/npm-tag.1 index 18d689f6818..13aafb17b23 100644 --- a/deps/npm/man/man1/npm-tag.1 +++ b/deps/npm/man/man1/npm-tag.1 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-TAG" "1" "July 2013" "" "" +.TH "NPM\-TAG" "1" "August 2013" "" "" . .SH "NAME" \fBnpm-tag\fR \-\- Tag a published version diff --git a/deps/npm/man/man1/npm-test.1 b/deps/npm/man/man1/npm-test.1 index b8d01e6b917..228ebdb235d 100644 --- a/deps/npm/man/man1/npm-test.1 +++ b/deps/npm/man/man1/npm-test.1 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-TEST" "1" "July 2013" "" "" +.TH "NPM\-TEST" "1" "August 2013" "" "" . .SH "NAME" \fBnpm-test\fR \-\- Test a package diff --git a/deps/npm/man/man1/npm-uninstall.1 b/deps/npm/man/man1/npm-uninstall.1 index b19c51b1f2d..6bd7f10b8ef 100644 --- a/deps/npm/man/man1/npm-uninstall.1 +++ b/deps/npm/man/man1/npm-uninstall.1 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-RM" "1" "July 2013" "" "" +.TH "NPM\-RM" "1" "August 2013" "" "" . .SH "NAME" \fBnpm-rm\fR \-\- Remove a package diff --git a/deps/npm/man/man1/npm-unpublish.1 b/deps/npm/man/man1/npm-unpublish.1 index d7b64656ce3..4efc34c08c3 100644 --- a/deps/npm/man/man1/npm-unpublish.1 +++ b/deps/npm/man/man1/npm-unpublish.1 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-UNPUBLISH" "1" "July 2013" "" "" +.TH "NPM\-UNPUBLISH" "1" "August 2013" "" "" . .SH "NAME" \fBnpm-unpublish\fR \-\- Remove a package from the registry diff --git a/deps/npm/man/man1/npm-update.1 b/deps/npm/man/man1/npm-update.1 index 126b2ed3b20..32d0b53a85f 100644 --- a/deps/npm/man/man1/npm-update.1 +++ b/deps/npm/man/man1/npm-update.1 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-UPDATE" "1" "July 2013" "" "" +.TH "NPM\-UPDATE" "1" "August 2013" "" "" . .SH "NAME" \fBnpm-update\fR \-\- Update a package diff --git a/deps/npm/man/man1/npm-version.1 b/deps/npm/man/man1/npm-version.1 index 55c72ccb079..32d3276d5ef 100644 --- a/deps/npm/man/man1/npm-version.1 +++ b/deps/npm/man/man1/npm-version.1 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-VERSION" "1" "July 2013" "" "" +.TH "NPM\-VERSION" "1" "August 2013" "" "" . .SH "NAME" \fBnpm-version\fR \-\- Bump a package version diff --git a/deps/npm/man/man1/npm-view.1 b/deps/npm/man/man1/npm-view.1 index 39beb4bfe89..60a7009660f 100644 --- a/deps/npm/man/man1/npm-view.1 +++ b/deps/npm/man/man1/npm-view.1 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-VIEW" "1" "July 2013" "" "" +.TH "NPM\-VIEW" "1" "August 2013" "" "" . .SH "NAME" \fBnpm-view\fR \-\- View registry info diff --git a/deps/npm/man/man1/npm-whoami.1 b/deps/npm/man/man1/npm-whoami.1 index b840711b35a..fcf8ae9772c 100644 --- a/deps/npm/man/man1/npm-whoami.1 +++ b/deps/npm/man/man1/npm-whoami.1 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-WHOAMI" "1" "July 2013" "" "" +.TH "NPM\-WHOAMI" "1" "August 2013" "" "" . .SH "NAME" \fBnpm-whoami\fR \-\- Display npm username diff --git a/deps/npm/man/man1/npm.1 b/deps/npm/man/man1/npm.1 index ac03f7d2b9b..7ab75321dc1 100644 --- a/deps/npm/man/man1/npm.1 +++ b/deps/npm/man/man1/npm.1 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM" "1" "July 2013" "" "" +.TH "NPM" "1" "August 2013" "" "" . .SH "NAME" \fBnpm\fR \-\- node package manager @@ -14,7 +14,7 @@ npm <command> [args] .fi . .SH "VERSION" -1.3.6 +1.3.8 . .SH "DESCRIPTION" npm is the package manager for the Node JavaScript platform\. It puts diff --git a/deps/npm/man/man1/repo.1 b/deps/npm/man/man1/repo.1 new file mode 100644 index 00000000000..f2e8cb42171 --- /dev/null +++ b/deps/npm/man/man1/repo.1 @@ -0,0 +1,45 @@ +.\" Generated with Ronnjs 0.3.8 +.\" http://github.com/kapouer/ronnjs/ +. +.TH "NPM\-REPO" "1" "August 2013" "" "" +. +.SH "NAME" +\fBnpm-repo\fR \-\- Open package repository page in the browser +. +.SH "SYNOPSIS" +. +.nf +npm repo <pkgname> +. +.fi +. +.SH "DESCRIPTION" +This command tries to guess at the likely location of a package\'s +repository URL, and then tries to open it using the \fB\-\-browser\fR +config param\. +. +.SH "CONFIGURATION" +. +.SS "browser" +. +.IP "\(bu" 4 +Default: OS X: \fB"open"\fR, Windows: \fB"start"\fR, Others: \fB"xdg\-open"\fR +. +.IP "\(bu" 4 +Type: String +. +.IP "" 0 +. +.P +The browser that is called by the \fBnpm repo\fR command to open websites\. +. +.SH "SEE ALSO" +. +.IP "\(bu" 4 +npm help docs +. +.IP "\(bu" 4 +npm help config +. +.IP "" 0 + diff --git a/deps/npm/man/man3/npm-bin.3 b/deps/npm/man/man3/npm-bin.3 index db4e120bf1c..425f976f275 100644 --- a/deps/npm/man/man3/npm-bin.3 +++ b/deps/npm/man/man3/npm-bin.3 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-BIN" "3" "July 2013" "" "" +.TH "NPM\-BIN" "3" "August 2013" "" "" . .SH "NAME" \fBnpm-bin\fR \-\- Display npm bin folder diff --git a/deps/npm/man/man3/npm-bugs.3 b/deps/npm/man/man3/npm-bugs.3 index 5742fcb55d3..116eb5b1b5c 100644 --- a/deps/npm/man/man3/npm-bugs.3 +++ b/deps/npm/man/man3/npm-bugs.3 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-BUGS" "3" "July 2013" "" "" +.TH "NPM\-BUGS" "3" "August 2013" "" "" . .SH "NAME" \fBnpm-bugs\fR \-\- Bugs for a package in a web browser maybe diff --git a/deps/npm/man/man3/npm-commands.3 b/deps/npm/man/man3/npm-commands.3 index ee74bfe35c2..cc361bbbcbd 100644 --- a/deps/npm/man/man3/npm-commands.3 +++ b/deps/npm/man/man3/npm-commands.3 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-COMMANDS" "3" "July 2013" "" "" +.TH "NPM\-COMMANDS" "3" "August 2013" "" "" . .SH "NAME" \fBnpm-commands\fR \-\- npm commands diff --git a/deps/npm/man/man3/npm-config.3 b/deps/npm/man/man3/npm-config.3 index 35ca2259d2d..e5ef65707d5 100644 --- a/deps/npm/man/man3/npm-config.3 +++ b/deps/npm/man/man3/npm-config.3 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-CONFIG" "3" "July 2013" "" "" +.TH "NPM\-CONFIG" "3" "August 2013" "" "" . .SH "NAME" \fBnpm-config\fR \-\- Manage the npm configuration files diff --git a/deps/npm/man/man3/npm-deprecate.3 b/deps/npm/man/man3/npm-deprecate.3 index 2372a1c5ed9..e841e52e6fb 100644 --- a/deps/npm/man/man3/npm-deprecate.3 +++ b/deps/npm/man/man3/npm-deprecate.3 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-DEPRECATE" "3" "July 2013" "" "" +.TH "NPM\-DEPRECATE" "3" "August 2013" "" "" . .SH "NAME" \fBnpm-deprecate\fR \-\- Deprecate a version of a package diff --git a/deps/npm/man/man3/npm-docs.3 b/deps/npm/man/man3/npm-docs.3 index 7585e223ece..ebd5a45b22b 100644 --- a/deps/npm/man/man3/npm-docs.3 +++ b/deps/npm/man/man3/npm-docs.3 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-DOCS" "3" "July 2013" "" "" +.TH "NPM\-DOCS" "3" "August 2013" "" "" . .SH "NAME" \fBnpm-docs\fR \-\- Docs for a package in a web browser maybe diff --git a/deps/npm/man/man3/npm-edit.3 b/deps/npm/man/man3/npm-edit.3 index 6bcd05d3755..16c2fb7d1be 100644 --- a/deps/npm/man/man3/npm-edit.3 +++ b/deps/npm/man/man3/npm-edit.3 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-EDIT" "3" "July 2013" "" "" +.TH "NPM\-EDIT" "3" "August 2013" "" "" . .SH "NAME" \fBnpm-edit\fR \-\- Edit an installed package diff --git a/deps/npm/man/man3/npm-explore.3 b/deps/npm/man/man3/npm-explore.3 index 1b5975ab32f..a8864e3fb14 100644 --- a/deps/npm/man/man3/npm-explore.3 +++ b/deps/npm/man/man3/npm-explore.3 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-EXPLORE" "3" "July 2013" "" "" +.TH "NPM\-EXPLORE" "3" "August 2013" "" "" . .SH "NAME" \fBnpm-explore\fR \-\- Browse an installed package diff --git a/deps/npm/man/man3/npm-help-search.3 b/deps/npm/man/man3/npm-help-search.3 index a250c5ffe54..bbd463a75df 100644 --- a/deps/npm/man/man3/npm-help-search.3 +++ b/deps/npm/man/man3/npm-help-search.3 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-HELP\-SEARCH" "3" "July 2013" "" "" +.TH "NPM\-HELP\-SEARCH" "3" "August 2013" "" "" . .SH "NAME" \fBnpm-help-search\fR \-\- Search the help pages diff --git a/deps/npm/man/man3/npm-init.3 b/deps/npm/man/man3/npm-init.3 index c08338cde5f..865539dcd3d 100644 --- a/deps/npm/man/man3/npm-init.3 +++ b/deps/npm/man/man3/npm-init.3 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "INIT" "3" "July 2013" "" "" +.TH "INIT" "3" "August 2013" "" "" . .SH "NAME" \fBinit\fR \-\- Interactively create a package\.json file diff --git a/deps/npm/man/man3/npm-install.3 b/deps/npm/man/man3/npm-install.3 index 5e6e52a5f81..f67dd08a024 100644 --- a/deps/npm/man/man3/npm-install.3 +++ b/deps/npm/man/man3/npm-install.3 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-INSTALL" "3" "July 2013" "" "" +.TH "NPM\-INSTALL" "3" "August 2013" "" "" . .SH "NAME" \fBnpm-install\fR \-\- install a package programmatically diff --git a/deps/npm/man/man3/npm-link.3 b/deps/npm/man/man3/npm-link.3 index be3642754ee..7c2ef35d81e 100644 --- a/deps/npm/man/man3/npm-link.3 +++ b/deps/npm/man/man3/npm-link.3 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-LINK" "3" "July 2013" "" "" +.TH "NPM\-LINK" "3" "August 2013" "" "" . .SH "NAME" \fBnpm-link\fR \-\- Symlink a package folder diff --git a/deps/npm/man/man3/npm-load.3 b/deps/npm/man/man3/npm-load.3 index 823020747b9..2c3efa9571d 100644 --- a/deps/npm/man/man3/npm-load.3 +++ b/deps/npm/man/man3/npm-load.3 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-LOAD" "3" "July 2013" "" "" +.TH "NPM\-LOAD" "3" "August 2013" "" "" . .SH "NAME" \fBnpm-load\fR \-\- Load config settings diff --git a/deps/npm/man/man3/npm-ls.3 b/deps/npm/man/man3/npm-ls.3 index bac38958ed4..7a41df49ee7 100644 --- a/deps/npm/man/man3/npm-ls.3 +++ b/deps/npm/man/man3/npm-ls.3 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-LS" "3" "July 2013" "" "" +.TH "NPM\-LS" "3" "August 2013" "" "" . .SH "NAME" \fBnpm-ls\fR \-\- List installed packages diff --git a/deps/npm/man/man3/npm-outdated.3 b/deps/npm/man/man3/npm-outdated.3 index 41638a32b60..698d16ec555 100644 --- a/deps/npm/man/man3/npm-outdated.3 +++ b/deps/npm/man/man3/npm-outdated.3 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-OUTDATED" "3" "July 2013" "" "" +.TH "NPM\-OUTDATED" "3" "August 2013" "" "" . .SH "NAME" \fBnpm-outdated\fR \-\- Check for outdated packages diff --git a/deps/npm/man/man3/npm-owner.3 b/deps/npm/man/man3/npm-owner.3 index 380c97c932d..6b37b4dedc7 100644 --- a/deps/npm/man/man3/npm-owner.3 +++ b/deps/npm/man/man3/npm-owner.3 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-OWNER" "3" "July 2013" "" "" +.TH "NPM\-OWNER" "3" "August 2013" "" "" . .SH "NAME" \fBnpm-owner\fR \-\- Manage package owners diff --git a/deps/npm/man/man3/npm-pack.3 b/deps/npm/man/man3/npm-pack.3 index 8562e3dd6f0..335b298ac09 100644 --- a/deps/npm/man/man3/npm-pack.3 +++ b/deps/npm/man/man3/npm-pack.3 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-PACK" "3" "July 2013" "" "" +.TH "NPM\-PACK" "3" "August 2013" "" "" . .SH "NAME" \fBnpm-pack\fR \-\- Create a tarball from a package diff --git a/deps/npm/man/man3/npm-prefix.3 b/deps/npm/man/man3/npm-prefix.3 index 7ae64f54178..a8824ec98bb 100644 --- a/deps/npm/man/man3/npm-prefix.3 +++ b/deps/npm/man/man3/npm-prefix.3 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-PREFIX" "3" "July 2013" "" "" +.TH "NPM\-PREFIX" "3" "August 2013" "" "" . .SH "NAME" \fBnpm-prefix\fR \-\- Display prefix diff --git a/deps/npm/man/man3/npm-prune.3 b/deps/npm/man/man3/npm-prune.3 index 9fa7bf78db8..f7ae4bdaad7 100644 --- a/deps/npm/man/man3/npm-prune.3 +++ b/deps/npm/man/man3/npm-prune.3 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-PRUNE" "3" "July 2013" "" "" +.TH "NPM\-PRUNE" "3" "August 2013" "" "" . .SH "NAME" \fBnpm-prune\fR \-\- Remove extraneous packages diff --git a/deps/npm/man/man3/npm-publish.3 b/deps/npm/man/man3/npm-publish.3 index 964c39df09d..0b37ad9c190 100644 --- a/deps/npm/man/man3/npm-publish.3 +++ b/deps/npm/man/man3/npm-publish.3 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-PUBLISH" "3" "July 2013" "" "" +.TH "NPM\-PUBLISH" "3" "August 2013" "" "" . .SH "NAME" \fBnpm-publish\fR \-\- Publish a package diff --git a/deps/npm/man/man3/npm-rebuild.3 b/deps/npm/man/man3/npm-rebuild.3 index 6ec98558aaf..1f572390c9a 100644 --- a/deps/npm/man/man3/npm-rebuild.3 +++ b/deps/npm/man/man3/npm-rebuild.3 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-REBUILD" "3" "July 2013" "" "" +.TH "NPM\-REBUILD" "3" "August 2013" "" "" . .SH "NAME" \fBnpm-rebuild\fR \-\- Rebuild a package diff --git a/deps/npm/man/man3/npm-restart.3 b/deps/npm/man/man3/npm-restart.3 index 9a1af15ff7e..cdc5cd9c66d 100644 --- a/deps/npm/man/man3/npm-restart.3 +++ b/deps/npm/man/man3/npm-restart.3 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-RESTART" "3" "July 2013" "" "" +.TH "NPM\-RESTART" "3" "August 2013" "" "" . .SH "NAME" \fBnpm-restart\fR \-\- Start a package diff --git a/deps/npm/man/man3/npm-root.3 b/deps/npm/man/man3/npm-root.3 index 6635da7e13c..bb189f42b1e 100644 --- a/deps/npm/man/man3/npm-root.3 +++ b/deps/npm/man/man3/npm-root.3 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-ROOT" "3" "July 2013" "" "" +.TH "NPM\-ROOT" "3" "August 2013" "" "" . .SH "NAME" \fBnpm-root\fR \-\- Display npm root diff --git a/deps/npm/man/man3/npm-run-script.3 b/deps/npm/man/man3/npm-run-script.3 index b509d962db4..9615d6146bc 100644 --- a/deps/npm/man/man3/npm-run-script.3 +++ b/deps/npm/man/man3/npm-run-script.3 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-RUN\-SCRIPT" "3" "July 2013" "" "" +.TH "NPM\-RUN\-SCRIPT" "3" "August 2013" "" "" . .SH "NAME" \fBnpm-run-script\fR \-\- Run arbitrary package scripts diff --git a/deps/npm/man/man3/npm-search.3 b/deps/npm/man/man3/npm-search.3 index 193b01e695e..71ac889506b 100644 --- a/deps/npm/man/man3/npm-search.3 +++ b/deps/npm/man/man3/npm-search.3 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-SEARCH" "3" "July 2013" "" "" +.TH "NPM\-SEARCH" "3" "August 2013" "" "" . .SH "NAME" \fBnpm-search\fR \-\- Search for packages diff --git a/deps/npm/man/man3/npm-shrinkwrap.3 b/deps/npm/man/man3/npm-shrinkwrap.3 index befe0641722..beea7397839 100644 --- a/deps/npm/man/man3/npm-shrinkwrap.3 +++ b/deps/npm/man/man3/npm-shrinkwrap.3 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-SHRINKWRAP" "3" "July 2013" "" "" +.TH "NPM\-SHRINKWRAP" "3" "August 2013" "" "" . .SH "NAME" \fBnpm-shrinkwrap\fR \-\- programmatically generate package shrinkwrap file diff --git a/deps/npm/man/man3/npm-start.3 b/deps/npm/man/man3/npm-start.3 index 057eda3f8fe..143b35978b9 100644 --- a/deps/npm/man/man3/npm-start.3 +++ b/deps/npm/man/man3/npm-start.3 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-START" "3" "July 2013" "" "" +.TH "NPM\-START" "3" "August 2013" "" "" . .SH "NAME" \fBnpm-start\fR \-\- Start a package diff --git a/deps/npm/man/man3/npm-stop.3 b/deps/npm/man/man3/npm-stop.3 index 469742f1de4..94fb46ac869 100644 --- a/deps/npm/man/man3/npm-stop.3 +++ b/deps/npm/man/man3/npm-stop.3 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-STOP" "3" "July 2013" "" "" +.TH "NPM\-STOP" "3" "August 2013" "" "" . .SH "NAME" \fBnpm-stop\fR \-\- Stop a package diff --git a/deps/npm/man/man3/npm-submodule.3 b/deps/npm/man/man3/npm-submodule.3 index 577c12e0298..1f37a0fa2c7 100644 --- a/deps/npm/man/man3/npm-submodule.3 +++ b/deps/npm/man/man3/npm-submodule.3 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-SUBMODULE" "3" "July 2013" "" "" +.TH "NPM\-SUBMODULE" "3" "August 2013" "" "" . .SH "NAME" \fBnpm-submodule\fR \-\- Add a package as a git submodule diff --git a/deps/npm/man/man3/npm-tag.3 b/deps/npm/man/man3/npm-tag.3 index 6df97e69f10..3c6ddaafd16 100644 --- a/deps/npm/man/man3/npm-tag.3 +++ b/deps/npm/man/man3/npm-tag.3 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-TAG" "3" "July 2013" "" "" +.TH "NPM\-TAG" "3" "August 2013" "" "" . .SH "NAME" \fBnpm-tag\fR \-\- Tag a published version diff --git a/deps/npm/man/man3/npm-test.3 b/deps/npm/man/man3/npm-test.3 index b2830e4b604..09e5ed89da4 100644 --- a/deps/npm/man/man3/npm-test.3 +++ b/deps/npm/man/man3/npm-test.3 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-TEST" "3" "July 2013" "" "" +.TH "NPM\-TEST" "3" "August 2013" "" "" . .SH "NAME" \fBnpm-test\fR \-\- Test a package diff --git a/deps/npm/man/man3/npm-uninstall.3 b/deps/npm/man/man3/npm-uninstall.3 index a429f024d3b..a5df776ccdf 100644 --- a/deps/npm/man/man3/npm-uninstall.3 +++ b/deps/npm/man/man3/npm-uninstall.3 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-UNINSTALL" "3" "July 2013" "" "" +.TH "NPM\-UNINSTALL" "3" "August 2013" "" "" . .SH "NAME" \fBnpm-uninstall\fR \-\- uninstall a package programmatically diff --git a/deps/npm/man/man3/npm-unpublish.3 b/deps/npm/man/man3/npm-unpublish.3 index 446a7a28e13..dd2824fb734 100644 --- a/deps/npm/man/man3/npm-unpublish.3 +++ b/deps/npm/man/man3/npm-unpublish.3 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-UNPUBLISH" "3" "July 2013" "" "" +.TH "NPM\-UNPUBLISH" "3" "August 2013" "" "" . .SH "NAME" \fBnpm-unpublish\fR \-\- Remove a package from the registry diff --git a/deps/npm/man/man3/npm-update.3 b/deps/npm/man/man3/npm-update.3 index a19286fbb93..58e631f92ed 100644 --- a/deps/npm/man/man3/npm-update.3 +++ b/deps/npm/man/man3/npm-update.3 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-UPDATE" "3" "July 2013" "" "" +.TH "NPM\-UPDATE" "3" "August 2013" "" "" . .SH "NAME" \fBnpm-update\fR \-\- Update a package diff --git a/deps/npm/man/man3/npm-version.3 b/deps/npm/man/man3/npm-version.3 index e7d79148aa3..902a9739246 100644 --- a/deps/npm/man/man3/npm-version.3 +++ b/deps/npm/man/man3/npm-version.3 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-VERSION" "3" "July 2013" "" "" +.TH "NPM\-VERSION" "3" "August 2013" "" "" . .SH "NAME" \fBnpm-version\fR \-\- Bump a package version diff --git a/deps/npm/man/man3/npm-view.3 b/deps/npm/man/man3/npm-view.3 index 7301634975d..c6ad4c4ce6c 100644 --- a/deps/npm/man/man3/npm-view.3 +++ b/deps/npm/man/man3/npm-view.3 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-VIEW" "3" "July 2013" "" "" +.TH "NPM\-VIEW" "3" "August 2013" "" "" . .SH "NAME" \fBnpm-view\fR \-\- View registry info diff --git a/deps/npm/man/man3/npm-whoami.3 b/deps/npm/man/man3/npm-whoami.3 index bde276ba1bf..e0c5232aeeb 100644 --- a/deps/npm/man/man3/npm-whoami.3 +++ b/deps/npm/man/man3/npm-whoami.3 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-WHOAMI" "3" "July 2013" "" "" +.TH "NPM\-WHOAMI" "3" "August 2013" "" "" . .SH "NAME" \fBnpm-whoami\fR \-\- Display npm username diff --git a/deps/npm/man/man3/npm.3 b/deps/npm/man/man3/npm.3 index 53ca7e80485..5d1453a008f 100644 --- a/deps/npm/man/man3/npm.3 +++ b/deps/npm/man/man3/npm.3 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM" "3" "July 2013" "" "" +.TH "NPM" "3" "August 2013" "" "" . .SH "NAME" \fBnpm\fR \-\- node package manager @@ -10,7 +10,7 @@ . .nf var npm = require("npm") -npm\.load([configObject,] function (er, npm) { +npm\.load([configObject], function (er, npm) { // use the npm object, now that it\'s loaded\. npm\.config\.set(key, val) val = npm\.config\.get(key) @@ -21,7 +21,7 @@ npm\.load([configObject,] function (er, npm) { .fi . .SH "VERSION" -1.3.6 +1.3.8 . .SH "DESCRIPTION" This is the API documentation for npm\. diff --git a/deps/npm/man/man3/repo.3 b/deps/npm/man/man3/repo.3 new file mode 100644 index 00000000000..796cb09a066 --- /dev/null +++ b/deps/npm/man/man3/repo.3 @@ -0,0 +1,28 @@ +.\" Generated with Ronnjs 0.3.8 +.\" http://github.com/kapouer/ronnjs/ +. +.TH "NPM\-REPO" "3" "August 2013" "" "" +. +.SH "NAME" +\fBnpm-repo\fR \-\- Open package repository page in the browser +. +.SH "SYNOPSIS" +. +.nf +npm\.commands\.repo(package, callback) +. +.fi +. +.SH "DESCRIPTION" +This command tries to guess at the likely location of a package\'s +repository URL, and then tries to open it using the \fB\-\-browser\fR +config param\. +. +.P +Like other commands, the first parameter is an array\. This command only +uses the first element, which is expected to be a package name with an +optional version number\. +. +.P +This command will launch a browser, so this command may not be the most +friendly for programmatic use\. diff --git a/deps/npm/man/man5/npm-folders.5 b/deps/npm/man/man5/npm-folders.5 index 2f2fb97bd7f..7502cf9944a 100644 --- a/deps/npm/man/man5/npm-folders.5 +++ b/deps/npm/man/man5/npm-folders.5 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-FOLDERS" "5" "July 2013" "" "" +.TH "NPM\-FOLDERS" "5" "August 2013" "" "" . .SH "NAME" \fBnpm-folders\fR \-\- Folder Structures Used by npm diff --git a/deps/npm/man/man5/npm-global.5 b/deps/npm/man/man5/npm-global.5 index 2f2fb97bd7f..7502cf9944a 100644 --- a/deps/npm/man/man5/npm-global.5 +++ b/deps/npm/man/man5/npm-global.5 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-FOLDERS" "5" "July 2013" "" "" +.TH "NPM\-FOLDERS" "5" "August 2013" "" "" . .SH "NAME" \fBnpm-folders\fR \-\- Folder Structures Used by npm diff --git a/deps/npm/man/man5/npm-json.5 b/deps/npm/man/man5/npm-json.5 index 8a064e5c503..89fbe6cec6d 100644 --- a/deps/npm/man/man5/npm-json.5 +++ b/deps/npm/man/man5/npm-json.5 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "PACKAGE\.JSON" "5" "July 2013" "" "" +.TH "PACKAGE\.JSON" "5" "August 2013" "" "" . .SH "NAME" \fBpackage.json\fR \-\- Specifics of npm\'s package\.json handling @@ -91,24 +91,7 @@ Version must be parseable by node\-semver \fIhttps://github\.com/isaacs/node\-se with npm as a dependency\. (\fBnpm install semver\fR to use it yourself\.) . .P -Here\'s how npm\'s semver implementation deviates from what\'s on semver\.org: -. -.IP "\(bu" 4 -Versions can start with "v" -. -.IP "\(bu" 4 -A numeric item separated from the main three\-number version by a hyphen -will be interpreted as a "build" number, and will \fIincrease\fR the version\. -But, if the tag is not a number separated by a hyphen, then it\'s treated -as a pre\-release tag, and is \fIless than\fR the version without a tag\. -So, \fB0\.1\.2\-7 > 0\.1\.2\-7\-beta > 0\.1\.2\-6 > 0\.1\.2 > 0\.1\.2beta\fR -. -.IP "" 0 -. -.P -This is a little bit confusing to explain, but matches what you see in practice -when people create tags in git like "v1\.2\.3" and then do "git describe" to generate -a patch version\. +npm help More on version numbers and ranges at semver\. . .SH "description" Put a description in it\. It\'s a string\. This helps people discover your @@ -460,24 +443,21 @@ npm help See \fBnpm\-confignpm help \fR and \fBnpm\-scripts\fR for more on pac configs\. . .SH "dependencies" -Dependencies are specified with a simple hash of package name to version -range\. The version range is EITHER a string which has one or more -space\-separated descriptors, OR a range like "fromVersion \- toVersion" +Dependencies are specified with a simple hash of package name to +version range\. The version range is a string which has one or more +space\-separated descriptors\. Dependencies can also be identified with +a tarball or git URL\. . .P -\fBPlease do not put test harnesses in your \fBdependencies\fR hash\.\fR See \fBdevDependencies\fR, below\. +\fBPlease do not put test harnesses or transpilers in your \fBdependencies\fR hash\.\fR See \fBdevDependencies\fR, below\. . .P -Version range descriptors may be any of the following styles, where "version" -is a semver compatible version identifier\. +npm help See semver for more details about specifying version ranges\. . .IP "\(bu" 4 \fBversion\fR Must match \fBversion\fR exactly . .IP "\(bu" 4 -\fB=version\fR Same as just \fBversion\fR -. -.IP "\(bu" 4 \fB>version\fR Must be greater than \fBversion\fR . .IP "\(bu" 4 @@ -490,10 +470,10 @@ is a semver compatible version identifier\. \fB<=version\fR . .IP "\(bu" 4 -\fB~version\fR See \'Tilde Version Ranges\' below +npm help \fB~version\fR "Approximately equivalent to version" See semver . .IP "\(bu" 4 -\fB1\.2\.x\fR See \'X Version Ranges\' below +\fB1\.2\.x\fR 1\.2\.0, 1\.2\.1, etc\., but not 1\.3\.0 . .IP "\(bu" 4 \fBhttp://\.\.\.\fR See \'URLs as Dependencies\' below @@ -539,63 +519,8 @@ For example, these are all valid: . .IP "" 0 . -.SS "Tilde Version Ranges" -A range specifier starting with a tilde \fB~\fR character is matched against -a version in the following fashion\. -. -.IP "\(bu" 4 -The version must be at least as high as the range\. -. -.IP "\(bu" 4 -The version must be less than the next major revision above the range\. -. -.IP "" 0 -. -.P -For example, the following are equivalent: -. -.IP "\(bu" 4 -\fB"~1\.2\.3" = ">=1\.2\.3 <1\.3\.0"\fR -. -.IP "\(bu" 4 -\fB"~1\.2" = ">=1\.2\.0 <1\.3\.0"\fR -. -.IP "\(bu" 4 -\fB"~1" = ">=1\.0\.0 <1\.1\.0"\fR -. -.IP "" 0 -. -.SS "X Version Ranges" -An "x" in a version range specifies that the version number must start -with the supplied digits, but any digit may be used in place of the x\. -. -.P -The following are equivalent: -. -.IP "\(bu" 4 -\fB"1\.2\.x" = ">=1\.2\.0 <1\.3\.0"\fR -. -.IP "\(bu" 4 -\fB"1\.x\.x" = ">=1\.0\.0 <2\.0\.0"\fR -. -.IP "\(bu" 4 -\fB"1\.2" = "1\.2\.x"\fR -. -.IP "\(bu" 4 -\fB"1\.x" = "1\.x\.x"\fR -. -.IP "\(bu" 4 -\fB"1" = "1\.x\.x"\fR -. -.IP "" 0 -. -.P -You may not supply a comparator with a version containing an x\. Any -digits after the first "x" are ignored\. -. .SS "URLs as Dependencies" -Starting with npm version 0\.2\.14, you may specify a tarball URL in place -of a version range\. +You may specify a tarball URL in place of a version range\. . .P This tarball will be downloaded and installed locally to your package at @@ -630,10 +555,38 @@ the external test or documentation framework that you use\. In this case, it\'s best to list these additional items in a \fBdevDependencies\fR hash\. . .P -These things will be installed whenever the \fB\-\-dev\fR configuration flag -is set\. This flag is set automatically when doing \fBnpm link\fR or when doing \fBnpm install\fR from the root of a package, and can be managed like any other npm +These things will be installed when doing \fBnpm link\fR or \fBnpm install\fR +from the root of a package, and can be managed like any other npm npm help configuration param\. See \fBnpm\-config\fR for more on the topic\. . +.P +For build steps that are not platform\-specific, such as compiling +CoffeeScript or other languages to JavaScript, use the \fBprepublish\fR +script to do this, and make the required package a devDependency\. +. +.P +For example: +. +.P +\fBjson +{ "name": "ethopia\-waza", + "description": "a delightfully fruity coffee varietal", + "version": "1\.2\.3", + "devDependencies": { + "coffee\-script": "~1\.6\.3" + }, + "scripts": { + "prepublish": "coffee \-o lib/ \-c src/waza\.coffee" + }, + "main": "lib/waza\.js" +}\fR +. +.P +The \fBprepublish\fR script will be run before publishing, so that users +can consume the functionality without requiring them to compile it +themselves\. In dev mode (ie, locally running \fBnpm install\fR), it\'ll +run this script as well, so that you can test it easily\. +. .SH "bundledDependencies" Array of package names that will be bundled when publishing the package\. . @@ -680,7 +633,7 @@ You can specify the version of node that your stuff works on: .IP "" 4 . .nf -{ "engines" : { "node" : ">=0\.1\.27 <0\.1\.30" } } +{ "engines" : { "node" : ">=0\.10\.3 <0\.12" } } . .fi . diff --git a/deps/npm/man/man5/npmrc.5 b/deps/npm/man/man5/npmrc.5 index ca4ca548f05..25e7716d73f 100644 --- a/deps/npm/man/man5/npmrc.5 +++ b/deps/npm/man/man5/npmrc.5 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPMRC" "5" "July 2013" "" "" +.TH "NPMRC" "5" "August 2013" "" "" . .SH "NAME" \fBnpmrc\fR \-\- The npm config files diff --git a/deps/npm/man/man5/package.json.5 b/deps/npm/man/man5/package.json.5 index 8a064e5c503..89fbe6cec6d 100644 --- a/deps/npm/man/man5/package.json.5 +++ b/deps/npm/man/man5/package.json.5 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "PACKAGE\.JSON" "5" "July 2013" "" "" +.TH "PACKAGE\.JSON" "5" "August 2013" "" "" . .SH "NAME" \fBpackage.json\fR \-\- Specifics of npm\'s package\.json handling @@ -91,24 +91,7 @@ Version must be parseable by node\-semver \fIhttps://github\.com/isaacs/node\-se with npm as a dependency\. (\fBnpm install semver\fR to use it yourself\.) . .P -Here\'s how npm\'s semver implementation deviates from what\'s on semver\.org: -. -.IP "\(bu" 4 -Versions can start with "v" -. -.IP "\(bu" 4 -A numeric item separated from the main three\-number version by a hyphen -will be interpreted as a "build" number, and will \fIincrease\fR the version\. -But, if the tag is not a number separated by a hyphen, then it\'s treated -as a pre\-release tag, and is \fIless than\fR the version without a tag\. -So, \fB0\.1\.2\-7 > 0\.1\.2\-7\-beta > 0\.1\.2\-6 > 0\.1\.2 > 0\.1\.2beta\fR -. -.IP "" 0 -. -.P -This is a little bit confusing to explain, but matches what you see in practice -when people create tags in git like "v1\.2\.3" and then do "git describe" to generate -a patch version\. +npm help More on version numbers and ranges at semver\. . .SH "description" Put a description in it\. It\'s a string\. This helps people discover your @@ -460,24 +443,21 @@ npm help See \fBnpm\-confignpm help \fR and \fBnpm\-scripts\fR for more on pac configs\. . .SH "dependencies" -Dependencies are specified with a simple hash of package name to version -range\. The version range is EITHER a string which has one or more -space\-separated descriptors, OR a range like "fromVersion \- toVersion" +Dependencies are specified with a simple hash of package name to +version range\. The version range is a string which has one or more +space\-separated descriptors\. Dependencies can also be identified with +a tarball or git URL\. . .P -\fBPlease do not put test harnesses in your \fBdependencies\fR hash\.\fR See \fBdevDependencies\fR, below\. +\fBPlease do not put test harnesses or transpilers in your \fBdependencies\fR hash\.\fR See \fBdevDependencies\fR, below\. . .P -Version range descriptors may be any of the following styles, where "version" -is a semver compatible version identifier\. +npm help See semver for more details about specifying version ranges\. . .IP "\(bu" 4 \fBversion\fR Must match \fBversion\fR exactly . .IP "\(bu" 4 -\fB=version\fR Same as just \fBversion\fR -. -.IP "\(bu" 4 \fB>version\fR Must be greater than \fBversion\fR . .IP "\(bu" 4 @@ -490,10 +470,10 @@ is a semver compatible version identifier\. \fB<=version\fR . .IP "\(bu" 4 -\fB~version\fR See \'Tilde Version Ranges\' below +npm help \fB~version\fR "Approximately equivalent to version" See semver . .IP "\(bu" 4 -\fB1\.2\.x\fR See \'X Version Ranges\' below +\fB1\.2\.x\fR 1\.2\.0, 1\.2\.1, etc\., but not 1\.3\.0 . .IP "\(bu" 4 \fBhttp://\.\.\.\fR See \'URLs as Dependencies\' below @@ -539,63 +519,8 @@ For example, these are all valid: . .IP "" 0 . -.SS "Tilde Version Ranges" -A range specifier starting with a tilde \fB~\fR character is matched against -a version in the following fashion\. -. -.IP "\(bu" 4 -The version must be at least as high as the range\. -. -.IP "\(bu" 4 -The version must be less than the next major revision above the range\. -. -.IP "" 0 -. -.P -For example, the following are equivalent: -. -.IP "\(bu" 4 -\fB"~1\.2\.3" = ">=1\.2\.3 <1\.3\.0"\fR -. -.IP "\(bu" 4 -\fB"~1\.2" = ">=1\.2\.0 <1\.3\.0"\fR -. -.IP "\(bu" 4 -\fB"~1" = ">=1\.0\.0 <1\.1\.0"\fR -. -.IP "" 0 -. -.SS "X Version Ranges" -An "x" in a version range specifies that the version number must start -with the supplied digits, but any digit may be used in place of the x\. -. -.P -The following are equivalent: -. -.IP "\(bu" 4 -\fB"1\.2\.x" = ">=1\.2\.0 <1\.3\.0"\fR -. -.IP "\(bu" 4 -\fB"1\.x\.x" = ">=1\.0\.0 <2\.0\.0"\fR -. -.IP "\(bu" 4 -\fB"1\.2" = "1\.2\.x"\fR -. -.IP "\(bu" 4 -\fB"1\.x" = "1\.x\.x"\fR -. -.IP "\(bu" 4 -\fB"1" = "1\.x\.x"\fR -. -.IP "" 0 -. -.P -You may not supply a comparator with a version containing an x\. Any -digits after the first "x" are ignored\. -. .SS "URLs as Dependencies" -Starting with npm version 0\.2\.14, you may specify a tarball URL in place -of a version range\. +You may specify a tarball URL in place of a version range\. . .P This tarball will be downloaded and installed locally to your package at @@ -630,10 +555,38 @@ the external test or documentation framework that you use\. In this case, it\'s best to list these additional items in a \fBdevDependencies\fR hash\. . .P -These things will be installed whenever the \fB\-\-dev\fR configuration flag -is set\. This flag is set automatically when doing \fBnpm link\fR or when doing \fBnpm install\fR from the root of a package, and can be managed like any other npm +These things will be installed when doing \fBnpm link\fR or \fBnpm install\fR +from the root of a package, and can be managed like any other npm npm help configuration param\. See \fBnpm\-config\fR for more on the topic\. . +.P +For build steps that are not platform\-specific, such as compiling +CoffeeScript or other languages to JavaScript, use the \fBprepublish\fR +script to do this, and make the required package a devDependency\. +. +.P +For example: +. +.P +\fBjson +{ "name": "ethopia\-waza", + "description": "a delightfully fruity coffee varietal", + "version": "1\.2\.3", + "devDependencies": { + "coffee\-script": "~1\.6\.3" + }, + "scripts": { + "prepublish": "coffee \-o lib/ \-c src/waza\.coffee" + }, + "main": "lib/waza\.js" +}\fR +. +.P +The \fBprepublish\fR script will be run before publishing, so that users +can consume the functionality without requiring them to compile it +themselves\. In dev mode (ie, locally running \fBnpm install\fR), it\'ll +run this script as well, so that you can test it easily\. +. .SH "bundledDependencies" Array of package names that will be bundled when publishing the package\. . @@ -680,7 +633,7 @@ You can specify the version of node that your stuff works on: .IP "" 4 . .nf -{ "engines" : { "node" : ">=0\.1\.27 <0\.1\.30" } } +{ "engines" : { "node" : ">=0\.10\.3 <0\.12" } } . .fi . diff --git a/deps/npm/man/man7/npm-coding-style.7 b/deps/npm/man/man7/npm-coding-style.7 index 47417d2dea0..f085ec8fe74 100644 --- a/deps/npm/man/man7/npm-coding-style.7 +++ b/deps/npm/man/man7/npm-coding-style.7 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-CODING\-STYLE" "7" "July 2013" "" "" +.TH "NPM\-CODING\-STYLE" "7" "August 2013" "" "" . .SH "NAME" \fBnpm-coding-style\fR \-\- npm\'s "funny" coding style diff --git a/deps/npm/man/man7/npm-config.7 b/deps/npm/man/man7/npm-config.7 index f30758b8fa7..e90514eadf1 100644 --- a/deps/npm/man/man7/npm-config.7 +++ b/deps/npm/man/man7/npm-config.7 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-CONFIG" "7" "July 2013" "" "" +.TH "NPM\-CONFIG" "7" "August 2013" "" "" . .SH "NAME" \fBnpm-config\fR \-\- More than you probably want to know about npm configuration diff --git a/deps/npm/man/man7/npm-developers.7 b/deps/npm/man/man7/npm-developers.7 index 619e8ecb189..71d902bfd2a 100644 --- a/deps/npm/man/man7/npm-developers.7 +++ b/deps/npm/man/man7/npm-developers.7 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-DEVELOPERS" "7" "July 2013" "" "" +.TH "NPM\-DEVELOPERS" "7" "August 2013" "" "" . .SH "NAME" \fBnpm-developers\fR \-\- Developer Guide diff --git a/deps/npm/man/man7/npm-disputes.7 b/deps/npm/man/man7/npm-disputes.7 index 7d074dd5513..37fba251126 100644 --- a/deps/npm/man/man7/npm-disputes.7 +++ b/deps/npm/man/man7/npm-disputes.7 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-DISPUTES" "7" "July 2013" "" "" +.TH "NPM\-DISPUTES" "7" "August 2013" "" "" . .SH "NAME" \fBnpm-disputes\fR \-\- Handling Module Name Disputes diff --git a/deps/npm/man/man7/npm-faq.7 b/deps/npm/man/man7/npm-faq.7 index 1fde2985f1a..71f954d0ddc 100644 --- a/deps/npm/man/man7/npm-faq.7 +++ b/deps/npm/man/man7/npm-faq.7 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-FAQ" "7" "July 2013" "" "" +.TH "NPM\-FAQ" "7" "August 2013" "" "" . .SH "NAME" \fBnpm-faq\fR \-\- Frequently Asked Questions diff --git a/deps/npm/man/man7/npm-index.7 b/deps/npm/man/man7/npm-index.7 index dd3f6a806f5..1a507ebae6d 100644 --- a/deps/npm/man/man7/npm-index.7 +++ b/deps/npm/man/man7/npm-index.7 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-INDEX" "7" "July 2013" "" "" +.TH "NPM\-INDEX" "7" "August 2013" "" "" . .SH "NAME" \fBnpm-index\fR \-\- Index of all npm documentation @@ -147,6 +147,9 @@ View registry info npm help .SH "npm\-whoami" Display npm username . +npm help .SH "repo" +Open package repository page in the browser +. npm apihelp .SH "npm" node package manager . @@ -261,6 +264,9 @@ View registry info npm apihelp .SH "npm\-whoami" Display npm username . +npm apihelp .SH "repo" +Open package repository page in the browser +. npm help .SH "npm\-folders" Folder Structures Used by npm . diff --git a/deps/npm/man/man7/npm-registry.7 b/deps/npm/man/man7/npm-registry.7 index 19a4bff02d4..4d194bdeac6 100644 --- a/deps/npm/man/man7/npm-registry.7 +++ b/deps/npm/man/man7/npm-registry.7 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-REGISTRY" "7" "July 2013" "" "" +.TH "NPM\-REGISTRY" "7" "August 2013" "" "" . .SH "NAME" \fBnpm-registry\fR \-\- The JavaScript Package Registry @@ -55,40 +55,8 @@ registry using npm\. What little security there is would be for nought otherwise\. . .SH "Do I have to use couchdb to build a registry that npm can talk to?" -No, but it\'s way easier\. -. -.SH "I published something elsewhere, and want to tell the npm registry about it\." -That is supported, but not using the npm client\. You\'ll have to get -your hands dirty and do some HTTP\. The request looks something like -this: -. -.IP "" 4 -. -.nf -PUT /my\-foreign\-package -content\-type:application/json -accept:application/json -authorization:Basic $base_64_encoded -{ "name":"my\-foreign\-package" -, "maintainers":["owner","usernames"] -, "description":"A package that is hosted elsewhere" -, "keywords":["nih","my cheese smells the best"] -, "url":"http://my\-different\-registry\.com/blerg/my\-local\-package" -} -. -.fi -. -.IP "" 0 -. -.P -(Keywords and description are optional, but recommended\. Name, -maintainers, and url are required\.) -. -.P -Then, when a user tries to install "my\-foreign\-package", it\'ll redirect -to your registry\. If that doesn\'t resolve to a valid package entry, -then it\'ll fail, so please make sure that you understand the spec, and -ask for help on the \fInpm\-@googlegroups\.com\fR mailing list\. +No, but it\'s way easier\. Basically, yes, you do, or you have to +effectively implement the entire CouchDB API anyway\. . .SH "Is there a website or something to see package docs and such?" Yes, head over to \fIhttps://npmjs\.org/\fR diff --git a/deps/npm/man/man7/npm-scripts.7 b/deps/npm/man/man7/npm-scripts.7 index d88c63ec5a9..1120378a748 100644 --- a/deps/npm/man/man7/npm-scripts.7 +++ b/deps/npm/man/man7/npm-scripts.7 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-SCRIPTS" "7" "July 2013" "" "" +.TH "NPM\-SCRIPTS" "7" "August 2013" "" "" . .SH "NAME" \fBnpm-scripts\fR \-\- How npm handles the "scripts" field @@ -63,7 +63,7 @@ stop and start scripts if no \fBrestart\fR script is provided\. .IP "" 0 . .P -Additionally, arbitrary scrips can be run by doing \fBnpm run\-script <stage> <pkg>\fR\|\. +Additionally, arbitrary scripts can be run by doing \fBnpm run\-script <stage> <pkg>\fR\|\. . .SH "NOTE: INSTALL SCRIPTS ARE AN ANTIPATTERN" \fBtl;dr\fR Don\'t use \fBinstall\fR\|\. Use a \fB\|\.gyp\fR file for compilation, and \fBprepublish\fR for anything else\. diff --git a/deps/npm/man/man7/removing-npm.7 b/deps/npm/man/man7/removing-npm.7 index d741b60f5a7..39fc54aa3b0 100644 --- a/deps/npm/man/man7/removing-npm.7 +++ b/deps/npm/man/man7/removing-npm.7 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "NPM\-REMOVAL" "1" "July 2013" "" "" +.TH "NPM\-REMOVAL" "1" "August 2013" "" "" . .SH "NAME" \fBnpm-removal\fR \-\- Cleaning the Slate diff --git a/deps/npm/man/man7/semver.7 b/deps/npm/man/man7/semver.7 index 3be3da95da6..af6b4bd7062 100644 --- a/deps/npm/man/man7/semver.7 +++ b/deps/npm/man/man7/semver.7 @@ -1,7 +1,7 @@ .\" Generated with Ronnjs 0.3.8 .\" http://github.com/kapouer/ronnjs/ . -.TH "SEMVER" "7" "July 2013" "" "" +.TH "SEMVER" "7" "August 2013" "" "" . .SH "NAME" \fBsemver\fR \-\- The semantic versioner for npm diff --git a/deps/npm/node_modules/github-url-from-git/.npmignore b/deps/npm/node_modules/github-url-from-git/.npmignore new file mode 100644 index 00000000000..3c3629e647f --- /dev/null +++ b/deps/npm/node_modules/github-url-from-git/.npmignore @@ -0,0 +1 @@ +node_modules diff --git a/deps/npm/node_modules/github-url-from-git/History.md b/deps/npm/node_modules/github-url-from-git/History.md new file mode 100644 index 00000000000..fcb296bc68a --- /dev/null +++ b/deps/npm/node_modules/github-url-from-git/History.md @@ -0,0 +1,10 @@ + +1.1.1 / 2013-04-23 +================== + + * package.json: Move test stuff to devDeps + +1.1.0 / 2013-04-19 +================== + + * Add support for gist urls diff --git a/deps/npm/node_modules/github-url-from-git/Makefile b/deps/npm/node_modules/github-url-from-git/Makefile new file mode 100644 index 00000000000..37f330e81b9 --- /dev/null +++ b/deps/npm/node_modules/github-url-from-git/Makefile @@ -0,0 +1,5 @@ + +test: + @./node_modules/.bin/mocha test.js --reporter spec --require should + +.PHONY: test diff --git a/deps/npm/node_modules/github-url-from-git/Readme.md b/deps/npm/node_modules/github-url-from-git/Readme.md new file mode 100644 index 00000000000..d027e8ec66b --- /dev/null +++ b/deps/npm/node_modules/github-url-from-git/Readme.md @@ -0,0 +1,41 @@ + +# github-url-from-git + +```js +describe('parse(url)', function(){ + it('should support git://*', function(){ + var url = 'git://github.com/jamesor/mongoose-versioner'; + parse(url).should.equal('https://github.com/jamesor/mongoose-versioner'); + }) + + it('should support git://*.git', function(){ + var url = 'git://github.com/treygriffith/cellar.git'; + parse(url).should.equal('https://github.com/treygriffith/cellar'); + }) + + it('should support https://*', function(){ + var url = 'https://github.com/Empeeric/i18n-node'; + parse(url).should.equal('https://github.com/Empeeric/i18n-node'); + }) + + it('should support https://*.git', function(){ + var url = 'https://jpillora@github.com/banchee/tranquil.git'; + parse(url).should.equal('https://github.com/banchee/tranquil'); + }) + + it('should return undefined on failure', function(){ + var url = 'git://github.com/justgord/.git'; + assert(null == parse(url)); + }) + + it('should parse git@gist urls', function() { + var url = 'git@gist.github.com:3135914.git'; + parse(url).should.equal('https://gist.github.com/3135914') + }) + + it('should parse https://gist urls', function() { + var url = 'https://gist.github.com/3135914.git'; + parse(url).should.equal('https://gist.github.com/3135914') + }) +}) +``` diff --git a/deps/npm/node_modules/github-url-from-git/index.js b/deps/npm/node_modules/github-url-from-git/index.js new file mode 100644 index 00000000000..9ccc215f00a --- /dev/null +++ b/deps/npm/node_modules/github-url-from-git/index.js @@ -0,0 +1,12 @@ +var re = /^(?:https?:\/\/|git:\/\/)?(?:[^@]+@)?(gist.github.com|github.com)[:\/]([^\/]+\/[^\/]+?|[0-9]+)$/ + +module.exports = function(url){ + try { + var m = re.exec(url.replace(/\.git$/, '')); + var host = m[1]; + var path = m[2]; + return 'https://' + host + '/' + path; + } catch (err) { + // ignore + } +}; diff --git a/deps/npm/node_modules/github-url-from-git/package.json b/deps/npm/node_modules/github-url-from-git/package.json new file mode 100644 index 00000000000..5673fb98957 --- /dev/null +++ b/deps/npm/node_modules/github-url-from-git/package.json @@ -0,0 +1,31 @@ +{ + "name": "github-url-from-git", + "version": "1.1.1", + "description": "Parse a github git url and return the github repo url", + "main": "index.js", + "scripts": { + "test": "mocha test.js --reporter spec --require should" + }, + "repository": "", + "keywords": [ + "github", + "git", + "url", + "parser" + ], + "author": "", + "license": "MIT", + "devDependencies": { + "better-assert": "~1.0.0", + "mocha": "~1.9.0", + "should": "~1.2.2" + }, + "readme": "\n# github-url-from-git\n\n```js\ndescribe('parse(url)', function(){\n it('should support git://*', function(){\n var url = 'git://github.com/jamesor/mongoose-versioner';\n parse(url).should.equal('https://github.com/jamesor/mongoose-versioner');\n })\n\n it('should support git://*.git', function(){\n var url = 'git://github.com/treygriffith/cellar.git';\n parse(url).should.equal('https://github.com/treygriffith/cellar');\n })\n\n it('should support https://*', function(){\n var url = 'https://github.com/Empeeric/i18n-node';\n parse(url).should.equal('https://github.com/Empeeric/i18n-node');\n })\n\n it('should support https://*.git', function(){\n var url = 'https://jpillora@github.com/banchee/tranquil.git';\n parse(url).should.equal('https://github.com/banchee/tranquil');\n })\n\n it('should return undefined on failure', function(){\n var url = 'git://github.com/justgord/.git';\n assert(null == parse(url));\n })\n\n it('should parse git@gist urls', function() {\n var url = 'git@gist.github.com:3135914.git';\n parse(url).should.equal('https://gist.github.com/3135914')\n })\n\n it('should parse https://gist urls', function() {\n var url = 'https://gist.github.com/3135914.git';\n parse(url).should.equal('https://gist.github.com/3135914')\n })\n})\n```\n", + "readmeFilename": "Readme.md", + "_id": "github-url-from-git@1.1.1", + "dist": { + "shasum": "a14903bccbd30c91ea41765ae68ba1b27a53c4d1" + }, + "_from": "github-url-from-git@1.1.1", + "_resolved": "https://registry.npmjs.org/github-url-from-git/-/github-url-from-git-1.1.1.tgz" +} diff --git a/deps/npm/node_modules/github-url-from-git/test.js b/deps/npm/node_modules/github-url-from-git/test.js new file mode 100644 index 00000000000..e472302a00b --- /dev/null +++ b/deps/npm/node_modules/github-url-from-git/test.js @@ -0,0 +1,40 @@ + +var parse = require('./'); +var assert = require('better-assert'); + +describe('parse(url)', function(){ + it('should support git://*', function(){ + var url = 'git://github.com/jamesor/mongoose-versioner'; + parse(url).should.equal('https://github.com/jamesor/mongoose-versioner'); + }) + + it('should support git://*.git', function(){ + var url = 'git://github.com/treygriffith/cellar.git'; + parse(url).should.equal('https://github.com/treygriffith/cellar'); + }) + + it('should support https://*', function(){ + var url = 'https://github.com/Empeeric/i18n-node'; + parse(url).should.equal('https://github.com/Empeeric/i18n-node'); + }) + + it('should support https://*.git', function(){ + var url = 'https://jpillora@github.com/banchee/tranquil.git'; + parse(url).should.equal('https://github.com/banchee/tranquil'); + }) + + it('should return undefined on failure', function(){ + var url = 'git://github.com/justgord/.git'; + assert(null == parse(url)); + }) + + it('should parse git@gist urls', function() { + var url = 'git@gist.github.com:3135914.git'; + parse(url).should.equal('https://gist.github.com/3135914') + }) + + it('should parse https://gist urls', function() { + var url = 'https://gist.github.com/3135914.git'; + parse(url).should.equal('https://gist.github.com/3135914') + }) +}) diff --git a/deps/npm/node_modules/glob/glob.js b/deps/npm/node_modules/glob/glob.js index f0118a4f47f..176be02f4cb 100644 --- a/deps/npm/node_modules/glob/glob.js +++ b/deps/npm/node_modules/glob/glob.js @@ -36,7 +36,7 @@ module.exports = glob -var fs = require("graceful-fs") +var fs = require("fs") , minimatch = require("minimatch") , Minimatch = minimatch.Minimatch , inherits = require("inherits") diff --git a/deps/npm/node_modules/glob/package.json b/deps/npm/node_modules/glob/package.json index fe224bd210d..73aa885e764 100644 --- a/deps/npm/node_modules/glob/package.json +++ b/deps/npm/node_modules/glob/package.json @@ -6,7 +6,7 @@ }, "name": "glob", "description": "a little globber", - "version": "3.2.3", + "version": "3.2.6", "repository": { "type": "git", "url": "git://github.com/isaacs/node-glob.git" @@ -17,7 +17,6 @@ }, "dependencies": { "minimatch": "~0.2.11", - "graceful-fs": "~2.0.0", "inherits": "2" }, "devDependencies": { @@ -34,6 +33,6 @@ "bugs": { "url": "https://github.com/isaacs/node-glob/issues" }, - "_id": "glob@3.2.3", + "_id": "glob@3.2.6", "_from": "glob@latest" } diff --git a/deps/npm/node_modules/glob/test/bash-results.json b/deps/npm/node_modules/glob/test/bash-results.json index a9bc347dea5..3ffadba6836 100644 --- a/deps/npm/node_modules/glob/test/bash-results.json +++ b/deps/npm/node_modules/glob/test/bash-results.json @@ -283,7 +283,6 @@ "{./*/*,/tmp/glob-test/*}": [ "./examples/g.js", "./examples/usr-local.js", - "./node_modules/graceful-fs", "./node_modules/inherits", "./node_modules/minimatch", "./node_modules/mkdirp", diff --git a/deps/npm/node_modules/glob/test/nocase-nomagic.js b/deps/npm/node_modules/glob/test/nocase-nomagic.js index d86297098d8..2503f23101c 100644 --- a/deps/npm/node_modules/glob/test/nocase-nomagic.js +++ b/deps/npm/node_modules/glob/test/nocase-nomagic.js @@ -1,4 +1,4 @@ -var fs = require('graceful-fs'); +var fs = require('fs'); var test = require('tap').test; var glob = require('../'); diff --git a/deps/npm/node_modules/init-package-json/default-input.js b/deps/npm/node_modules/init-package-json/default-input.js index d501b06447e..80b20a94a7b 100644 --- a/deps/npm/node_modules/init-package-json/default-input.js +++ b/deps/npm/node_modules/init-package-json/default-input.js @@ -176,4 +176,4 @@ if (!package.author) { : prompt('author') } -exports.license = prompt('license', 'BSD') +exports.license = prompt('license', 'BSD-2-Clause') diff --git a/deps/npm/node_modules/init-package-json/package.json b/deps/npm/node_modules/init-package-json/package.json index a97b5053f54..7c710378874 100644 --- a/deps/npm/node_modules/init-package-json/package.json +++ b/deps/npm/node_modules/init-package-json/package.json @@ -1,6 +1,6 @@ { "name": "init-package-json", - "version": "0.0.10", + "version": "0.0.11", "main": "init-package-json.js", "scripts": { "test": "tap test/*.js" @@ -41,6 +41,6 @@ "bugs": { "url": "https://github.com/isaacs/init-package-json/issues" }, - "_id": "init-package-json@0.0.10", + "_id": "init-package-json@0.0.11", "_from": "init-package-json@latest" } diff --git a/deps/npm/node_modules/node-gyp/addon.gypi b/deps/npm/node_modules/node-gyp/addon.gypi index 065b975d47b..6b9e20e2063 100644 --- a/deps/npm/node_modules/node-gyp/addon.gypi +++ b/deps/npm/node_modules/node-gyp/addon.gypi @@ -29,7 +29,21 @@ }, }], [ 'OS=="win"', { - 'libraries': [ '-l<(node_root_dir)/$(Configuration)/node.lib' ], + 'libraries': [ + '-lkernel32.lib', + '-luser32.lib', + '-lgdi32.lib', + '-lwinspool.lib', + '-lcomdlg32.lib', + '-ladvapi32.lib', + '-lshell32.lib', + '-lole32.lib', + '-loleaut32.lib', + '-luuid.lib', + '-lodbc32.lib', + '-lDelayImp.lib', + '-l<(node_root_dir)/$(Configuration)/node.lib' + ], # warning C4251: 'node::ObjectWrap::handle_' : class 'v8::Persistent<T>' # needs to have dll-interface to be used by clients of class 'node::ObjectWrap' 'msvs_disabled_warnings': [ 4251 ], diff --git a/deps/npm/node_modules/node-gyp/package.json b/deps/npm/node_modules/node-gyp/package.json index 807454fa2d5..41bf9bfdb42 100644 --- a/deps/npm/node_modules/node-gyp/package.json +++ b/deps/npm/node_modules/node-gyp/package.json @@ -10,7 +10,7 @@ "bindings", "gyp" ], - "version": "0.10.6", + "version": "0.10.9", "installVersion": 9, "author": { "name": "Nathan Rajlich", @@ -37,7 +37,7 @@ "osenv": "0", "request": "2", "rimraf": "2", - "semver": "~2.0.7", + "semver": "~2.1", "tar": "0", "which": "1" }, @@ -49,6 +49,6 @@ "bugs": { "url": "https://github.com/TooTallNate/node-gyp/issues" }, - "_id": "node-gyp@0.10.6", + "_id": "node-gyp@0.10.9", "_from": "node-gyp@latest" } diff --git a/deps/npm/node_modules/npm-registry-client/node_modules/couch-login/package.json b/deps/npm/node_modules/npm-registry-client/node_modules/couch-login/package.json index b65ced071c2..0b2c63a4f28 100644 --- a/deps/npm/node_modules/npm-registry-client/node_modules/couch-login/package.json +++ b/deps/npm/node_modules/npm-registry-client/node_modules/couch-login/package.json @@ -6,7 +6,7 @@ }, "name": "couch-login", "description": "A module for doing logged-in requests to a couchdb server", - "version": "0.1.17", + "version": "0.1.18", "repository": { "type": "git", "url": "git://github.com/isaacs/couch-login.git" @@ -16,7 +16,7 @@ "test": "tap test/*.js" }, "dependencies": { - "request": "2 >=2.14" + "request": "2 >=2.25.0" }, "devDependencies": { "tap": "~0.2.4" @@ -26,6 +26,6 @@ "bugs": { "url": "https://github.com/isaacs/couch-login/issues" }, - "_id": "couch-login@0.1.17", - "_from": "couch-login@~0.1.15" + "_id": "couch-login@0.1.18", + "_from": "couch-login@~0.1.18" } diff --git a/deps/npm/node_modules/npm-registry-client/node_modules/couch-login/test/basic.js b/deps/npm/node_modules/npm-registry-client/node_modules/couch-login/test/basic.js index 9e222e14341..4dea12b3f23 100644 --- a/deps/npm/node_modules/npm-registry-client/node_modules/couch-login/test/basic.js +++ b/deps/npm/node_modules/npm-registry-client/node_modules/couch-login/test/basic.js @@ -246,7 +246,8 @@ tap.test('anonymous get', function (t) { t.ifError(er) if (er) return t.end() t.equal(res.statusCode, 200) - t.deepEqual(data, { couchdb: 'Welcome', version: '1.2.0' }) + t.has(data, { couchdb: 'Welcome' }) + t.ok(data.version) t.end() }) }) diff --git a/deps/npm/node_modules/npm-registry-client/node_modules/couch-login/test/fixtures/couch.ini b/deps/npm/node_modules/npm-registry-client/node_modules/couch-login/test/fixtures/couch.ini index 4579a2f027c..5f357971314 100644 --- a/deps/npm/node_modules/npm-registry-client/node_modules/couch-login/test/fixtures/couch.ini +++ b/deps/npm/node_modules/npm-registry-client/node_modules/couch-login/test/fixtures/couch.ini @@ -1,6 +1,7 @@ [couchdb] database_dir = test/fixtures view_index_dir = test/fixtures +uuid = 3ec49bc6c314484cb21d684dc3fc778e [httpd] port = 15985 diff --git a/deps/npm/node_modules/npm-registry-client/package.json b/deps/npm/node_modules/npm-registry-client/package.json index 152ed8713c2..f24f4a9d339 100644 --- a/deps/npm/node_modules/npm-registry-client/package.json +++ b/deps/npm/node_modules/npm-registry-client/package.json @@ -6,7 +6,7 @@ }, "name": "npm-registry-client", "description": "Client for the npm registry", - "version": "0.2.27", + "version": "0.2.28", "repository": { "url": "git://github.com/isaacs/npm-registry-client" }, @@ -15,15 +15,15 @@ "test": "tap test/*.js" }, "dependencies": { - "request": "2 >=2.20.0", + "request": "2 >=2.25.0", "graceful-fs": "~2.0.0", - "semver": "~2.0.5", + "semver": "~2.1.0", "slide": "~1.1.3", "chownr": "0", "mkdirp": "~0.3.3", "rimraf": "~2", "retry": "0.6.0", - "couch-login": "~0.1.15", + "couch-login": "~0.1.18", "npmlog": "" }, "devDependencies": { @@ -38,6 +38,6 @@ "bugs": { "url": "https://github.com/isaacs/npm-registry-client/issues" }, - "_id": "npm-registry-client@0.2.27", + "_id": "npm-registry-client@0.2.28", "_from": "npm-registry-client@latest" } diff --git a/deps/npm/node_modules/npm-registry-client/test/fixtures/server.js b/deps/npm/node_modules/npm-registry-client/test/fixtures/server.js new file mode 100644 index 00000000000..468a89e5bfb --- /dev/null +++ b/deps/npm/node_modules/npm-registry-client/test/fixtures/server.js @@ -0,0 +1,56 @@ +// a fake registry server. + +var http = require('http') +var server = http.createServer(handler) +var port = server.port = process.env.PORT || 1337 +server.listen(port) + +module.exports = server + +server._expect = {} + +var expect = {} +function handler (req, res) { + req.connection.setTimeout(1000) + + var u = '* ' + req.url + , mu = req.method + ' ' + req.url + + var k = server._expect[mu] ? mu : server._expect[u] ? u : null + if (!k) throw Error('unexpected request', req.method, req.url) + + var fn = server._expect[k].shift() + if (!fn) throw Error('unexpected request', req.method, req.url) + + + var remain = (Object.keys(server._expect).reduce(function (s, k) { + return s + server._expect[k].length + }, 0)) + if (remain === 0) server.close() + else console.error("TEST SERVER: %d reqs remain", remain) + console.error(Object.keys(server._expect).map(function(k) { + return [k, server._expect[k].length] + }).reduce(function (acc, kv) { + acc[kv[0]] = kv[1] + return acc + }, {})) + + res.json = json + fn(req, res) +} + +function json (o) { + this.setHeader('content-type', 'application/json') + this.end(JSON.stringify(o)) +} + +server.expect = function (method, u, fn) { + if (typeof u === 'function') { + fn = u + u = method + method = '*' + } + u = method + ' ' + u + server._expect[u] = server._expect[u] || [] + server._expect[u].push(fn) +} diff --git a/deps/npm/node_modules/npm-registry-client/test/fixtures/underscore/1.3.3/cache.json b/deps/npm/node_modules/npm-registry-client/test/fixtures/underscore/1.3.3/cache.json new file mode 100644 index 00000000000..01da3002763 --- /dev/null +++ b/deps/npm/node_modules/npm-registry-client/test/fixtures/underscore/1.3.3/cache.json @@ -0,0 +1 @@ +{"name":"underscore","description":"JavaScript's functional programming helper library.","homepage":"http://documentcloud.github.com/underscore/","keywords":["util","functional","server","client","browser"],"author":{"name":"Jeremy Ashkenas","email":"jeremy@documentcloud.org"},"repository":{"type":"git","url":"git://github.com/documentcloud/underscore.git"},"main":"underscore.js","version":"1.3.3","_npmUser":{"name":"jashkenas","email":"jashkenas@gmail.com"},"_id":"underscore@1.3.3","dependencies":{},"devDependencies":{},"optionalDependencies":{},"engines":{"node":"*"},"_engineSupported":true,"_npmVersion":"1.1.1","_nodeVersion":"v0.6.11","_defaultsLoaded":true,"dist":{"shasum":"47ac53683daf832bfa952e1774417da47817ae42","tarball":"http://registry.npmjs.org/underscore/-/underscore-1.3.3.tgz"},"readme":" __ \n /\\ \\ __ \n __ __ ___ \\_\\ \\ __ _ __ ____ ___ ___ _ __ __ /\\_\\ ____ \n /\\ \\/\\ \\ /' _ `\\ /'_ \\ /'__`\\/\\ __\\/ ,__\\ / ___\\ / __`\\/\\ __\\/'__`\\ \\/\\ \\ /',__\\ \n \\ \\ \\_\\ \\/\\ \\/\\ \\/\\ \\ \\ \\/\\ __/\\ \\ \\//\\__, `\\/\\ \\__//\\ \\ \\ \\ \\ \\//\\ __/ __ \\ \\ \\/\\__, `\\\n \\ \\____/\\ \\_\\ \\_\\ \\___,_\\ \\____\\\\ \\_\\\\/\\____/\\ \\____\\ \\____/\\ \\_\\\\ \\____\\/\\_\\ _\\ \\ \\/\\____/\n \\/___/ \\/_/\\/_/\\/__,_ /\\/____/ \\/_/ \\/___/ \\/____/\\/___/ \\/_/ \\/____/\\/_//\\ \\_\\ \\/___/ \n \\ \\____/ \n \\/___/\n \nUnderscore.js is a utility-belt library for JavaScript that provides \nsupport for the usual functional suspects (each, map, reduce, filter...) \nwithout extending any core JavaScript objects.\n\nFor Docs, License, Tests, and pre-packed downloads, see:\nhttp://documentcloud.github.com/underscore/\n\nMany thanks to our contributors:\nhttps://github.com/documentcloud/underscore/contributors\n","maintainers":[{"name":"documentcloud","email":"jeremy@documentcloud.org"},{"name":"jashkenas","email":"jashkenas@gmail.com"}],"directories":{}}
\ No newline at end of file diff --git a/deps/npm/node_modules/npm-registry-client/test/fixtures/underscore/cache.json b/deps/npm/node_modules/npm-registry-client/test/fixtures/underscore/cache.json new file mode 100644 index 00000000000..d899f11922a --- /dev/null +++ b/deps/npm/node_modules/npm-registry-client/test/fixtures/underscore/cache.json @@ -0,0 +1 @@ +{"_id":"underscore","_rev":"72-47f2986bfd8e8b55068b204588bbf484","name":"underscore","description":"JavaScript's functional programming helper library.","dist-tags":{"latest":"1.3.3","stable":"1.3.3"},"versions":{"1.0.3":{"name":"underscore","description":"Functional programming aid for JavaScript. Works well with jQuery.","url":"http://documentcloud.github.com/underscore/","keywords":["util","functional","server","client","browser"],"author":{"name":"Jeremy Ashkenas","email":"jeremy@documentcloud.org"},"contributors":[],"dependencies":{},"lib":".","main":"underscore","version":"1.0.3","_id":"underscore@1.0.3","engines":{"node":"*"},"_nodeSupported":true,"_npmVersion":"0.2.7-2","_nodeVersion":"v0.3.1-pre","dist":{"tarball":"http://registry.npmjs.org/underscore/-/underscore-1.0.3.tgz"},"directories":{},"_npmUser":{"name":"jashkenas","email":"jashkenas@gmail.com"},"maintainers":[{"name":"documentcloud","email":"jeremy@documentcloud.org"},{"name":"jashkenas","email":"jashkenas@gmail.com"}]},"1.0.4":{"name":"underscore","description":"Functional programming aid for JavaScript. Works well with jQuery.","url":"http://documentcloud.github.com/underscore/","keywords":["util","functional","server","client","browser"],"author":{"name":"Jeremy Ashkenas","email":"jeremy@documentcloud.org"},"contributors":[],"dependencies":{},"lib":".","main":"underscore","version":"1.0.4","_id":"underscore@1.0.4","engines":{"node":"*"},"_nodeSupported":true,"_npmVersion":"0.2.7-2","_nodeVersion":"v0.3.1-pre","dist":{"tarball":"http://registry.npmjs.org/underscore/-/underscore-1.0.4.tgz"},"directories":{},"_npmUser":{"name":"jashkenas","email":"jashkenas@gmail.com"},"maintainers":[{"name":"documentcloud","email":"jeremy@documentcloud.org"},{"name":"jashkenas","email":"jashkenas@gmail.com"}]},"1.1.0":{"name":"underscore","description":"Functional programming aid for JavaScript. Works well with jQuery.","url":"http://documentcloud.github.com/underscore/","keywords":["util","functional","server","client","browser"],"author":{"name":"Jeremy Ashkenas","email":"jeremy@documentcloud.org"},"contributors":[],"dependencies":{},"lib":".","main":"underscore","version":"1.1.0","_id":"underscore@1.1.0","engines":{"node":"*"},"_nodeSupported":true,"_npmVersion":"0.2.7-2","_nodeVersion":"v0.3.1-pre","dist":{"tarball":"http://registry.npmjs.org/underscore/-/underscore-1.1.0.tgz"},"directories":{},"_npmUser":{"name":"jashkenas","email":"jashkenas@gmail.com"},"maintainers":[{"name":"documentcloud","email":"jeremy@documentcloud.org"},{"name":"jashkenas","email":"jashkenas@gmail.com"}]},"1.1.1":{"name":"underscore","description":"Functional programming aid for JavaScript. Works well with jQuery.","url":"http://documentcloud.github.com/underscore/","keywords":["util","functional","server","client","browser"],"author":{"name":"Jeremy Ashkenas","email":"jeremy@documentcloud.org"},"contributors":[],"dependencies":{},"lib":".","main":"underscore","version":"1.1.1","_id":"underscore@1.1.1","engines":{"node":"*"},"_nodeSupported":true,"_npmVersion":"0.2.7-2","_nodeVersion":"v0.3.1-pre","dist":{"tarball":"http://registry.npmjs.org/underscore/-/underscore-1.1.1.tgz"},"directories":{},"_npmUser":{"name":"jashkenas","email":"jashkenas@gmail.com"},"maintainers":[{"name":"documentcloud","email":"jeremy@documentcloud.org"},{"name":"jashkenas","email":"jashkenas@gmail.com"}]},"1.1.2":{"name":"underscore","description":"Functional programming aid for JavaScript. Works well with jQuery.","url":"http://documentcloud.github.com/underscore/","keywords":["util","functional","server","client","browser"],"author":{"name":"Jeremy Ashkenas","email":"jeremy@documentcloud.org"},"contributors":[],"dependencies":{},"lib":".","main":"underscore","version":"1.1.2","_id":"underscore@1.1.2","engines":{"node":"*"},"_nodeSupported":true,"_npmVersion":"0.2.7-2","_nodeVersion":"v0.3.1-pre","dist":{"tarball":"http://registry.npmjs.org/underscore/-/underscore-1.1.2.tgz"},"directories":{},"_npmUser":{"name":"jashkenas","email":"jashkenas@gmail.com"},"maintainers":[{"name":"documentcloud","email":"jeremy@documentcloud.org"},{"name":"jashkenas","email":"jashkenas@gmail.com"}]},"1.1.3":{"name":"underscore","description":"Functional programming aid for JavaScript. Works well with jQuery.","url":"http://documentcloud.github.com/underscore/","keywords":["util","functional","server","client","browser"],"author":{"name":"Jeremy Ashkenas","email":"jeremy@documentcloud.org"},"contributors":[],"dependencies":{},"lib":".","main":"underscore","version":"1.1.3","_id":"underscore@1.1.3","engines":{"node":"*"},"_nodeSupported":true,"_npmVersion":"0.2.8-1","_nodeVersion":"v0.2.5","dist":{"tarball":"http://registry.npmjs.org/underscore/-/underscore-1.1.3.tgz"},"directories":{},"_npmUser":{"name":"jashkenas","email":"jashkenas@gmail.com"},"maintainers":[{"name":"documentcloud","email":"jeremy@documentcloud.org"},{"name":"jashkenas","email":"jashkenas@gmail.com"}]},"1.1.4":{"name":"underscore","description":"Functional programming aid for JavaScript. Works well with jQuery.","url":"http://documentcloud.github.com/underscore/","keywords":["util","functional","server","client","browser"],"author":{"name":"Jeremy Ashkenas","email":"jeremy@documentcloud.org"},"contributors":[],"dependencies":{},"lib":".","main":"underscore.js","version":"1.1.4","_id":"underscore@1.1.4","engines":{"node":"*"},"_engineSupported":true,"_npmVersion":"0.3.9","_nodeVersion":"v0.5.0-pre","dist":{"shasum":"9e82274902865625b3a6d4c315a38ffd80047dae","tarball":"http://registry.npmjs.org/underscore/-/underscore-1.1.4.tgz"},"_npmUser":{"name":"jashkenas","email":"jashkenas@gmail.com"},"maintainers":[{"name":"documentcloud","email":"jeremy@documentcloud.org"},{"name":"jashkenas","email":"jashkenas@gmail.com"}],"directories":{}},"1.1.5":{"name":"underscore","description":"JavaScript's functional programming helper library.","homepage":"http://documentcloud.github.com/underscore/","keywords":["util","functional","server","client","browser"],"author":{"name":"Jeremy Ashkenas","email":"jeremy@documentcloud.org"},"contributors":[],"dependencies":{},"repository":{"type":"git","url":"git://github.com/documentcloud/underscore.git"},"main":"underscore.js","version":"1.1.5","_id":"underscore@1.1.5","engines":{"node":"*"},"_engineSupported":true,"_npmVersion":"0.3.16","_nodeVersion":"v0.4.2","directories":{},"files":[""],"_defaultsLoaded":true,"dist":{"shasum":"23601d62c75619998b2f0db24938102793336a56","tarball":"http://registry.npmjs.org/underscore/-/underscore-1.1.5.tgz"},"_npmUser":{"name":"jashkenas","email":"jashkenas@gmail.com"},"maintainers":[{"name":"documentcloud","email":"jeremy@documentcloud.org"},{"name":"jashkenas","email":"jashkenas@gmail.com"}]},"1.1.6":{"name":"underscore","description":"JavaScript's functional programming helper library.","homepage":"http://documentcloud.github.com/underscore/","keywords":["util","functional","server","client","browser"],"author":{"name":"Jeremy Ashkenas","email":"jeremy@documentcloud.org"},"contributors":[],"dependencies":{},"repository":{"type":"git","url":"git://github.com/documentcloud/underscore.git"},"main":"underscore.js","version":"1.1.6","_id":"underscore@1.1.6","engines":{"node":"*"},"_engineSupported":true,"_npmVersion":"0.3.18","_nodeVersion":"v0.4.2","directories":{},"files":[""],"_defaultsLoaded":true,"dist":{"shasum":"6868da1bdd72d75285be0b4e50f228e70d001a2c","tarball":"http://registry.npmjs.org/underscore/-/underscore-1.1.6.tgz"},"_npmUser":{"name":"jashkenas","email":"jashkenas@gmail.com"},"maintainers":[{"name":"documentcloud","email":"jeremy@documentcloud.org"},{"name":"jashkenas","email":"jashkenas@gmail.com"}]},"1.1.7":{"name":"underscore","description":"JavaScript's functional programming helper library.","homepage":"http://documentcloud.github.com/underscore/","keywords":["util","functional","server","client","browser"],"author":{"name":"Jeremy Ashkenas","email":"jeremy@documentcloud.org"},"contributors":[],"dependencies":{},"repository":{"type":"git","url":"git://github.com/documentcloud/underscore.git"},"main":"underscore.js","version":"1.1.7","devDependencies":{},"_id":"underscore@1.1.7","engines":{"node":"*"},"_engineSupported":true,"_npmVersion":"1.0.3","_nodeVersion":"v0.4.7","_defaultsLoaded":true,"dist":{"shasum":"40bab84bad19d230096e8d6ef628bff055d83db0","tarball":"http://registry.npmjs.org/underscore/-/underscore-1.1.7.tgz"},"scripts":{},"_npmUser":{"name":"jashkenas","email":"jashkenas@gmail.com"},"maintainers":[{"name":"documentcloud","email":"jeremy@documentcloud.org"},{"name":"jashkenas","email":"jashkenas@gmail.com"}],"directories":{}},"1.2.0":{"name":"underscore","description":"JavaScript's functional programming helper library.","homepage":"http://documentcloud.github.com/underscore/","keywords":["util","functional","server","client","browser"],"author":{"name":"Jeremy Ashkenas","email":"jeremy@documentcloud.org"},"contributors":[],"dependencies":{},"repository":{"type":"git","url":"git://github.com/documentcloud/underscore.git"},"main":"underscore.js","version":"1.2.0","_npmJsonOpts":{"file":"/Users/jashkenas/.npm/underscore/1.2.0/package/package.json","wscript":false,"contributors":false,"serverjs":false},"_id":"underscore@1.2.0","devDependencies":{},"engines":{"node":"*"},"_engineSupported":true,"_npmVersion":"1.0.22","_nodeVersion":"v0.4.10","_defaultsLoaded":true,"dist":{"shasum":"b32ce32c8c118caa8031c10b54c7f65ab3b557fd","tarball":"http://registry.npmjs.org/underscore/-/underscore-1.2.0.tgz"},"scripts":{},"maintainers":[{"name":"documentcloud","email":"jeremy@documentcloud.org"},{"name":"jashkenas","email":"jashkenas@gmail.com"}],"_npmUser":{"name":"jashkenas","email":"jashkenas@gmail.com"},"directories":{}},"1.2.1":{"name":"underscore","description":"JavaScript's functional programming helper library.","homepage":"http://documentcloud.github.com/underscore/","keywords":["util","functional","server","client","browser"],"author":{"name":"Jeremy Ashkenas","email":"jeremy@documentcloud.org"},"contributors":[],"dependencies":{},"repository":{"type":"git","url":"git://github.com/documentcloud/underscore.git"},"main":"underscore.js","version":"1.2.1","_npmJsonOpts":{"file":"/Users/jashkenas/.npm/underscore/1.2.1/package/package.json","wscript":false,"contributors":false,"serverjs":false},"_id":"underscore@1.2.1","devDependencies":{},"engines":{"node":"*"},"_engineSupported":true,"_npmVersion":"1.0.22","_nodeVersion":"v0.4.10","_defaultsLoaded":true,"dist":{"shasum":"fc5c6b0765673d92a2d4ac8b4dc0aa88702e2bd4","tarball":"http://registry.npmjs.org/underscore/-/underscore-1.2.1.tgz"},"scripts":{},"maintainers":[{"name":"documentcloud","email":"jeremy@documentcloud.org"},{"name":"jashkenas","email":"jashkenas@gmail.com"}],"_npmUser":{"name":"jashkenas","email":"jashkenas@gmail.com"},"directories":{}},"1.2.2":{"name":"underscore","description":"JavaScript's functional programming helper library.","homepage":"http://documentcloud.github.com/underscore/","keywords":["util","functional","server","client","browser"],"author":{"name":"Jeremy Ashkenas","email":"jeremy@documentcloud.org"},"contributors":[],"dependencies":{},"repository":{"type":"git","url":"git://github.com/documentcloud/underscore.git"},"main":"underscore.js","version":"1.2.2","_npmUser":{"name":"jashkenas","email":"jashkenas@gmail.com"},"_id":"underscore@1.2.2","devDependencies":{},"engines":{"node":"*"},"_engineSupported":true,"_npmVersion":"1.0.104","_nodeVersion":"v0.6.0","_defaultsLoaded":true,"dist":{"shasum":"74dd40e9face84e724eb2edae945b8aedc233ba3","tarball":"http://registry.npmjs.org/underscore/-/underscore-1.2.2.tgz"},"maintainers":[{"name":"documentcloud","email":"jeremy@documentcloud.org"},{"name":"jashkenas","email":"jashkenas@gmail.com"}],"directories":{}},"1.2.3":{"name":"underscore","description":"JavaScript's functional programming helper library.","homepage":"http://documentcloud.github.com/underscore/","keywords":["util","functional","server","client","browser"],"author":{"name":"Jeremy Ashkenas","email":"jeremy@documentcloud.org"},"contributors":[],"dependencies":{},"repository":{"type":"git","url":"git://github.com/documentcloud/underscore.git"},"main":"underscore.js","version":"1.2.3","_npmUser":{"name":"jashkenas","email":"jashkenas@gmail.com"},"_id":"underscore@1.2.3","devDependencies":{},"engines":{"node":"*"},"_engineSupported":true,"_npmVersion":"1.0.104","_nodeVersion":"v0.6.0","_defaultsLoaded":true,"dist":{"shasum":"11b874da70f4683d7d48bba2b44be1e600d2f6cf","tarball":"http://registry.npmjs.org/underscore/-/underscore-1.2.3.tgz"},"maintainers":[{"name":"documentcloud","email":"jeremy@documentcloud.org"},{"name":"jashkenas","email":"jashkenas@gmail.com"}],"directories":{}},"1.2.4":{"name":"underscore","description":"JavaScript's functional programming helper library.","homepage":"http://documentcloud.github.com/underscore/","keywords":["util","functional","server","client","browser"],"author":{"name":"Jeremy Ashkenas","email":"jeremy@documentcloud.org"},"contributors":[],"repository":{"type":"git","url":"git://github.com/documentcloud/underscore.git"},"main":"underscore.js","version":"1.2.4","_npmUser":{"name":"jashkenas","email":"jashkenas@gmail.com"},"_id":"underscore@1.2.4","dependencies":{},"devDependencies":{},"engines":{"node":"*"},"_engineSupported":true,"_npmVersion":"1.0.104","_nodeVersion":"v0.6.6","_defaultsLoaded":true,"dist":{"shasum":"e8da6241aa06f64df2473bb2590b8c17c84c3c7e","tarball":"http://registry.npmjs.org/underscore/-/underscore-1.2.4.tgz"},"maintainers":[{"name":"documentcloud","email":"jeremy@documentcloud.org"},{"name":"jashkenas","email":"jashkenas@gmail.com"}],"directories":{}},"1.3.0":{"name":"underscore","description":"JavaScript's functional programming helper library.","homepage":"http://documentcloud.github.com/underscore/","keywords":["util","functional","server","client","browser"],"author":{"name":"Jeremy Ashkenas","email":"jeremy@documentcloud.org"},"contributors":[],"repository":{"type":"git","url":"git://github.com/documentcloud/underscore.git"},"main":"underscore.js","version":"1.3.0","_npmUser":{"name":"jashkenas","email":"jashkenas@gmail.com"},"_id":"underscore@1.3.0","dependencies":{},"devDependencies":{},"engines":{"node":"*"},"_engineSupported":true,"_npmVersion":"1.0.104","_nodeVersion":"v0.6.6","_defaultsLoaded":true,"dist":{"shasum":"253b2d79b7bb67943ced0fc744eb18267963ede8","tarball":"http://registry.npmjs.org/underscore/-/underscore-1.3.0.tgz"},"maintainers":[{"name":"documentcloud","email":"jeremy@documentcloud.org"},{"name":"jashkenas","email":"jashkenas@gmail.com"}],"directories":{}},"1.3.1":{"name":"underscore","description":"JavaScript's functional programming helper library.","homepage":"http://documentcloud.github.com/underscore/","keywords":["util","functional","server","client","browser"],"author":{"name":"Jeremy Ashkenas","email":"jeremy@documentcloud.org"},"repository":{"type":"git","url":"git://github.com/documentcloud/underscore.git"},"main":"underscore.js","version":"1.3.1","_npmUser":{"name":"jashkenas","email":"jashkenas@gmail.com"},"_id":"underscore@1.3.1","dependencies":{},"devDependencies":{},"engines":{"node":"*"},"_engineSupported":true,"_npmVersion":"1.0.104","_nodeVersion":"v0.6.6","_defaultsLoaded":true,"dist":{"shasum":"6cb8aad0e77eb5dbbfb54b22bcd8697309cf9641","tarball":"http://registry.npmjs.org/underscore/-/underscore-1.3.1.tgz"},"maintainers":[{"name":"documentcloud","email":"jeremy@documentcloud.org"},{"name":"jashkenas","email":"jashkenas@gmail.com"}],"directories":{}},"1.3.2":{"name":"underscore","description":"JavaScript's functional programming helper library.","homepage":"http://documentcloud.github.com/underscore/","keywords":["util","functional","server","client","browser"],"author":{"name":"Jeremy Ashkenas","email":"jeremy@documentcloud.org"},"repository":{"type":"git","url":"git://github.com/documentcloud/underscore.git"},"main":"underscore.js","version":"1.3.2","_npmUser":{"name":"jashkenas","email":"jashkenas@gmail.com"},"_id":"underscore@1.3.2","dependencies":{},"devDependencies":{},"optionalDependencies":{},"engines":{"node":"*"},"_engineSupported":true,"_npmVersion":"1.1.1","_nodeVersion":"v0.6.11","_defaultsLoaded":true,"dist":{"shasum":"1b4e455089ab1d1d38ab6794ffe6cf08f764394a","tarball":"http://registry.npmjs.org/underscore/-/underscore-1.3.2.tgz"},"readme":" __ \n /\\ \\ __ \n __ __ ___ \\_\\ \\ __ _ __ ____ ___ ___ _ __ __ /\\_\\ ____ \n /\\ \\/\\ \\ /' _ `\\ /'_ \\ /'__`\\/\\ __\\/ ,__\\ / ___\\ / __`\\/\\ __\\/'__`\\ \\/\\ \\ /',__\\ \n \\ \\ \\_\\ \\/\\ \\/\\ \\/\\ \\ \\ \\/\\ __/\\ \\ \\//\\__, `\\/\\ \\__//\\ \\ \\ \\ \\ \\//\\ __/ __ \\ \\ \\/\\__, `\\\n \\ \\____/\\ \\_\\ \\_\\ \\___,_\\ \\____\\\\ \\_\\\\/\\____/\\ \\____\\ \\____/\\ \\_\\\\ \\____\\/\\_\\ _\\ \\ \\/\\____/\n \\/___/ \\/_/\\/_/\\/__,_ /\\/____/ \\/_/ \\/___/ \\/____/\\/___/ \\/_/ \\/____/\\/_//\\ \\_\\ \\/___/ \n \\ \\____/ \n \\/___/\n \nUnderscore.js is a utility-belt library for JavaScript that provides \nsupport for the usual functional suspects (each, map, reduce, filter...) \nwithout extending any core JavaScript objects.\n\nFor Docs, License, Tests, and pre-packed downloads, see:\nhttp://documentcloud.github.com/underscore/\n\nMany thanks to our contributors:\nhttps://github.com/documentcloud/underscore/contributors\n","maintainers":[{"name":"documentcloud","email":"jeremy@documentcloud.org"},{"name":"jashkenas","email":"jashkenas@gmail.com"}],"directories":{}},"1.3.3":{"name":"underscore","description":"JavaScript's functional programming helper library.","homepage":"http://documentcloud.github.com/underscore/","keywords":["util","functional","server","client","browser"],"author":{"name":"Jeremy Ashkenas","email":"jeremy@documentcloud.org"},"repository":{"type":"git","url":"git://github.com/documentcloud/underscore.git"},"main":"underscore.js","version":"1.3.3","_npmUser":{"name":"jashkenas","email":"jashkenas@gmail.com"},"_id":"underscore@1.3.3","dependencies":{},"devDependencies":{},"optionalDependencies":{},"engines":{"node":"*"},"_engineSupported":true,"_npmVersion":"1.1.1","_nodeVersion":"v0.6.11","_defaultsLoaded":true,"dist":{"shasum":"47ac53683daf832bfa952e1774417da47817ae42","tarball":"http://registry.npmjs.org/underscore/-/underscore-1.3.3.tgz"},"readme":" __ \n /\\ \\ __ \n __ __ ___ \\_\\ \\ __ _ __ ____ ___ ___ _ __ __ /\\_\\ ____ \n /\\ \\/\\ \\ /' _ `\\ /'_ \\ /'__`\\/\\ __\\/ ,__\\ / ___\\ / __`\\/\\ __\\/'__`\\ \\/\\ \\ /',__\\ \n \\ \\ \\_\\ \\/\\ \\/\\ \\/\\ \\ \\ \\/\\ __/\\ \\ \\//\\__, `\\/\\ \\__//\\ \\ \\ \\ \\ \\//\\ __/ __ \\ \\ \\/\\__, `\\\n \\ \\____/\\ \\_\\ \\_\\ \\___,_\\ \\____\\\\ \\_\\\\/\\____/\\ \\____\\ \\____/\\ \\_\\\\ \\____\\/\\_\\ _\\ \\ \\/\\____/\n \\/___/ \\/_/\\/_/\\/__,_ /\\/____/ \\/_/ \\/___/ \\/____/\\/___/ \\/_/ \\/____/\\/_//\\ \\_\\ \\/___/ \n \\ \\____/ \n \\/___/\n \nUnderscore.js is a utility-belt library for JavaScript that provides \nsupport for the usual functional suspects (each, map, reduce, filter...) \nwithout extending any core JavaScript objects.\n\nFor Docs, License, Tests, and pre-packed downloads, see:\nhttp://documentcloud.github.com/underscore/\n\nMany thanks to our contributors:\nhttps://github.com/documentcloud/underscore/contributors\n","maintainers":[{"name":"documentcloud","email":"jeremy@documentcloud.org"},{"name":"jashkenas","email":"jashkenas@gmail.com"}],"directories":{}}},"maintainers":[{"name":"documentcloud","email":"jeremy@documentcloud.org"},{"name":"jashkenas","email":"jashkenas@gmail.com"}],"author":{"name":"Jeremy Ashkenas","email":"jeremy@documentcloud.org"},"time":{"1.0.3":"2011-12-07T15:12:18.045Z","1.0.4":"2011-12-07T15:12:18.045Z","1.1.0":"2011-12-07T15:12:18.045Z","1.1.1":"2011-12-07T15:12:18.045Z","1.1.2":"2011-12-07T15:12:18.045Z","1.1.3":"2011-12-07T15:12:18.045Z","1.1.4":"2011-12-07T15:12:18.045Z","1.1.5":"2011-12-07T15:12:18.045Z","1.1.6":"2011-12-07T15:12:18.045Z","1.1.7":"2011-12-07T15:12:18.045Z","1.2.0":"2011-12-07T15:12:18.045Z","1.2.1":"2011-12-07T15:12:18.045Z","1.2.2":"2011-11-14T20:28:47.115Z","1.2.3":"2011-12-07T15:12:18.045Z","1.2.4":"2012-01-09T17:23:14.818Z","1.3.0":"2012-01-11T16:41:38.459Z","1.3.1":"2012-01-23T22:57:36.474Z","1.3.2":"2012-04-09T18:38:14.345Z","1.3.3":"2012-04-10T14:43:48.089Z"},"repository":{"type":"git","url":"git://github.com/documentcloud/underscore.git"},"users":{"vesln":true,"mvolkmann":true,"lancehunt":true,"mikl":true,"linus":true,"vasc":true,"bat":true,"dmalam":true,"mbrevoort":true,"danielr":true,"rsimoes":true,"thlorenz":true}}
\ No newline at end of file diff --git a/deps/npm/node_modules/read-package-json/node_modules/normalize-package-data/README.md b/deps/npm/node_modules/read-package-json/node_modules/normalize-package-data/README.md index 71fa95065af..4a357b2aafa 100644 --- a/deps/npm/node_modules/read-package-json/node_modules/normalize-package-data/README.md +++ b/deps/npm/node_modules/read-package-json/node_modules/normalize-package-data/README.md @@ -21,7 +21,23 @@ normalizeData(packageData) // packageData is now normalized ``` -Optionally, you may pass a "warning" function. It gets called whenever the normalizeData function encounters something that doesn't look right. It indicates less than perfect input data. +#### Strict mode + +You may activate strict validation by passing true as the second argument. + +```javascript +normalizeData = require('normalize-package-data') +packageData = fs.readfileSync("package.json") +warnFn = function(msg) { console.error(msg) } +normalizeData(packageData, true) +// packageData is now normalized +``` + +If strict mode is activated, only Semver 2.0 version strings are accepted. Otherwise, Semver 1.0 strings are accepted as well. Packages must have a name, and the name field must not have contain leading or trailing whitespace. + +#### Warnings + +Optionally, you may pass a "warning" function. It gets called whenever the `normalizeData` function encounters something that doesn't look right. It indicates less than perfect input data. ```javascript normalizeData = require('normalize-package-data') @@ -31,7 +47,9 @@ normalizeData(packageData, warnFn) // packageData is now normalized. Any number of warnings may have been logged. ``` -If you don't provide a warning function, `normalizeData` functions silently. +You may combine strict validation with warnings by passing `true` as the second argument, and `warnFn` as third. + +When `private` field is set to `true`, no warnings will be generated. ### Potential exceptions @@ -39,7 +57,7 @@ If the supplied data has an invalid name or version vield, `normalizeData` will ## What normalization (currently) entails -* The value of `name` field gets trimmed. +* The value of `name` field gets trimmed (unless in strict mode). * The value of the `version` field gets cleaned by `semver.clean`. See [documentation for the semver module](https://github.com/isaacs/node-semver). * If `name` and/or `version` fields are missing, they are set to empty strings. * If `files` field is not an array, it will be removed. diff --git a/deps/npm/node_modules/read-package-json/node_modules/normalize-package-data/lib/normalize.js b/deps/npm/node_modules/read-package-json/node_modules/normalize-package-data/lib/normalize.js index 5ff5b6395d2..a44b0246a0f 100644 --- a/deps/npm/node_modules/read-package-json/node_modules/normalize-package-data/lib/normalize.js +++ b/deps/npm/node_modules/read-package-json/node_modules/normalize-package-data/lib/normalize.js @@ -17,7 +17,7 @@ thingsToFix = thingsToFix.concat(otherThingsToFix) function normalize (data, warn, strict) { if(warn === true) warn = null, strict = true if(!strict) strict = false - if(!warn) warn = function(msg) { /* noop */ } + if(!warn || data.private) warn = function(msg) { /* noop */ } if (data.scripts && data.scripts.install === "node-gyp rebuild" && diff --git a/deps/npm/node_modules/read-package-json/node_modules/normalize-package-data/package.json b/deps/npm/node_modules/read-package-json/node_modules/normalize-package-data/package.json index cf8acaaf9bb..9e8154c3cc0 100644 --- a/deps/npm/node_modules/read-package-json/node_modules/normalize-package-data/package.json +++ b/deps/npm/node_modules/read-package-json/node_modules/normalize-package-data/package.json @@ -1,6 +1,6 @@ { "name": "normalize-package-data", - "version": "0.2.0", + "version": "0.2.1", "author": { "name": "Meryn Stol", "email": "merynstol@gmail.com" @@ -33,11 +33,11 @@ "email": "merynstol@gmail.com" } ], - "readme": "# normalize-package-data [![Build Status](https://travis-ci.org/meryn/normalize-package-data.png?branch=master)](https://travis-ci.org/meryn/normalize-package-data)\n\nnormalize-package data exports a function that normalizes package metadata. This data is typically found in a package.json file, but in principle could come from any source - for example the npm registry.\n\nnormalize-package-data is used by [read-package-json](https://npmjs.org/package/read-package-json) to normalize the data it reads from a package.json file. In turn, read-package-json is used by [npm](https://npmjs.org/package/npm) and various npm-related tools.\n\n## Installation\n\n```\nnpm install normalize-package-data\n```\n\n## Usage\n\nBasic usage is really simple. You call the function that normalize-package-data exports. Let's call it `normalizeData`.\n\n```javascript\nnormalizeData = require('normalize-package-data')\npackageData = fs.readfileSync(\"package.json\")\nnormalizeData(packageData)\n// packageData is now normalized\n```\n\nOptionally, you may pass a \"warning\" function. It gets called whenever the normalizeData function encounters something that doesn't look right. It indicates less than perfect input data.\n\n```javascript\nnormalizeData = require('normalize-package-data')\npackageData = fs.readfileSync(\"package.json\")\nwarnFn = function(msg) { console.error(msg) }\nnormalizeData(packageData, warnFn)\n// packageData is now normalized. Any number of warnings may have been logged.\n```\n\nIf you don't provide a warning function, `normalizeData` functions silently.\n\n### Potential exceptions\n\nIf the supplied data has an invalid name or version vield, `normalizeData` will throw an error. Depending on where you call `normalizeData`, you may want to catch these errors so can pass them to a callback.\n\n## What normalization (currently) entails\n\n* The value of `name` field gets trimmed.\n* The value of the `version` field gets cleaned by `semver.clean`. See [documentation for the semver module](https://github.com/isaacs/node-semver).\n* If `name` and/or `version` fields are missing, they are set to empty strings.\n* If `files` field is not an array, it will be removed.\n* If `bin` field is a string, then `bin` field will become an object with `name` set to the value of the `name` field, and `bin` set to the original string value.\n* If `man` field is a string, it will become an array with the original string as its sole member.\n* If `keywords` field is string, it is considered to be a list of keywords separated by one or more white-space characters. It gets converted to an array by splitting on `\\s+`.\n* All people fields (`author`, `maintainers`, `contributors`) get converted into objects with name, email and url properties.\n* If `bundledDependencies` field (a typo) exists and `bundleDependencies` field does not, `bundledDependencies` will get renamed to `bundleDependencies`.\n* If the value of any of the dependencies fields (`dependencies`, `devDependencies`, `optionalDependencies`) is a string, it gets converted into an object with familiar `name=>value` pairs.\n* The values in `optionalDependencies` get added to `dependencies`. The `optionalDependencies` array is left untouched.\n* If `description` field does not exists, but `readme` field does, then (more or less) the first paragraph of text that's found in the readme is taken as value for `description`.\n* If `repository` field is a string, it will become an object with `url` set to the original string value, and `type` set to `\"git\"`.\n* If `bugs` field is a string, the value of `bugs` field is changed into an object with `url` set to the original string value.\n* If `bugs` field does not exist, but `repository` field points to a repository hosted on GitHub, the value of the `bugs` field gets set to an url in the form of https://github.com/[owner-name]/[repo-name]/issues . If the repository field points to a GitHub Gist repo url, the associated http url is chosen.\n* If `bugs` field is an object, the resulting value only has email and url properties. If email and url properties are not strings, they are ignored. If no valid values for either email or url is found, bugs field will be removed.\n* If `homepage` field is not a string, it will be removed.\n* If the url in the `homepage` field does not specify a protocol, then http is assumed. For example, `myproject.org` will be changed to `http://myproject.org`.\n\n### Rules for name field\n\nIf `name` field is given, the value of the name field must be a string. The string may not:\n\n* start with a period.\n* contain the following characters: `/@\\s+%`\n* contain and characters that would need to be encoded for use in urls.\n* resemble the word `node_modules` or `favicon.ico` (case doesn't matter).\n\n### Rules for version field\n\nIf `version` field is given, the value of the version field must be a valid *semver* string, as determined by the `semver.valid` method. See [documentation for the semver module](https://github.com/isaacs/node-semver).\n\n## Credits\n\nThis package contains code based on read-package-json written by Isaac Z. Schlueter. Used with permisson.\n\n## License\n\nnormalize-package-data is released under the [BSD 2-Clause License](http://opensource.org/licenses/MIT). \nCopyright (c) 2013 Meryn Stol ", + "readme": "# normalize-package-data [![Build Status](https://travis-ci.org/meryn/normalize-package-data.png?branch=master)](https://travis-ci.org/meryn/normalize-package-data)\n\nnormalize-package data exports a function that normalizes package metadata. This data is typically found in a package.json file, but in principle could come from any source - for example the npm registry.\n\nnormalize-package-data is used by [read-package-json](https://npmjs.org/package/read-package-json) to normalize the data it reads from a package.json file. In turn, read-package-json is used by [npm](https://npmjs.org/package/npm) and various npm-related tools.\n\n## Installation\n\n```\nnpm install normalize-package-data\n```\n\n## Usage\n\nBasic usage is really simple. You call the function that normalize-package-data exports. Let's call it `normalizeData`.\n\n```javascript\nnormalizeData = require('normalize-package-data')\npackageData = fs.readfileSync(\"package.json\")\nnormalizeData(packageData)\n// packageData is now normalized\n```\n\n#### Strict mode\n\nYou may activate strict validation by passing true as the second argument.\n\n```javascript\nnormalizeData = require('normalize-package-data')\npackageData = fs.readfileSync(\"package.json\")\nwarnFn = function(msg) { console.error(msg) }\nnormalizeData(packageData, true)\n// packageData is now normalized\n```\n\nIf strict mode is activated, only Semver 2.0 version strings are accepted. Otherwise, Semver 1.0 strings are accepted as well. Packages must have a name, and the name field must not have contain leading or trailing whitespace.\n\n#### Warnings\n\nOptionally, you may pass a \"warning\" function. It gets called whenever the `normalizeData` function encounters something that doesn't look right. It indicates less than perfect input data.\n\n```javascript\nnormalizeData = require('normalize-package-data')\npackageData = fs.readfileSync(\"package.json\")\nwarnFn = function(msg) { console.error(msg) }\nnormalizeData(packageData, warnFn)\n// packageData is now normalized. Any number of warnings may have been logged.\n```\n\nYou may combine strict validation with warnings by passing `true` as the second argument, and `warnFn` as third.\n\nWhen `private` field is set to `true`, no warnings will be generated.\n\n### Potential exceptions\n\nIf the supplied data has an invalid name or version vield, `normalizeData` will throw an error. Depending on where you call `normalizeData`, you may want to catch these errors so can pass them to a callback.\n\n## What normalization (currently) entails\n\n* The value of `name` field gets trimmed (unless in strict mode).\n* The value of the `version` field gets cleaned by `semver.clean`. See [documentation for the semver module](https://github.com/isaacs/node-semver).\n* If `name` and/or `version` fields are missing, they are set to empty strings.\n* If `files` field is not an array, it will be removed.\n* If `bin` field is a string, then `bin` field will become an object with `name` set to the value of the `name` field, and `bin` set to the original string value.\n* If `man` field is a string, it will become an array with the original string as its sole member.\n* If `keywords` field is string, it is considered to be a list of keywords separated by one or more white-space characters. It gets converted to an array by splitting on `\\s+`.\n* All people fields (`author`, `maintainers`, `contributors`) get converted into objects with name, email and url properties.\n* If `bundledDependencies` field (a typo) exists and `bundleDependencies` field does not, `bundledDependencies` will get renamed to `bundleDependencies`.\n* If the value of any of the dependencies fields (`dependencies`, `devDependencies`, `optionalDependencies`) is a string, it gets converted into an object with familiar `name=>value` pairs.\n* The values in `optionalDependencies` get added to `dependencies`. The `optionalDependencies` array is left untouched.\n* If `description` field does not exists, but `readme` field does, then (more or less) the first paragraph of text that's found in the readme is taken as value for `description`.\n* If `repository` field is a string, it will become an object with `url` set to the original string value, and `type` set to `\"git\"`.\n* If `bugs` field is a string, the value of `bugs` field is changed into an object with `url` set to the original string value.\n* If `bugs` field does not exist, but `repository` field points to a repository hosted on GitHub, the value of the `bugs` field gets set to an url in the form of https://github.com/[owner-name]/[repo-name]/issues . If the repository field points to a GitHub Gist repo url, the associated http url is chosen.\n* If `bugs` field is an object, the resulting value only has email and url properties. If email and url properties are not strings, they are ignored. If no valid values for either email or url is found, bugs field will be removed.\n* If `homepage` field is not a string, it will be removed.\n* If the url in the `homepage` field does not specify a protocol, then http is assumed. For example, `myproject.org` will be changed to `http://myproject.org`.\n\n### Rules for name field\n\nIf `name` field is given, the value of the name field must be a string. The string may not:\n\n* start with a period.\n* contain the following characters: `/@\\s+%`\n* contain and characters that would need to be encoded for use in urls.\n* resemble the word `node_modules` or `favicon.ico` (case doesn't matter).\n\n### Rules for version field\n\nIf `version` field is given, the value of the version field must be a valid *semver* string, as determined by the `semver.valid` method. See [documentation for the semver module](https://github.com/isaacs/node-semver).\n\n## Credits\n\nThis package contains code based on read-package-json written by Isaac Z. Schlueter. Used with permisson.\n\n## License\n\nnormalize-package-data is released under the [BSD 2-Clause License](http://opensource.org/licenses/MIT). \nCopyright (c) 2013 Meryn Stol ", "readmeFilename": "README.md", "bugs": { "url": "https://github.com/meryn/normalize-package-data/issues" }, - "_id": "normalize-package-data@0.2.0", + "_id": "normalize-package-data@0.2.1", "_from": "normalize-package-data@~0.2" } diff --git a/deps/npm/node_modules/read-package-json/node_modules/normalize-package-data/test/typo.js b/deps/npm/node_modules/read-package-json/node_modules/normalize-package-data/test/typo.js index 72932e9497d..941d68bfeae 100644 --- a/deps/npm/node_modules/read-package-json/node_modules/normalize-package-data/test/typo.js +++ b/deps/npm/node_modules/read-package-json/node_modules/normalize-package-data/test/typo.js @@ -94,5 +94,15 @@ test('typos', function(t) { t.same(warnings, expect) + warnings.length = 0 + expect = [] + + normalize({private: true + ,name:"name" + ,version:"1.2.5" + ,scripts:{server:"start",tests:"test"}}, warn) + + t.same(warnings, expect) + t.end(); }) diff --git a/deps/npm/node_modules/read-package-json/package.json b/deps/npm/node_modules/read-package-json/package.json index d41635ee96b..c9f17ef8740 100644 --- a/deps/npm/node_modules/read-package-json/package.json +++ b/deps/npm/node_modules/read-package-json/package.json @@ -33,9 +33,5 @@ "url": "https://github.com/isaacs/read-package-json/issues" }, "_id": "read-package-json@1.1.1", - "dist": { - "shasum": "5d679b34ddf53ac3bc232aeb421f6b6857f925e5" - }, - "_from": "read-package-json@1.1.1", - "_resolved": "https://registry.npmjs.org/read-package-json/-/read-package-json-1.1.1.tgz" + "_from": "read-package-json@~1.1.0" } diff --git a/deps/npm/node_modules/request/.npmignore b/deps/npm/node_modules/request/.npmignore new file mode 100644 index 00000000000..3c3629e647f --- /dev/null +++ b/deps/npm/node_modules/request/.npmignore @@ -0,0 +1 @@ +node_modules diff --git a/deps/npm/node_modules/request/README.md b/deps/npm/node_modules/request/README.md index eca6a5ab302..1d2f79b47dd 100644 --- a/deps/npm/node_modules/request/README.md +++ b/deps/npm/node_modules/request/README.md @@ -118,7 +118,7 @@ form.append('remote_file', request('http://google.com/doodle.png')) ## HTTP Authentication ```javascript -request.auth('username', 'password', false).get('http://some.server.com/'); +request.get('http://some.server.com/').auth('username', 'password', false); // or request.get('http://some.server.com/', { 'auth': { @@ -209,13 +209,13 @@ The first argument can be either a url or an options object. The only required o * `oauth` - Options for OAuth HMAC-SHA1 signing, see documentation above. * `hawk` - Options for [Hawk signing](https://github.com/hueniverse/hawk). The `credentials` key must contain the necessary signing info, [see hawk docs for details](https://github.com/hueniverse/hawk#usage-example). * `strictSSL` - Set to `true` to require that SSL certificates be valid. Note: to use your own certificate authority, you need to specify an agent that was created with that ca as an option. -* `jar` - Set to `false` if you don't want cookies to be remembered for future use or define your custom cookie jar (see examples section) +* `jar` - Set to `true` if you want cookies to be remembered for future use, or define your custom cookie jar (see examples section) * `aws` - object containing aws signing information, should have the properties `key` and `secret` as well as `bucket` unless you're specifying your bucket as part of the path, or you are making a request that doesn't use a bucket (i.e. GET Services) * `httpSignature` - Options for the [HTTP Signature Scheme](https://github.com/joyent/node-http-signature/blob/master/http_signing.md) using [Joyent's library](https://github.com/joyent/node-http-signature). The `keyId` and `key` properties must be specified. See the docs for other options. * `localAddress` - Local interface to bind for network connections. -The callback argument gets 3 arguments. The first is an error when applicable (usually from the http.Client option not the http.ClientRequest object). The second in an http.ClientResponse object. The third is the response body String or Buffer. +The callback argument gets 3 arguments. The first is an error when applicable (usually from the http.Client option not the http.ClientRequest object). The second is an http.ClientResponse object. The third is the response body String or Buffer. ## Convenience methods @@ -314,10 +314,10 @@ request.jar() } ) ``` -Cookies are enabled by default (so they can be used in subsequent requests). To disable cookies set jar to false (either in defaults or in the options sent). +Cookies are disabled by default (else, they would be used in subsequent requests). To enable cookies set jar to true (either in defaults or in the options sent). ```javascript -var request = request.defaults({jar: false}) +var request = request.defaults({jar: true}) request('http://www.google.com', function () { request('http://images.google.com') }) diff --git a/deps/npm/node_modules/request/index.js b/deps/npm/node_modules/request/index.js index 22707be7087..d56f9ecff13 100755 --- a/deps/npm/node_modules/request/index.js +++ b/deps/npm/node_modules/request/index.js @@ -151,7 +151,7 @@ Request.prototype.init = function (options) { self.on('complete', self.callback.bind(self, null)) } - if (self.url) { + if (self.url && !self.uri) { // People use this property instead all the time so why not just support it. self.uri = self.url delete self.url @@ -384,7 +384,7 @@ Request.prototype.init = function (options) { } } - self.once('pipe', function (src) { + self.on('pipe', function (src) { if (self.ntick && self._started) throw new Error("You cannot pipe to this stream after the outbound request has started.") self.src = src if (isReadStream(src)) { @@ -405,9 +405,9 @@ Request.prototype.init = function (options) { } } - self.on('pipe', function () { - console.error("You have already piped to this stream. Pipeing twice is likely to break the request.") - }) + // self.on('pipe', function () { + // console.error("You have already piped to this stream. Pipeing twice is likely to break the request.") + // }) }) process.nextTick(function () { @@ -551,9 +551,19 @@ Request.prototype.getAgent = function () { if (options.cert) poolKey += options.cert.toString('ascii') + options.key.toString('ascii') + + if (options.ciphers) { + if (poolKey) poolKey += ':' + poolKey += options.ciphers + } + + if (options.secureOptions) { + if (poolKey) poolKey += ':' + poolKey += options.secureOptions + } } - if (!poolKey && Agent === this.httpModule.Agent && this.httpModule.globalAgent) { + if (this.pool === globalPool && !poolKey && Object.keys(options).length === 0 && this.httpModule.globalAgent) { // not doing anything special. Use the globalAgent return this.httpModule.globalAgent } @@ -663,8 +673,13 @@ Request.prototype.onResponse = function (response) { } var addCookie = function (cookie) { - if (self._jar) self._jar.add(new Cookie(cookie)) - else cookieJar.add(new Cookie(cookie)) + if (self._jar){ + if(self._jar.add){ + self._jar.add(new Cookie(cookie)) + } + else cookieJar.add(new Cookie(cookie)) + } + } if (response.headers['set-cookie'] && (!self._disableCookies)) { @@ -806,7 +821,7 @@ Request.prototype.onResponse = function (response) { if (self.encoding) { if (self.dests.length !== 0) { - console.error("Ingoring encoding parameter as this stream is being piped to another stream which makes the encoding option invalid.") + console.error("Ignoring encoding parameter as this stream is being piped to another stream which makes the encoding option invalid.") } else { response.setEncoding(self.encoding) } @@ -876,6 +891,16 @@ Request.prototype.onResponse = function (response) { self.emit('complete', response, response.body) }) } + //if no callback + else{ + self.on("end", function () { + if (self._aborted) { + debug('aborted', self.uri.href) + return + } + self.emit('complete', response); + }); + } } debug('finish init function', self.uri.href) } @@ -902,7 +927,7 @@ Request.prototype.pipeDest = function (dest) { dest.headers['content-length'] = response.headers['content-length'] } } - if (dest.setHeader) { + if (dest.setHeader && !dest.headersSent) { for (var i in response.headers) { dest.setHeader(i, response.headers[i]) } @@ -1130,11 +1155,11 @@ Request.prototype.jar = function (jar) { this.originalCookieHeader = this.headers.cookie } - if (jar === false) { + if (!jar) { // disable cookies cookies = false this._disableCookies = true - } else if (jar) { + } else if (jar && jar.get) { // fetch cookie from the user defined cookie jar cookies = jar.get({ url: this.uri.href }) } else { @@ -1233,6 +1258,8 @@ function request (uri, options, callback) { module.exports = request +request.Request = Request; + request.debug = process.env.NODE_DEBUG && /request/.test(process.env.NODE_DEBUG) request.initParams = initParams diff --git a/deps/npm/node_modules/request/node_modules/form-data/.npmignore b/deps/npm/node_modules/request/node_modules/form-data/.npmignore deleted file mode 100644 index 85957343efd..00000000000 --- a/deps/npm/node_modules/request/node_modules/form-data/.npmignore +++ /dev/null @@ -1,5 +0,0 @@ -*.un~ -/node_modules/* -/test/tmp -/.idea -*.iml diff --git a/deps/npm/node_modules/request/node_modules/form-data/.travis.yml b/deps/npm/node_modules/request/node_modules/form-data/.travis.yml deleted file mode 100644 index f7e975f5ee0..00000000000 --- a/deps/npm/node_modules/request/node_modules/form-data/.travis.yml +++ /dev/null @@ -1,4 +0,0 @@ -language: node_js -node_js: - - "0.6" - - "0.8" diff --git a/deps/npm/node_modules/request/node_modules/form-data/Makefile b/deps/npm/node_modules/request/node_modules/form-data/Makefile deleted file mode 100644 index b4ff85a33b6..00000000000 --- a/deps/npm/node_modules/request/node_modules/form-data/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -SHELL := /bin/bash - -test: - @./test/run.js - -.PHONY: test - diff --git a/deps/npm/node_modules/request/node_modules/form-data/Readme.md b/deps/npm/node_modules/request/node_modules/form-data/Readme.md index db671128534..ca5ebade4f0 100644 --- a/deps/npm/node_modules/request/node_modules/form-data/Readme.md +++ b/deps/npm/node_modules/request/node_modules/form-data/Readme.md @@ -1,10 +1,8 @@ -# Form-Data [![Build Status](https://travis-ci.org/alexindigo/node-form-data.png?branch=master)](https://travis-ci.org/alexindigo/node-form-data) +# Form-Data [![Build Status](https://travis-ci.org/felixge/node-form-data.png?branch=master)](https://travis-ci.org/felixge/node-form-data) [![Dependency Status](https://gemnasium.com/felixge/node-form-data.png)](https://gemnasium.com/felixge/node-form-data) -A module to create readable `"multipart/form-data"` streams. Can be used to -submit forms and file uploads to other web applications. +A module to create readable ```"multipart/form-data"``` streams. Can be used to submit forms and file uploads to other web applications. -The API of this module is inspired by the -[XMLHttpRequest-2 FormData Interface][xhr2-fd]. +The API of this module is inspired by the [XMLHttpRequest-2 FormData Interface][xhr2-fd]. [xhr2-fd]: http://dev.w3.org/2006/webapi/XMLHttpRequest-2/Overview.html#the-formdata-interface @@ -137,6 +135,10 @@ form.submit({ }); ``` +## Notes + +- ```getLengthSync()``` method DOESN'T calculate length for streams, use ```knownLength``` options as workaround. + ## TODO - Add new streams (0.10) support and try really hard not to break it for 0.8.x. diff --git a/deps/npm/node_modules/request/node_modules/form-data/lib/form_data.js b/deps/npm/node_modules/request/node_modules/form-data/lib/form_data.js index 127b70a9942..c95c915abf4 100644 --- a/deps/npm/node_modules/request/node_modules/form-data/lib/form_data.js +++ b/deps/npm/node_modules/request/node_modules/form-data/lib/form_data.js @@ -28,6 +28,14 @@ FormData.prototype.append = function(field, value, options) { // all that streamy business can't handle numbers if (typeof value == 'number') value = ''+value; + // https://github.com/felixge/node-form-data/issues/38 + if (util.isArray(value)) { + // Please convert your array into string + // the way web server expects it + this._error(new Error('Arrays are not supported.')); + return; + } + var header = this._multiPartHeader(field, value, options); var footer = this._multiPartFooter(field, value, options); @@ -42,7 +50,7 @@ FormData.prototype.append = function(field, value, options) { FormData.prototype._trackLength = function(header, value, options) { var valueLength = 0; - // used w/ trackLengthSync(), when length is known. + // used w/ getLengthSync(), when length is known. // e.g. for streaming directly from a remote server, // w/ a known file a size, and not wanting to wait for // incoming file to finish to get its size. @@ -66,15 +74,11 @@ FormData.prototype._trackLength = function(header, value, options) { return; } + // no need to bother with the length + if (!options.knownLength) this._lengthRetrievers.push(function(next) { - // do we already know the size? - // 0 additional leaves value from getSyncLength() - if (options.knownLength != null) { - next(null, 0); - - // check if it's local file - } else if (value.hasOwnProperty('fd')) { + if (value.hasOwnProperty('fd')) { fs.stat(value.path, function(err, stat) { if (err) { next(err); @@ -197,14 +201,27 @@ FormData.prototype._generateBoundary = function() { this._boundary = boundary; }; -FormData.prototype.getLengthSync = function() { - var knownLength = this._overheadLength + this._valueLength; +// Note: getLengthSync DOESN'T calculate streams length +// As workaround one can calculate file size manually +// and add it as knownLength option +FormData.prototype.getLengthSync = function(debug) { + var knownLength = this._overheadLength + this._valueLength; - if (this._streams.length) { - knownLength += this._lastBoundary().length; - } + // Don't get confused, there are 3 "internal" streams for each keyval pair + // so it basically checks if there is any value added to the form + if (this._streams.length) { + knownLength += this._lastBoundary().length; + } + + // https://github.com/felixge/node-form-data/issues/40 + if (this._lengthRetrievers.length) { + // Some async length retrivers are present + // therefore synchronous length calculation is false. + // Please use getLength(callback) to get proper length + this._error(new Error('Cannot calculate proper length in synchronous way.')); + } - return knownLength; + return knownLength; }; FormData.prototype.getLength = function(cb) { @@ -279,6 +296,14 @@ FormData.prototype.submit = function(params, cb) { }.bind(this)); }; +FormData.prototype._error = function(err) { + if (this.error) return; + + this.error = err; + this.pause(); + this.emit('error', err); +}; + /* * Santa's little helpers */ diff --git a/deps/npm/node_modules/request/node_modules/form-data/node-form-data.sublime-project b/deps/npm/node_modules/request/node_modules/form-data/node-form-data.sublime-project deleted file mode 100644 index 38100b87f7f..00000000000 --- a/deps/npm/node_modules/request/node_modules/form-data/node-form-data.sublime-project +++ /dev/null @@ -1,8 +0,0 @@ -{ - "folders": - [ - { - "path": "/Users/alexi/Dropbox/Projects/node-form-data" - } - ] -} diff --git a/deps/npm/node_modules/request/node_modules/form-data/node-form-data.sublime-workspace b/deps/npm/node_modules/request/node_modules/form-data/node-form-data.sublime-workspace deleted file mode 100644 index e5eb02dc54a..00000000000 --- a/deps/npm/node_modules/request/node_modules/form-data/node-form-data.sublime-workspace +++ /dev/null @@ -1,673 +0,0 @@ -{ - "auto_complete": - { - "selected_items": - [ - [ - "back", - "background-clip" - ], - [ - "di", - "display" - ], - [ - "background-", - "background-position" - ], - [ - "de", - "defaults" - ], - [ - "no", - "normal" - ], - [ - "line", - "line-height" - ] - ] - }, - "buffers": - [ - { - "file": "test/integration/test-pipe.js", - "settings": - { - "buffer_size": 3625, - "line_ending": "Unix" - } - }, - { - "file": "package.json", - "settings": - { - "buffer_size": 673, - "line_ending": "Unix" - } - }, - { - "file": "lib/form_data.js", - "settings": - { - "buffer_size": 7510, - "line_ending": "Unix" - } - }, - { - "contents": "/*!\n * jQuery JavaScript Library v1.8.3\n * http://jquery.com/\n *\n * Includes Sizzle.js\n * http://sizzlejs.com/\n *\n * Copyright 2012 jQuery Foundation and other contributors\n * Released under the MIT license\n * http://jquery.org/license\n *\n * Date: Tue Nov 13 2012 08:20:33 GMT-0500 (Eastern Standard Time)\n */\n(function( window, undefined ) {\nvar\n // A central reference to the root jQuery(document)\n rootjQuery,\n\n // The deferred used on DOM ready\n readyList,\n\n // Use the correct document accordingly with window argument (sandbox)\n document = window.document,\n location = window.location,\n navigator = window.navigator,\n\n // Map over jQuery in case of overwrite\n _jQuery = window.jQuery,\n\n // Map over the $ in case of overwrite\n _$ = window.$,\n\n // Save a reference to some core methods\n core_push = Array.prototype.push,\n core_slice = Array.prototype.slice,\n core_indexOf = Array.prototype.indexOf,\n core_toString = Object.prototype.toString,\n core_hasOwn = Object.prototype.hasOwnProperty,\n core_trim = String.prototype.trim,\n\n // Define a local copy of jQuery\n jQuery = function( selector, context ) {\n // The jQuery object is actually just the init constructor 'enhanced'\n return new jQuery.fn.init( selector, context, rootjQuery );\n },\n\n // Used for matching numbers\n core_pnum = /[\\-+]?(?:\\d*\\.|)\\d+(?:[eE][\\-+]?\\d+|)/.source,\n\n // Used for detecting and trimming whitespace\n core_rnotwhite = /\\S/,\n core_rspace = /\\s+/,\n\n // Make sure we trim BOM and NBSP (here's looking at you, Safari 5.0 and IE)\n rtrim = /^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g,\n\n // A simple way to check for HTML strings\n // Prioritize #id over <tag> to avoid XSS via location.hash (#9521)\n rquickExpr = /^(?:[^#<]*(<[\\w\\W]+>)[^>]*$|#([\\w\\-]*)$)/,\n\n // Match a standalone tag\n rsingleTag = /^<(\\w+)\\s*\\/?>(?:<\\/\\1>|)$/,\n\n // JSON RegExp\n rvalidchars = /^[\\],:{}\\s]*$/,\n rvalidbraces = /(?:^|:|,)(?:\\s*\\[)+/g,\n rvalidescape = /\\\\(?:[\"\\\\\\/bfnrt]|u[\\da-fA-F]{4})/g,\n rvalidtokens = /\"[^\"\\\\\\r\\n]*\"|true|false|null|-?(?:\\d\\d*\\.|)\\d+(?:[eE][\\-+]?\\d+|)/g,\n\n // Matches dashed string for camelizing\n rmsPrefix = /^-ms-/,\n rdashAlpha = /-([\\da-z])/gi,\n\n // Used by jQuery.camelCase as callback to replace()\n fcamelCase = function( all, letter ) {\n return ( letter + \"\" ).toUpperCase();\n },\n\n // The ready event handler and self cleanup method\n DOMContentLoaded = function() {\n if ( document.addEventListener ) {\n document.removeEventListener( \"DOMContentLoaded\", DOMContentLoaded, false );\n jQuery.ready();\n } else if ( document.readyState === \"complete\" ) {\n // we're here because readyState === \"complete\" in oldIE\n // which is good enough for us to call the dom ready!\n document.detachEvent( \"onreadystatechange\", DOMContentLoaded );\n jQuery.ready();\n }\n },\n\n // [[Class]] -> type pairs\n class2type = {};\n\njQuery.fn = jQuery.prototype = {\n constructor: jQuery,\n init: function( selector, context, rootjQuery ) {\n var match, elem, ret, doc;\n\n // Handle $(\"\"), $(null), $(undefined), $(false)\n if ( !selector ) {\n return this;\n }\n\n // Handle $(DOMElement)\n if ( selector.nodeType ) {\n this.context = this[0] = selector;\n this.length = 1;\n return this;\n }\n\n // Handle HTML strings\n if ( typeof selector === \"string\" ) {\n if ( selector.charAt(0) === \"<\" && selector.charAt( selector.length - 1 ) === \">\" && selector.length >= 3 ) {\n // Assume that strings that start and end with <> are HTML and skip the regex check\n match = [ null, selector, null ];\n\n } else {\n match = rquickExpr.exec( selector );\n }\n\n // Match html or make sure no context is specified for #id\n if ( match && (match[1] || !context) ) {\n\n // HANDLE: $(html) -> $(array)\n if ( match[1] ) {\n context = context instanceof jQuery ? context[0] : context;\n doc = ( context && context.nodeType ? context.ownerDocument || context : document );\n\n // scripts is true for back-compat\n selector = jQuery.parseHTML( match[1], doc, true );\n if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) {\n this.attr.call( selector, context, true );\n }\n\n return jQuery.merge( this, selector );\n\n // HANDLE: $(#id)\n } else {\n elem = document.getElementById( match[2] );\n\n // Check parentNode to catch when Blackberry 4.6 returns\n // nodes that are no longer in the document #6963\n if ( elem && elem.parentNode ) {\n // Handle the case where IE and Opera return items\n // by name instead of ID\n if ( elem.id !== match[2] ) {\n return rootjQuery.find( selector );\n }\n\n // Otherwise, we inject the element directly into the jQuery object\n this.length = 1;\n this[0] = elem;\n }\n\n this.context = document;\n this.selector = selector;\n return this;\n }\n\n // HANDLE: $(expr, $(...))\n } else if ( !context || context.jquery ) {\n return ( context || rootjQuery ).find( selector );\n\n // HANDLE: $(expr, context)\n // (which is just equivalent to: $(context).find(expr)\n } else {\n return this.constructor( context ).find( selector );\n }\n\n // HANDLE: $(function)\n // Shortcut for document ready\n } else if ( jQuery.isFunction( selector ) ) {\n return rootjQuery.ready( selector );\n }\n\n if ( selector.selector !== undefined ) {\n this.selector = selector.selector;\n this.context = selector.context;\n }\n\n return jQuery.makeArray( selector, this );\n },\n\n // Start with an empty selector\n selector: \"\",\n\n // The current version of jQuery being used\n jquery: \"1.8.3\",\n\n // The default length of a jQuery object is 0\n length: 0,\n\n // The number of elements contained in the matched element set\n size: function() {\n return this.length;\n },\n\n toArray: function() {\n return core_slice.call( this );\n },\n\n // Get the Nth element in the matched element set OR\n // Get the whole matched element set as a clean array\n get: function( num ) {\n return num == null ?\n\n // Return a 'clean' array\n this.toArray() :\n\n // Return just the object\n ( num < 0 ? this[ this.length + num ] : this[ num ] );\n },\n\n // Take an array of elements and push it onto the stack\n // (returning the new matched element set)\n pushStack: function( elems, name, selector ) {\n\n // Build a new jQuery matched element set\n var ret = jQuery.merge( this.constructor(), elems );\n\n // Add the old object onto the stack (as a reference)\n ret.prevObject = this;\n\n ret.context = this.context;\n\n if ( name === \"find\" ) {\n ret.selector = this.selector + ( this.selector ? \" \" : \"\" ) + selector;\n } else if ( name ) {\n ret.selector = this.selector + \".\" + name + \"(\" + selector + \")\";\n }\n\n // Return the newly-formed element set\n return ret;\n },\n\n // Execute a callback for every element in the matched set.\n // (You can seed the arguments with an array of args, but this is\n // only used internally.)\n each: function( callback, args ) {\n return jQuery.each( this, callback, args );\n },\n\n ready: function( fn ) {\n // Add the callback\n jQuery.ready.promise().done( fn );\n\n return this;\n },\n\n eq: function( i ) {\n i = +i;\n return i === -1 ?\n this.slice( i ) :\n this.slice( i, i + 1 );\n },\n\n first: function() {\n return this.eq( 0 );\n },\n\n last: function() {\n return this.eq( -1 );\n },\n\n slice: function() {\n return this.pushStack( core_slice.apply( this, arguments ),\n \"slice\", core_slice.call(arguments).join(\",\") );\n },\n\n map: function( callback ) {\n return this.pushStack( jQuery.map(this, function( elem, i ) {\n return callback.call( elem, i, elem );\n }));\n },\n\n end: function() {\n return this.prevObject || this.constructor(null);\n },\n\n // For internal use only.\n // Behaves like an Array's method, not like a jQuery method.\n push: core_push,\n sort: [].sort,\n splice: [].splice\n};\n\n// Give the init function the jQuery prototype for later instantiation\njQuery.fn.init.prototype = jQuery.fn;\n\njQuery.extend = jQuery.fn.extend = function() {\n var options, name, src, copy, copyIsArray, clone,\n target = arguments[0] || {},\n i = 1,\n length = arguments.length,\n deep = false;\n\n // Handle a deep copy situation\n if ( typeof target === \"boolean\" ) {\n deep = target;\n target = arguments[1] || {};\n // skip the boolean and the target\n i = 2;\n }\n\n // Handle case when target is a string or something (possible in deep copy)\n if ( typeof target !== \"object\" && !jQuery.isFunction(target) ) {\n target = {};\n }\n\n // extend jQuery itself if only one argument is passed\n if ( length === i ) {\n target = this;\n --i;\n }\n\n for ( ; i < length; i++ ) {\n // Only deal with non-null/undefined values\n if ( (options = arguments[ i ]) != null ) {\n // Extend the base object\n for ( name in options ) {\n src = target[ name ];\n copy = options[ name ];\n\n // Prevent never-ending loop\n if ( target === copy ) {\n continue;\n }\n\n // Recurse if we're merging plain objects or arrays\n if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {\n if ( copyIsArray ) {\n copyIsArray = false;\n clone = src && jQuery.isArray(src) ? src : [];\n\n } else {\n clone = src && jQuery.isPlainObject(src) ? src : {};\n }\n\n // Never move original objects, clone them\n target[ name ] = jQuery.extend( deep, clone, copy );\n\n // Don't bring in undefined values\n } else if ( copy !== undefined ) {\n target[ name ] = copy;\n }\n }\n }\n }\n\n // Return the modified object\n return target;\n};\n\njQuery.extend({\n noConflict: function( deep ) {\n if ( window.$ === jQuery ) {\n window.$ = _$;\n }\n\n if ( deep && window.jQuery === jQuery ) {\n window.jQuery = _jQuery;\n }\n\n return jQuery;\n },\n\n // Is the DOM ready to be used? Set to true once it occurs.\n isReady: false,\n\n // A counter to track how many items to wait for before\n // the ready event fires. See #6781\n readyWait: 1,\n\n // Hold (or release) the ready event\n holdReady: function( hold ) {\n if ( hold ) {\n jQuery.readyWait++;\n } else {\n jQuery.ready( true );\n }\n },\n\n // Handle when the DOM is ready\n ready: function( wait ) {\n\n // Abort if there are pending holds or we're already ready\n if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {\n return;\n }\n\n // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).\n if ( !document.body ) {\n return setTimeout( jQuery.ready, 1 );\n }\n\n // Remember that the DOM is ready\n jQuery.isReady = true;\n\n // If a normal DOM Ready event fired, decrement, and wait if need be\n if ( wait !== true && --jQuery.readyWait > 0 ) {\n return;\n }\n\n // If there are functions bound, to execute\n readyList.resolveWith( document, [ jQuery ] );\n\n // Trigger any bound ready events\n if ( jQuery.fn.trigger ) {\n jQuery( document ).trigger(\"ready\").off(\"ready\");\n }\n },\n\n // See test/unit/core.js for details concerning isFunction.\n // Since version 1.3, DOM methods and functions like alert\n // aren't supported. They return false on IE (#2968).\n isFunction: function( obj ) {\n return jQuery.type(obj) === \"function\";\n },\n\n isArray: Array.isArray || function( obj ) {\n return jQuery.type(obj) === \"array\";\n },\n\n isWindow: function( obj ) {\n return obj != null && obj == obj.window;\n },\n\n isNumeric: function( obj ) {\n return !isNaN( parseFloat(obj) ) && isFinite( obj );\n },\n\n type: function( obj ) {\n return obj == null ?\n String( obj ) :\n class2type[ core_toString.call(obj) ] || \"object\";\n },\n\n isPlainObject: function( obj ) {\n // Must be an Object.\n // Because of IE, we also have to check the presence of the constructor property.\n // Make sure that DOM nodes and window objects don't pass through, as well\n if ( !obj || jQuery.type(obj) !== \"object\" || obj.nodeType || jQuery.isWindow( obj ) ) {\n return false;\n }\n\n try {\n // Not own constructor property must be Object\n if ( obj.constructor &&\n !core_hasOwn.call(obj, \"constructor\") &&\n !core_hasOwn.call(obj.constructor.prototype, \"isPrototypeOf\") ) {\n return false;\n }\n } catch ( e ) {\n // IE8,9 Will throw exceptions on certain host objects #9897\n return false;\n }\n\n // Own properties are enumerated firstly, so to speed up,\n // if last one is own, then all properties are own.\n\n var key;\n for ( key in obj ) {}\n\n return key === undefined || core_hasOwn.call( obj, key );\n },\n\n isEmptyObject: function( obj ) {\n var name;\n for ( name in obj ) {\n return false;\n }\n return true;\n },\n\n error: function( msg ) {\n throw new Error( msg );\n },\n\n // data: string of html\n // context (optional): If specified, the fragment will be created in this context, defaults to document\n // scripts (optional): If true, will include scripts passed in the html string\n parseHTML: function( data, context, scripts ) {\n var parsed;\n if ( !data || typeof data !== \"string\" ) {\n return null;\n }\n if ( typeof context === \"boolean\" ) {\n scripts = context;\n context = 0;\n }\n context = context || document;\n\n // Single tag\n if ( (parsed = rsingleTag.exec( data )) ) {\n return [ context.createElement( parsed[1] ) ];\n }\n\n parsed = jQuery.buildFragment( [ data ], context, scripts ? null : [] );\n return jQuery.merge( [],\n (parsed.cacheable ? jQuery.clone( parsed.fragment ) : parsed.fragment).childNodes );\n },\n\n parseJSON: function( data ) {\n if ( !data || typeof data !== \"string\") {\n return null;\n }\n\n // Make sure leading/trailing whitespace is removed (IE can't handle it)\n data = jQuery.trim( data );\n\n // Attempt to parse using the native JSON parser first\n if ( window.JSON && window.JSON.parse ) {\n return window.JSON.parse( data );\n }\n\n // Make sure the incoming data is actual JSON\n // Logic borrowed from http://json.org/json2.js\n if ( rvalidchars.test( data.replace( rvalidescape, \"@\" )\n .replace( rvalidtokens, \"]\" )\n .replace( rvalidbraces, \"\")) ) {\n\n return ( new Function( \"return \" + data ) )();\n\n }\n jQuery.error( \"Invalid JSON: \" + data );\n },\n\n // Cross-browser xml parsing\n parseXML: function( data ) {\n var xml, tmp;\n if ( !data || typeof data !== \"string\" ) {\n return null;\n }\n try {\n if ( window.DOMParser ) { // Standard\n tmp = new DOMParser();\n xml = tmp.parseFromString( data , \"text/xml\" );\n } else { // IE\n xml = new ActiveXObject( \"Microsoft.XMLDOM\" );\n xml.async = \"false\";\n xml.loadXML( data );\n }\n } catch( e ) {\n xml = undefined;\n }\n if ( !xml || !xml.documentElement || xml.getElementsByTagName( \"parsererror\" ).length ) {\n jQuery.error( \"Invalid XML: \" + data );\n }\n return xml;\n },\n\n noop: function() {},\n\n // Evaluates a script in a global context\n // Workarounds based on findings by Jim Driscoll\n // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context\n globalEval: function( data ) {\n if ( data && core_rnotwhite.test( data ) ) {\n // We use execScript on Internet Explorer\n // We use an anonymous function so that context is window\n // rather than jQuery in Firefox\n ( window.execScript || function( data ) {\n window[ \"eval\" ].call( window, data );\n } )( data );\n }\n },\n\n // Convert dashed to camelCase; used by the css and data modules\n // Microsoft forgot to hump their vendor prefix (#9572)\n camelCase: function( string ) {\n return string.replace( rmsPrefix, \"ms-\" ).replace( rdashAlpha, fcamelCase );\n },\n\n nodeName: function( elem, name ) {\n return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();\n },\n\n // args is for internal usage only\n each: function( obj, callback, args ) {\n var name,\n i = 0,\n length = obj.length,\n isObj = length === undefined || jQuery.isFunction( obj );\n\n if ( args ) {\n if ( isObj ) {\n for ( name in obj ) {\n if ( callback.apply( obj[ name ], args ) === false ) {\n break;\n }\n }\n } else {\n for ( ; i < length; ) {\n if ( callback.apply( obj[ i++ ], args ) === false ) {\n break;\n }\n }\n }\n\n // A special, fast, case for the most common use of each\n } else {\n if ( isObj ) {\n for ( name in obj ) {\n if ( callback.call( obj[ name ], name, obj[ name ] ) === false ) {\n break;\n }\n }\n } else {\n for ( ; i < length; ) {\n if ( callback.call( obj[ i ], i, obj[ i++ ] ) === false ) {\n break;\n }\n }\n }\n }\n\n return obj;\n },\n\n // Use native String.trim function wherever possible\n trim: core_trim && !core_trim.call(\"\\uFEFF\\xA0\") ?\n function( text ) {\n return text == null ?\n \"\" :\n core_trim.call( text );\n } :\n\n // Otherwise use our own trimming functionality\n function( text ) {\n return text == null ?\n \"\" :\n ( text + \"\" ).replace( rtrim, \"\" );\n },\n\n // results is for internal usage only\n makeArray: function( arr, results ) {\n var type,\n ret = results || [];\n\n if ( arr != null ) {\n // The window, strings (and functions) also have 'length'\n // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930\n type = jQuery.type( arr );\n\n if ( arr.length == null || type === \"string\" || type === \"function\" || type === \"regexp\" || jQuery.isWindow( arr ) ) {\n core_push.call( ret, arr );\n } else {\n jQuery.merge( ret, arr );\n }\n }\n\n return ret;\n },\n\n inArray: function( elem, arr, i ) {\n var len;\n\n if ( arr ) {\n if ( core_indexOf ) {\n return core_indexOf.call( arr, elem, i );\n }\n\n len = arr.length;\n i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0;\n\n for ( ; i < len; i++ ) {\n // Skip accessing in sparse arrays\n if ( i in arr && arr[ i ] === elem ) {\n return i;\n }\n }\n }\n\n return -1;\n },\n\n merge: function( first, second ) {\n var l = second.length,\n i = first.length,\n j = 0;\n\n if ( typeof l === \"number\" ) {\n for ( ; j < l; j++ ) {\n first[ i++ ] = second[ j ];\n }\n\n } else {\n while ( second[j] !== undefined ) {\n first[ i++ ] = second[ j++ ];\n }\n }\n\n first.length = i;\n\n return first;\n },\n\n grep: function( elems, callback, inv ) {\n var retVal,\n ret = [],\n i = 0,\n length = elems.length;\n inv = !!inv;\n\n // Go through the array, only saving the items\n // that pass the validator function\n for ( ; i < length; i++ ) {\n retVal = !!callback( elems[ i ], i );\n if ( inv !== retVal ) {\n ret.push( elems[ i ] );\n }\n }\n\n return ret;\n },\n\n // arg is for internal usage only\n map: function( elems, callback, arg ) {\n var value, key,\n ret = [],\n i = 0,\n length = elems.length,\n // jquery objects are treated as arrays\n isArray = elems instanceof jQuery || length !== undefined && typeof length === \"number\" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems ) ) ;\n\n // Go through the array, translating each of the items to their\n if ( isArray ) {\n for ( ; i < length; i++ ) {\n value = callback( elems[ i ], i, arg );\n\n if ( value != null ) {\n ret[ ret.length ] = value;\n }\n }\n\n // Go through every key on the object,\n } else {\n for ( key in elems ) {\n value = callback( elems[ key ], key, arg );\n\n if ( value != null ) {\n ret[ ret.length ] = value;\n }\n }\n }\n\n // Flatten any nested arrays\n return ret.concat.apply( [], ret );\n },\n\n // A global GUID counter for objects\n guid: 1,\n\n // Bind a function to a context, optionally partially applying any\n // arguments.\n proxy: function( fn, context ) {\n var tmp, args, proxy;\n\n if ( typeof context === \"string\" ) {\n tmp = fn[ context ];\n context = fn;\n fn = tmp;\n }\n\n // Quick check to determine if target is callable, in the spec\n // this throws a TypeError, but we will just return undefined.\n if ( !jQuery.isFunction( fn ) ) {\n return undefined;\n }\n\n // Simulated bind\n args = core_slice.call( arguments, 2 );\n proxy = function() {\n return fn.apply( context, args.concat( core_slice.call( arguments ) ) );\n };\n\n // Set the guid of unique handler to the same of original handler, so it can be removed\n proxy.guid = fn.guid = fn.guid || jQuery.guid++;\n\n return proxy;\n },\n\n // Multifunctional method to get and set values of a collection\n // The value/s can optionally be executed if it's a function\n access: function( elems, fn, key, value, chainable, emptyGet, pass ) {\n var exec,\n bulk = key == null,\n i = 0,\n length = elems.length;\n\n // Sets many values\n if ( key && typeof key === \"object\" ) {\n for ( i in key ) {\n jQuery.access( elems, fn, i, key[i], 1, emptyGet, value );\n }\n chainable = 1;\n\n // Sets one value\n } else if ( value !== undefined ) {\n // Optionally, function values get executed if exec is true\n exec = pass === undefined && jQuery.isFunction( value );\n\n if ( bulk ) {\n // Bulk operations only iterate when executing function values\n if ( exec ) {\n exec = fn;\n fn = function( elem, key, value ) {\n return exec.call( jQuery( elem ), value );\n };\n\n // Otherwise they run against the entire set\n } else {\n fn.call( elems, value );\n fn = null;\n }\n }\n\n if ( fn ) {\n for (; i < length; i++ ) {\n fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );\n }\n }\n\n chainable = 1;\n }\n\n return chainable ?\n elems :\n\n // Gets\n bulk ?\n fn.call( elems ) :\n length ? fn( elems[0], key ) : emptyGet;\n },\n\n now: function() {\n return ( new Date() ).getTime();\n }\n});\n\njQuery.ready.promise = function( obj ) {\n if ( !readyList ) {\n\n readyList = jQuery.Deferred();\n\n // Catch cases where $(document).ready() is called after the browser event has already occurred.\n // we once tried to use readyState \"interactive\" here, but it caused issues like the one\n // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15\n if ( document.readyState === \"complete\" ) {\n // Handle it asynchronously to allow scripts the opportunity to delay ready\n setTimeout( jQuery.ready, 1 );\n\n // Standards-based browsers support DOMContentLoaded\n } else if ( document.addEventListener ) {\n // Use the handy event callback\n document.addEventListener( \"DOMContentLoaded\", DOMContentLoaded, false );\n\n // A fallback to window.onload, that will always work\n window.addEventListener( \"load\", jQuery.ready, false );\n\n // If IE event model is used\n } else {\n // Ensure firing before onload, maybe late but safe also for iframes\n document.attachEvent( \"onreadystatechange\", DOMContentLoaded );\n\n // A fallback to window.onload, that will always work\n window.attachEvent( \"onload\", jQuery.ready );\n\n // If IE and not a frame\n // continually check to see if the document is ready\n var top = false;\n\n try {\n top = window.frameElement == null && document.documentElement;\n } catch(e) {}\n\n if ( top && top.doScroll ) {\n (function doScrollCheck() {\n if ( !jQuery.isReady ) {\n\n try {\n // Use the trick by Diego Perini\n // http://javascript.nwbox.com/IEContentLoaded/\n top.doScroll(\"left\");\n } catch(e) {\n return setTimeout( doScrollCheck, 50 );\n }\n\n // and execute any waiting functions\n jQuery.ready();\n }\n })();\n }\n }\n }\n return readyList.promise( obj );\n};\n\n// Populate the class2type map\njQuery.each(\"Boolean Number String Function Array Date RegExp Object\".split(\" \"), function(i, name) {\n class2type[ \"[object \" + name + \"]\" ] = name.toLowerCase();\n});\n\n// All jQuery objects should point back to these\nrootjQuery = jQuery(document);\n// String to Object options format cache\nvar optionsCache = {};\n\n// Convert String-formatted options into Object-formatted ones and store in cache\nfunction createOptions( options ) {\n var object = optionsCache[ options ] = {};\n jQuery.each( options.split( core_rspace ), function( _, flag ) {\n object[ flag ] = true;\n });\n return object;\n}\n\n/*\n * Create a callback list using the following parameters:\n *\n * options: an optional list of space-separated options that will change how\n * the callback list behaves or a more traditional option object\n *\n * By default a callback list will act like an event callback list and can be\n * \"fired\" multiple times.\n *\n * Possible options:\n *\n * once: will ensure the callback list can only be fired once (like a Deferred)\n *\n * memory: will keep track of previous values and will call any callback added\n * after the list has been fired right away with the latest \"memorized\"\n * values (like a Deferred)\n *\n * unique: will ensure a callback can only be added once (no duplicate in the list)\n *\n * stopOnFalse: interrupt callings when a callback returns false\n *\n */\njQuery.Callbacks = function( options ) {\n\n // Convert options from String-formatted to Object-formatted if needed\n // (we check in cache first)\n options = typeof options === \"string\" ?\n ( optionsCache[ options ] || createOptions( options ) ) :\n jQuery.extend( {}, options );\n\n var // Last fire value (for non-forgettable lists)\n memory,\n // Flag to know if list was already fired\n fired,\n // Flag to know if list is currently firing\n firing,\n // First callback to fire (used internally by add and fireWith)\n firingStart,\n // End of the loop when firing\n firingLength,\n // Index of currently firing callback (modified by remove if needed)\n firingIndex,\n // Actual callback list\n list = [],\n // Stack of fire calls for repeatable lists\n stack = !options.once && [],\n // Fire callbacks\n fire = function( data ) {\n memory = options.memory && data;\n fired = true;\n firingIndex = firingStart || 0;\n firingStart = 0;\n firingLength = list.length;\n firing = true;\n for ( ; list && firingIndex < firingLength; firingIndex++ ) {\n if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) {\n memory = false; // To prevent further calls using add\n break;\n }\n }\n firing = false;\n if ( list ) {\n if ( stack ) {\n if ( stack.length ) {\n fire( stack.shift() );\n }\n } else if ( memory ) {\n list = [];\n } else {\n self.disable();\n }\n }\n },\n // Actual Callbacks object\n self = {\n // Add a callback or a collection of callbacks to the list\n add: function() {\n if ( list ) {\n // First, we save the current length\n var start = list.length;\n (function add( args ) {\n jQuery.each( args, function( _, arg ) {\n var type = jQuery.type( arg );\n if ( type === \"function\" ) {\n if ( !options.unique || !self.has( arg ) ) {\n list.push( arg );\n }\n } else if ( arg && arg.length && type !== \"string\" ) {\n // Inspect recursively\n add( arg );\n }\n });\n })( arguments );\n // Do we need to add the callbacks to the\n // current firing batch?\n if ( firing ) {\n firingLength = list.length;\n // With memory, if we're not firing then\n // we should call right away\n } else if ( memory ) {\n firingStart = start;\n fire( memory );\n }\n }\n return this;\n },\n // Remove a callback from the list\n remove: function() {\n if ( list ) {\n jQuery.each( arguments, function( _, arg ) {\n var index;\n while( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {\n list.splice( index, 1 );\n // Handle firing indexes\n if ( firing ) {\n if ( index <= firingLength ) {\n firingLength--;\n }\n if ( index <= firingIndex ) {\n firingIndex--;\n }\n }\n }\n });\n }\n return this;\n },\n // Control if a given callback is in the list\n has: function( fn ) {\n return jQuery.inArray( fn, list ) > -1;\n },\n // Remove all callbacks from the list\n empty: function() {\n list = [];\n return this;\n },\n // Have the list do nothing anymore\n disable: function() {\n list = stack = memory = undefined;\n return this;\n },\n // Is it disabled?\n disabled: function() {\n return !list;\n },\n // Lock the list in its current state\n lock: function() {\n stack = undefined;\n if ( !memory ) {\n self.disable();\n }\n return this;\n },\n // Is it locked?\n locked: function() {\n return !stack;\n },\n // Call all callbacks with the given context and arguments\n fireWith: function( context, args ) {\n args = args || [];\n args = [ context, args.slice ? args.slice() : args ];\n if ( list && ( !fired || stack ) ) {\n if ( firing ) {\n stack.push( args );\n } else {\n fire( args );\n }\n }\n return this;\n },\n // Call all the callbacks with the given arguments\n fire: function() {\n self.fireWith( this, arguments );\n return this;\n },\n // To know if the callbacks have already been called at least once\n fired: function() {\n return !!fired;\n }\n };\n\n return self;\n};\njQuery.extend({\n\n Deferred: function( func ) {\n var tuples = [\n // action, add listener, listener list, final state\n [ \"resolve\", \"done\", jQuery.Callbacks(\"once memory\"), \"resolved\" ],\n [ \"reject\", \"fail\", jQuery.Callbacks(\"once memory\"), \"rejected\" ],\n [ \"notify\", \"progress\", jQuery.Callbacks(\"memory\") ]\n ],\n state = \"pending\",\n promise = {\n state: function() {\n return state;\n },\n always: function() {\n deferred.done( arguments ).fail( arguments );\n return this;\n },\n then: function( /* fnDone, fnFail, fnProgress */ ) {\n var fns = arguments;\n return jQuery.Deferred(function( newDefer ) {\n jQuery.each( tuples, function( i, tuple ) {\n var action = tuple[ 0 ],\n fn = fns[ i ];\n // deferred[ done | fail | progress ] for forwarding actions to newDefer\n deferred[ tuple[1] ]( jQuery.isFunction( fn ) ?\n function() {\n var returned = fn.apply( this, arguments );\n if ( returned && jQuery.isFunction( returned.promise ) ) {\n returned.promise()\n .done( newDefer.resolve )\n .fail( newDefer.reject )\n .progress( newDefer.notify );\n } else {\n newDefer[ action + \"With\" ]( this === deferred ? newDefer : this, [ returned ] );\n }\n } :\n newDefer[ action ]\n );\n });\n fns = null;\n }).promise();\n },\n // Get a promise for this deferred\n // If obj is provided, the promise aspect is added to the object\n promise: function( obj ) {\n return obj != null ? jQuery.extend( obj, promise ) : promise;\n }\n },\n deferred = {};\n\n // Keep pipe for back-compat\n promise.pipe = promise.then;\n\n // Add list-specific methods\n jQuery.each( tuples, function( i, tuple ) {\n var list = tuple[ 2 ],\n stateString = tuple[ 3 ];\n\n // promise[ done | fail | progress ] = list.add\n promise[ tuple[1] ] = list.add;\n\n // Handle state\n if ( stateString ) {\n list.add(function() {\n // state = [ resolved | rejected ]\n state = stateString;\n\n // [ reject_list | resolve_list ].disable; progress_list.lock\n }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock );\n }\n\n // deferred[ resolve | reject | notify ] = list.fire\n deferred[ tuple[0] ] = list.fire;\n deferred[ tuple[0] + \"With\" ] = list.fireWith;\n });\n\n // Make the deferred a promise\n promise.promise( deferred );\n\n // Call given func if any\n if ( func ) {\n func.call( deferred, deferred );\n }\n\n // All done!\n return deferred;\n },\n\n // Deferred helper\n when: function( subordinate /* , ..., subordinateN */ ) {\n var i = 0,\n resolveValues = core_slice.call( arguments ),\n length = resolveValues.length,\n\n // the count of uncompleted subordinates\n remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,\n\n // the master Deferred. If resolveValues consist of only a single Deferred, just use that.\n deferred = remaining === 1 ? subordinate : jQuery.Deferred(),\n\n // Update function for both resolve and progress values\n updateFunc = function( i, contexts, values ) {\n return function( value ) {\n contexts[ i ] = this;\n values[ i ] = arguments.length > 1 ? core_slice.call( arguments ) : value;\n if( values === progressValues ) {\n deferred.notifyWith( contexts, values );\n } else if ( !( --remaining ) ) {\n deferred.resolveWith( contexts, values );\n }\n };\n },\n\n progressValues, progressContexts, resolveContexts;\n\n // add listeners to Deferred subordinates; treat others as resolved\n if ( length > 1 ) {\n progressValues = new Array( length );\n progressContexts = new Array( length );\n resolveContexts = new Array( length );\n for ( ; i < length; i++ ) {\n if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) {\n resolveValues[ i ].promise()\n .done( updateFunc( i, resolveContexts, resolveValues ) )\n .fail( deferred.reject )\n .progress( updateFunc( i, progressContexts, progressValues ) );\n } else {\n --remaining;\n }\n }\n }\n\n // if we're not waiting on anything, resolve the master\n if ( !remaining ) {\n deferred.resolveWith( resolveContexts, resolveValues );\n }\n\n return deferred.promise();\n }\n});\njQuery.support = (function() {\n\n var support,\n all,\n a,\n select,\n opt,\n input,\n fragment,\n eventName,\n i,\n isSupported,\n clickFn,\n div = document.createElement(\"div\");\n\n // Setup\n div.setAttribute( \"className\", \"t\" );\n div.innerHTML = \" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>\";\n\n // Support tests won't run in some limited or non-browser environments\n all = div.getElementsByTagName(\"*\");\n a = div.getElementsByTagName(\"a\")[ 0 ];\n if ( !all || !a || !all.length ) {\n return {};\n }\n\n // First batch of tests\n select = document.createElement(\"select\");\n opt = select.appendChild( document.createElement(\"option\") );\n input = div.getElementsByTagName(\"input\")[ 0 ];\n\n a.style.cssText = \"top:1px;float:left;opacity:.5\";\n support = {\n // IE strips leading whitespace when .innerHTML is used\n leadingWhitespace: ( div.firstChild.nodeType === 3 ),\n\n // Make sure that tbody elements aren't automatically inserted\n // IE will insert them into empty tables\n tbody: !div.getElementsByTagName(\"tbody\").length,\n\n // Make sure that link elements get serialized correctly by innerHTML\n // This requires a wrapper element in IE\n htmlSerialize: !!div.getElementsByTagName(\"link\").length,\n\n // Get the style information from getAttribute\n // (IE uses .cssText instead)\n style: /top/.test( a.getAttribute(\"style\") ),\n\n // Make sure that URLs aren't manipulated\n // (IE normalizes it by default)\n hrefNormalized: ( a.getAttribute(\"href\") === \"/a\" ),\n\n // Make sure that element opacity exists\n // (IE uses filter instead)\n // Use a regex to work around a WebKit issue. See #5145\n opacity: /^0.5/.test( a.style.opacity ),\n\n // Verify style float existence\n // (IE uses styleFloat instead of cssFloat)\n cssFloat: !!a.style.cssFloat,\n\n // Make sure that if no value is specified for a checkbox\n // that it defaults to \"on\".\n // (WebKit defaults to \"\" instead)\n checkOn: ( input.value === \"on\" ),\n\n // Make sure that a selected-by-default option has a working selected property.\n // (WebKit defaults to false instead of true, IE too, if it's in an optgroup)\n optSelected: opt.selected,\n\n // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7)\n getSetAttribute: div.className !== \"t\",\n\n // Tests for enctype support on a form (#6743)\n enctype: !!document.createElement(\"form\").enctype,\n\n // Makes sure cloning an html5 element does not cause problems\n // Where outerHTML is undefined, this still works\n html5Clone: document.createElement(\"nav\").cloneNode( true ).outerHTML !== \"<:nav></:nav>\",\n\n // jQuery.support.boxModel DEPRECATED in 1.8 since we don't support Quirks Mode\n boxModel: ( document.compatMode === \"CSS1Compat\" ),\n\n // Will be defined later\n submitBubbles: true,\n changeBubbles: true,\n focusinBubbles: false,\n deleteExpando: true,\n noCloneEvent: true,\n inlineBlockNeedsLayout: false,\n shrinkWrapBlocks: false,\n reliableMarginRight: true,\n boxSizingReliable: true,\n pixelPosition: false\n };\n\n // Make sure checked status is properly cloned\n input.checked = true;\n support.noCloneChecked = input.cloneNode( true ).checked;\n\n // Make sure that the options inside disabled selects aren't marked as disabled\n // (WebKit marks them as disabled)\n select.disabled = true;\n support.optDisabled = !opt.disabled;\n\n // Test to see if it's possible to delete an expando from an element\n // Fails in Internet Explorer\n try {\n delete div.test;\n } catch( e ) {\n support.deleteExpando = false;\n }\n\n if ( !div.addEventListener && div.attachEvent && div.fireEvent ) {\n div.attachEvent( \"onclick\", clickFn = function() {\n // Cloning a node shouldn't copy over any\n // bound event handlers (IE does this)\n support.noCloneEvent = false;\n });\n div.cloneNode( true ).fireEvent(\"onclick\");\n div.detachEvent( \"onclick\", clickFn );\n }\n\n // Check if a radio maintains its value\n // after being appended to the DOM\n input = document.createElement(\"input\");\n input.value = \"t\";\n input.setAttribute( \"type\", \"radio\" );\n support.radioValue = input.value === \"t\";\n\n input.setAttribute( \"checked\", \"checked\" );\n\n // #11217 - WebKit loses check when the name is after the checked attribute\n input.setAttribute( \"name\", \"t\" );\n\n div.appendChild( input );\n fragment = document.createDocumentFragment();\n fragment.appendChild( div.lastChild );\n\n // WebKit doesn't clone checked state correctly in fragments\n support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked;\n\n // Check if a disconnected checkbox will retain its checked\n // value of true after appended to the DOM (IE6/7)\n support.appendChecked = input.checked;\n\n fragment.removeChild( input );\n fragment.appendChild( div );\n\n // Technique from Juriy Zaytsev\n // http://perfectionkills.com/detecting-event-support-without-browser-sniffing/\n // We only care about the case where non-standard event systems\n // are used, namely in IE. Short-circuiting here helps us to\n // avoid an eval call (in setAttribute) which can cause CSP\n // to go haywire. See: https://developer.mozilla.org/en/Security/CSP\n if ( div.attachEvent ) {\n for ( i in {\n submit: true,\n change: true,\n focusin: true\n }) {\n eventName = \"on\" + i;\n isSupported = ( eventName in div );\n if ( !isSupported ) {\n div.setAttribute( eventName, \"return;\" );\n isSupported = ( typeof div[ eventName ] === \"function\" );\n }\n support[ i + \"Bubbles\" ] = isSupported;\n }\n }\n\n // Run tests that need a body at doc ready\n jQuery(function() {\n var container, div, tds, marginDiv,\n divReset = \"padding:0;margin:0;border:0;display:block;overflow:hidden;\",\n body = document.getElementsByTagName(\"body\")[0];\n\n if ( !body ) {\n // Return for frameset docs that don't have a body\n return;\n }\n\n container = document.createElement(\"div\");\n container.style.cssText = \"visibility:hidden;border:0;width:0;height:0;position:static;top:0;margin-top:1px\";\n body.insertBefore( container, body.firstChild );\n\n // Construct the test element\n div = document.createElement(\"div\");\n container.appendChild( div );\n\n // Check if table cells still have offsetWidth/Height when they are set\n // to display:none and there are still other visible table cells in a\n // table row; if so, offsetWidth/Height are not reliable for use when\n // determining if an element has been hidden directly using\n // display:none (it is still safe to use offsets if a parent element is\n // hidden; don safety goggles and see bug #4512 for more information).\n // (only IE 8 fails this test)\n div.innerHTML = \"<table><tr><td></td><td>t</td></tr></table>\";\n tds = div.getElementsByTagName(\"td\");\n tds[ 0 ].style.cssText = \"padding:0;margin:0;border:0;display:none\";\n isSupported = ( tds[ 0 ].offsetHeight === 0 );\n\n tds[ 0 ].style.display = \"\";\n tds[ 1 ].style.display = \"none\";\n\n // Check if empty table cells still have offsetWidth/Height\n // (IE <= 8 fail this test)\n support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 );\n\n // Check box-sizing and margin behavior\n div.innerHTML = \"\";\n div.style.cssText = \"box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;\";\n support.boxSizing = ( div.offsetWidth === 4 );\n support.doesNotIncludeMarginInBodyOffset = ( body.offsetTop !== 1 );\n\n // NOTE: To any future maintainer, we've window.getComputedStyle\n // because jsdom on node.js will break without it.\n if ( window.getComputedStyle ) {\n support.pixelPosition = ( window.getComputedStyle( div, null ) || {} ).top !== \"1%\";\n support.boxSizingReliable = ( window.getComputedStyle( div, null ) || { width: \"4px\" } ).width === \"4px\";\n\n // Check if div with explicit width and no margin-right incorrectly\n // gets computed margin-right based on width of container. For more\n // info see bug #3333\n // Fails in WebKit before Feb 2011 nightlies\n // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right\n marginDiv = document.createElement(\"div\");\n marginDiv.style.cssText = div.style.cssText = divReset;\n marginDiv.style.marginRight = marginDiv.style.width = \"0\";\n div.style.width = \"1px\";\n div.appendChild( marginDiv );\n support.reliableMarginRight =\n !parseFloat( ( window.getComputedStyle( marginDiv, null ) || {} ).marginRight );\n }\n\n if ( typeof div.style.zoom !== \"undefined\" ) {\n // Check if natively block-level elements act like inline-block\n // elements when setting their display to 'inline' and giving\n // them layout\n // (IE < 8 does this)\n div.innerHTML = \"\";\n div.style.cssText = divReset + \"width:1px;padding:1px;display:inline;zoom:1\";\n support.inlineBlockNeedsLayout = ( div.offsetWidth === 3 );\n\n // Check if elements with layout shrink-wrap their children\n // (IE 6 does this)\n div.style.display = \"block\";\n div.style.overflow = \"visible\";\n div.innerHTML = \"<div></div>\";\n div.firstChild.style.width = \"5px\";\n support.shrinkWrapBlocks = ( div.offsetWidth !== 3 );\n\n container.style.zoom = 1;\n }\n\n // Null elements to avoid leaks in IE\n body.removeChild( container );\n container = div = tds = marginDiv = null;\n });\n\n // Null elements to avoid leaks in IE\n fragment.removeChild( div );\n all = a = select = opt = input = fragment = div = null;\n\n return support;\n})();\nvar rbrace = /(?:\\{[\\s\\S]*\\}|\\[[\\s\\S]*\\])$/,\n rmultiDash = /([A-Z])/g;\n\njQuery.extend({\n cache: {},\n\n deletedIds: [],\n\n // Remove at next major release (1.9/2.0)\n uuid: 0,\n\n // Unique for each copy of jQuery on the page\n // Non-digits removed to match rinlinejQuery\n expando: \"jQuery\" + ( jQuery.fn.jquery + Math.random() ).replace( /\\D/g, \"\" ),\n\n // The following elements throw uncatchable exceptions if you\n // attempt to add expando properties to them.\n noData: {\n \"embed\": true,\n // Ban all objects except for Flash (which handle expandos)\n \"object\": \"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000\",\n \"applet\": true\n },\n\n hasData: function( elem ) {\n elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ];\n return !!elem && !isEmptyDataObject( elem );\n },\n\n data: function( elem, name, data, pvt /* Internal Use Only */ ) {\n if ( !jQuery.acceptData( elem ) ) {\n return;\n }\n\n var thisCache, ret,\n internalKey = jQuery.expando,\n getByName = typeof name === \"string\",\n\n // We have to handle DOM nodes and JS objects differently because IE6-7\n // can't GC object references properly across the DOM-JS boundary\n isNode = elem.nodeType,\n\n // Only DOM nodes need the global jQuery cache; JS object data is\n // attached directly to the object so GC can occur automatically\n cache = isNode ? jQuery.cache : elem,\n\n // Only defining an ID for JS objects if its cache already exists allows\n // the code to shortcut on the same path as a DOM node with no cache\n id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey;\n\n // Avoid doing any more work than we need to when trying to get data on an\n // object that has no data at all\n if ( (!id || !cache[id] || (!pvt && !cache[id].data)) && getByName && data === undefined ) {\n return;\n }\n\n if ( !id ) {\n // Only DOM nodes need a new unique ID for each element since their data\n // ends up in the global cache\n if ( isNode ) {\n elem[ internalKey ] = id = jQuery.deletedIds.pop() || jQuery.guid++;\n } else {\n id = internalKey;\n }\n }\n\n if ( !cache[ id ] ) {\n cache[ id ] = {};\n\n // Avoids exposing jQuery metadata on plain JS objects when the object\n // is serialized using JSON.stringify\n if ( !isNode ) {\n cache[ id ].toJSON = jQuery.noop;\n }\n }\n\n // An object can be passed to jQuery.data instead of a key/value pair; this gets\n // shallow copied over onto the existing cache\n if ( typeof name === \"object\" || typeof name === \"function\" ) {\n if ( pvt ) {\n cache[ id ] = jQuery.extend( cache[ id ], name );\n } else {\n cache[ id ].data = jQuery.extend( cache[ id ].data, name );\n }\n }\n\n thisCache = cache[ id ];\n\n // jQuery data() is stored in a separate object inside the object's internal data\n // cache in order to avoid key collisions between internal data and user-defined\n // data.\n if ( !pvt ) {\n if ( !thisCache.data ) {\n thisCache.data = {};\n }\n\n thisCache = thisCache.data;\n }\n\n if ( data !== undefined ) {\n thisCache[ jQuery.camelCase( name ) ] = data;\n }\n\n // Check for both converted-to-camel and non-converted data property names\n // If a data property was specified\n if ( getByName ) {\n\n // First Try to find as-is property data\n ret = thisCache[ name ];\n\n // Test for null|undefined property data\n if ( ret == null ) {\n\n // Try to find the camelCased property\n ret = thisCache[ jQuery.camelCase( name ) ];\n }\n } else {\n ret = thisCache;\n }\n\n return ret;\n },\n\n removeData: function( elem, name, pvt /* Internal Use Only */ ) {\n if ( !jQuery.acceptData( elem ) ) {\n return;\n }\n\n var thisCache, i, l,\n\n isNode = elem.nodeType,\n\n // See jQuery.data for more information\n cache = isNode ? jQuery.cache : elem,\n id = isNode ? elem[ jQuery.expando ] : jQuery.expando;\n\n // If there is already no cache entry for this object, there is no\n // purpose in continuing\n if ( !cache[ id ] ) {\n return;\n }\n\n if ( name ) {\n\n thisCache = pvt ? cache[ id ] : cache[ id ].data;\n\n if ( thisCache ) {\n\n // Support array or space separated string names for data keys\n if ( !jQuery.isArray( name ) ) {\n\n // try the string as a key before any manipulation\n if ( name in thisCache ) {\n name = [ name ];\n } else {\n\n // split the camel cased version by spaces unless a key with the spaces exists\n name = jQuery.camelCase( name );\n if ( name in thisCache ) {\n name = [ name ];\n } else {\n name = name.split(\" \");\n }\n }\n }\n\n for ( i = 0, l = name.length; i < l; i++ ) {\n delete thisCache[ name[i] ];\n }\n\n // If there is no data left in the cache, we want to continue\n // and let the cache object itself get destroyed\n if ( !( pvt ? isEmptyDataObject : jQuery.isEmptyObject )( thisCache ) ) {\n return;\n }\n }\n }\n\n // See jQuery.data for more information\n if ( !pvt ) {\n delete cache[ id ].data;\n\n // Don't destroy the parent cache unless the internal data object\n // had been the only thing left in it\n if ( !isEmptyDataObject( cache[ id ] ) ) {\n return;\n }\n }\n\n // Destroy the cache\n if ( isNode ) {\n jQuery.cleanData( [ elem ], true );\n\n // Use delete when supported for expandos or `cache` is not a window per isWindow (#10080)\n } else if ( jQuery.support.deleteExpando || cache != cache.window ) {\n delete cache[ id ];\n\n // When all else fails, null\n } else {\n cache[ id ] = null;\n }\n },\n\n // For internal use only.\n _data: function( elem, name, data ) {\n return jQuery.data( elem, name, data, true );\n },\n\n // A method for determining if a DOM node can handle the data expando\n acceptData: function( elem ) {\n var noData = elem.nodeName && jQuery.noData[ elem.nodeName.toLowerCase() ];\n\n // nodes accept data unless otherwise specified; rejection can be conditional\n return !noData || noData !== true && elem.getAttribute(\"classid\") === noData;\n }\n});\n\njQuery.fn.extend({\n data: function( key, value ) {\n var parts, part, attr, name, l,\n elem = this[0],\n i = 0,\n data = null;\n\n // Gets all values\n if ( key === undefined ) {\n if ( this.length ) {\n data = jQuery.data( elem );\n\n if ( elem.nodeType === 1 && !jQuery._data( elem, \"parsedAttrs\" ) ) {\n attr = elem.attributes;\n for ( l = attr.length; i < l; i++ ) {\n name = attr[i].name;\n\n if ( !name.indexOf( \"data-\" ) ) {\n name = jQuery.camelCase( name.substring(5) );\n\n dataAttr( elem, name, data[ name ] );\n }\n }\n jQuery._data( elem, \"parsedAttrs\", true );\n }\n }\n\n return data;\n }\n\n // Sets multiple values\n if ( typeof key === \"object\" ) {\n return this.each(function() {\n jQuery.data( this, key );\n });\n }\n\n parts = key.split( \".\", 2 );\n parts[1] = parts[1] ? \".\" + parts[1] : \"\";\n part = parts[1] + \"!\";\n\n return jQuery.access( this, function( value ) {\n\n if ( value === undefined ) {\n data = this.triggerHandler( \"getData\" + part, [ parts[0] ] );\n\n // Try to fetch any internally stored data first\n if ( data === undefined && elem ) {\n data = jQuery.data( elem, key );\n data = dataAttr( elem, key, data );\n }\n\n return data === undefined && parts[1] ?\n this.data( parts[0] ) :\n data;\n }\n\n parts[1] = value;\n this.each(function() {\n var self = jQuery( this );\n\n self.triggerHandler( \"setData\" + part, parts );\n jQuery.data( this, key, value );\n self.triggerHandler( \"changeData\" + part, parts );\n });\n }, null, value, arguments.length > 1, null, false );\n },\n\n removeData: function( key ) {\n return this.each(function() {\n jQuery.removeData( this, key );\n });\n }\n});\n\nfunction dataAttr( elem, key, data ) {\n // If nothing was found internally, try to fetch any\n // data from the HTML5 data-* attribute\n if ( data === undefined && elem.nodeType === 1 ) {\n\n var name = \"data-\" + key.replace( rmultiDash, \"-$1\" ).toLowerCase();\n\n data = elem.getAttribute( name );\n\n if ( typeof data === \"string\" ) {\n try {\n data = data === \"true\" ? true :\n data === \"false\" ? false :\n data === \"null\" ? null :\n // Only convert to a number if it doesn't change the string\n +data + \"\" === data ? +data :\n rbrace.test( data ) ? jQuery.parseJSON( data ) :\n data;\n } catch( e ) {}\n\n // Make sure we set the data so it isn't changed later\n jQuery.data( elem, key, data );\n\n } else {\n data = undefined;\n }\n }\n\n return data;\n}\n\n// checks a cache object for emptiness\nfunction isEmptyDataObject( obj ) {\n var name;\n for ( name in obj ) {\n\n // if the public data object is empty, the private is still empty\n if ( name === \"data\" && jQuery.isEmptyObject( obj[name] ) ) {\n continue;\n }\n if ( name !== \"toJSON\" ) {\n return false;\n }\n }\n\n return true;\n}\njQuery.extend({\n queue: function( elem, type, data ) {\n var queue;\n\n if ( elem ) {\n type = ( type || \"fx\" ) + \"queue\";\n queue = jQuery._data( elem, type );\n\n // Speed up dequeue by getting out quickly if this is just a lookup\n if ( data ) {\n if ( !queue || jQuery.isArray(data) ) {\n queue = jQuery._data( elem, type, jQuery.makeArray(data) );\n } else {\n queue.push( data );\n }\n }\n return queue || [];\n }\n },\n\n dequeue: function( elem, type ) {\n type = type || \"fx\";\n\n var queue = jQuery.queue( elem, type ),\n startLength = queue.length,\n fn = queue.shift(),\n hooks = jQuery._queueHooks( elem, type ),\n next = function() {\n jQuery.dequeue( elem, type );\n };\n\n // If the fx queue is dequeued, always remove the progress sentinel\n if ( fn === \"inprogress\" ) {\n fn = queue.shift();\n startLength--;\n }\n\n if ( fn ) {\n\n // Add a progress sentinel to prevent the fx queue from being\n // automatically dequeued\n if ( type === \"fx\" ) {\n queue.unshift( \"inprogress\" );\n }\n\n // clear up the last queue stop function\n delete hooks.stop;\n fn.call( elem, next, hooks );\n }\n\n if ( !startLength && hooks ) {\n hooks.empty.fire();\n }\n },\n\n // not intended for public consumption - generates a queueHooks object, or returns the current one\n _queueHooks: function( elem, type ) {\n var key = type + \"queueHooks\";\n return jQuery._data( elem, key ) || jQuery._data( elem, key, {\n empty: jQuery.Callbacks(\"once memory\").add(function() {\n jQuery.removeData( elem, type + \"queue\", true );\n jQuery.removeData( elem, key, true );\n })\n });\n }\n});\n\njQuery.fn.extend({\n queue: function( type, data ) {\n var setter = 2;\n\n if ( typeof type !== \"string\" ) {\n data = type;\n type = \"fx\";\n setter--;\n }\n\n if ( arguments.length < setter ) {\n return jQuery.queue( this[0], type );\n }\n\n return data === undefined ?\n this :\n this.each(function() {\n var queue = jQuery.queue( this, type, data );\n\n // ensure a hooks for this queue\n jQuery._queueHooks( this, type );\n\n if ( type === \"fx\" && queue[0] !== \"inprogress\" ) {\n jQuery.dequeue( this, type );\n }\n });\n },\n dequeue: function( type ) {\n return this.each(function() {\n jQuery.dequeue( this, type );\n });\n },\n // Based off of the plugin by Clint Helfers, with permission.\n // http://blindsignals.com/index.php/2009/07/jquery-delay/\n delay: function( time, type ) {\n time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;\n type = type || \"fx\";\n\n return this.queue( type, function( next, hooks ) {\n var timeout = setTimeout( next, time );\n hooks.stop = function() {\n clearTimeout( timeout );\n };\n });\n },\n clearQueue: function( type ) {\n return this.queue( type || \"fx\", [] );\n },\n // Get a promise resolved when queues of a certain type\n // are emptied (fx is the type by default)\n promise: function( type, obj ) {\n var tmp,\n count = 1,\n defer = jQuery.Deferred(),\n elements = this,\n i = this.length,\n resolve = function() {\n if ( !( --count ) ) {\n defer.resolveWith( elements, [ elements ] );\n }\n };\n\n if ( typeof type !== \"string\" ) {\n obj = type;\n type = undefined;\n }\n type = type || \"fx\";\n\n while( i-- ) {\n tmp = jQuery._data( elements[ i ], type + \"queueHooks\" );\n if ( tmp && tmp.empty ) {\n count++;\n tmp.empty.add( resolve );\n }\n }\n resolve();\n return defer.promise( obj );\n }\n});\nvar nodeHook, boolHook, fixSpecified,\n rclass = /[\\t\\r\\n]/g,\n rreturn = /\\r/g,\n rtype = /^(?:button|input)$/i,\n rfocusable = /^(?:button|input|object|select|textarea)$/i,\n rclickable = /^a(?:rea|)$/i,\n rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,\n getSetAttribute = jQuery.support.getSetAttribute;\n\njQuery.fn.extend({\n attr: function( name, value ) {\n return jQuery.access( this, jQuery.attr, name, value, arguments.length > 1 );\n },\n\n removeAttr: function( name ) {\n return this.each(function() {\n jQuery.removeAttr( this, name );\n });\n },\n\n prop: function( name, value ) {\n return jQuery.access( this, jQuery.prop, name, value, arguments.length > 1 );\n },\n\n removeProp: function( name ) {\n name = jQuery.propFix[ name ] || name;\n return this.each(function() {\n // try/catch handles cases where IE balks (such as removing a property on window)\n try {\n this[ name ] = undefined;\n delete this[ name ];\n } catch( e ) {}\n });\n },\n\n addClass: function( value ) {\n var classNames, i, l, elem,\n setClass, c, cl;\n\n if ( jQuery.isFunction( value ) ) {\n return this.each(function( j ) {\n jQuery( this ).addClass( value.call(this, j, this.className) );\n });\n }\n\n if ( value && typeof value === \"string\" ) {\n classNames = value.split( core_rspace );\n\n for ( i = 0, l = this.length; i < l; i++ ) {\n elem = this[ i ];\n\n if ( elem.nodeType === 1 ) {\n if ( !elem.className && classNames.length === 1 ) {\n elem.className = value;\n\n } else {\n setClass = \" \" + elem.className + \" \";\n\n for ( c = 0, cl = classNames.length; c < cl; c++ ) {\n if ( setClass.indexOf( \" \" + classNames[ c ] + \" \" ) < 0 ) {\n setClass += classNames[ c ] + \" \";\n }\n }\n elem.className = jQuery.trim( setClass );\n }\n }\n }\n }\n\n return this;\n },\n\n removeClass: function( value ) {\n var removes, className, elem, c, cl, i, l;\n\n if ( jQuery.isFunction( value ) ) {\n return this.each(function( j ) {\n jQuery( this ).removeClass( value.call(this, j, this.className) );\n });\n }\n if ( (value && typeof value === \"string\") || value === undefined ) {\n removes = ( value || \"\" ).split( core_rspace );\n\n for ( i = 0, l = this.length; i < l; i++ ) {\n elem = this[ i ];\n if ( elem.nodeType === 1 && elem.className ) {\n\n className = (\" \" + elem.className + \" \").replace( rclass, \" \" );\n\n // loop over each item in the removal list\n for ( c = 0, cl = removes.length; c < cl; c++ ) {\n // Remove until there is nothing to remove,\n while ( className.indexOf(\" \" + removes[ c ] + \" \") >= 0 ) {\n className = className.replace( \" \" + removes[ c ] + \" \" , \" \" );\n }\n }\n elem.className = value ? jQuery.trim( className ) : \"\";\n }\n }\n }\n\n return this;\n },\n\n toggleClass: function( value, stateVal ) {\n var type = typeof value,\n isBool = typeof stateVal === \"boolean\";\n\n if ( jQuery.isFunction( value ) ) {\n return this.each(function( i ) {\n jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal );\n });\n }\n\n return this.each(function() {\n if ( type === \"string\" ) {\n // toggle individual class names\n var className,\n i = 0,\n self = jQuery( this ),\n state = stateVal,\n classNames = value.split( core_rspace );\n\n while ( (className = classNames[ i++ ]) ) {\n // check each className given, space separated list\n state = isBool ? state : !self.hasClass( className );\n self[ state ? \"addClass\" : \"removeClass\" ]( className );\n }\n\n } else if ( type === \"undefined\" || type === \"boolean\" ) {\n if ( this.className ) {\n // store className if set\n jQuery._data( this, \"__className__\", this.className );\n }\n\n // toggle whole className\n this.className = this.className || value === false ? \"\" : jQuery._data( this, \"__className__\" ) || \"\";\n }\n });\n },\n\n hasClass: function( selector ) {\n var className = \" \" + selector + \" \",\n i = 0,\n l = this.length;\n for ( ; i < l; i++ ) {\n if ( this[i].nodeType === 1 && (\" \" + this[i].className + \" \").replace(rclass, \" \").indexOf( className ) >= 0 ) {\n return true;\n }\n }\n\n return false;\n },\n\n val: function( value ) {\n var hooks, ret, isFunction,\n elem = this[0];\n\n if ( !arguments.length ) {\n if ( elem ) {\n hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ];\n\n if ( hooks && \"get\" in hooks && (ret = hooks.get( elem, \"value\" )) !== undefined ) {\n return ret;\n }\n\n ret = elem.value;\n\n return typeof ret === \"string\" ?\n // handle most common string cases\n ret.replace(rreturn, \"\") :\n // handle cases where value is null/undef or number\n ret == null ? \"\" : ret;\n }\n\n return;\n }\n\n isFunction = jQuery.isFunction( value );\n\n return this.each(function( i ) {\n var val,\n self = jQuery(this);\n\n if ( this.nodeType !== 1 ) {\n return;\n }\n\n if ( isFunction ) {\n val = value.call( this, i, self.val() );\n } else {\n val = value;\n }\n\n // Treat null/undefined as \"\"; convert numbers to string\n if ( val == null ) {\n val = \"\";\n } else if ( typeof val === \"number\" ) {\n val += \"\";\n } else if ( jQuery.isArray( val ) ) {\n val = jQuery.map(val, function ( value ) {\n return value == null ? \"\" : value + \"\";\n });\n }\n\n hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];\n\n // If set returns undefined, fall back to normal setting\n if ( !hooks || !(\"set\" in hooks) || hooks.set( this, val, \"value\" ) === undefined ) {\n this.value = val;\n }\n });\n }\n});\n\njQuery.extend({\n valHooks: {\n option: {\n get: function( elem ) {\n // attributes.value is undefined in Blackberry 4.7 but\n // uses .value. See #6932\n var val = elem.attributes.value;\n return !val || val.specified ? elem.value : elem.text;\n }\n },\n select: {\n get: function( elem ) {\n var value, option,\n options = elem.options,\n index = elem.selectedIndex,\n one = elem.type === \"select-one\" || index < 0,\n values = one ? null : [],\n max = one ? index + 1 : options.length,\n i = index < 0 ?\n max :\n one ? index : 0;\n\n // Loop through all the selected options\n for ( ; i < max; i++ ) {\n option = options[ i ];\n\n // oldIE doesn't update selected after form reset (#2551)\n if ( ( option.selected || i === index ) &&\n // Don't return options that are disabled or in a disabled optgroup\n ( jQuery.support.optDisabled ? !option.disabled : option.getAttribute(\"disabled\") === null ) &&\n ( !option.parentNode.disabled || !jQuery.nodeName( option.parentNode, \"optgroup\" ) ) ) {\n\n // Get the specific value for the option\n value = jQuery( option ).val();\n\n // We don't need an array for one selects\n if ( one ) {\n return value;\n }\n\n // Multi-Selects return an array\n values.push( value );\n }\n }\n\n return values;\n },\n\n set: function( elem, value ) {\n var values = jQuery.makeArray( value );\n\n jQuery(elem).find(\"option\").each(function() {\n this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0;\n });\n\n if ( !values.length ) {\n elem.selectedIndex = -1;\n }\n return values;\n }\n }\n },\n\n // Unused in 1.8, left in so attrFn-stabbers won't die; remove in 1.9\n attrFn: {},\n\n attr: function( elem, name, value, pass ) {\n var ret, hooks, notxml,\n nType = elem.nodeType;\n\n // don't get/set attributes on text, comment and attribute nodes\n if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {\n return;\n }\n\n if ( pass && jQuery.isFunction( jQuery.fn[ name ] ) ) {\n return jQuery( elem )[ name ]( value );\n }\n\n // Fallback to prop when attributes are not supported\n if ( typeof elem.getAttribute === \"undefined\" ) {\n return jQuery.prop( elem, name, value );\n }\n\n notxml = nType !== 1 || !jQuery.isXMLDoc( elem );\n\n // All attributes are lowercase\n // Grab necessary hook if one is defined\n if ( notxml ) {\n name = name.toLowerCase();\n hooks = jQuery.attrHooks[ name ] || ( rboolean.test( name ) ? boolHook : nodeHook );\n }\n\n if ( value !== undefined ) {\n\n if ( value === null ) {\n jQuery.removeAttr( elem, name );\n return;\n\n } else if ( hooks && \"set\" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) {\n return ret;\n\n } else {\n elem.setAttribute( name, value + \"\" );\n return value;\n }\n\n } else if ( hooks && \"get\" in hooks && notxml && (ret = hooks.get( elem, name )) !== null ) {\n return ret;\n\n } else {\n\n ret = elem.getAttribute( name );\n\n // Non-existent attributes return null, we normalize to undefined\n return ret === null ?\n undefined :\n ret;\n }\n },\n\n removeAttr: function( elem, value ) {\n var propName, attrNames, name, isBool,\n i = 0;\n\n if ( value && elem.nodeType === 1 ) {\n\n attrNames = value.split( core_rspace );\n\n for ( ; i < attrNames.length; i++ ) {\n name = attrNames[ i ];\n\n if ( name ) {\n propName = jQuery.propFix[ name ] || name;\n isBool = rboolean.test( name );\n\n // See #9699 for explanation of this approach (setting first, then removal)\n // Do not do this for boolean attributes (see #10870)\n if ( !isBool ) {\n jQuery.attr( elem, name, \"\" );\n }\n elem.removeAttribute( getSetAttribute ? name : propName );\n\n // Set corresponding property to false for boolean attributes\n if ( isBool && propName in elem ) {\n elem[ propName ] = false;\n }\n }\n }\n }\n },\n\n attrHooks: {\n type: {\n set: function( elem, value ) {\n // We can't allow the type property to be changed (since it causes problems in IE)\n if ( rtype.test( elem.nodeName ) && elem.parentNode ) {\n jQuery.error( \"type property can't be changed\" );\n } else if ( !jQuery.support.radioValue && value === \"radio\" && jQuery.nodeName(elem, \"input\") ) {\n // Setting the type on a radio button after the value resets the value in IE6-9\n // Reset value to it's default in case type is set after value\n // This is for element creation\n var val = elem.value;\n elem.setAttribute( \"type\", value );\n if ( val ) {\n elem.value = val;\n }\n return value;\n }\n }\n },\n // Use the value property for back compat\n // Use the nodeHook for button elements in IE6/7 (#1954)\n value: {\n get: function( elem, name ) {\n if ( nodeHook && jQuery.nodeName( elem, \"button\" ) ) {\n return nodeHook.get( elem, name );\n }\n return name in elem ?\n elem.value :\n null;\n },\n set: function( elem, value, name ) {\n if ( nodeHook && jQuery.nodeName( elem, \"button\" ) ) {\n return nodeHook.set( elem, value, name );\n }\n // Does not return so that setAttribute is also used\n elem.value = value;\n }\n }\n },\n\n propFix: {\n tabindex: \"tabIndex\",\n readonly: \"readOnly\",\n \"for\": \"htmlFor\",\n \"class\": \"className\",\n maxlength: \"maxLength\",\n cellspacing: \"cellSpacing\",\n cellpadding: \"cellPadding\",\n rowspan: \"rowSpan\",\n colspan: \"colSpan\",\n usemap: \"useMap\",\n frameborder: \"frameBorder\",\n contenteditable: \"contentEditable\"\n },\n\n prop: function( elem, name, value ) {\n var ret, hooks, notxml,\n nType = elem.nodeType;\n\n // don't get/set properties on text, comment and attribute nodes\n if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {\n return;\n }\n\n notxml = nType !== 1 || !jQuery.isXMLDoc( elem );\n\n if ( notxml ) {\n // Fix name and attach hooks\n name = jQuery.propFix[ name ] || name;\n hooks = jQuery.propHooks[ name ];\n }\n\n if ( value !== undefined ) {\n if ( hooks && \"set\" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {\n return ret;\n\n } else {\n return ( elem[ name ] = value );\n }\n\n } else {\n if ( hooks && \"get\" in hooks && (ret = hooks.get( elem, name )) !== null ) {\n return ret;\n\n } else {\n return elem[ name ];\n }\n }\n },\n\n propHooks: {\n tabIndex: {\n get: function( elem ) {\n // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set\n // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/\n var attributeNode = elem.getAttributeNode(\"tabindex\");\n\n return attributeNode && attributeNode.specified ?\n parseInt( attributeNode.value, 10 ) :\n rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?\n 0 :\n undefined;\n }\n }\n }\n});\n\n// Hook for boolean attributes\nboolHook = {\n get: function( elem, name ) {\n // Align boolean attributes with corresponding properties\n // Fall back to attribute presence where some booleans are not supported\n var attrNode,\n property = jQuery.prop( elem, name );\n return property === true || typeof property !== \"boolean\" && ( attrNode = elem.getAttributeNode(name) ) && attrNode.nodeValue !== false ?\n name.toLowerCase() :\n undefined;\n },\n set: function( elem, value, name ) {\n var propName;\n if ( value === false ) {\n // Remove boolean attributes when set to false\n jQuery.removeAttr( elem, name );\n } else {\n // value is true since we know at this point it's type boolean and not false\n // Set boolean attributes to the same name and set the DOM property\n propName = jQuery.propFix[ name ] || name;\n if ( propName in elem ) {\n // Only set the IDL specifically if it already exists on the element\n elem[ propName ] = true;\n }\n\n elem.setAttribute( name, name.toLowerCase() );\n }\n return name;\n }\n};\n\n// IE6/7 do not support getting/setting some attributes with get/setAttribute\nif ( !getSetAttribute ) {\n\n fixSpecified = {\n name: true,\n id: true,\n coords: true\n };\n\n // Use this for any attribute in IE6/7\n // This fixes almost every IE6/7 issue\n nodeHook = jQuery.valHooks.button = {\n get: function( elem, name ) {\n var ret;\n ret = elem.getAttributeNode( name );\n return ret && ( fixSpecified[ name ] ? ret.value !== \"\" : ret.specified ) ?\n ret.value :\n undefined;\n },\n set: function( elem, value, name ) {\n // Set the existing or create a new attribute node\n var ret = elem.getAttributeNode( name );\n if ( !ret ) {\n ret = document.createAttribute( name );\n elem.setAttributeNode( ret );\n }\n return ( ret.value = value + \"\" );\n }\n };\n\n // Set width and height to auto instead of 0 on empty string( Bug #8150 )\n // This is for removals\n jQuery.each([ \"width\", \"height\" ], function( i, name ) {\n jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {\n set: function( elem, value ) {\n if ( value === \"\" ) {\n elem.setAttribute( name, \"auto\" );\n return value;\n }\n }\n });\n });\n\n // Set contenteditable to false on removals(#10429)\n // Setting to empty string throws an error as an invalid value\n jQuery.attrHooks.contenteditable = {\n get: nodeHook.get,\n set: function( elem, value, name ) {\n if ( value === \"\" ) {\n value = \"false\";\n }\n nodeHook.set( elem, value, name );\n }\n };\n}\n\n\n// Some attributes require a special call on IE\nif ( !jQuery.support.hrefNormalized ) {\n jQuery.each([ \"href\", \"src\", \"width\", \"height\" ], function( i, name ) {\n jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {\n get: function( elem ) {\n var ret = elem.getAttribute( name, 2 );\n return ret === null ? undefined : ret;\n }\n });\n });\n}\n\nif ( !jQuery.support.style ) {\n jQuery.attrHooks.style = {\n get: function( elem ) {\n // Return undefined in the case of empty string\n // Normalize to lowercase since IE uppercases css property names\n return elem.style.cssText.toLowerCase() || undefined;\n },\n set: function( elem, value ) {\n return ( elem.style.cssText = value + \"\" );\n }\n };\n}\n\n// Safari mis-reports the default selected property of an option\n// Accessing the parent's selectedIndex property fixes it\nif ( !jQuery.support.optSelected ) {\n jQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, {\n get: function( elem ) {\n var parent = elem.parentNode;\n\n if ( parent ) {\n parent.selectedIndex;\n\n // Make sure that it also works with optgroups, see #5701\n if ( parent.parentNode ) {\n parent.parentNode.selectedIndex;\n }\n }\n return null;\n }\n });\n}\n\n// IE6/7 call enctype encoding\nif ( !jQuery.support.enctype ) {\n jQuery.propFix.enctype = \"encoding\";\n}\n\n// Radios and checkboxes getter/setter\nif ( !jQuery.support.checkOn ) {\n jQuery.each([ \"radio\", \"checkbox\" ], function() {\n jQuery.valHooks[ this ] = {\n get: function( elem ) {\n // Handle the case where in Webkit \"\" is returned instead of \"on\" if a value isn't specified\n return elem.getAttribute(\"value\") === null ? \"on\" : elem.value;\n }\n };\n });\n}\njQuery.each([ \"radio\", \"checkbox\" ], function() {\n jQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], {\n set: function( elem, value ) {\n if ( jQuery.isArray( value ) ) {\n return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 );\n }\n }\n });\n});\nvar rformElems = /^(?:textarea|input|select)$/i,\n rtypenamespace = /^([^\\.]*|)(?:\\.(.+)|)$/,\n rhoverHack = /(?:^|\\s)hover(\\.\\S+|)\\b/,\n rkeyEvent = /^key/,\n rmouseEvent = /^(?:mouse|contextmenu)|click/,\n rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,\n hoverHack = function( events ) {\n return jQuery.event.special.hover ? events : events.replace( rhoverHack, \"mouseenter$1 mouseleave$1\" );\n };\n\n/*\n * Helper functions for managing events -- not part of the public interface.\n * Props to Dean Edwards' addEvent library for many of the ideas.\n */\njQuery.event = {\n\n add: function( elem, types, handler, data, selector ) {\n\n var elemData, eventHandle, events,\n t, tns, type, namespaces, handleObj,\n handleObjIn, handlers, special;\n\n // Don't attach events to noData or text/comment nodes (allow plain objects tho)\n if ( elem.nodeType === 3 || elem.nodeType === 8 || !types || !handler || !(elemData = jQuery._data( elem )) ) {\n return;\n }\n\n // Caller can pass in an object of custom data in lieu of the handler\n if ( handler.handler ) {\n handleObjIn = handler;\n handler = handleObjIn.handler;\n selector = handleObjIn.selector;\n }\n\n // Make sure that the handler has a unique ID, used to find/remove it later\n if ( !handler.guid ) {\n handler.guid = jQuery.guid++;\n }\n\n // Init the element's event structure and main handler, if this is the first\n events = elemData.events;\n if ( !events ) {\n elemData.events = events = {};\n }\n eventHandle = elemData.handle;\n if ( !eventHandle ) {\n elemData.handle = eventHandle = function( e ) {\n // Discard the second event of a jQuery.event.trigger() and\n // when an event is called after a page has unloaded\n return typeof jQuery !== \"undefined\" && (!e || jQuery.event.triggered !== e.type) ?\n jQuery.event.dispatch.apply( eventHandle.elem, arguments ) :\n undefined;\n };\n // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events\n eventHandle.elem = elem;\n }\n\n // Handle multiple events separated by a space\n // jQuery(...).bind(\"mouseover mouseout\", fn);\n types = jQuery.trim( hoverHack(types) ).split( \" \" );\n for ( t = 0; t < types.length; t++ ) {\n\n tns = rtypenamespace.exec( types[t] ) || [];\n type = tns[1];\n namespaces = ( tns[2] || \"\" ).split( \".\" ).sort();\n\n // If event changes its type, use the special event handlers for the changed type\n special = jQuery.event.special[ type ] || {};\n\n // If selector defined, determine special event api type, otherwise given type\n type = ( selector ? special.delegateType : special.bindType ) || type;\n\n // Update special based on newly reset type\n special = jQuery.event.special[ type ] || {};\n\n // handleObj is passed to all event handlers\n handleObj = jQuery.extend({\n type: type,\n origType: tns[1],\n data: data,\n handler: handler,\n guid: handler.guid,\n selector: selector,\n needsContext: selector && jQuery.expr.match.needsContext.test( selector ),\n namespace: namespaces.join(\".\")\n }, handleObjIn );\n\n // Init the event handler queue if we're the first\n handlers = events[ type ];\n if ( !handlers ) {\n handlers = events[ type ] = [];\n handlers.delegateCount = 0;\n\n // Only use addEventListener/attachEvent if the special events handler returns false\n if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {\n // Bind the global event handler to the element\n if ( elem.addEventListener ) {\n elem.addEventListener( type, eventHandle, false );\n\n } else if ( elem.attachEvent ) {\n elem.attachEvent( \"on\" + type, eventHandle );\n }\n }\n }\n\n if ( special.add ) {\n special.add.call( elem, handleObj );\n\n if ( !handleObj.handler.guid ) {\n handleObj.handler.guid = handler.guid;\n }\n }\n\n // Add to the element's handler list, delegates in front\n if ( selector ) {\n handlers.splice( handlers.delegateCount++, 0, handleObj );\n } else {\n handlers.push( handleObj );\n }\n\n // Keep track of which events have ever been used, for event optimization\n jQuery.event.global[ type ] = true;\n }\n\n // Nullify elem to prevent memory leaks in IE\n elem = null;\n },\n\n global: {},\n\n // Detach an event or set of events from an element\n remove: function( elem, types, handler, selector, mappedTypes ) {\n\n var t, tns, type, origType, namespaces, origCount,\n j, events, special, eventType, handleObj,\n elemData = jQuery.hasData( elem ) && jQuery._data( elem );\n\n if ( !elemData || !(events = elemData.events) ) {\n return;\n }\n\n // Once for each type.namespace in types; type may be omitted\n types = jQuery.trim( hoverHack( types || \"\" ) ).split(\" \");\n for ( t = 0; t < types.length; t++ ) {\n tns = rtypenamespace.exec( types[t] ) || [];\n type = origType = tns[1];\n namespaces = tns[2];\n\n // Unbind all events (on this namespace, if provided) for the element\n if ( !type ) {\n for ( type in events ) {\n jQuery.event.remove( elem, type + types[ t ], handler, selector, true );\n }\n continue;\n }\n\n special = jQuery.event.special[ type ] || {};\n type = ( selector? special.delegateType : special.bindType ) || type;\n eventType = events[ type ] || [];\n origCount = eventType.length;\n namespaces = namespaces ? new RegExp(\"(^|\\\\.)\" + namespaces.split(\".\").sort().join(\"\\\\.(?:.*\\\\.|)\") + \"(\\\\.|$)\") : null;\n\n // Remove matching events\n for ( j = 0; j < eventType.length; j++ ) {\n handleObj = eventType[ j ];\n\n if ( ( mappedTypes || origType === handleObj.origType ) &&\n ( !handler || handler.guid === handleObj.guid ) &&\n ( !namespaces || namespaces.test( handleObj.namespace ) ) &&\n ( !selector || selector === handleObj.selector || selector === \"**\" && handleObj.selector ) ) {\n eventType.splice( j--, 1 );\n\n if ( handleObj.selector ) {\n eventType.delegateCount--;\n }\n if ( special.remove ) {\n special.remove.call( elem, handleObj );\n }\n }\n }\n\n // Remove generic event handler if we removed something and no more handlers exist\n // (avoids potential for endless recursion during removal of special event handlers)\n if ( eventType.length === 0 && origCount !== eventType.length ) {\n if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) {\n jQuery.removeEvent( elem, type, elemData.handle );\n }\n\n delete events[ type ];\n }\n }\n\n // Remove the expando if it's no longer used\n if ( jQuery.isEmptyObject( events ) ) {\n delete elemData.handle;\n\n // removeData also checks for emptiness and clears the expando if empty\n // so use it instead of delete\n jQuery.removeData( elem, \"events\", true );\n }\n },\n\n // Events that are safe to short-circuit if no handlers are attached.\n // Native DOM events should not be added, they may have inline handlers.\n customEvent: {\n \"getData\": true,\n \"setData\": true,\n \"changeData\": true\n },\n\n trigger: function( event, data, elem, onlyHandlers ) {\n // Don't do events on text and comment nodes\n if ( elem && (elem.nodeType === 3 || elem.nodeType === 8) ) {\n return;\n }\n\n // Event object or event type\n var cache, exclusive, i, cur, old, ontype, special, handle, eventPath, bubbleType,\n type = event.type || event,\n namespaces = [];\n\n // focus/blur morphs to focusin/out; ensure we're not firing them right now\n if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {\n return;\n }\n\n if ( type.indexOf( \"!\" ) >= 0 ) {\n // Exclusive events trigger only for the exact event (no namespaces)\n type = type.slice(0, -1);\n exclusive = true;\n }\n\n if ( type.indexOf( \".\" ) >= 0 ) {\n // Namespaced trigger; create a regexp to match event type in handle()\n namespaces = type.split(\".\");\n type = namespaces.shift();\n namespaces.sort();\n }\n\n if ( (!elem || jQuery.event.customEvent[ type ]) && !jQuery.event.global[ type ] ) {\n // No jQuery handlers for this event type, and it can't have inline handlers\n return;\n }\n\n // Caller can pass in an Event, Object, or just an event type string\n event = typeof event === \"object\" ?\n // jQuery.Event object\n event[ jQuery.expando ] ? event :\n // Object literal\n new jQuery.Event( type, event ) :\n // Just the event type (string)\n new jQuery.Event( type );\n\n event.type = type;\n event.isTrigger = true;\n event.exclusive = exclusive;\n event.namespace = namespaces.join( \".\" );\n event.namespace_re = event.namespace? new RegExp(\"(^|\\\\.)\" + namespaces.join(\"\\\\.(?:.*\\\\.|)\") + \"(\\\\.|$)\") : null;\n ontype = type.indexOf( \":\" ) < 0 ? \"on\" + type : \"\";\n\n // Handle a global trigger\n if ( !elem ) {\n\n // TODO: Stop taunting the data cache; remove global events and always attach to document\n cache = jQuery.cache;\n for ( i in cache ) {\n if ( cache[ i ].events && cache[ i ].events[ type ] ) {\n jQuery.event.trigger( event, data, cache[ i ].handle.elem, true );\n }\n }\n return;\n }\n\n // Clean up the event in case it is being reused\n event.result = undefined;\n if ( !event.target ) {\n event.target = elem;\n }\n\n // Clone any incoming data and prepend the event, creating the handler arg list\n data = data != null ? jQuery.makeArray( data ) : [];\n data.unshift( event );\n\n // Allow special events to draw outside the lines\n special = jQuery.event.special[ type ] || {};\n if ( special.trigger && special.trigger.apply( elem, data ) === false ) {\n return;\n }\n\n // Determine event propagation path in advance, per W3C events spec (#9951)\n // Bubble up to document, then to window; watch for a global ownerDocument var (#9724)\n eventPath = [[ elem, special.bindType || type ]];\n if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {\n\n bubbleType = special.delegateType || type;\n cur = rfocusMorph.test( bubbleType + type ) ? elem : elem.parentNode;\n for ( old = elem; cur; cur = cur.parentNode ) {\n eventPath.push([ cur, bubbleType ]);\n old = cur;\n }\n\n // Only add window if we got to document (e.g., not plain obj or detached DOM)\n if ( old === (elem.ownerDocument || document) ) {\n eventPath.push([ old.defaultView || old.parentWindow || window, bubbleType ]);\n }\n }\n\n // Fire handlers on the event path\n for ( i = 0; i < eventPath.length && !event.isPropagationStopped(); i++ ) {\n\n cur = eventPath[i][0];\n event.type = eventPath[i][1];\n\n handle = ( jQuery._data( cur, \"events\" ) || {} )[ event.type ] && jQuery._data( cur, \"handle\" );\n if ( handle ) {\n handle.apply( cur, data );\n }\n // Note that this is a bare JS function and not a jQuery handler\n handle = ontype && cur[ ontype ];\n if ( handle && jQuery.acceptData( cur ) && handle.apply && handle.apply( cur, data ) === false ) {\n event.preventDefault();\n }\n }\n event.type = type;\n\n // If nobody prevented the default action, do it now\n if ( !onlyHandlers && !event.isDefaultPrevented() ) {\n\n if ( (!special._default || special._default.apply( elem.ownerDocument, data ) === false) &&\n !(type === \"click\" && jQuery.nodeName( elem, \"a\" )) && jQuery.acceptData( elem ) ) {\n\n // Call a native DOM method on the target with the same name name as the event.\n // Can't use an .isFunction() check here because IE6/7 fails that test.\n // Don't do default actions on window, that's where global variables be (#6170)\n // IE<9 dies on focus/blur to hidden element (#1486)\n if ( ontype && elem[ type ] && ((type !== \"focus\" && type !== \"blur\") || event.target.offsetWidth !== 0) && !jQuery.isWindow( elem ) ) {\n\n // Don't re-trigger an onFOO event when we call its FOO() method\n old = elem[ ontype ];\n\n if ( old ) {\n elem[ ontype ] = null;\n }\n\n // Prevent re-triggering of the same event, since we already bubbled it above\n jQuery.event.triggered = type;\n elem[ type ]();\n jQuery.event.triggered = undefined;\n\n if ( old ) {\n elem[ ontype ] = old;\n }\n }\n }\n }\n\n return event.result;\n },\n\n dispatch: function( event ) {\n\n // Make a writable jQuery.Event from the native event object\n event = jQuery.event.fix( event || window.event );\n\n var i, j, cur, ret, selMatch, matched, matches, handleObj, sel, related,\n handlers = ( (jQuery._data( this, \"events\" ) || {} )[ event.type ] || []),\n delegateCount = handlers.delegateCount,\n args = core_slice.call( arguments ),\n run_all = !event.exclusive && !event.namespace,\n special = jQuery.event.special[ event.type ] || {},\n handlerQueue = [];\n\n // Use the fix-ed jQuery.Event rather than the (read-only) native event\n args[0] = event;\n event.delegateTarget = this;\n\n // Call the preDispatch hook for the mapped type, and let it bail if desired\n if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {\n return;\n }\n\n // Determine handlers that should run if there are delegated events\n // Avoid non-left-click bubbling in Firefox (#3861)\n if ( delegateCount && !(event.button && event.type === \"click\") ) {\n\n for ( cur = event.target; cur != this; cur = cur.parentNode || this ) {\n\n // Don't process clicks (ONLY) on disabled elements (#6911, #8165, #11382, #11764)\n if ( cur.disabled !== true || event.type !== \"click\" ) {\n selMatch = {};\n matches = [];\n for ( i = 0; i < delegateCount; i++ ) {\n handleObj = handlers[ i ];\n sel = handleObj.selector;\n\n if ( selMatch[ sel ] === undefined ) {\n selMatch[ sel ] = handleObj.needsContext ?\n jQuery( sel, this ).index( cur ) >= 0 :\n jQuery.find( sel, this, null, [ cur ] ).length;\n }\n if ( selMatch[ sel ] ) {\n matches.push( handleObj );\n }\n }\n if ( matches.length ) {\n handlerQueue.push({ elem: cur, matches: matches });\n }\n }\n }\n }\n\n // Add the remaining (directly-bound) handlers\n if ( handlers.length > delegateCount ) {\n handlerQueue.push({ elem: this, matches: handlers.slice( delegateCount ) });\n }\n\n // Run delegates first; they may want to stop propagation beneath us\n for ( i = 0; i < handlerQueue.length && !event.isPropagationStopped(); i++ ) {\n matched = handlerQueue[ i ];\n event.currentTarget = matched.elem;\n\n for ( j = 0; j < matched.matches.length && !event.isImmediatePropagationStopped(); j++ ) {\n handleObj = matched.matches[ j ];\n\n // Triggered event must either 1) be non-exclusive and have no namespace, or\n // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace).\n if ( run_all || (!event.namespace && !handleObj.namespace) || event.namespace_re && event.namespace_re.test( handleObj.namespace ) ) {\n\n event.data = handleObj.data;\n event.handleObj = handleObj;\n\n ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler )\n .apply( matched.elem, args );\n\n if ( ret !== undefined ) {\n event.result = ret;\n if ( ret === false ) {\n event.preventDefault();\n event.stopPropagation();\n }\n }\n }\n }\n }\n\n // Call the postDispatch hook for the mapped type\n if ( special.postDispatch ) {\n special.postDispatch.call( this, event );\n }\n\n return event.result;\n },\n\n // Includes some event props shared by KeyEvent and MouseEvent\n // *** attrChange attrName relatedNode srcElement are not normalized, non-W3C, deprecated, will be removed in 1.8 ***\n props: \"attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which\".split(\" \"),\n\n fixHooks: {},\n\n keyHooks: {\n props: \"char charCode key keyCode\".split(\" \"),\n filter: function( event, original ) {\n\n // Add which for key events\n if ( event.which == null ) {\n event.which = original.charCode != null ? original.charCode : original.keyCode;\n }\n\n return event;\n }\n },\n\n mouseHooks: {\n props: \"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement\".split(\" \"),\n filter: function( event, original ) {\n var eventDoc, doc, body,\n button = original.button,\n fromElement = original.fromElement;\n\n // Calculate pageX/Y if missing and clientX/Y available\n if ( event.pageX == null && original.clientX != null ) {\n eventDoc = event.target.ownerDocument || document;\n doc = eventDoc.documentElement;\n body = eventDoc.body;\n\n event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 );\n event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 );\n }\n\n // Add relatedTarget, if necessary\n if ( !event.relatedTarget && fromElement ) {\n event.relatedTarget = fromElement === event.target ? original.toElement : fromElement;\n }\n\n // Add which for click: 1 === left; 2 === middle; 3 === right\n // Note: button is not normalized, so don't use it\n if ( !event.which && button !== undefined ) {\n event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );\n }\n\n return event;\n }\n },\n\n fix: function( event ) {\n if ( event[ jQuery.expando ] ) {\n return event;\n }\n\n // Create a writable copy of the event object and normalize some properties\n var i, prop,\n originalEvent = event,\n fixHook = jQuery.event.fixHooks[ event.type ] || {},\n copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;\n\n event = jQuery.Event( originalEvent );\n\n for ( i = copy.length; i; ) {\n prop = copy[ --i ];\n event[ prop ] = originalEvent[ prop ];\n }\n\n // Fix target property, if necessary (#1925, IE 6/7/8 & Safari2)\n if ( !event.target ) {\n event.target = originalEvent.srcElement || document;\n }\n\n // Target should not be a text node (#504, Safari)\n if ( event.target.nodeType === 3 ) {\n event.target = event.target.parentNode;\n }\n\n // For mouse/key events, metaKey==false if it's undefined (#3368, #11328; IE6/7/8)\n event.metaKey = !!event.metaKey;\n\n return fixHook.filter? fixHook.filter( event, originalEvent ) : event;\n },\n\n special: {\n load: {\n // Prevent triggered image.load events from bubbling to window.load\n noBubble: true\n },\n\n focus: {\n delegateType: \"focusin\"\n },\n blur: {\n delegateType: \"focusout\"\n },\n\n beforeunload: {\n setup: function( data, namespaces, eventHandle ) {\n // We only want to do this special case on windows\n if ( jQuery.isWindow( this ) ) {\n this.onbeforeunload = eventHandle;\n }\n },\n\n teardown: function( namespaces, eventHandle ) {\n if ( this.onbeforeunload === eventHandle ) {\n this.onbeforeunload = null;\n }\n }\n }\n },\n\n simulate: function( type, elem, event, bubble ) {\n // Piggyback on a donor event to simulate a different one.\n // Fake originalEvent to avoid donor's stopPropagation, but if the\n // simulated event prevents default then we do the same on the donor.\n var e = jQuery.extend(\n new jQuery.Event(),\n event,\n { type: type,\n isSimulated: true,\n originalEvent: {}\n }\n );\n if ( bubble ) {\n jQuery.event.trigger( e, null, elem );\n } else {\n jQuery.event.dispatch.call( elem, e );\n }\n if ( e.isDefaultPrevented() ) {\n event.preventDefault();\n }\n }\n};\n\n// Some plugins are using, but it's undocumented/deprecated and will be removed.\n// The 1.7 special event interface should provide all the hooks needed now.\njQuery.event.handle = jQuery.event.dispatch;\n\njQuery.removeEvent = document.removeEventListener ?\n function( elem, type, handle ) {\n if ( elem.removeEventListener ) {\n elem.removeEventListener( type, handle, false );\n }\n } :\n function( elem, type, handle ) {\n var name = \"on\" + type;\n\n if ( elem.detachEvent ) {\n\n // #8545, #7054, preventing memory leaks for custom events in IE6-8\n // detachEvent needed property on element, by name of that event, to properly expose it to GC\n if ( typeof elem[ name ] === \"undefined\" ) {\n elem[ name ] = null;\n }\n\n elem.detachEvent( name, handle );\n }\n };\n\njQuery.Event = function( src, props ) {\n // Allow instantiation without the 'new' keyword\n if ( !(this instanceof jQuery.Event) ) {\n return new jQuery.Event( src, props );\n }\n\n // Event object\n if ( src && src.type ) {\n this.originalEvent = src;\n this.type = src.type;\n\n // Events bubbling up the document may have been marked as prevented\n // by a handler lower down the tree; reflect the correct value.\n this.isDefaultPrevented = ( src.defaultPrevented || src.returnValue === false ||\n src.getPreventDefault && src.getPreventDefault() ) ? returnTrue : returnFalse;\n\n // Event type\n } else {\n this.type = src;\n }\n\n // Put explicitly provided properties onto the event object\n if ( props ) {\n jQuery.extend( this, props );\n }\n\n // Create a timestamp if incoming event doesn't have one\n this.timeStamp = src && src.timeStamp || jQuery.now();\n\n // Mark it as fixed\n this[ jQuery.expando ] = true;\n};\n\nfunction returnFalse() {\n return false;\n}\nfunction returnTrue() {\n return true;\n}\n\n// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding\n// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html\njQuery.Event.prototype = {\n preventDefault: function() {\n this.isDefaultPrevented = returnTrue;\n\n var e = this.originalEvent;\n if ( !e ) {\n return;\n }\n\n // if preventDefault exists run it on the original event\n if ( e.preventDefault ) {\n e.preventDefault();\n\n // otherwise set the returnValue property of the original event to false (IE)\n } else {\n e.returnValue = false;\n }\n },\n stopPropagation: function() {\n this.isPropagationStopped = returnTrue;\n\n var e = this.originalEvent;\n if ( !e ) {\n return;\n }\n // if stopPropagation exists run it on the original event\n if ( e.stopPropagation ) {\n e.stopPropagation();\n }\n // otherwise set the cancelBubble property of the original event to true (IE)\n e.cancelBubble = true;\n },\n stopImmediatePropagation: function() {\n this.isImmediatePropagationStopped = returnTrue;\n this.stopPropagation();\n },\n isDefaultPrevented: returnFalse,\n isPropagationStopped: returnFalse,\n isImmediatePropagationStopped: returnFalse\n};\n\n// Create mouseenter/leave events using mouseover/out and event-time checks\njQuery.each({\n mouseenter: \"mouseover\",\n mouseleave: \"mouseout\"\n}, function( orig, fix ) {\n jQuery.event.special[ orig ] = {\n delegateType: fix,\n bindType: fix,\n\n handle: function( event ) {\n var ret,\n target = this,\n related = event.relatedTarget,\n handleObj = event.handleObj,\n selector = handleObj.selector;\n\n // For mousenter/leave call the handler if related is outside the target.\n // NB: No relatedTarget if the mouse left/entered the browser window\n if ( !related || (related !== target && !jQuery.contains( target, related )) ) {\n event.type = handleObj.origType;\n ret = handleObj.handler.apply( this, arguments );\n event.type = fix;\n }\n return ret;\n }\n };\n});\n\n// IE submit delegation\nif ( !jQuery.support.submitBubbles ) {\n\n jQuery.event.special.submit = {\n setup: function() {\n // Only need this for delegated form submit events\n if ( jQuery.nodeName( this, \"form\" ) ) {\n return false;\n }\n\n // Lazy-add a submit handler when a descendant form may potentially be submitted\n jQuery.event.add( this, \"click._submit keypress._submit\", function( e ) {\n // Node name check avoids a VML-related crash in IE (#9807)\n var elem = e.target,\n form = jQuery.nodeName( elem, \"input\" ) || jQuery.nodeName( elem, \"button\" ) ? elem.form : undefined;\n if ( form && !jQuery._data( form, \"_submit_attached\" ) ) {\n jQuery.event.add( form, \"submit._submit\", function( event ) {\n event._submit_bubble = true;\n });\n jQuery._data( form, \"_submit_attached\", true );\n }\n });\n // return undefined since we don't need an event listener\n },\n\n postDispatch: function( event ) {\n // If form was submitted by the user, bubble the event up the tree\n if ( event._submit_bubble ) {\n delete event._submit_bubble;\n if ( this.parentNode && !event.isTrigger ) {\n jQuery.event.simulate( \"submit\", this.parentNode, event, true );\n }\n }\n },\n\n teardown: function() {\n // Only need this for delegated form submit events\n if ( jQuery.nodeName( this, \"form\" ) ) {\n return false;\n }\n\n // Remove delegated handlers; cleanData eventually reaps submit handlers attached above\n jQuery.event.remove( this, \"._submit\" );\n }\n };\n}\n\n// IE change delegation and checkbox/radio fix\nif ( !jQuery.support.changeBubbles ) {\n\n jQuery.event.special.change = {\n\n setup: function() {\n\n if ( rformElems.test( this.nodeName ) ) {\n // IE doesn't fire change on a check/radio until blur; trigger it on click\n // after a propertychange. Eat the blur-change in special.change.handle.\n // This still fires onchange a second time for check/radio after blur.\n if ( this.type === \"checkbox\" || this.type === \"radio\" ) {\n jQuery.event.add( this, \"propertychange._change\", function( event ) {\n if ( event.originalEvent.propertyName === \"checked\" ) {\n this._just_changed = true;\n }\n });\n jQuery.event.add( this, \"click._change\", function( event ) {\n if ( this._just_changed && !event.isTrigger ) {\n this._just_changed = false;\n }\n // Allow triggered, simulated change events (#11500)\n jQuery.event.simulate( \"change\", this, event, true );\n });\n }\n return false;\n }\n // Delegated event; lazy-add a change handler on descendant inputs\n jQuery.event.add( this, \"beforeactivate._change\", function( e ) {\n var elem = e.target;\n\n if ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, \"_change_attached\" ) ) {\n jQuery.event.add( elem, \"change._change\", function( event ) {\n if ( this.parentNode && !event.isSimulated && !event.isTrigger ) {\n jQuery.event.simulate( \"change\", this.parentNode, event, true );\n }\n });\n jQuery._data( elem, \"_change_attached\", true );\n }\n });\n },\n\n handle: function( event ) {\n var elem = event.target;\n\n // Swallow native change events from checkbox/radio, we already triggered them above\n if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== \"radio\" && elem.type !== \"checkbox\") ) {\n return event.handleObj.handler.apply( this, arguments );\n }\n },\n\n teardown: function() {\n jQuery.event.remove( this, \"._change\" );\n\n return !rformElems.test( this.nodeName );\n }\n };\n}\n\n// Create \"bubbling\" focus and blur events\nif ( !jQuery.support.focusinBubbles ) {\n jQuery.each({ focus: \"focusin\", blur: \"focusout\" }, function( orig, fix ) {\n\n // Attach a single capturing handler while someone wants focusin/focusout\n var attaches = 0,\n handler = function( event ) {\n jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true );\n };\n\n jQuery.event.special[ fix ] = {\n setup: function() {\n if ( attaches++ === 0 ) {\n document.addEventListener( orig, handler, true );\n }\n },\n teardown: function() {\n if ( --attaches === 0 ) {\n document.removeEventListener( orig, handler, true );\n }\n }\n };\n });\n}\n\njQuery.fn.extend({\n\n on: function( types, selector, data, fn, /*INTERNAL*/ one ) {\n var origFn, type;\n\n // Types can be a map of types/handlers\n if ( typeof types === \"object\" ) {\n // ( types-Object, selector, data )\n if ( typeof selector !== \"string\" ) { // && selector != null\n // ( types-Object, data )\n data = data || selector;\n selector = undefined;\n }\n for ( type in types ) {\n this.on( type, selector, data, types[ type ], one );\n }\n return this;\n }\n\n if ( data == null && fn == null ) {\n // ( types, fn )\n fn = selector;\n data = selector = undefined;\n } else if ( fn == null ) {\n if ( typeof selector === \"string\" ) {\n // ( types, selector, fn )\n fn = data;\n data = undefined;\n } else {\n // ( types, data, fn )\n fn = data;\n data = selector;\n selector = undefined;\n }\n }\n if ( fn === false ) {\n fn = returnFalse;\n } else if ( !fn ) {\n return this;\n }\n\n if ( one === 1 ) {\n origFn = fn;\n fn = function( event ) {\n // Can use an empty set, since event contains the info\n jQuery().off( event );\n return origFn.apply( this, arguments );\n };\n // Use same guid so caller can remove using origFn\n fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );\n }\n return this.each( function() {\n jQuery.event.add( this, types, fn, data, selector );\n });\n },\n one: function( types, selector, data, fn ) {\n return this.on( types, selector, data, fn, 1 );\n },\n off: function( types, selector, fn ) {\n var handleObj, type;\n if ( types && types.preventDefault && types.handleObj ) {\n // ( event ) dispatched jQuery.Event\n handleObj = types.handleObj;\n jQuery( types.delegateTarget ).off(\n handleObj.namespace ? handleObj.origType + \".\" + handleObj.namespace : handleObj.origType,\n handleObj.selector,\n handleObj.handler\n );\n return this;\n }\n if ( typeof types === \"object\" ) {\n // ( types-object [, selector] )\n for ( type in types ) {\n this.off( type, selector, types[ type ] );\n }\n return this;\n }\n if ( selector === false || typeof selector === \"function\" ) {\n // ( types [, fn] )\n fn = selector;\n selector = undefined;\n }\n if ( fn === false ) {\n fn = returnFalse;\n }\n return this.each(function() {\n jQuery.event.remove( this, types, fn, selector );\n });\n },\n\n bind: function( types, data, fn ) {\n return this.on( types, null, data, fn );\n },\n unbind: function( types, fn ) {\n return this.off( types, null, fn );\n },\n\n live: function( types, data, fn ) {\n jQuery( this.context ).on( types, this.selector, data, fn );\n return this;\n },\n die: function( types, fn ) {\n jQuery( this.context ).off( types, this.selector || \"**\", fn );\n return this;\n },\n\n delegate: function( selector, types, data, fn ) {\n return this.on( types, selector, data, fn );\n },\n undelegate: function( selector, types, fn ) {\n // ( namespace ) or ( selector, types [, fn] )\n return arguments.length === 1 ? this.off( selector, \"**\" ) : this.off( types, selector || \"**\", fn );\n },\n\n trigger: function( type, data ) {\n return this.each(function() {\n jQuery.event.trigger( type, data, this );\n });\n },\n triggerHandler: function( type, data ) {\n if ( this[0] ) {\n return jQuery.event.trigger( type, data, this[0], true );\n }\n },\n\n toggle: function( fn ) {\n // Save reference to arguments for access in closure\n var args = arguments,\n guid = fn.guid || jQuery.guid++,\n i = 0,\n toggler = function( event ) {\n // Figure out which function to execute\n var lastToggle = ( jQuery._data( this, \"lastToggle\" + fn.guid ) || 0 ) % i;\n jQuery._data( this, \"lastToggle\" + fn.guid, lastToggle + 1 );\n\n // Make sure that clicks stop\n event.preventDefault();\n\n // and execute the function\n return args[ lastToggle ].apply( this, arguments ) || false;\n };\n\n // link all the functions, so any of them can unbind this click handler\n toggler.guid = guid;\n while ( i < args.length ) {\n args[ i++ ].guid = guid;\n }\n\n return this.click( toggler );\n },\n\n hover: function( fnOver, fnOut ) {\n return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );\n }\n});\n\njQuery.each( (\"blur focus focusin focusout load resize scroll unload click dblclick \" +\n \"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave \" +\n \"change select submit keydown keypress keyup error contextmenu\").split(\" \"), function( i, name ) {\n\n // Handle event binding\n jQuery.fn[ name ] = function( data, fn ) {\n if ( fn == null ) {\n fn = data;\n data = null;\n }\n\n return arguments.length > 0 ?\n this.on( name, null, data, fn ) :\n this.trigger( name );\n };\n\n if ( rkeyEvent.test( name ) ) {\n jQuery.event.fixHooks[ name ] = jQuery.event.keyHooks;\n }\n\n if ( rmouseEvent.test( name ) ) {\n jQuery.event.fixHooks[ name ] = jQuery.event.mouseHooks;\n }\n});\n/*!\n * Sizzle CSS Selector Engine\n * Copyright 2012 jQuery Foundation and other contributors\n * Released under the MIT license\n * http://sizzlejs.com/\n */\n(function( window, undefined ) {\n\nvar cachedruns,\n assertGetIdNotName,\n Expr,\n getText,\n isXML,\n contains,\n compile,\n sortOrder,\n hasDuplicate,\n outermostContext,\n\n baseHasDuplicate = true,\n strundefined = \"undefined\",\n\n expando = ( \"sizcache\" + Math.random() ).replace( \".\", \"\" ),\n\n Token = String,\n document = window.document,\n docElem = document.documentElement,\n dirruns = 0,\n done = 0,\n pop = [].pop,\n push = [].push,\n slice = [].slice,\n // Use a stripped-down indexOf if a native one is unavailable\n indexOf = [].indexOf || function( elem ) {\n var i = 0,\n len = this.length;\n for ( ; i < len; i++ ) {\n if ( this[i] === elem ) {\n return i;\n }\n }\n return -1;\n },\n\n // Augment a function for special use by Sizzle\n markFunction = function( fn, value ) {\n fn[ expando ] = value == null || value;\n return fn;\n },\n\n createCache = function() {\n var cache = {},\n keys = [];\n\n return markFunction(function( key, value ) {\n // Only keep the most recent entries\n if ( keys.push( key ) > Expr.cacheLength ) {\n delete cache[ keys.shift() ];\n }\n\n // Retrieve with (key + \" \") to avoid collision with native Object.prototype properties (see Issue #157)\n return (cache[ key + \" \" ] = value);\n }, cache );\n },\n\n classCache = createCache(),\n tokenCache = createCache(),\n compilerCache = createCache(),\n\n // Regex\n\n // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace\n whitespace = \"[\\\\x20\\\\t\\\\r\\\\n\\\\f]\",\n // http://www.w3.org/TR/css3-syntax/#characters\n characterEncoding = \"(?:\\\\\\\\.|[-\\\\w]|[^\\\\x00-\\\\xa0])+\",\n\n // Loosely modeled on CSS identifier characters\n // An unquoted value should be a CSS identifier (http://www.w3.org/TR/css3-selectors/#attribute-selectors)\n // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier\n identifier = characterEncoding.replace( \"w\", \"w#\" ),\n\n // Acceptable operators http://www.w3.org/TR/selectors/#attribute-selectors\n operators = \"([*^$|!~]?=)\",\n attributes = \"\\\\[\" + whitespace + \"*(\" + characterEncoding + \")\" + whitespace +\n \"*(?:\" + operators + whitespace + \"*(?:(['\\\"])((?:\\\\\\\\.|[^\\\\\\\\])*?)\\\\3|(\" + identifier + \")|)|)\" + whitespace + \"*\\\\]\",\n\n // Prefer arguments not in parens/brackets,\n // then attribute selectors and non-pseudos (denoted by :),\n // then anything else\n // These preferences are here to reduce the number of selectors\n // needing tokenize in the PSEUDO preFilter\n pseudos = \":(\" + characterEncoding + \")(?:\\\\((?:(['\\\"])((?:\\\\\\\\.|[^\\\\\\\\])*?)\\\\2|([^()[\\\\]]*|(?:(?:\" + attributes + \")|[^:]|\\\\\\\\.)*|.*))\\\\)|)\",\n\n // For matchExpr.POS and matchExpr.needsContext\n pos = \":(even|odd|eq|gt|lt|nth|first|last)(?:\\\\(\" + whitespace +\n \"*((?:-\\\\d)?\\\\d*)\" + whitespace + \"*\\\\)|)(?=[^-]|$)\",\n\n // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter\n rtrim = new RegExp( \"^\" + whitespace + \"+|((?:^|[^\\\\\\\\])(?:\\\\\\\\.)*)\" + whitespace + \"+$\", \"g\" ),\n\n rcomma = new RegExp( \"^\" + whitespace + \"*,\" + whitespace + \"*\" ),\n rcombinators = new RegExp( \"^\" + whitespace + \"*([\\\\x20\\\\t\\\\r\\\\n\\\\f>+~])\" + whitespace + \"*\" ),\n rpseudo = new RegExp( pseudos ),\n\n // Easily-parseable/retrievable ID or TAG or CLASS selectors\n rquickExpr = /^(?:#([\\w\\-]+)|(\\w+)|\\.([\\w\\-]+))$/,\n\n rnot = /^:not/,\n rsibling = /[\\x20\\t\\r\\n\\f]*[+~]/,\n rendsWithNot = /:not\\($/,\n\n rheader = /h\\d/i,\n rinputs = /input|select|textarea|button/i,\n\n rbackslash = /\\\\(?!\\\\)/g,\n\n matchExpr = {\n \"ID\": new RegExp( \"^#(\" + characterEncoding + \")\" ),\n \"CLASS\": new RegExp( \"^\\\\.(\" + characterEncoding + \")\" ),\n \"NAME\": new RegExp( \"^\\\\[name=['\\\"]?(\" + characterEncoding + \")['\\\"]?\\\\]\" ),\n \"TAG\": new RegExp( \"^(\" + characterEncoding.replace( \"w\", \"w*\" ) + \")\" ),\n \"ATTR\": new RegExp( \"^\" + attributes ),\n \"PSEUDO\": new RegExp( \"^\" + pseudos ),\n \"POS\": new RegExp( pos, \"i\" ),\n \"CHILD\": new RegExp( \"^:(only|nth|first|last)-child(?:\\\\(\" + whitespace +\n \"*(even|odd|(([+-]|)(\\\\d*)n|)\" + whitespace + \"*(?:([+-]|)\" + whitespace +\n \"*(\\\\d+)|))\" + whitespace + \"*\\\\)|)\", \"i\" ),\n // For use in libraries implementing .is()\n \"needsContext\": new RegExp( \"^\" + whitespace + \"*[>+~]|\" + pos, \"i\" )\n },\n\n // Support\n\n // Used for testing something on an element\n assert = function( fn ) {\n var div = document.createElement(\"div\");\n\n try {\n return fn( div );\n } catch (e) {\n return false;\n } finally {\n // release memory in IE\n div = null;\n }\n },\n\n // Check if getElementsByTagName(\"*\") returns only elements\n assertTagNameNoComments = assert(function( div ) {\n div.appendChild( document.createComment(\"\") );\n return !div.getElementsByTagName(\"*\").length;\n }),\n\n // Check if getAttribute returns normalized href attributes\n assertHrefNotNormalized = assert(function( div ) {\n div.innerHTML = \"<a href='#'></a>\";\n return div.firstChild && typeof div.firstChild.getAttribute !== strundefined &&\n div.firstChild.getAttribute(\"href\") === \"#\";\n }),\n\n // Check if attributes should be retrieved by attribute nodes\n assertAttributes = assert(function( div ) {\n div.innerHTML = \"<select></select>\";\n var type = typeof div.lastChild.getAttribute(\"multiple\");\n // IE8 returns a string for some attributes even when not present\n return type !== \"boolean\" && type !== \"string\";\n }),\n\n // Check if getElementsByClassName can be trusted\n assertUsableClassName = assert(function( div ) {\n // Opera can't find a second classname (in 9.6)\n div.innerHTML = \"<div class='hidden e'></div><div class='hidden'></div>\";\n if ( !div.getElementsByClassName || !div.getElementsByClassName(\"e\").length ) {\n return false;\n }\n\n // Safari 3.2 caches class attributes and doesn't catch changes\n div.lastChild.className = \"e\";\n return div.getElementsByClassName(\"e\").length === 2;\n }),\n\n // Check if getElementById returns elements by name\n // Check if getElementsByName privileges form controls or returns elements by ID\n assertUsableName = assert(function( div ) {\n // Inject content\n div.id = expando + 0;\n div.innerHTML = \"<a name='\" + expando + \"'></a><div name='\" + expando + \"'></div>\";\n docElem.insertBefore( div, docElem.firstChild );\n\n // Test\n var pass = document.getElementsByName &&\n // buggy browsers will return fewer than the correct 2\n document.getElementsByName( expando ).length === 2 +\n // buggy browsers will return more than the correct 0\n document.getElementsByName( expando + 0 ).length;\n assertGetIdNotName = !document.getElementById( expando );\n\n // Cleanup\n docElem.removeChild( div );\n\n return pass;\n });\n\n// If slice is not available, provide a backup\ntry {\n slice.call( docElem.childNodes, 0 )[0].nodeType;\n} catch ( e ) {\n slice = function( i ) {\n var elem,\n results = [];\n for ( ; (elem = this[i]); i++ ) {\n results.push( elem );\n }\n return results;\n };\n}\n\nfunction Sizzle( selector, context, results, seed ) {\n results = results || [];\n context = context || document;\n var match, elem, xml, m,\n nodeType = context.nodeType;\n\n if ( !selector || typeof selector !== \"string\" ) {\n return results;\n }\n\n if ( nodeType !== 1 && nodeType !== 9 ) {\n return [];\n }\n\n xml = isXML( context );\n\n if ( !xml && !seed ) {\n if ( (match = rquickExpr.exec( selector )) ) {\n // Speed-up: Sizzle(\"#ID\")\n if ( (m = match[1]) ) {\n if ( nodeType === 9 ) {\n elem = context.getElementById( m );\n // Check parentNode to catch when Blackberry 4.6 returns\n // nodes that are no longer in the document #6963\n if ( elem && elem.parentNode ) {\n // Handle the case where IE, Opera, and Webkit return items\n // by name instead of ID\n if ( elem.id === m ) {\n results.push( elem );\n return results;\n }\n } else {\n return results;\n }\n } else {\n // Context is not a document\n if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) &&\n contains( context, elem ) && elem.id === m ) {\n results.push( elem );\n return results;\n }\n }\n\n // Speed-up: Sizzle(\"TAG\")\n } else if ( match[2] ) {\n push.apply( results, slice.call(context.getElementsByTagName( selector ), 0) );\n return results;\n\n // Speed-up: Sizzle(\".CLASS\")\n } else if ( (m = match[3]) && assertUsableClassName && context.getElementsByClassName ) {\n push.apply( results, slice.call(context.getElementsByClassName( m ), 0) );\n return results;\n }\n }\n }\n\n // All others\n return select( selector.replace( rtrim, \"$1\" ), context, results, seed, xml );\n}\n\nSizzle.matches = function( expr, elements ) {\n return Sizzle( expr, null, null, elements );\n};\n\nSizzle.matchesSelector = function( elem, expr ) {\n return Sizzle( expr, null, null, [ elem ] ).length > 0;\n};\n\n// Returns a function to use in pseudos for input types\nfunction createInputPseudo( type ) {\n return function( elem ) {\n var name = elem.nodeName.toLowerCase();\n return name === \"input\" && elem.type === type;\n };\n}\n\n// Returns a function to use in pseudos for buttons\nfunction createButtonPseudo( type ) {\n return function( elem ) {\n var name = elem.nodeName.toLowerCase();\n return (name === \"input\" || name === \"button\") && elem.type === type;\n };\n}\n\n// Returns a function to use in pseudos for positionals\nfunction createPositionalPseudo( fn ) {\n return markFunction(function( argument ) {\n argument = +argument;\n return markFunction(function( seed, matches ) {\n var j,\n matchIndexes = fn( [], seed.length, argument ),\n i = matchIndexes.length;\n\n // Match elements found at the specified indexes\n while ( i-- ) {\n if ( seed[ (j = matchIndexes[i]) ] ) {\n seed[j] = !(matches[j] = seed[j]);\n }\n }\n });\n });\n}\n\n/**\n * Utility function for retrieving the text value of an array of DOM nodes\n * @param {Array|Element} elem\n */\ngetText = Sizzle.getText = function( elem ) {\n var node,\n ret = \"\",\n i = 0,\n nodeType = elem.nodeType;\n\n if ( nodeType ) {\n if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {\n // Use textContent for elements\n // innerText usage removed for consistency of new lines (see #11153)\n if ( typeof elem.textContent === \"string\" ) {\n return elem.textContent;\n } else {\n // Traverse its children\n for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {\n ret += getText( elem );\n }\n }\n } else if ( nodeType === 3 || nodeType === 4 ) {\n return elem.nodeValue;\n }\n // Do not include comment or processing instruction nodes\n } else {\n\n // If no nodeType, this is expected to be an array\n for ( ; (node = elem[i]); i++ ) {\n // Do not traverse comment nodes\n ret += getText( node );\n }\n }\n return ret;\n};\n\nisXML = Sizzle.isXML = function( elem ) {\n // documentElement is verified for cases where it doesn't yet exist\n // (such as loading iframes in IE - #4833)\n var documentElement = elem && (elem.ownerDocument || elem).documentElement;\n return documentElement ? documentElement.nodeName !== \"HTML\" : false;\n};\n\n// Element contains another\ncontains = Sizzle.contains = docElem.contains ?\n function( a, b ) {\n var adown = a.nodeType === 9 ? a.documentElement : a,\n bup = b && b.parentNode;\n return a === bup || !!( bup && bup.nodeType === 1 && adown.contains && adown.contains(bup) );\n } :\n docElem.compareDocumentPosition ?\n function( a, b ) {\n return b && !!( a.compareDocumentPosition( b ) & 16 );\n } :\n function( a, b ) {\n while ( (b = b.parentNode) ) {\n if ( b === a ) {\n return true;\n }\n }\n return false;\n };\n\nSizzle.attr = function( elem, name ) {\n var val,\n xml = isXML( elem );\n\n if ( !xml ) {\n name = name.toLowerCase();\n }\n if ( (val = Expr.attrHandle[ name ]) ) {\n return val( elem );\n }\n if ( xml || assertAttributes ) {\n return elem.getAttribute( name );\n }\n val = elem.getAttributeNode( name );\n return val ?\n typeof elem[ name ] === \"boolean\" ?\n elem[ name ] ? name : null :\n val.specified ? val.value : null :\n null;\n};\n\nExpr = Sizzle.selectors = {\n\n // Can be adjusted by the user\n cacheLength: 50,\n\n createPseudo: markFunction,\n\n match: matchExpr,\n\n // IE6/7 return a modified href\n attrHandle: assertHrefNotNormalized ?\n {} :\n {\n \"href\": function( elem ) {\n return elem.getAttribute( \"href\", 2 );\n },\n \"type\": function( elem ) {\n return elem.getAttribute(\"type\");\n }\n },\n\n find: {\n \"ID\": assertGetIdNotName ?\n function( id, context, xml ) {\n if ( typeof context.getElementById !== strundefined && !xml ) {\n var m = context.getElementById( id );\n // Check parentNode to catch when Blackberry 4.6 returns\n // nodes that are no longer in the document #6963\n return m && m.parentNode ? [m] : [];\n }\n } :\n function( id, context, xml ) {\n if ( typeof context.getElementById !== strundefined && !xml ) {\n var m = context.getElementById( id );\n\n return m ?\n m.id === id || typeof m.getAttributeNode !== strundefined && m.getAttributeNode(\"id\").value === id ?\n [m] :\n undefined :\n [];\n }\n },\n\n \"TAG\": assertTagNameNoComments ?\n function( tag, context ) {\n if ( typeof context.getElementsByTagName !== strundefined ) {\n return context.getElementsByTagName( tag );\n }\n } :\n function( tag, context ) {\n var results = context.getElementsByTagName( tag );\n\n // Filter out possible comments\n if ( tag === \"*\" ) {\n var elem,\n tmp = [],\n i = 0;\n\n for ( ; (elem = results[i]); i++ ) {\n if ( elem.nodeType === 1 ) {\n tmp.push( elem );\n }\n }\n\n return tmp;\n }\n return results;\n },\n\n \"NAME\": assertUsableName && function( tag, context ) {\n if ( typeof context.getElementsByName !== strundefined ) {\n return context.getElementsByName( name );\n }\n },\n\n \"CLASS\": assertUsableClassName && function( className, context, xml ) {\n if ( typeof context.getElementsByClassName !== strundefined && !xml ) {\n return context.getElementsByClassName( className );\n }\n }\n },\n\n relative: {\n \">\": { dir: \"parentNode\", first: true },\n \" \": { dir: \"parentNode\" },\n \"+\": { dir: \"previousSibling\", first: true },\n \"~\": { dir: \"previousSibling\" }\n },\n\n preFilter: {\n \"ATTR\": function( match ) {\n match[1] = match[1].replace( rbackslash, \"\" );\n\n // Move the given value to match[3] whether quoted or unquoted\n match[3] = ( match[4] || match[5] || \"\" ).replace( rbackslash, \"\" );\n\n if ( match[2] === \"~=\" ) {\n match[3] = \" \" + match[3] + \" \";\n }\n\n return match.slice( 0, 4 );\n },\n\n \"CHILD\": function( match ) {\n /* matches from matchExpr[\"CHILD\"]\n 1 type (only|nth|...)\n 2 argument (even|odd|\\d*|\\d*n([+-]\\d+)?|...)\n 3 xn-component of xn+y argument ([+-]?\\d*n|)\n 4 sign of xn-component\n 5 x of xn-component\n 6 sign of y-component\n 7 y of y-component\n */\n match[1] = match[1].toLowerCase();\n\n if ( match[1] === \"nth\" ) {\n // nth-child requires argument\n if ( !match[2] ) {\n Sizzle.error( match[0] );\n }\n\n // numeric x and y parameters for Expr.filter.CHILD\n // remember that false/true cast respectively to 0/1\n match[3] = +( match[3] ? match[4] + (match[5] || 1) : 2 * ( match[2] === \"even\" || match[2] === \"odd\" ) );\n match[4] = +( ( match[6] + match[7] ) || match[2] === \"odd\" );\n\n // other types prohibit arguments\n } else if ( match[2] ) {\n Sizzle.error( match[0] );\n }\n\n return match;\n },\n\n \"PSEUDO\": function( match ) {\n var unquoted, excess;\n if ( matchExpr[\"CHILD\"].test( match[0] ) ) {\n return null;\n }\n\n if ( match[3] ) {\n match[2] = match[3];\n } else if ( (unquoted = match[4]) ) {\n // Only check arguments that contain a pseudo\n if ( rpseudo.test(unquoted) &&\n // Get excess from tokenize (recursively)\n (excess = tokenize( unquoted, true )) &&\n // advance to the next closing parenthesis\n (excess = unquoted.indexOf( \")\", unquoted.length - excess ) - unquoted.length) ) {\n\n // excess is a negative index\n unquoted = unquoted.slice( 0, excess );\n match[0] = match[0].slice( 0, excess );\n }\n match[2] = unquoted;\n }\n\n // Return only captures needed by the pseudo filter method (type and argument)\n return match.slice( 0, 3 );\n }\n },\n\n filter: {\n \"ID\": assertGetIdNotName ?\n function( id ) {\n id = id.replace( rbackslash, \"\" );\n return function( elem ) {\n return elem.getAttribute(\"id\") === id;\n };\n } :\n function( id ) {\n id = id.replace( rbackslash, \"\" );\n return function( elem ) {\n var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode(\"id\");\n return node && node.value === id;\n };\n },\n\n \"TAG\": function( nodeName ) {\n if ( nodeName === \"*\" ) {\n return function() { return true; };\n }\n nodeName = nodeName.replace( rbackslash, \"\" ).toLowerCase();\n\n return function( elem ) {\n return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;\n };\n },\n\n \"CLASS\": function( className ) {\n var pattern = classCache[ expando ][ className + \" \" ];\n\n return pattern ||\n (pattern = new RegExp( \"(^|\" + whitespace + \")\" + className + \"(\" + whitespace + \"|$)\" )) &&\n classCache( className, function( elem ) {\n return pattern.test( elem.className || (typeof elem.getAttribute !== strundefined && elem.getAttribute(\"class\")) || \"\" );\n });\n },\n\n \"ATTR\": function( name, operator, check ) {\n return function( elem, context ) {\n var result = Sizzle.attr( elem, name );\n\n if ( result == null ) {\n return operator === \"!=\";\n }\n if ( !operator ) {\n return true;\n }\n\n result += \"\";\n\n return operator === \"=\" ? result === check :\n operator === \"!=\" ? result !== check :\n operator === \"^=\" ? check && result.indexOf( check ) === 0 :\n operator === \"*=\" ? check && result.indexOf( check ) > -1 :\n operator === \"$=\" ? check && result.substr( result.length - check.length ) === check :\n operator === \"~=\" ? ( \" \" + result + \" \" ).indexOf( check ) > -1 :\n operator === \"|=\" ? result === check || result.substr( 0, check.length + 1 ) === check + \"-\" :\n false;\n };\n },\n\n \"CHILD\": function( type, argument, first, last ) {\n\n if ( type === \"nth\" ) {\n return function( elem ) {\n var node, diff,\n parent = elem.parentNode;\n\n if ( first === 1 && last === 0 ) {\n return true;\n }\n\n if ( parent ) {\n diff = 0;\n for ( node = parent.firstChild; node; node = node.nextSibling ) {\n if ( node.nodeType === 1 ) {\n diff++;\n if ( elem === node ) {\n break;\n }\n }\n }\n }\n\n // Incorporate the offset (or cast to NaN), then check against cycle size\n diff -= last;\n return diff === first || ( diff % first === 0 && diff / first >= 0 );\n };\n }\n\n return function( elem ) {\n var node = elem;\n\n switch ( type ) {\n case \"only\":\n case \"first\":\n while ( (node = node.previousSibling) ) {\n if ( node.nodeType === 1 ) {\n return false;\n }\n }\n\n if ( type === \"first\" ) {\n return true;\n }\n\n node = elem;\n\n /* falls through */\n case \"last\":\n while ( (node = node.nextSibling) ) {\n if ( node.nodeType === 1 ) {\n return false;\n }\n }\n\n return true;\n }\n };\n },\n\n \"PSEUDO\": function( pseudo, argument ) {\n // pseudo-class names are case-insensitive\n // http://www.w3.org/TR/selectors/#pseudo-classes\n // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters\n // Remember that setFilters inherits from pseudos\n var args,\n fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||\n Sizzle.error( \"unsupported pseudo: \" + pseudo );\n\n // The user may use createPseudo to indicate that\n // arguments are needed to create the filter function\n // just as Sizzle does\n if ( fn[ expando ] ) {\n return fn( argument );\n }\n\n // But maintain support for old signatures\n if ( fn.length > 1 ) {\n args = [ pseudo, pseudo, \"\", argument ];\n return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?\n markFunction(function( seed, matches ) {\n var idx,\n matched = fn( seed, argument ),\n i = matched.length;\n while ( i-- ) {\n idx = indexOf.call( seed, matched[i] );\n seed[ idx ] = !( matches[ idx ] = matched[i] );\n }\n }) :\n function( elem ) {\n return fn( elem, 0, args );\n };\n }\n\n return fn;\n }\n },\n\n pseudos: {\n \"not\": markFunction(function( selector ) {\n // Trim the selector passed to compile\n // to avoid treating leading and trailing\n // spaces as combinators\n var input = [],\n results = [],\n matcher = compile( selector.replace( rtrim, \"$1\" ) );\n\n return matcher[ expando ] ?\n markFunction(function( seed, matches, context, xml ) {\n var elem,\n unmatched = matcher( seed, null, xml, [] ),\n i = seed.length;\n\n // Match elements unmatched by `matcher`\n while ( i-- ) {\n if ( (elem = unmatched[i]) ) {\n seed[i] = !(matches[i] = elem);\n }\n }\n }) :\n function( elem, context, xml ) {\n input[0] = elem;\n matcher( input, null, xml, results );\n return !results.pop();\n };\n }),\n\n \"has\": markFunction(function( selector ) {\n return function( elem ) {\n return Sizzle( selector, elem ).length > 0;\n };\n }),\n\n \"contains\": markFunction(function( text ) {\n return function( elem ) {\n return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;\n };\n }),\n\n \"enabled\": function( elem ) {\n return elem.disabled === false;\n },\n\n \"disabled\": function( elem ) {\n return elem.disabled === true;\n },\n\n \"checked\": function( elem ) {\n // In CSS3, :checked should return both checked and selected elements\n // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked\n var nodeName = elem.nodeName.toLowerCase();\n return (nodeName === \"input\" && !!elem.checked) || (nodeName === \"option\" && !!elem.selected);\n },\n\n \"selected\": function( elem ) {\n // Accessing this property makes selected-by-default\n // options in Safari work properly\n if ( elem.parentNode ) {\n elem.parentNode.selectedIndex;\n }\n\n return elem.selected === true;\n },\n\n \"parent\": function( elem ) {\n return !Expr.pseudos[\"empty\"]( elem );\n },\n\n \"empty\": function( elem ) {\n // http://www.w3.org/TR/selectors/#empty-pseudo\n // :empty is only affected by element nodes and content nodes(including text(3), cdata(4)),\n // not comment, processing instructions, or others\n // Thanks to Diego Perini for the nodeName shortcut\n // Greater than \"@\" means alpha characters (specifically not starting with \"#\" or \"?\")\n var nodeType;\n elem = elem.firstChild;\n while ( elem ) {\n if ( elem.nodeName > \"@\" || (nodeType = elem.nodeType) === 3 || nodeType === 4 ) {\n return false;\n }\n elem = elem.nextSibling;\n }\n return true;\n },\n\n \"header\": function( elem ) {\n return rheader.test( elem.nodeName );\n },\n\n \"text\": function( elem ) {\n var type, attr;\n // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc)\n // use getAttribute instead to test this case\n return elem.nodeName.toLowerCase() === \"input\" &&\n (type = elem.type) === \"text\" &&\n ( (attr = elem.getAttribute(\"type\")) == null || attr.toLowerCase() === type );\n },\n\n // Input types\n \"radio\": createInputPseudo(\"radio\"),\n \"checkbox\": createInputPseudo(\"checkbox\"),\n \"file\": createInputPseudo(\"file\"),\n \"password\": createInputPseudo(\"password\"),\n \"image\": createInputPseudo(\"image\"),\n\n \"submit\": createButtonPseudo(\"submit\"),\n \"reset\": createButtonPseudo(\"reset\"),\n\n \"button\": function( elem ) {\n var name = elem.nodeName.toLowerCase();\n return name === \"input\" && elem.type === \"button\" || name === \"button\";\n },\n\n \"input\": function( elem ) {\n return rinputs.test( elem.nodeName );\n },\n\n \"focus\": function( elem ) {\n var doc = elem.ownerDocument;\n return elem === doc.activeElement && (!doc.hasFocus || doc.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);\n },\n\n \"active\": function( elem ) {\n return elem === elem.ownerDocument.activeElement;\n },\n\n // Positional types\n \"first\": createPositionalPseudo(function() {\n return [ 0 ];\n }),\n\n \"last\": createPositionalPseudo(function( matchIndexes, length ) {\n return [ length - 1 ];\n }),\n\n \"eq\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n return [ argument < 0 ? argument + length : argument ];\n }),\n\n \"even\": createPositionalPseudo(function( matchIndexes, length ) {\n for ( var i = 0; i < length; i += 2 ) {\n matchIndexes.push( i );\n }\n return matchIndexes;\n }),\n\n \"odd\": createPositionalPseudo(function( matchIndexes, length ) {\n for ( var i = 1; i < length; i += 2 ) {\n matchIndexes.push( i );\n }\n return matchIndexes;\n }),\n\n \"lt\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n for ( var i = argument < 0 ? argument + length : argument; --i >= 0; ) {\n matchIndexes.push( i );\n }\n return matchIndexes;\n }),\n\n \"gt\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n for ( var i = argument < 0 ? argument + length : argument; ++i < length; ) {\n matchIndexes.push( i );\n }\n return matchIndexes;\n })\n }\n};\n\nfunction siblingCheck( a, b, ret ) {\n if ( a === b ) {\n return ret;\n }\n\n var cur = a.nextSibling;\n\n while ( cur ) {\n if ( cur === b ) {\n return -1;\n }\n\n cur = cur.nextSibling;\n }\n\n return 1;\n}\n\nsortOrder = docElem.compareDocumentPosition ?\n function( a, b ) {\n if ( a === b ) {\n hasDuplicate = true;\n return 0;\n }\n\n return ( !a.compareDocumentPosition || !b.compareDocumentPosition ?\n a.compareDocumentPosition :\n a.compareDocumentPosition(b) & 4\n ) ? -1 : 1;\n } :\n function( a, b ) {\n // The nodes are identical, we can exit early\n if ( a === b ) {\n hasDuplicate = true;\n return 0;\n\n // Fallback to using sourceIndex (in IE) if it's available on both nodes\n } else if ( a.sourceIndex && b.sourceIndex ) {\n return a.sourceIndex - b.sourceIndex;\n }\n\n var al, bl,\n ap = [],\n bp = [],\n aup = a.parentNode,\n bup = b.parentNode,\n cur = aup;\n\n // If the nodes are siblings (or identical) we can do a quick check\n if ( aup === bup ) {\n return siblingCheck( a, b );\n\n // If no parents were found then the nodes are disconnected\n } else if ( !aup ) {\n return -1;\n\n } else if ( !bup ) {\n return 1;\n }\n\n // Otherwise they're somewhere else in the tree so we need\n // to build up a full list of the parentNodes for comparison\n while ( cur ) {\n ap.unshift( cur );\n cur = cur.parentNode;\n }\n\n cur = bup;\n\n while ( cur ) {\n bp.unshift( cur );\n cur = cur.parentNode;\n }\n\n al = ap.length;\n bl = bp.length;\n\n // Start walking down the tree looking for a discrepancy\n for ( var i = 0; i < al && i < bl; i++ ) {\n if ( ap[i] !== bp[i] ) {\n return siblingCheck( ap[i], bp[i] );\n }\n }\n\n // We ended someplace up the tree so do a sibling check\n return i === al ?\n siblingCheck( a, bp[i], -1 ) :\n siblingCheck( ap[i], b, 1 );\n };\n\n// Always assume the presence of duplicates if sort doesn't\n// pass them to our comparison function (as in Google Chrome).\n[0, 0].sort( sortOrder );\nbaseHasDuplicate = !hasDuplicate;\n\n// Document sorting and removing duplicates\nSizzle.uniqueSort = function( results ) {\n var elem,\n duplicates = [],\n i = 1,\n j = 0;\n\n hasDuplicate = baseHasDuplicate;\n results.sort( sortOrder );\n\n if ( hasDuplicate ) {\n for ( ; (elem = results[i]); i++ ) {\n if ( elem === results[ i - 1 ] ) {\n j = duplicates.push( i );\n }\n }\n while ( j-- ) {\n results.splice( duplicates[ j ], 1 );\n }\n }\n\n return results;\n};\n\nSizzle.error = function( msg ) {\n throw new Error( \"Syntax error, unrecognized expression: \" + msg );\n};\n\nfunction tokenize( selector, parseOnly ) {\n var matched, match, tokens, type,\n soFar, groups, preFilters,\n cached = tokenCache[ expando ][ selector + \" \" ];\n\n if ( cached ) {\n return parseOnly ? 0 : cached.slice( 0 );\n }\n\n soFar = selector;\n groups = [];\n preFilters = Expr.preFilter;\n\n while ( soFar ) {\n\n // Comma and first run\n if ( !matched || (match = rcomma.exec( soFar )) ) {\n if ( match ) {\n // Don't consume trailing commas as valid\n soFar = soFar.slice( match[0].length ) || soFar;\n }\n groups.push( tokens = [] );\n }\n\n matched = false;\n\n // Combinators\n if ( (match = rcombinators.exec( soFar )) ) {\n tokens.push( matched = new Token( match.shift() ) );\n soFar = soFar.slice( matched.length );\n\n // Cast descendant combinators to space\n matched.type = match[0].replace( rtrim, \" \" );\n }\n\n // Filters\n for ( type in Expr.filter ) {\n if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||\n (match = preFilters[ type ]( match ))) ) {\n\n tokens.push( matched = new Token( match.shift() ) );\n soFar = soFar.slice( matched.length );\n matched.type = type;\n matched.matches = match;\n }\n }\n\n if ( !matched ) {\n break;\n }\n }\n\n // Return the length of the invalid excess\n // if we're just parsing\n // Otherwise, throw an error or return tokens\n return parseOnly ?\n soFar.length :\n soFar ?\n Sizzle.error( selector ) :\n // Cache the tokens\n tokenCache( selector, groups ).slice( 0 );\n}\n\nfunction addCombinator( matcher, combinator, base ) {\n var dir = combinator.dir,\n checkNonElements = base && combinator.dir === \"parentNode\",\n doneName = done++;\n\n return combinator.first ?\n // Check against closest ancestor/preceding element\n function( elem, context, xml ) {\n while ( (elem = elem[ dir ]) ) {\n if ( checkNonElements || elem.nodeType === 1 ) {\n return matcher( elem, context, xml );\n }\n }\n } :\n\n // Check against all ancestor/preceding elements\n function( elem, context, xml ) {\n // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching\n if ( !xml ) {\n var cache,\n dirkey = dirruns + \" \" + doneName + \" \",\n cachedkey = dirkey + cachedruns;\n while ( (elem = elem[ dir ]) ) {\n if ( checkNonElements || elem.nodeType === 1 ) {\n if ( (cache = elem[ expando ]) === cachedkey ) {\n return elem.sizset;\n } else if ( typeof cache === \"string\" && cache.indexOf(dirkey) === 0 ) {\n if ( elem.sizset ) {\n return elem;\n }\n } else {\n elem[ expando ] = cachedkey;\n if ( matcher( elem, context, xml ) ) {\n elem.sizset = true;\n return elem;\n }\n elem.sizset = false;\n }\n }\n }\n } else {\n while ( (elem = elem[ dir ]) ) {\n if ( checkNonElements || elem.nodeType === 1 ) {\n if ( matcher( elem, context, xml ) ) {\n return elem;\n }\n }\n }\n }\n };\n}\n\nfunction elementMatcher( matchers ) {\n return matchers.length > 1 ?\n function( elem, context, xml ) {\n var i = matchers.length;\n while ( i-- ) {\n if ( !matchers[i]( elem, context, xml ) ) {\n return false;\n }\n }\n return true;\n } :\n matchers[0];\n}\n\nfunction condense( unmatched, map, filter, context, xml ) {\n var elem,\n newUnmatched = [],\n i = 0,\n len = unmatched.length,\n mapped = map != null;\n\n for ( ; i < len; i++ ) {\n if ( (elem = unmatched[i]) ) {\n if ( !filter || filter( elem, context, xml ) ) {\n newUnmatched.push( elem );\n if ( mapped ) {\n map.push( i );\n }\n }\n }\n }\n\n return newUnmatched;\n}\n\nfunction setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {\n if ( postFilter && !postFilter[ expando ] ) {\n postFilter = setMatcher( postFilter );\n }\n if ( postFinder && !postFinder[ expando ] ) {\n postFinder = setMatcher( postFinder, postSelector );\n }\n return markFunction(function( seed, results, context, xml ) {\n var temp, i, elem,\n preMap = [],\n postMap = [],\n preexisting = results.length,\n\n // Get initial elements from seed or context\n elems = seed || multipleContexts( selector || \"*\", context.nodeType ? [ context ] : context, [] ),\n\n // Prefilter to get matcher input, preserving a map for seed-results synchronization\n matcherIn = preFilter && ( seed || !selector ) ?\n condense( elems, preMap, preFilter, context, xml ) :\n elems,\n\n matcherOut = matcher ?\n // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,\n postFinder || ( seed ? preFilter : preexisting || postFilter ) ?\n\n // ...intermediate processing is necessary\n [] :\n\n // ...otherwise use results directly\n results :\n matcherIn;\n\n // Find primary matches\n if ( matcher ) {\n matcher( matcherIn, matcherOut, context, xml );\n }\n\n // Apply postFilter\n if ( postFilter ) {\n temp = condense( matcherOut, postMap );\n postFilter( temp, [], context, xml );\n\n // Un-match failing elements by moving them back to matcherIn\n i = temp.length;\n while ( i-- ) {\n if ( (elem = temp[i]) ) {\n matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);\n }\n }\n }\n\n if ( seed ) {\n if ( postFinder || preFilter ) {\n if ( postFinder ) {\n // Get the final matcherOut by condensing this intermediate into postFinder contexts\n temp = [];\n i = matcherOut.length;\n while ( i-- ) {\n if ( (elem = matcherOut[i]) ) {\n // Restore matcherIn since elem is not yet a final match\n temp.push( (matcherIn[i] = elem) );\n }\n }\n postFinder( null, (matcherOut = []), temp, xml );\n }\n\n // Move matched elements from seed to results to keep them synchronized\n i = matcherOut.length;\n while ( i-- ) {\n if ( (elem = matcherOut[i]) &&\n (temp = postFinder ? indexOf.call( seed, elem ) : preMap[i]) > -1 ) {\n\n seed[temp] = !(results[temp] = elem);\n }\n }\n }\n\n // Add elements to results, through postFinder if defined\n } else {\n matcherOut = condense(\n matcherOut === results ?\n matcherOut.splice( preexisting, matcherOut.length ) :\n matcherOut\n );\n if ( postFinder ) {\n postFinder( null, results, matcherOut, xml );\n } else {\n push.apply( results, matcherOut );\n }\n }\n });\n}\n\nfunction matcherFromTokens( tokens ) {\n var checkContext, matcher, j,\n len = tokens.length,\n leadingRelative = Expr.relative[ tokens[0].type ],\n implicitRelative = leadingRelative || Expr.relative[\" \"],\n i = leadingRelative ? 1 : 0,\n\n // The foundational matcher ensures that elements are reachable from top-level context(s)\n matchContext = addCombinator( function( elem ) {\n return elem === checkContext;\n }, implicitRelative, true ),\n matchAnyContext = addCombinator( function( elem ) {\n return indexOf.call( checkContext, elem ) > -1;\n }, implicitRelative, true ),\n matchers = [ function( elem, context, xml ) {\n return ( !leadingRelative && ( xml || context !== outermostContext ) ) || (\n (checkContext = context).nodeType ?\n matchContext( elem, context, xml ) :\n matchAnyContext( elem, context, xml ) );\n } ];\n\n for ( ; i < len; i++ ) {\n if ( (matcher = Expr.relative[ tokens[i].type ]) ) {\n matchers = [ addCombinator( elementMatcher( matchers ), matcher ) ];\n } else {\n matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );\n\n // Return special upon seeing a positional matcher\n if ( matcher[ expando ] ) {\n // Find the next relative operator (if any) for proper handling\n j = ++i;\n for ( ; j < len; j++ ) {\n if ( Expr.relative[ tokens[j].type ] ) {\n break;\n }\n }\n return setMatcher(\n i > 1 && elementMatcher( matchers ),\n i > 1 && tokens.slice( 0, i - 1 ).join(\"\").replace( rtrim, \"$1\" ),\n matcher,\n i < j && matcherFromTokens( tokens.slice( i, j ) ),\n j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),\n j < len && tokens.join(\"\")\n );\n }\n matchers.push( matcher );\n }\n }\n\n return elementMatcher( matchers );\n}\n\nfunction matcherFromGroupMatchers( elementMatchers, setMatchers ) {\n var bySet = setMatchers.length > 0,\n byElement = elementMatchers.length > 0,\n superMatcher = function( seed, context, xml, results, expandContext ) {\n var elem, j, matcher,\n setMatched = [],\n matchedCount = 0,\n i = \"0\",\n unmatched = seed && [],\n outermost = expandContext != null,\n contextBackup = outermostContext,\n // We must always have either seed elements or context\n elems = seed || byElement && Expr.find[\"TAG\"]( \"*\", expandContext && context.parentNode || context ),\n // Nested matchers should use non-integer dirruns\n dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.E);\n\n if ( outermost ) {\n outermostContext = context !== document && context;\n cachedruns = superMatcher.el;\n }\n\n // Add elements passing elementMatchers directly to results\n for ( ; (elem = elems[i]) != null; i++ ) {\n if ( byElement && elem ) {\n for ( j = 0; (matcher = elementMatchers[j]); j++ ) {\n if ( matcher( elem, context, xml ) ) {\n results.push( elem );\n break;\n }\n }\n if ( outermost ) {\n dirruns = dirrunsUnique;\n cachedruns = ++superMatcher.el;\n }\n }\n\n // Track unmatched elements for set filters\n if ( bySet ) {\n // They will have gone through all possible matchers\n if ( (elem = !matcher && elem) ) {\n matchedCount--;\n }\n\n // Lengthen the array for every element, matched or not\n if ( seed ) {\n unmatched.push( elem );\n }\n }\n }\n\n // Apply set filters to unmatched elements\n matchedCount += i;\n if ( bySet && i !== matchedCount ) {\n for ( j = 0; (matcher = setMatchers[j]); j++ ) {\n matcher( unmatched, setMatched, context, xml );\n }\n\n if ( seed ) {\n // Reintegrate element matches to eliminate the need for sorting\n if ( matchedCount > 0 ) {\n while ( i-- ) {\n if ( !(unmatched[i] || setMatched[i]) ) {\n setMatched[i] = pop.call( results );\n }\n }\n }\n\n // Discard index placeholder values to get only actual matches\n setMatched = condense( setMatched );\n }\n\n // Add matches to results\n push.apply( results, setMatched );\n\n // Seedless set matches succeeding multiple successful matchers stipulate sorting\n if ( outermost && !seed && setMatched.length > 0 &&\n ( matchedCount + setMatchers.length ) > 1 ) {\n\n Sizzle.uniqueSort( results );\n }\n }\n\n // Override manipulation of globals by nested matchers\n if ( outermost ) {\n dirruns = dirrunsUnique;\n outermostContext = contextBackup;\n }\n\n return unmatched;\n };\n\n superMatcher.el = 0;\n return bySet ?\n markFunction( superMatcher ) :\n superMatcher;\n}\n\ncompile = Sizzle.compile = function( selector, group /* Internal Use Only */ ) {\n var i,\n setMatchers = [],\n elementMatchers = [],\n cached = compilerCache[ expando ][ selector + \" \" ];\n\n if ( !cached ) {\n // Generate a function of recursive functions that can be used to check each element\n if ( !group ) {\n group = tokenize( selector );\n }\n i = group.length;\n while ( i-- ) {\n cached = matcherFromTokens( group[i] );\n if ( cached[ expando ] ) {\n setMatchers.push( cached );\n } else {\n elementMatchers.push( cached );\n }\n }\n\n // Cache the compiled function\n cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );\n }\n return cached;\n};\n\nfunction multipleContexts( selector, contexts, results ) {\n var i = 0,\n len = contexts.length;\n for ( ; i < len; i++ ) {\n Sizzle( selector, contexts[i], results );\n }\n return results;\n}\n\nfunction select( selector, context, results, seed, xml ) {\n var i, tokens, token, type, find,\n match = tokenize( selector ),\n j = match.length;\n\n if ( !seed ) {\n // Try to minimize operations if there is only one group\n if ( match.length === 1 ) {\n\n // Take a shortcut and set the context if the root selector is an ID\n tokens = match[0] = match[0].slice( 0 );\n if ( tokens.length > 2 && (token = tokens[0]).type === \"ID\" &&\n context.nodeType === 9 && !xml &&\n Expr.relative[ tokens[1].type ] ) {\n\n context = Expr.find[\"ID\"]( token.matches[0].replace( rbackslash, \"\" ), context, xml )[0];\n if ( !context ) {\n return results;\n }\n\n selector = selector.slice( tokens.shift().length );\n }\n\n // Fetch a seed set for right-to-left matching\n for ( i = matchExpr[\"POS\"].test( selector ) ? -1 : tokens.length - 1; i >= 0; i-- ) {\n token = tokens[i];\n\n // Abort if we hit a combinator\n if ( Expr.relative[ (type = token.type) ] ) {\n break;\n }\n if ( (find = Expr.find[ type ]) ) {\n // Search, expanding context for leading sibling combinators\n if ( (seed = find(\n token.matches[0].replace( rbackslash, \"\" ),\n rsibling.test( tokens[0].type ) && context.parentNode || context,\n xml\n )) ) {\n\n // If seed is empty or no tokens remain, we can return early\n tokens.splice( i, 1 );\n selector = seed.length && tokens.join(\"\");\n if ( !selector ) {\n push.apply( results, slice.call( seed, 0 ) );\n return results;\n }\n\n break;\n }\n }\n }\n }\n }\n\n // Compile and execute a filtering function\n // Provide `match` to avoid retokenization if we modified the selector above\n compile( selector, match )(\n seed,\n context,\n xml,\n results,\n rsibling.test( selector )\n );\n return results;\n}\n\nif ( document.querySelectorAll ) {\n (function() {\n var disconnectedMatch,\n oldSelect = select,\n rescape = /'|\\\\/g,\n rattributeQuotes = /\\=[\\x20\\t\\r\\n\\f]*([^'\"\\]]*)[\\x20\\t\\r\\n\\f]*\\]/g,\n\n // qSa(:focus) reports false when true (Chrome 21), no need to also add to buggyMatches since matches checks buggyQSA\n // A support test would require too much code (would include document ready)\n rbuggyQSA = [ \":focus\" ],\n\n // matchesSelector(:active) reports false when true (IE9/Opera 11.5)\n // A support test would require too much code (would include document ready)\n // just skip matchesSelector for :active\n rbuggyMatches = [ \":active\" ],\n matches = docElem.matchesSelector ||\n docElem.mozMatchesSelector ||\n docElem.webkitMatchesSelector ||\n docElem.oMatchesSelector ||\n docElem.msMatchesSelector;\n\n // Build QSA regex\n // Regex strategy adopted from Diego Perini\n assert(function( div ) {\n // Select is set to empty string on purpose\n // This is to test IE's treatment of not explictly\n // setting a boolean content attribute,\n // since its presence should be enough\n // http://bugs.jquery.com/ticket/12359\n div.innerHTML = \"<select><option selected=''></option></select>\";\n\n // IE8 - Some boolean attributes are not treated correctly\n if ( !div.querySelectorAll(\"[selected]\").length ) {\n rbuggyQSA.push( \"\\\\[\" + whitespace + \"*(?:checked|disabled|ismap|multiple|readonly|selected|value)\" );\n }\n\n // Webkit/Opera - :checked should return selected option elements\n // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked\n // IE8 throws error here (do not put tests after this one)\n if ( !div.querySelectorAll(\":checked\").length ) {\n rbuggyQSA.push(\":checked\");\n }\n });\n\n assert(function( div ) {\n\n // Opera 10-12/IE9 - ^= $= *= and empty values\n // Should not select anything\n div.innerHTML = \"<p test=''></p>\";\n if ( div.querySelectorAll(\"[test^='']\").length ) {\n rbuggyQSA.push( \"[*^$]=\" + whitespace + \"*(?:\\\"\\\"|'')\" );\n }\n\n // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)\n // IE8 throws error here (do not put tests after this one)\n div.innerHTML = \"<input type='hidden'/>\";\n if ( !div.querySelectorAll(\":enabled\").length ) {\n rbuggyQSA.push(\":enabled\", \":disabled\");\n }\n });\n\n // rbuggyQSA always contains :focus, so no need for a length check\n rbuggyQSA = /* rbuggyQSA.length && */ new RegExp( rbuggyQSA.join(\"|\") );\n\n select = function( selector, context, results, seed, xml ) {\n // Only use querySelectorAll when not filtering,\n // when this is not xml,\n // and when no QSA bugs apply\n if ( !seed && !xml && !rbuggyQSA.test( selector ) ) {\n var groups, i,\n old = true,\n nid = expando,\n newContext = context,\n newSelector = context.nodeType === 9 && selector;\n\n // qSA works strangely on Element-rooted queries\n // We can work around this by specifying an extra ID on the root\n // and working up from there (Thanks to Andrew Dupont for the technique)\n // IE 8 doesn't work on object elements\n if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== \"object\" ) {\n groups = tokenize( selector );\n\n if ( (old = context.getAttribute(\"id\")) ) {\n nid = old.replace( rescape, \"\\\\$&\" );\n } else {\n context.setAttribute( \"id\", nid );\n }\n nid = \"[id='\" + nid + \"'] \";\n\n i = groups.length;\n while ( i-- ) {\n groups[i] = nid + groups[i].join(\"\");\n }\n newContext = rsibling.test( selector ) && context.parentNode || context;\n newSelector = groups.join(\",\");\n }\n\n if ( newSelector ) {\n try {\n push.apply( results, slice.call( newContext.querySelectorAll(\n newSelector\n ), 0 ) );\n return results;\n } catch(qsaError) {\n } finally {\n if ( !old ) {\n context.removeAttribute(\"id\");\n }\n }\n }\n }\n\n return oldSelect( selector, context, results, seed, xml );\n };\n\n if ( matches ) {\n assert(function( div ) {\n // Check to see if it's possible to do matchesSelector\n // on a disconnected node (IE 9)\n disconnectedMatch = matches.call( div, \"div\" );\n\n // This should fail with an exception\n // Gecko does not error, returns false instead\n try {\n matches.call( div, \"[test!='']:sizzle\" );\n rbuggyMatches.push( \"!=\", pseudos );\n } catch ( e ) {}\n });\n\n // rbuggyMatches always contains :active and :focus, so no need for a length check\n rbuggyMatches = /* rbuggyMatches.length && */ new RegExp( rbuggyMatches.join(\"|\") );\n\n Sizzle.matchesSelector = function( elem, expr ) {\n // Make sure that attribute selectors are quoted\n expr = expr.replace( rattributeQuotes, \"='$1']\" );\n\n // rbuggyMatches always contains :active, so no need for an existence check\n if ( !isXML( elem ) && !rbuggyMatches.test( expr ) && !rbuggyQSA.test( expr ) ) {\n try {\n var ret = matches.call( elem, expr );\n\n // IE 9's matchesSelector returns false on disconnected nodes\n if ( ret || disconnectedMatch ||\n // As well, disconnected nodes are said to be in a document\n // fragment in IE 9\n elem.document && elem.document.nodeType !== 11 ) {\n return ret;\n }\n } catch(e) {}\n }\n\n return Sizzle( expr, null, null, [ elem ] ).length > 0;\n };\n }\n })();\n}\n\n// Deprecated\nExpr.pseudos[\"nth\"] = Expr.pseudos[\"eq\"];\n\n// Back-compat\nfunction setFilters() {}\nExpr.filters = setFilters.prototype = Expr.pseudos;\nExpr.setFilters = new setFilters();\n\n// Override sizzle attribute retrieval\nSizzle.attr = jQuery.attr;\njQuery.find = Sizzle;\njQuery.expr = Sizzle.selectors;\njQuery.expr[\":\"] = jQuery.expr.pseudos;\njQuery.unique = Sizzle.uniqueSort;\njQuery.text = Sizzle.getText;\njQuery.isXMLDoc = Sizzle.isXML;\njQuery.contains = Sizzle.contains;\n\n\n})( window );\nvar runtil = /Until$/,\n rparentsprev = /^(?:parents|prev(?:Until|All))/,\n isSimple = /^.[^:#\\[\\.,]*$/,\n rneedsContext = jQuery.expr.match.needsContext,\n // methods guaranteed to produce a unique set when starting from a unique set\n guaranteedUnique = {\n children: true,\n contents: true,\n next: true,\n prev: true\n };\n\njQuery.fn.extend({\n find: function( selector ) {\n var i, l, length, n, r, ret,\n self = this;\n\n if ( typeof selector !== \"string\" ) {\n return jQuery( selector ).filter(function() {\n for ( i = 0, l = self.length; i < l; i++ ) {\n if ( jQuery.contains( self[ i ], this ) ) {\n return true;\n }\n }\n });\n }\n\n ret = this.pushStack( \"\", \"find\", selector );\n\n for ( i = 0, l = this.length; i < l; i++ ) {\n length = ret.length;\n jQuery.find( selector, this[i], ret );\n\n if ( i > 0 ) {\n // Make sure that the results are unique\n for ( n = length; n < ret.length; n++ ) {\n for ( r = 0; r < length; r++ ) {\n if ( ret[r] === ret[n] ) {\n ret.splice(n--, 1);\n break;\n }\n }\n }\n }\n }\n\n return ret;\n },\n\n has: function( target ) {\n var i,\n targets = jQuery( target, this ),\n len = targets.length;\n\n return this.filter(function() {\n for ( i = 0; i < len; i++ ) {\n if ( jQuery.contains( this, targets[i] ) ) {\n return true;\n }\n }\n });\n },\n\n not: function( selector ) {\n return this.pushStack( winnow(this, selector, false), \"not\", selector);\n },\n\n filter: function( selector ) {\n return this.pushStack( winnow(this, selector, true), \"filter\", selector );\n },\n\n is: function( selector ) {\n return !!selector && (\n typeof selector === \"string\" ?\n // If this is a positional/relative selector, check membership in the returned set\n // so $(\"p:first\").is(\"p:last\") won't return true for a doc with two \"p\".\n rneedsContext.test( selector ) ?\n jQuery( selector, this.context ).index( this[0] ) >= 0 :\n jQuery.filter( selector, this ).length > 0 :\n this.filter( selector ).length > 0 );\n },\n\n closest: function( selectors, context ) {\n var cur,\n i = 0,\n l = this.length,\n ret = [],\n pos = rneedsContext.test( selectors ) || typeof selectors !== \"string\" ?\n jQuery( selectors, context || this.context ) :\n 0;\n\n for ( ; i < l; i++ ) {\n cur = this[i];\n\n while ( cur && cur.ownerDocument && cur !== context && cur.nodeType !== 11 ) {\n if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) {\n ret.push( cur );\n break;\n }\n cur = cur.parentNode;\n }\n }\n\n ret = ret.length > 1 ? jQuery.unique( ret ) : ret;\n\n return this.pushStack( ret, \"closest\", selectors );\n },\n\n // Determine the position of an element within\n // the matched set of elements\n index: function( elem ) {\n\n // No argument, return index in parent\n if ( !elem ) {\n return ( this[0] && this[0].parentNode ) ? this.prevAll().length : -1;\n }\n\n // index in selector\n if ( typeof elem === \"string\" ) {\n return jQuery.inArray( this[0], jQuery( elem ) );\n }\n\n // Locate the position of the desired element\n return jQuery.inArray(\n // If it receives a jQuery object, the first element is used\n elem.jquery ? elem[0] : elem, this );\n },\n\n add: function( selector, context ) {\n var set = typeof selector === \"string\" ?\n jQuery( selector, context ) :\n jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ),\n all = jQuery.merge( this.get(), set );\n\n return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ?\n all :\n jQuery.unique( all ) );\n },\n\n addBack: function( selector ) {\n return this.add( selector == null ?\n this.prevObject : this.prevObject.filter(selector)\n );\n }\n});\n\njQuery.fn.andSelf = jQuery.fn.addBack;\n\n// A painfully simple check to see if an element is disconnected\n// from a document (should be improved, where feasible).\nfunction isDisconnected( node ) {\n return !node || !node.parentNode || node.parentNode.nodeType === 11;\n}\n\nfunction sibling( cur, dir ) {\n do {\n cur = cur[ dir ];\n } while ( cur && cur.nodeType !== 1 );\n\n return cur;\n}\n\njQuery.each({\n parent: function( elem ) {\n var parent = elem.parentNode;\n return parent && parent.nodeType !== 11 ? parent : null;\n },\n parents: function( elem ) {\n return jQuery.dir( elem, \"parentNode\" );\n },\n parentsUntil: function( elem, i, until ) {\n return jQuery.dir( elem, \"parentNode\", until );\n },\n next: function( elem ) {\n return sibling( elem, \"nextSibling\" );\n },\n prev: function( elem ) {\n return sibling( elem, \"previousSibling\" );\n },\n nextAll: function( elem ) {\n return jQuery.dir( elem, \"nextSibling\" );\n },\n prevAll: function( elem ) {\n return jQuery.dir( elem, \"previousSibling\" );\n },\n nextUntil: function( elem, i, until ) {\n return jQuery.dir( elem, \"nextSibling\", until );\n },\n prevUntil: function( elem, i, until ) {\n return jQuery.dir( elem, \"previousSibling\", until );\n },\n siblings: function( elem ) {\n return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem );\n },\n children: function( elem ) {\n return jQuery.sibling( elem.firstChild );\n },\n contents: function( elem ) {\n return jQuery.nodeName( elem, \"iframe\" ) ?\n elem.contentDocument || elem.contentWindow.document :\n jQuery.merge( [], elem.childNodes );\n }\n}, function( name, fn ) {\n jQuery.fn[ name ] = function( until, selector ) {\n var ret = jQuery.map( this, fn, until );\n\n if ( !runtil.test( name ) ) {\n selector = until;\n }\n\n if ( selector && typeof selector === \"string\" ) {\n ret = jQuery.filter( selector, ret );\n }\n\n ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret;\n\n if ( this.length > 1 && rparentsprev.test( name ) ) {\n ret = ret.reverse();\n }\n\n return this.pushStack( ret, name, core_slice.call( arguments ).join(\",\") );\n };\n});\n\njQuery.extend({\n filter: function( expr, elems, not ) {\n if ( not ) {\n expr = \":not(\" + expr + \")\";\n }\n\n return elems.length === 1 ?\n jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] :\n jQuery.find.matches(expr, elems);\n },\n\n dir: function( elem, dir, until ) {\n var matched = [],\n cur = elem[ dir ];\n\n while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {\n if ( cur.nodeType === 1 ) {\n matched.push( cur );\n }\n cur = cur[dir];\n }\n return matched;\n },\n\n sibling: function( n, elem ) {\n var r = [];\n\n for ( ; n; n = n.nextSibling ) {\n if ( n.nodeType === 1 && n !== elem ) {\n r.push( n );\n }\n }\n\n return r;\n }\n});\n\n// Implement the identical functionality for filter and not\nfunction winnow( elements, qualifier, keep ) {\n\n // Can't pass null or undefined to indexOf in Firefox 4\n // Set to 0 to skip string check\n qualifier = qualifier || 0;\n\n if ( jQuery.isFunction( qualifier ) ) {\n return jQuery.grep(elements, function( elem, i ) {\n var retVal = !!qualifier.call( elem, i, elem );\n return retVal === keep;\n });\n\n } else if ( qualifier.nodeType ) {\n return jQuery.grep(elements, function( elem, i ) {\n return ( elem === qualifier ) === keep;\n });\n\n } else if ( typeof qualifier === \"string\" ) {\n var filtered = jQuery.grep(elements, function( elem ) {\n return elem.nodeType === 1;\n });\n\n if ( isSimple.test( qualifier ) ) {\n return jQuery.filter(qualifier, filtered, !keep);\n } else {\n qualifier = jQuery.filter( qualifier, filtered );\n }\n }\n\n return jQuery.grep(elements, function( elem, i ) {\n return ( jQuery.inArray( elem, qualifier ) >= 0 ) === keep;\n });\n}\nfunction createSafeFragment( document ) {\n var list = nodeNames.split( \"|\" ),\n safeFrag = document.createDocumentFragment();\n\n if ( safeFrag.createElement ) {\n while ( list.length ) {\n safeFrag.createElement(\n list.pop()\n );\n }\n }\n return safeFrag;\n}\n\nvar nodeNames = \"abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|\" +\n \"header|hgroup|mark|meter|nav|output|progress|section|summary|time|video\",\n rinlinejQuery = / jQuery\\d+=\"(?:null|\\d+)\"/g,\n rleadingWhitespace = /^\\s+/,\n rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\\w:]+)[^>]*)\\/>/gi,\n rtagName = /<([\\w:]+)/,\n rtbody = /<tbody/i,\n rhtml = /<|&#?\\w+;/,\n rnoInnerhtml = /<(?:script|style|link)/i,\n rnocache = /<(?:script|object|embed|option|style)/i,\n rnoshimcache = new RegExp(\"<(?:\" + nodeNames + \")[\\\\s/>]\", \"i\"),\n rcheckableType = /^(?:checkbox|radio)$/,\n // checked=\"checked\" or checked\n rchecked = /checked\\s*(?:[^=]|=\\s*.checked.)/i,\n rscriptType = /\\/(java|ecma)script/i,\n rcleanScript = /^\\s*<!(?:\\[CDATA\\[|\\-\\-)|[\\]\\-]{2}>\\s*$/g,\n wrapMap = {\n option: [ 1, \"<select multiple='multiple'>\", \"</select>\" ],\n legend: [ 1, \"<fieldset>\", \"</fieldset>\" ],\n thead: [ 1, \"<table>\", \"</table>\" ],\n tr: [ 2, \"<table><tbody>\", \"</tbody></table>\" ],\n td: [ 3, \"<table><tbody><tr>\", \"</tr></tbody></table>\" ],\n col: [ 2, \"<table><tbody></tbody><colgroup>\", \"</colgroup></table>\" ],\n area: [ 1, \"<map>\", \"</map>\" ],\n _default: [ 0, \"\", \"\" ]\n },\n safeFragment = createSafeFragment( document ),\n fragmentDiv = safeFragment.appendChild( document.createElement(\"div\") );\n\nwrapMap.optgroup = wrapMap.option;\nwrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;\nwrapMap.th = wrapMap.td;\n\n// IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags,\n// unless wrapped in a div with non-breaking characters in front of it.\nif ( !jQuery.support.htmlSerialize ) {\n wrapMap._default = [ 1, \"X<div>\", \"</div>\" ];\n}\n\njQuery.fn.extend({\n text: function( value ) {\n return jQuery.access( this, function( value ) {\n return value === undefined ?\n jQuery.text( this ) :\n this.empty().append( ( this[0] && this[0].ownerDocument || document ).createTextNode( value ) );\n }, null, value, arguments.length );\n },\n\n wrapAll: function( html ) {\n if ( jQuery.isFunction( html ) ) {\n return this.each(function(i) {\n jQuery(this).wrapAll( html.call(this, i) );\n });\n }\n\n if ( this[0] ) {\n // The elements to wrap the target around\n var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);\n\n if ( this[0].parentNode ) {\n wrap.insertBefore( this[0] );\n }\n\n wrap.map(function() {\n var elem = this;\n\n while ( elem.firstChild && elem.firstChild.nodeType === 1 ) {\n elem = elem.firstChild;\n }\n\n return elem;\n }).append( this );\n }\n\n return this;\n },\n\n wrapInner: function( html ) {\n if ( jQuery.isFunction( html ) ) {\n return this.each(function(i) {\n jQuery(this).wrapInner( html.call(this, i) );\n });\n }\n\n return this.each(function() {\n var self = jQuery( this ),\n contents = self.contents();\n\n if ( contents.length ) {\n contents.wrapAll( html );\n\n } else {\n self.append( html );\n }\n });\n },\n\n wrap: function( html ) {\n var isFunction = jQuery.isFunction( html );\n\n return this.each(function(i) {\n jQuery( this ).wrapAll( isFunction ? html.call(this, i) : html );\n });\n },\n\n unwrap: function() {\n return this.parent().each(function() {\n if ( !jQuery.nodeName( this, \"body\" ) ) {\n jQuery( this ).replaceWith( this.childNodes );\n }\n }).end();\n },\n\n append: function() {\n return this.domManip(arguments, true, function( elem ) {\n if ( this.nodeType === 1 || this.nodeType === 11 ) {\n this.appendChild( elem );\n }\n });\n },\n\n prepend: function() {\n return this.domManip(arguments, true, function( elem ) {\n if ( this.nodeType === 1 || this.nodeType === 11 ) {\n this.insertBefore( elem, this.firstChild );\n }\n });\n },\n\n before: function() {\n if ( !isDisconnected( this[0] ) ) {\n return this.domManip(arguments, false, function( elem ) {\n this.parentNode.insertBefore( elem, this );\n });\n }\n\n if ( arguments.length ) {\n var set = jQuery.clean( arguments );\n return this.pushStack( jQuery.merge( set, this ), \"before\", this.selector );\n }\n },\n\n after: function() {\n if ( !isDisconnected( this[0] ) ) {\n return this.domManip(arguments, false, function( elem ) {\n this.parentNode.insertBefore( elem, this.nextSibling );\n });\n }\n\n if ( arguments.length ) {\n var set = jQuery.clean( arguments );\n return this.pushStack( jQuery.merge( this, set ), \"after\", this.selector );\n }\n },\n\n // keepData is for internal use only--do not document\n remove: function( selector, keepData ) {\n var elem,\n i = 0;\n\n for ( ; (elem = this[i]) != null; i++ ) {\n if ( !selector || jQuery.filter( selector, [ elem ] ).length ) {\n if ( !keepData && elem.nodeType === 1 ) {\n jQuery.cleanData( elem.getElementsByTagName(\"*\") );\n jQuery.cleanData( [ elem ] );\n }\n\n if ( elem.parentNode ) {\n elem.parentNode.removeChild( elem );\n }\n }\n }\n\n return this;\n },\n\n empty: function() {\n var elem,\n i = 0;\n\n for ( ; (elem = this[i]) != null; i++ ) {\n // Remove element nodes and prevent memory leaks\n if ( elem.nodeType === 1 ) {\n jQuery.cleanData( elem.getElementsByTagName(\"*\") );\n }\n\n // Remove any remaining nodes\n while ( elem.firstChild ) {\n elem.removeChild( elem.firstChild );\n }\n }\n\n return this;\n },\n\n clone: function( dataAndEvents, deepDataAndEvents ) {\n dataAndEvents = dataAndEvents == null ? false : dataAndEvents;\n deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;\n\n return this.map( function () {\n return jQuery.clone( this, dataAndEvents, deepDataAndEvents );\n });\n },\n\n html: function( value ) {\n return jQuery.access( this, function( value ) {\n var elem = this[0] || {},\n i = 0,\n l = this.length;\n\n if ( value === undefined ) {\n return elem.nodeType === 1 ?\n elem.innerHTML.replace( rinlinejQuery, \"\" ) :\n undefined;\n }\n\n // See if we can take a shortcut and just use innerHTML\n if ( typeof value === \"string\" && !rnoInnerhtml.test( value ) &&\n ( jQuery.support.htmlSerialize || !rnoshimcache.test( value ) ) &&\n ( jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value ) ) &&\n !wrapMap[ ( rtagName.exec( value ) || [\"\", \"\"] )[1].toLowerCase() ] ) {\n\n value = value.replace( rxhtmlTag, \"<$1></$2>\" );\n\n try {\n for (; i < l; i++ ) {\n // Remove element nodes and prevent memory leaks\n elem = this[i] || {};\n if ( elem.nodeType === 1 ) {\n jQuery.cleanData( elem.getElementsByTagName( \"*\" ) );\n elem.innerHTML = value;\n }\n }\n\n elem = 0;\n\n // If using innerHTML throws an exception, use the fallback method\n } catch(e) {}\n }\n\n if ( elem ) {\n this.empty().append( value );\n }\n }, null, value, arguments.length );\n },\n\n replaceWith: function( value ) {\n if ( !isDisconnected( this[0] ) ) {\n // Make sure that the elements are removed from the DOM before they are inserted\n // this can help fix replacing a parent with child elements\n if ( jQuery.isFunction( value ) ) {\n return this.each(function(i) {\n var self = jQuery(this), old = self.html();\n self.replaceWith( value.call( this, i, old ) );\n });\n }\n\n if ( typeof value !== \"string\" ) {\n value = jQuery( value ).detach();\n }\n\n return this.each(function() {\n var next = this.nextSibling,\n parent = this.parentNode;\n\n jQuery( this ).remove();\n\n if ( next ) {\n jQuery(next).before( value );\n } else {\n jQuery(parent).append( value );\n }\n });\n }\n\n return this.length ?\n this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), \"replaceWith\", value ) :\n this;\n },\n\n detach: function( selector ) {\n return this.remove( selector, true );\n },\n\n domManip: function( args, table, callback ) {\n\n // Flatten any nested arrays\n args = [].concat.apply( [], args );\n\n var results, first, fragment, iNoClone,\n i = 0,\n value = args[0],\n scripts = [],\n l = this.length;\n\n // We can't cloneNode fragments that contain checked, in WebKit\n if ( !jQuery.support.checkClone && l > 1 && typeof value === \"string\" && rchecked.test( value ) ) {\n return this.each(function() {\n jQuery(this).domManip( args, table, callback );\n });\n }\n\n if ( jQuery.isFunction(value) ) {\n return this.each(function(i) {\n var self = jQuery(this);\n args[0] = value.call( this, i, table ? self.html() : undefined );\n self.domManip( args, table, callback );\n });\n }\n\n if ( this[0] ) {\n results = jQuery.buildFragment( args, this, scripts );\n fragment = results.fragment;\n first = fragment.firstChild;\n\n if ( fragment.childNodes.length === 1 ) {\n fragment = first;\n }\n\n if ( first ) {\n table = table && jQuery.nodeName( first, \"tr\" );\n\n // Use the original fragment for the last item instead of the first because it can end up\n // being emptied incorrectly in certain situations (#8070).\n // Fragments from the fragment cache must always be cloned and never used in place.\n for ( iNoClone = results.cacheable || l - 1; i < l; i++ ) {\n callback.call(\n table && jQuery.nodeName( this[i], \"table\" ) ?\n findOrAppend( this[i], \"tbody\" ) :\n this[i],\n i === iNoClone ?\n fragment :\n jQuery.clone( fragment, true, true )\n );\n }\n }\n\n // Fix #11809: Avoid leaking memory\n fragment = first = null;\n\n if ( scripts.length ) {\n jQuery.each( scripts, function( i, elem ) {\n if ( elem.src ) {\n if ( jQuery.ajax ) {\n jQuery.ajax({\n url: elem.src,\n type: \"GET\",\n dataType: \"script\",\n async: false,\n global: false,\n \"throws\": true\n });\n } else {\n jQuery.error(\"no ajax\");\n }\n } else {\n jQuery.globalEval( ( elem.text || elem.textContent || elem.innerHTML || \"\" ).replace( rcleanScript, \"\" ) );\n }\n\n if ( elem.parentNode ) {\n elem.parentNode.removeChild( elem );\n }\n });\n }\n }\n\n return this;\n }\n});\n\nfunction findOrAppend( elem, tag ) {\n return elem.getElementsByTagName( tag )[0] || elem.appendChild( elem.ownerDocument.createElement( tag ) );\n}\n\nfunction cloneCopyEvent( src, dest ) {\n\n if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) {\n return;\n }\n\n var type, i, l,\n oldData = jQuery._data( src ),\n curData = jQuery._data( dest, oldData ),\n events = oldData.events;\n\n if ( events ) {\n delete curData.handle;\n curData.events = {};\n\n for ( type in events ) {\n for ( i = 0, l = events[ type ].length; i < l; i++ ) {\n jQuery.event.add( dest, type, events[ type ][ i ] );\n }\n }\n }\n\n // make the cloned public data object a copy from the original\n if ( curData.data ) {\n curData.data = jQuery.extend( {}, curData.data );\n }\n}\n\nfunction cloneFixAttributes( src, dest ) {\n var nodeName;\n\n // We do not need to do anything for non-Elements\n if ( dest.nodeType !== 1 ) {\n return;\n }\n\n // clearAttributes removes the attributes, which we don't want,\n // but also removes the attachEvent events, which we *do* want\n if ( dest.clearAttributes ) {\n dest.clearAttributes();\n }\n\n // mergeAttributes, in contrast, only merges back on the\n // original attributes, not the events\n if ( dest.mergeAttributes ) {\n dest.mergeAttributes( src );\n }\n\n nodeName = dest.nodeName.toLowerCase();\n\n if ( nodeName === \"object\" ) {\n // IE6-10 improperly clones children of object elements using classid.\n // IE10 throws NoModificationAllowedError if parent is null, #12132.\n if ( dest.parentNode ) {\n dest.outerHTML = src.outerHTML;\n }\n\n // This path appears unavoidable for IE9. When cloning an object\n // element in IE9, the outerHTML strategy above is not sufficient.\n // If the src has innerHTML and the destination does not,\n // copy the src.innerHTML into the dest.innerHTML. #10324\n if ( jQuery.support.html5Clone && (src.innerHTML && !jQuery.trim(dest.innerHTML)) ) {\n dest.innerHTML = src.innerHTML;\n }\n\n } else if ( nodeName === \"input\" && rcheckableType.test( src.type ) ) {\n // IE6-8 fails to persist the checked state of a cloned checkbox\n // or radio button. Worse, IE6-7 fail to give the cloned element\n // a checked appearance if the defaultChecked value isn't also set\n\n dest.defaultChecked = dest.checked = src.checked;\n\n // IE6-7 get confused and end up setting the value of a cloned\n // checkbox/radio button to an empty string instead of \"on\"\n if ( dest.value !== src.value ) {\n dest.value = src.value;\n }\n\n // IE6-8 fails to return the selected option to the default selected\n // state when cloning options\n } else if ( nodeName === \"option\" ) {\n dest.selected = src.defaultSelected;\n\n // IE6-8 fails to set the defaultValue to the correct value when\n // cloning other types of input fields\n } else if ( nodeName === \"input\" || nodeName === \"textarea\" ) {\n dest.defaultValue = src.defaultValue;\n\n // IE blanks contents when cloning scripts\n } else if ( nodeName === \"script\" && dest.text !== src.text ) {\n dest.text = src.text;\n }\n\n // Event data gets referenced instead of copied if the expando\n // gets copied too\n dest.removeAttribute( jQuery.expando );\n}\n\njQuery.buildFragment = function( args, context, scripts ) {\n var fragment, cacheable, cachehit,\n first = args[ 0 ];\n\n // Set context from what may come in as undefined or a jQuery collection or a node\n // Updated to fix #12266 where accessing context[0] could throw an exception in IE9/10 &\n // also doubles as fix for #8950 where plain objects caused createDocumentFragment exception\n context = context || document;\n context = !context.nodeType && context[0] || context;\n context = context.ownerDocument || context;\n\n // Only cache \"small\" (1/2 KB) HTML strings that are associated with the main document\n // Cloning options loses the selected state, so don't cache them\n // IE 6 doesn't like it when you put <object> or <embed> elements in a fragment\n // Also, WebKit does not clone 'checked' attributes on cloneNode, so don't cache\n // Lastly, IE6,7,8 will not correctly reuse cached fragments that were created from unknown elems #10501\n if ( args.length === 1 && typeof first === \"string\" && first.length < 512 && context === document &&\n first.charAt(0) === \"<\" && !rnocache.test( first ) &&\n (jQuery.support.checkClone || !rchecked.test( first )) &&\n (jQuery.support.html5Clone || !rnoshimcache.test( first )) ) {\n\n // Mark cacheable and look for a hit\n cacheable = true;\n fragment = jQuery.fragments[ first ];\n cachehit = fragment !== undefined;\n }\n\n if ( !fragment ) {\n fragment = context.createDocumentFragment();\n jQuery.clean( args, context, fragment, scripts );\n\n // Update the cache, but only store false\n // unless this is a second parsing of the same content\n if ( cacheable ) {\n jQuery.fragments[ first ] = cachehit && fragment;\n }\n }\n\n return { fragment: fragment, cacheable: cacheable };\n};\n\njQuery.fragments = {};\n\njQuery.each({\n appendTo: \"append\",\n prependTo: \"prepend\",\n insertBefore: \"before\",\n insertAfter: \"after\",\n replaceAll: \"replaceWith\"\n}, function( name, original ) {\n jQuery.fn[ name ] = function( selector ) {\n var elems,\n i = 0,\n ret = [],\n insert = jQuery( selector ),\n l = insert.length,\n parent = this.length === 1 && this[0].parentNode;\n\n if ( (parent == null || parent && parent.nodeType === 11 && parent.childNodes.length === 1) && l === 1 ) {\n insert[ original ]( this[0] );\n return this;\n } else {\n for ( ; i < l; i++ ) {\n elems = ( i > 0 ? this.clone(true) : this ).get();\n jQuery( insert[i] )[ original ]( elems );\n ret = ret.concat( elems );\n }\n\n return this.pushStack( ret, name, insert.selector );\n }\n };\n});\n\nfunction getAll( elem ) {\n if ( typeof elem.getElementsByTagName !== \"undefined\" ) {\n return elem.getElementsByTagName( \"*\" );\n\n } else if ( typeof elem.querySelectorAll !== \"undefined\" ) {\n return elem.querySelectorAll( \"*\" );\n\n } else {\n return [];\n }\n}\n\n// Used in clean, fixes the defaultChecked property\nfunction fixDefaultChecked( elem ) {\n if ( rcheckableType.test( elem.type ) ) {\n elem.defaultChecked = elem.checked;\n }\n}\n\njQuery.extend({\n clone: function( elem, dataAndEvents, deepDataAndEvents ) {\n var srcElements,\n destElements,\n i,\n clone;\n\n if ( jQuery.support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( \"<\" + elem.nodeName + \">\" ) ) {\n clone = elem.cloneNode( true );\n\n // IE<=8 does not properly clone detached, unknown element nodes\n } else {\n fragmentDiv.innerHTML = elem.outerHTML;\n fragmentDiv.removeChild( clone = fragmentDiv.firstChild );\n }\n\n if ( (!jQuery.support.noCloneEvent || !jQuery.support.noCloneChecked) &&\n (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) {\n // IE copies events bound via attachEvent when using cloneNode.\n // Calling detachEvent on the clone will also remove the events\n // from the original. In order to get around this, we use some\n // proprietary methods to clear the events. Thanks to MooTools\n // guys for this hotness.\n\n cloneFixAttributes( elem, clone );\n\n // Using Sizzle here is crazy slow, so we use getElementsByTagName instead\n srcElements = getAll( elem );\n destElements = getAll( clone );\n\n // Weird iteration because IE will replace the length property\n // with an element if you are cloning the body and one of the\n // elements on the page has a name or id of \"length\"\n for ( i = 0; srcElements[i]; ++i ) {\n // Ensure that the destination node is not null; Fixes #9587\n if ( destElements[i] ) {\n cloneFixAttributes( srcElements[i], destElements[i] );\n }\n }\n }\n\n // Copy the events from the original to the clone\n if ( dataAndEvents ) {\n cloneCopyEvent( elem, clone );\n\n if ( deepDataAndEvents ) {\n srcElements = getAll( elem );\n destElements = getAll( clone );\n\n for ( i = 0; srcElements[i]; ++i ) {\n cloneCopyEvent( srcElements[i], destElements[i] );\n }\n }\n }\n\n srcElements = destElements = null;\n\n // Return the cloned set\n return clone;\n },\n\n clean: function( elems, context, fragment, scripts ) {\n var i, j, elem, tag, wrap, depth, div, hasBody, tbody, len, handleScript, jsTags,\n safe = context === document && safeFragment,\n ret = [];\n\n // Ensure that context is a document\n if ( !context || typeof context.createDocumentFragment === \"undefined\" ) {\n context = document;\n }\n\n // Use the already-created safe fragment if context permits\n for ( i = 0; (elem = elems[i]) != null; i++ ) {\n if ( typeof elem === \"number\" ) {\n elem += \"\";\n }\n\n if ( !elem ) {\n continue;\n }\n\n // Convert html string into DOM nodes\n if ( typeof elem === \"string\" ) {\n if ( !rhtml.test( elem ) ) {\n elem = context.createTextNode( elem );\n } else {\n // Ensure a safe container in which to render the html\n safe = safe || createSafeFragment( context );\n div = context.createElement(\"div\");\n safe.appendChild( div );\n\n // Fix \"XHTML\"-style tags in all browsers\n elem = elem.replace(rxhtmlTag, \"<$1></$2>\");\n\n // Go to html and back, then peel off extra wrappers\n tag = ( rtagName.exec( elem ) || [\"\", \"\"] )[1].toLowerCase();\n wrap = wrapMap[ tag ] || wrapMap._default;\n depth = wrap[0];\n div.innerHTML = wrap[1] + elem + wrap[2];\n\n // Move to the right depth\n while ( depth-- ) {\n div = div.lastChild;\n }\n\n // Remove IE's autoinserted <tbody> from table fragments\n if ( !jQuery.support.tbody ) {\n\n // String was a <table>, *may* have spurious <tbody>\n hasBody = rtbody.test(elem);\n tbody = tag === \"table\" && !hasBody ?\n div.firstChild && div.firstChild.childNodes :\n\n // String was a bare <thead> or <tfoot>\n wrap[1] === \"<table>\" && !hasBody ?\n div.childNodes :\n [];\n\n for ( j = tbody.length - 1; j >= 0 ; --j ) {\n if ( jQuery.nodeName( tbody[ j ], \"tbody\" ) && !tbody[ j ].childNodes.length ) {\n tbody[ j ].parentNode.removeChild( tbody[ j ] );\n }\n }\n }\n\n // IE completely kills leading whitespace when innerHTML is used\n if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {\n div.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild );\n }\n\n elem = div.childNodes;\n\n // Take out of fragment container (we need a fresh div each time)\n div.parentNode.removeChild( div );\n }\n }\n\n if ( elem.nodeType ) {\n ret.push( elem );\n } else {\n jQuery.merge( ret, elem );\n }\n }\n\n // Fix #11356: Clear elements from safeFragment\n if ( div ) {\n elem = div = safe = null;\n }\n\n // Reset defaultChecked for any radios and checkboxes\n // about to be appended to the DOM in IE 6/7 (#8060)\n if ( !jQuery.support.appendChecked ) {\n for ( i = 0; (elem = ret[i]) != null; i++ ) {\n if ( jQuery.nodeName( elem, \"input\" ) ) {\n fixDefaultChecked( elem );\n } else if ( typeof elem.getElementsByTagName !== \"undefined\" ) {\n jQuery.grep( elem.getElementsByTagName(\"input\"), fixDefaultChecked );\n }\n }\n }\n\n // Append elements to a provided document fragment\n if ( fragment ) {\n // Special handling of each script element\n handleScript = function( elem ) {\n // Check if we consider it executable\n if ( !elem.type || rscriptType.test( elem.type ) ) {\n // Detach the script and store it in the scripts array (if provided) or the fragment\n // Return truthy to indicate that it has been handled\n return scripts ?\n scripts.push( elem.parentNode ? elem.parentNode.removeChild( elem ) : elem ) :\n fragment.appendChild( elem );\n }\n };\n\n for ( i = 0; (elem = ret[i]) != null; i++ ) {\n // Check if we're done after handling an executable script\n if ( !( jQuery.nodeName( elem, \"script\" ) && handleScript( elem ) ) ) {\n // Append to fragment and handle embedded scripts\n fragment.appendChild( elem );\n if ( typeof elem.getElementsByTagName !== \"undefined\" ) {\n // handleScript alters the DOM, so use jQuery.merge to ensure snapshot iteration\n jsTags = jQuery.grep( jQuery.merge( [], elem.getElementsByTagName(\"script\") ), handleScript );\n\n // Splice the scripts into ret after their former ancestor and advance our index beyond them\n ret.splice.apply( ret, [i + 1, 0].concat( jsTags ) );\n i += jsTags.length;\n }\n }\n }\n }\n\n return ret;\n },\n\n cleanData: function( elems, /* internal */ acceptData ) {\n var data, id, elem, type,\n i = 0,\n internalKey = jQuery.expando,\n cache = jQuery.cache,\n deleteExpando = jQuery.support.deleteExpando,\n special = jQuery.event.special;\n\n for ( ; (elem = elems[i]) != null; i++ ) {\n\n if ( acceptData || jQuery.acceptData( elem ) ) {\n\n id = elem[ internalKey ];\n data = id && cache[ id ];\n\n if ( data ) {\n if ( data.events ) {\n for ( type in data.events ) {\n if ( special[ type ] ) {\n jQuery.event.remove( elem, type );\n\n // This is a shortcut to avoid jQuery.event.remove's overhead\n } else {\n jQuery.removeEvent( elem, type, data.handle );\n }\n }\n }\n\n // Remove cache only if it was not already removed by jQuery.event.remove\n if ( cache[ id ] ) {\n\n delete cache[ id ];\n\n // IE does not allow us to delete expando properties from nodes,\n // nor does it have a removeAttribute function on Document nodes;\n // we must handle all of these cases\n if ( deleteExpando ) {\n delete elem[ internalKey ];\n\n } else if ( elem.removeAttribute ) {\n elem.removeAttribute( internalKey );\n\n } else {\n elem[ internalKey ] = null;\n }\n\n jQuery.deletedIds.push( id );\n }\n }\n }\n }\n }\n});\n// Limit scope pollution from any deprecated API\n(function() {\n\nvar matched, browser;\n\n// Use of jQuery.browser is frowned upon.\n// More details: http://api.jquery.com/jQuery.browser\n// jQuery.uaMatch maintained for back-compat\njQuery.uaMatch = function( ua ) {\n ua = ua.toLowerCase();\n\n var match = /(chrome)[ \\/]([\\w.]+)/.exec( ua ) ||\n /(webkit)[ \\/]([\\w.]+)/.exec( ua ) ||\n /(opera)(?:.*version|)[ \\/]([\\w.]+)/.exec( ua ) ||\n /(msie) ([\\w.]+)/.exec( ua ) ||\n ua.indexOf(\"compatible\") < 0 && /(mozilla)(?:.*? rv:([\\w.]+)|)/.exec( ua ) ||\n [];\n\n return {\n browser: match[ 1 ] || \"\",\n version: match[ 2 ] || \"0\"\n };\n};\n\nmatched = jQuery.uaMatch( navigator.userAgent );\nbrowser = {};\n\nif ( matched.browser ) {\n browser[ matched.browser ] = true;\n browser.version = matched.version;\n}\n\n// Chrome is Webkit, but Webkit is also Safari.\nif ( browser.chrome ) {\n browser.webkit = true;\n} else if ( browser.webkit ) {\n browser.safari = true;\n}\n\njQuery.browser = browser;\n\njQuery.sub = function() {\n function jQuerySub( selector, context ) {\n return new jQuerySub.fn.init( selector, context );\n }\n jQuery.extend( true, jQuerySub, this );\n jQuerySub.superclass = this;\n jQuerySub.fn = jQuerySub.prototype = this();\n jQuerySub.fn.constructor = jQuerySub;\n jQuerySub.sub = this.sub;\n jQuerySub.fn.init = function init( selector, context ) {\n if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) {\n context = jQuerySub( context );\n }\n\n return jQuery.fn.init.call( this, selector, context, rootjQuerySub );\n };\n jQuerySub.fn.init.prototype = jQuerySub.fn;\n var rootjQuerySub = jQuerySub(document);\n return jQuerySub;\n};\n\n})();\nvar curCSS, iframe, iframeDoc,\n ralpha = /alpha\\([^)]*\\)/i,\n ropacity = /opacity=([^)]*)/,\n rposition = /^(top|right|bottom|left)$/,\n // swappable if display is none or starts with table except \"table\", \"table-cell\", or \"table-caption\"\n // see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display\n rdisplayswap = /^(none|table(?!-c[ea]).+)/,\n rmargin = /^margin/,\n rnumsplit = new RegExp( \"^(\" + core_pnum + \")(.*)$\", \"i\" ),\n rnumnonpx = new RegExp( \"^(\" + core_pnum + \")(?!px)[a-z%]+$\", \"i\" ),\n rrelNum = new RegExp( \"^([-+])=(\" + core_pnum + \")\", \"i\" ),\n elemdisplay = { BODY: \"block\" },\n\n cssShow = { position: \"absolute\", visibility: \"hidden\", display: \"block\" },\n cssNormalTransform = {\n letterSpacing: 0,\n fontWeight: 400\n },\n\n cssExpand = [ \"Top\", \"Right\", \"Bottom\", \"Left\" ],\n cssPrefixes = [ \"Webkit\", \"O\", \"Moz\", \"ms\" ],\n\n eventsToggle = jQuery.fn.toggle;\n\n// return a css property mapped to a potentially vendor prefixed property\nfunction vendorPropName( style, name ) {\n\n // shortcut for names that are not vendor prefixed\n if ( name in style ) {\n return name;\n }\n\n // check for vendor prefixed names\n var capName = name.charAt(0).toUpperCase() + name.slice(1),\n origName = name,\n i = cssPrefixes.length;\n\n while ( i-- ) {\n name = cssPrefixes[ i ] + capName;\n if ( name in style ) {\n return name;\n }\n }\n\n return origName;\n}\n\nfunction isHidden( elem, el ) {\n elem = el || elem;\n return jQuery.css( elem, \"display\" ) === \"none\" || !jQuery.contains( elem.ownerDocument, elem );\n}\n\nfunction showHide( elements, show ) {\n var elem, display,\n values = [],\n index = 0,\n length = elements.length;\n\n for ( ; index < length; index++ ) {\n elem = elements[ index ];\n if ( !elem.style ) {\n continue;\n }\n values[ index ] = jQuery._data( elem, \"olddisplay\" );\n if ( show ) {\n // Reset the inline display of this element to learn if it is\n // being hidden by cascaded rules or not\n if ( !values[ index ] && elem.style.display === \"none\" ) {\n elem.style.display = \"\";\n }\n\n // Set elements which have been overridden with display: none\n // in a stylesheet to whatever the default browser style is\n // for such an element\n if ( elem.style.display === \"\" && isHidden( elem ) ) {\n values[ index ] = jQuery._data( elem, \"olddisplay\", css_defaultDisplay(elem.nodeName) );\n }\n } else {\n display = curCSS( elem, \"display\" );\n\n if ( !values[ index ] && display !== \"none\" ) {\n jQuery._data( elem, \"olddisplay\", display );\n }\n }\n }\n\n // Set the display of most of the elements in a second loop\n // to avoid the constant reflow\n for ( index = 0; index < length; index++ ) {\n elem = elements[ index ];\n if ( !elem.style ) {\n continue;\n }\n if ( !show || elem.style.display === \"none\" || elem.style.display === \"\" ) {\n elem.style.display = show ? values[ index ] || \"\" : \"none\";\n }\n }\n\n return elements;\n}\n\njQuery.fn.extend({\n css: function( name, value ) {\n return jQuery.access( this, function( elem, name, value ) {\n return value !== undefined ?\n jQuery.style( elem, name, value ) :\n jQuery.css( elem, name );\n }, name, value, arguments.length > 1 );\n },\n show: function() {\n return showHide( this, true );\n },\n hide: function() {\n return showHide( this );\n },\n toggle: function( state, fn2 ) {\n var bool = typeof state === \"boolean\";\n\n if ( jQuery.isFunction( state ) && jQuery.isFunction( fn2 ) ) {\n return eventsToggle.apply( this, arguments );\n }\n\n return this.each(function() {\n if ( bool ? state : isHidden( this ) ) {\n jQuery( this ).show();\n } else {\n jQuery( this ).hide();\n }\n });\n }\n});\n\njQuery.extend({\n // Add in style property hooks for overriding the default\n // behavior of getting and setting a style property\n cssHooks: {\n opacity: {\n get: function( elem, computed ) {\n if ( computed ) {\n // We should always get a number back from opacity\n var ret = curCSS( elem, \"opacity\" );\n return ret === \"\" ? \"1\" : ret;\n\n }\n }\n }\n },\n\n // Exclude the following css properties to add px\n cssNumber: {\n \"fillOpacity\": true,\n \"fontWeight\": true,\n \"lineHeight\": true,\n \"opacity\": true,\n \"orphans\": true,\n \"widows\": true,\n \"zIndex\": true,\n \"zoom\": true\n },\n\n // Add in properties whose names you wish to fix before\n // setting or getting the value\n cssProps: {\n // normalize float css property\n \"float\": jQuery.support.cssFloat ? \"cssFloat\" : \"styleFloat\"\n },\n\n // Get and set the style property on a DOM Node\n style: function( elem, name, value, extra ) {\n // Don't set styles on text and comment nodes\n if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {\n return;\n }\n\n // Make sure that we're working with the right name\n var ret, type, hooks,\n origName = jQuery.camelCase( name ),\n style = elem.style;\n\n name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) );\n\n // gets hook for the prefixed version\n // followed by the unprefixed version\n hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];\n\n // Check if we're setting a value\n if ( value !== undefined ) {\n type = typeof value;\n\n // convert relative number strings (+= or -=) to relative numbers. #7345\n if ( type === \"string\" && (ret = rrelNum.exec( value )) ) {\n value = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) );\n // Fixes bug #9237\n type = \"number\";\n }\n\n // Make sure that NaN and null values aren't set. See: #7116\n if ( value == null || type === \"number\" && isNaN( value ) ) {\n return;\n }\n\n // If a number was passed in, add 'px' to the (except for certain CSS properties)\n if ( type === \"number\" && !jQuery.cssNumber[ origName ] ) {\n value += \"px\";\n }\n\n // If a hook was provided, use that value, otherwise just set the specified value\n if ( !hooks || !(\"set\" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) {\n // Wrapped to prevent IE from throwing errors when 'invalid' values are provided\n // Fixes bug #5509\n try {\n style[ name ] = value;\n } catch(e) {}\n }\n\n } else {\n // If a hook was provided get the non-computed value from there\n if ( hooks && \"get\" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {\n return ret;\n }\n\n // Otherwise just get the value from the style object\n return style[ name ];\n }\n },\n\n css: function( elem, name, numeric, extra ) {\n var val, num, hooks,\n origName = jQuery.camelCase( name );\n\n // Make sure that we're working with the right name\n name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) );\n\n // gets hook for the prefixed version\n // followed by the unprefixed version\n hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];\n\n // If a hook was provided get the computed value from there\n if ( hooks && \"get\" in hooks ) {\n val = hooks.get( elem, true, extra );\n }\n\n // Otherwise, if a way to get the computed value exists, use that\n if ( val === undefined ) {\n val = curCSS( elem, name );\n }\n\n //convert \"normal\" to computed value\n if ( val === \"normal\" && name in cssNormalTransform ) {\n val = cssNormalTransform[ name ];\n }\n\n // Return, converting to number if forced or a qualifier was provided and val looks numeric\n if ( numeric || extra !== undefined ) {\n num = parseFloat( val );\n return numeric || jQuery.isNumeric( num ) ? num || 0 : val;\n }\n return val;\n },\n\n // A method for quickly swapping in/out CSS properties to get correct calculations\n swap: function( elem, options, callback ) {\n var ret, name,\n old = {};\n\n // Remember the old values, and insert the new ones\n for ( name in options ) {\n old[ name ] = elem.style[ name ];\n elem.style[ name ] = options[ name ];\n }\n\n ret = callback.call( elem );\n\n // Revert the old values\n for ( name in options ) {\n elem.style[ name ] = old[ name ];\n }\n\n return ret;\n }\n});\n\n// NOTE: To any future maintainer, we've window.getComputedStyle\n// because jsdom on node.js will break without it.\nif ( window.getComputedStyle ) {\n curCSS = function( elem, name ) {\n var ret, width, minWidth, maxWidth,\n computed = window.getComputedStyle( elem, null ),\n style = elem.style;\n\n if ( computed ) {\n\n // getPropertyValue is only needed for .css('filter') in IE9, see #12537\n ret = computed.getPropertyValue( name ) || computed[ name ];\n\n if ( ret === \"\" && !jQuery.contains( elem.ownerDocument, elem ) ) {\n ret = jQuery.style( elem, name );\n }\n\n // A tribute to the \"awesome hack by Dean Edwards\"\n // Chrome < 17 and Safari 5.0 uses \"computed value\" instead of \"used value\" for margin-right\n // Safari 5.1.7 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels\n // this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values\n if ( rnumnonpx.test( ret ) && rmargin.test( name ) ) {\n width = style.width;\n minWidth = style.minWidth;\n maxWidth = style.maxWidth;\n\n style.minWidth = style.maxWidth = style.width = ret;\n ret = computed.width;\n\n style.width = width;\n style.minWidth = minWidth;\n style.maxWidth = maxWidth;\n }\n }\n\n return ret;\n };\n} else if ( document.documentElement.currentStyle ) {\n curCSS = function( elem, name ) {\n var left, rsLeft,\n ret = elem.currentStyle && elem.currentStyle[ name ],\n style = elem.style;\n\n // Avoid setting ret to empty string here\n // so we don't default to auto\n if ( ret == null && style && style[ name ] ) {\n ret = style[ name ];\n }\n\n // From the awesome hack by Dean Edwards\n // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291\n\n // If we're not dealing with a regular pixel number\n // but a number that has a weird ending, we need to convert it to pixels\n // but not position css attributes, as those are proportional to the parent element instead\n // and we can't measure the parent instead because it might trigger a \"stacking dolls\" problem\n if ( rnumnonpx.test( ret ) && !rposition.test( name ) ) {\n\n // Remember the original values\n left = style.left;\n rsLeft = elem.runtimeStyle && elem.runtimeStyle.left;\n\n // Put in the new values to get a computed value out\n if ( rsLeft ) {\n elem.runtimeStyle.left = elem.currentStyle.left;\n }\n style.left = name === \"fontSize\" ? \"1em\" : ret;\n ret = style.pixelLeft + \"px\";\n\n // Revert the changed values\n style.left = left;\n if ( rsLeft ) {\n elem.runtimeStyle.left = rsLeft;\n }\n }\n\n return ret === \"\" ? \"auto\" : ret;\n };\n}\n\nfunction setPositiveNumber( elem, value, subtract ) {\n var matches = rnumsplit.exec( value );\n return matches ?\n Math.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || \"px\" ) :\n value;\n}\n\nfunction augmentWidthOrHeight( elem, name, extra, isBorderBox ) {\n var i = extra === ( isBorderBox ? \"border\" : \"content\" ) ?\n // If we already have the right measurement, avoid augmentation\n 4 :\n // Otherwise initialize for horizontal or vertical properties\n name === \"width\" ? 1 : 0,\n\n val = 0;\n\n for ( ; i < 4; i += 2 ) {\n // both box models exclude margin, so add it if we want it\n if ( extra === \"margin\" ) {\n // we use jQuery.css instead of curCSS here\n // because of the reliableMarginRight CSS hook!\n val += jQuery.css( elem, extra + cssExpand[ i ], true );\n }\n\n // From this point on we use curCSS for maximum performance (relevant in animations)\n if ( isBorderBox ) {\n // border-box includes padding, so remove it if we want content\n if ( extra === \"content\" ) {\n val -= parseFloat( curCSS( elem, \"padding\" + cssExpand[ i ] ) ) || 0;\n }\n\n // at this point, extra isn't border nor margin, so remove border\n if ( extra !== \"margin\" ) {\n val -= parseFloat( curCSS( elem, \"border\" + cssExpand[ i ] + \"Width\" ) ) || 0;\n }\n } else {\n // at this point, extra isn't content, so add padding\n val += parseFloat( curCSS( elem, \"padding\" + cssExpand[ i ] ) ) || 0;\n\n // at this point, extra isn't content nor padding, so add border\n if ( extra !== \"padding\" ) {\n val += parseFloat( curCSS( elem, \"border\" + cssExpand[ i ] + \"Width\" ) ) || 0;\n }\n }\n }\n\n return val;\n}\n\nfunction getWidthOrHeight( elem, name, extra ) {\n\n // Start with offset property, which is equivalent to the border-box value\n var val = name === \"width\" ? elem.offsetWidth : elem.offsetHeight,\n valueIsBorderBox = true,\n isBorderBox = jQuery.support.boxSizing && jQuery.css( elem, \"boxSizing\" ) === \"border-box\";\n\n // some non-html elements return undefined for offsetWidth, so check for null/undefined\n // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285\n // MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668\n if ( val <= 0 || val == null ) {\n // Fall back to computed then uncomputed css if necessary\n val = curCSS( elem, name );\n if ( val < 0 || val == null ) {\n val = elem.style[ name ];\n }\n\n // Computed unit is not pixels. Stop here and return.\n if ( rnumnonpx.test(val) ) {\n return val;\n }\n\n // we need the check for style in case a browser which returns unreliable values\n // for getComputedStyle silently falls back to the reliable elem.style\n valueIsBorderBox = isBorderBox && ( jQuery.support.boxSizingReliable || val === elem.style[ name ] );\n\n // Normalize \"\", auto, and prepare for extra\n val = parseFloat( val ) || 0;\n }\n\n // use the active box-sizing model to add/subtract irrelevant styles\n return ( val +\n augmentWidthOrHeight(\n elem,\n name,\n extra || ( isBorderBox ? \"border\" : \"content\" ),\n valueIsBorderBox\n )\n ) + \"px\";\n}\n\n\n// Try to determine the default display value of an element\nfunction css_defaultDisplay( nodeName ) {\n if ( elemdisplay[ nodeName ] ) {\n return elemdisplay[ nodeName ];\n }\n\n var elem = jQuery( \"<\" + nodeName + \">\" ).appendTo( document.body ),\n display = elem.css(\"display\");\n elem.remove();\n\n // If the simple way fails,\n // get element's real default display by attaching it to a temp iframe\n if ( display === \"none\" || display === \"\" ) {\n // Use the already-created iframe if possible\n iframe = document.body.appendChild(\n iframe || jQuery.extend( document.createElement(\"iframe\"), {\n frameBorder: 0,\n width: 0,\n height: 0\n })\n );\n\n // Create a cacheable copy of the iframe document on first call.\n // IE and Opera will allow us to reuse the iframeDoc without re-writing the fake HTML\n // document to it; WebKit & Firefox won't allow reusing the iframe document.\n if ( !iframeDoc || !iframe.createElement ) {\n iframeDoc = ( iframe.contentWindow || iframe.contentDocument ).document;\n iframeDoc.write(\"<!doctype html><html><body>\");\n iframeDoc.close();\n }\n\n elem = iframeDoc.body.appendChild( iframeDoc.createElement(nodeName) );\n\n display = curCSS( elem, \"display\" );\n document.body.removeChild( iframe );\n }\n\n // Store the correct default display\n elemdisplay[ nodeName ] = display;\n\n return display;\n}\n\njQuery.each([ \"height\", \"width\" ], function( i, name ) {\n jQuery.cssHooks[ name ] = {\n get: function( elem, computed, extra ) {\n if ( computed ) {\n // certain elements can have dimension info if we invisibly show them\n // however, it must have a current display style that would benefit from this\n if ( elem.offsetWidth === 0 && rdisplayswap.test( curCSS( elem, \"display\" ) ) ) {\n return jQuery.swap( elem, cssShow, function() {\n return getWidthOrHeight( elem, name, extra );\n });\n } else {\n return getWidthOrHeight( elem, name, extra );\n }\n }\n },\n\n set: function( elem, value, extra ) {\n return setPositiveNumber( elem, value, extra ?\n augmentWidthOrHeight(\n elem,\n name,\n extra,\n jQuery.support.boxSizing && jQuery.css( elem, \"boxSizing\" ) === \"border-box\"\n ) : 0\n );\n }\n };\n});\n\nif ( !jQuery.support.opacity ) {\n jQuery.cssHooks.opacity = {\n get: function( elem, computed ) {\n // IE uses filters for opacity\n return ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || \"\" ) ?\n ( 0.01 * parseFloat( RegExp.$1 ) ) + \"\" :\n computed ? \"1\" : \"\";\n },\n\n set: function( elem, value ) {\n var style = elem.style,\n currentStyle = elem.currentStyle,\n opacity = jQuery.isNumeric( value ) ? \"alpha(opacity=\" + value * 100 + \")\" : \"\",\n filter = currentStyle && currentStyle.filter || style.filter || \"\";\n\n // IE has trouble with opacity if it does not have layout\n // Force it by setting the zoom level\n style.zoom = 1;\n\n // if setting opacity to 1, and no other filters exist - attempt to remove filter attribute #6652\n if ( value >= 1 && jQuery.trim( filter.replace( ralpha, \"\" ) ) === \"\" &&\n style.removeAttribute ) {\n\n // Setting style.filter to null, \"\" & \" \" still leave \"filter:\" in the cssText\n // if \"filter:\" is present at all, clearType is disabled, we want to avoid this\n // style.removeAttribute is IE Only, but so apparently is this code path...\n style.removeAttribute( \"filter\" );\n\n // if there there is no filter style applied in a css rule, we are done\n if ( currentStyle && !currentStyle.filter ) {\n return;\n }\n }\n\n // otherwise, set new filter values\n style.filter = ralpha.test( filter ) ?\n filter.replace( ralpha, opacity ) :\n filter + \" \" + opacity;\n }\n };\n}\n\n// These hooks cannot be added until DOM ready because the support test\n// for it is not run until after DOM ready\njQuery(function() {\n if ( !jQuery.support.reliableMarginRight ) {\n jQuery.cssHooks.marginRight = {\n get: function( elem, computed ) {\n // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right\n // Work around by temporarily setting element display to inline-block\n return jQuery.swap( elem, { \"display\": \"inline-block\" }, function() {\n if ( computed ) {\n return curCSS( elem, \"marginRight\" );\n }\n });\n }\n };\n }\n\n // Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084\n // getComputedStyle returns percent when specified for top/left/bottom/right\n // rather than make the css module depend on the offset module, we just check for it here\n if ( !jQuery.support.pixelPosition && jQuery.fn.position ) {\n jQuery.each( [ \"top\", \"left\" ], function( i, prop ) {\n jQuery.cssHooks[ prop ] = {\n get: function( elem, computed ) {\n if ( computed ) {\n var ret = curCSS( elem, prop );\n // if curCSS returns percentage, fallback to offset\n return rnumnonpx.test( ret ) ? jQuery( elem ).position()[ prop ] + \"px\" : ret;\n }\n }\n };\n });\n }\n\n});\n\nif ( jQuery.expr && jQuery.expr.filters ) {\n jQuery.expr.filters.hidden = function( elem ) {\n return ( elem.offsetWidth === 0 && elem.offsetHeight === 0 ) || (!jQuery.support.reliableHiddenOffsets && ((elem.style && elem.style.display) || curCSS( elem, \"display\" )) === \"none\");\n };\n\n jQuery.expr.filters.visible = function( elem ) {\n return !jQuery.expr.filters.hidden( elem );\n };\n}\n\n// These hooks are used by animate to expand properties\njQuery.each({\n margin: \"\",\n padding: \"\",\n border: \"Width\"\n}, function( prefix, suffix ) {\n jQuery.cssHooks[ prefix + suffix ] = {\n expand: function( value ) {\n var i,\n\n // assumes a single number if not a string\n parts = typeof value === \"string\" ? value.split(\" \") : [ value ],\n expanded = {};\n\n for ( i = 0; i < 4; i++ ) {\n expanded[ prefix + cssExpand[ i ] + suffix ] =\n parts[ i ] || parts[ i - 2 ] || parts[ 0 ];\n }\n\n return expanded;\n }\n };\n\n if ( !rmargin.test( prefix ) ) {\n jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;\n }\n});\nvar r20 = /%20/g,\n rbracket = /\\[\\]$/,\n rCRLF = /\\r?\\n/g,\n rinput = /^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,\n rselectTextarea = /^(?:select|textarea)/i;\n\njQuery.fn.extend({\n serialize: function() {\n return jQuery.param( this.serializeArray() );\n },\n serializeArray: function() {\n return this.map(function(){\n return this.elements ? jQuery.makeArray( this.elements ) : this;\n })\n .filter(function(){\n return this.name && !this.disabled &&\n ( this.checked || rselectTextarea.test( this.nodeName ) ||\n rinput.test( this.type ) );\n })\n .map(function( i, elem ){\n var val = jQuery( this ).val();\n\n return val == null ?\n null :\n jQuery.isArray( val ) ?\n jQuery.map( val, function( val, i ){\n return { name: elem.name, value: val.replace( rCRLF, \"\\r\\n\" ) };\n }) :\n { name: elem.name, value: val.replace( rCRLF, \"\\r\\n\" ) };\n }).get();\n }\n});\n\n//Serialize an array of form elements or a set of\n//key/values into a query string\njQuery.param = function( a, traditional ) {\n var prefix,\n s = [],\n add = function( key, value ) {\n // If value is a function, invoke it and return its value\n value = jQuery.isFunction( value ) ? value() : ( value == null ? \"\" : value );\n s[ s.length ] = encodeURIComponent( key ) + \"=\" + encodeURIComponent( value );\n };\n\n // Set traditional to true for jQuery <= 1.3.2 behavior.\n if ( traditional === undefined ) {\n traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional;\n }\n\n // If an array was passed in, assume that it is an array of form elements.\n if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {\n // Serialize the form elements\n jQuery.each( a, function() {\n add( this.name, this.value );\n });\n\n } else {\n // If traditional, encode the \"old\" way (the way 1.3.2 or older\n // did it), otherwise encode params recursively.\n for ( prefix in a ) {\n buildParams( prefix, a[ prefix ], traditional, add );\n }\n }\n\n // Return the resulting serialization\n return s.join( \"&\" ).replace( r20, \"+\" );\n};\n\nfunction buildParams( prefix, obj, traditional, add ) {\n var name;\n\n if ( jQuery.isArray( obj ) ) {\n // Serialize array item.\n jQuery.each( obj, function( i, v ) {\n if ( traditional || rbracket.test( prefix ) ) {\n // Treat each array item as a scalar.\n add( prefix, v );\n\n } else {\n // If array item is non-scalar (array or object), encode its\n // numeric index to resolve deserialization ambiguity issues.\n // Note that rack (as of 1.0.0) can't currently deserialize\n // nested arrays properly, and attempting to do so may cause\n // a server error. Possible fixes are to modify rack's\n // deserialization algorithm or to provide an option or flag\n // to force array serialization to be shallow.\n buildParams( prefix + \"[\" + ( typeof v === \"object\" ? i : \"\" ) + \"]\", v, traditional, add );\n }\n });\n\n } else if ( !traditional && jQuery.type( obj ) === \"object\" ) {\n // Serialize object item.\n for ( name in obj ) {\n buildParams( prefix + \"[\" + name + \"]\", obj[ name ], traditional, add );\n }\n\n } else {\n // Serialize scalar item.\n add( prefix, obj );\n }\n}\nvar\n // Document location\n ajaxLocParts,\n ajaxLocation,\n\n rhash = /#.*$/,\n rheaders = /^(.*?):[ \\t]*([^\\r\\n]*)\\r?$/mg, // IE leaves an \\r character at EOL\n // #7653, #8125, #8152: local protocol detection\n rlocalProtocol = /^(?:about|app|app\\-storage|.+\\-extension|file|res|widget):$/,\n rnoContent = /^(?:GET|HEAD)$/,\n rprotocol = /^\\/\\//,\n rquery = /\\?/,\n rscript = /<script\\b[^<]*(?:(?!<\\/script>)<[^<]*)*<\\/script>/gi,\n rts = /([?&])_=[^&]*/,\n rurl = /^([\\w\\+\\.\\-]+:)(?:\\/\\/([^\\/?#:]*)(?::(\\d+)|)|)/,\n\n // Keep a copy of the old load method\n _load = jQuery.fn.load,\n\n /* Prefilters\n * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)\n * 2) These are called:\n * - BEFORE asking for a transport\n * - AFTER param serialization (s.data is a string if s.processData is true)\n * 3) key is the dataType\n * 4) the catchall symbol \"*\" can be used\n * 5) execution will start with transport dataType and THEN continue down to \"*\" if needed\n */\n prefilters = {},\n\n /* Transports bindings\n * 1) key is the dataType\n * 2) the catchall symbol \"*\" can be used\n * 3) selection will start with transport dataType and THEN go to \"*\" if needed\n */\n transports = {},\n\n // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression\n allTypes = [\"*/\"] + [\"*\"];\n\n// #8138, IE may throw an exception when accessing\n// a field from window.location if document.domain has been set\ntry {\n ajaxLocation = location.href;\n} catch( e ) {\n // Use the href attribute of an A element\n // since IE will modify it given document.location\n ajaxLocation = document.createElement( \"a\" );\n ajaxLocation.href = \"\";\n ajaxLocation = ajaxLocation.href;\n}\n\n// Segment location into parts\najaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];\n\n// Base \"constructor\" for jQuery.ajaxPrefilter and jQuery.ajaxTransport\nfunction addToPrefiltersOrTransports( structure ) {\n\n // dataTypeExpression is optional and defaults to \"*\"\n return function( dataTypeExpression, func ) {\n\n if ( typeof dataTypeExpression !== \"string\" ) {\n func = dataTypeExpression;\n dataTypeExpression = \"*\";\n }\n\n var dataType, list, placeBefore,\n dataTypes = dataTypeExpression.toLowerCase().split( core_rspace ),\n i = 0,\n length = dataTypes.length;\n\n if ( jQuery.isFunction( func ) ) {\n // For each dataType in the dataTypeExpression\n for ( ; i < length; i++ ) {\n dataType = dataTypes[ i ];\n // We control if we're asked to add before\n // any existing element\n placeBefore = /^\\+/.test( dataType );\n if ( placeBefore ) {\n dataType = dataType.substr( 1 ) || \"*\";\n }\n list = structure[ dataType ] = structure[ dataType ] || [];\n // then we add to the structure accordingly\n list[ placeBefore ? \"unshift\" : \"push\" ]( func );\n }\n }\n };\n}\n\n// Base inspection function for prefilters and transports\nfunction inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR,\n dataType /* internal */, inspected /* internal */ ) {\n\n dataType = dataType || options.dataTypes[ 0 ];\n inspected = inspected || {};\n\n inspected[ dataType ] = true;\n\n var selection,\n list = structure[ dataType ],\n i = 0,\n length = list ? list.length : 0,\n executeOnly = ( structure === prefilters );\n\n for ( ; i < length && ( executeOnly || !selection ); i++ ) {\n selection = list[ i ]( options, originalOptions, jqXHR );\n // If we got redirected to another dataType\n // we try there if executing only and not done already\n if ( typeof selection === \"string\" ) {\n if ( !executeOnly || inspected[ selection ] ) {\n selection = undefined;\n } else {\n options.dataTypes.unshift( selection );\n selection = inspectPrefiltersOrTransports(\n structure, options, originalOptions, jqXHR, selection, inspected );\n }\n }\n }\n // If we're only executing or nothing was selected\n // we try the catchall dataType if not done already\n if ( ( executeOnly || !selection ) && !inspected[ \"*\" ] ) {\n selection = inspectPrefiltersOrTransports(\n structure, options, originalOptions, jqXHR, \"*\", inspected );\n }\n // unnecessary when only executing (prefilters)\n // but it'll be ignored by the caller in that case\n return selection;\n}\n\n// A special extend for ajax options\n// that takes \"flat\" options (not to be deep extended)\n// Fixes #9887\nfunction ajaxExtend( target, src ) {\n var key, deep,\n flatOptions = jQuery.ajaxSettings.flatOptions || {};\n for ( key in src ) {\n if ( src[ key ] !== undefined ) {\n ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];\n }\n }\n if ( deep ) {\n jQuery.extend( true, target, deep );\n }\n}\n\njQuery.fn.load = function( url, params, callback ) {\n if ( typeof url !== \"string\" && _load ) {\n return _load.apply( this, arguments );\n }\n\n // Don't do a request if no elements are being requested\n if ( !this.length ) {\n return this;\n }\n\n var selector, type, response,\n self = this,\n off = url.indexOf(\" \");\n\n if ( off >= 0 ) {\n selector = url.slice( off, url.length );\n url = url.slice( 0, off );\n }\n\n // If it's a function\n if ( jQuery.isFunction( params ) ) {\n\n // We assume that it's the callback\n callback = params;\n params = undefined;\n\n // Otherwise, build a param string\n } else if ( params && typeof params === \"object\" ) {\n type = \"POST\";\n }\n\n // Request the remote document\n jQuery.ajax({\n url: url,\n\n // if \"type\" variable is undefined, then \"GET\" method will be used\n type: type,\n dataType: \"html\",\n data: params,\n complete: function( jqXHR, status ) {\n if ( callback ) {\n self.each( callback, response || [ jqXHR.responseText, status, jqXHR ] );\n }\n }\n }).done(function( responseText ) {\n\n // Save response for use in complete callback\n response = arguments;\n\n // See if a selector was specified\n self.html( selector ?\n\n // Create a dummy div to hold the results\n jQuery(\"<div>\")\n\n // inject the contents of the document in, removing the scripts\n // to avoid any 'Permission Denied' errors in IE\n .append( responseText.replace( rscript, \"\" ) )\n\n // Locate the specified elements\n .find( selector ) :\n\n // If not, just inject the full result\n responseText );\n\n });\n\n return this;\n};\n\n// Attach a bunch of functions for handling common AJAX events\njQuery.each( \"ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend\".split( \" \" ), function( i, o ){\n jQuery.fn[ o ] = function( f ){\n return this.on( o, f );\n };\n});\n\njQuery.each( [ \"get\", \"post\" ], function( i, method ) {\n jQuery[ method ] = function( url, data, callback, type ) {\n // shift arguments if data argument was omitted\n if ( jQuery.isFunction( data ) ) {\n type = type || callback;\n callback = data;\n data = undefined;\n }\n\n return jQuery.ajax({\n type: method,\n url: url,\n data: data,\n success: callback,\n dataType: type\n });\n };\n});\n\njQuery.extend({\n\n getScript: function( url, callback ) {\n return jQuery.get( url, undefined, callback, \"script\" );\n },\n\n getJSON: function( url, data, callback ) {\n return jQuery.get( url, data, callback, \"json\" );\n },\n\n // Creates a full fledged settings object into target\n // with both ajaxSettings and settings fields.\n // If target is omitted, writes into ajaxSettings.\n ajaxSetup: function( target, settings ) {\n if ( settings ) {\n // Building a settings object\n ajaxExtend( target, jQuery.ajaxSettings );\n } else {\n // Extending ajaxSettings\n settings = target;\n target = jQuery.ajaxSettings;\n }\n ajaxExtend( target, settings );\n return target;\n },\n\n ajaxSettings: {\n url: ajaxLocation,\n isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),\n global: true,\n type: \"GET\",\n contentType: \"application/x-www-form-urlencoded; charset=UTF-8\",\n processData: true,\n async: true,\n /*\n timeout: 0,\n data: null,\n dataType: null,\n username: null,\n password: null,\n cache: null,\n throws: false,\n traditional: false,\n headers: {},\n */\n\n accepts: {\n xml: \"application/xml, text/xml\",\n html: \"text/html\",\n text: \"text/plain\",\n json: \"application/json, text/javascript\",\n \"*\": allTypes\n },\n\n contents: {\n xml: /xml/,\n html: /html/,\n json: /json/\n },\n\n responseFields: {\n xml: \"responseXML\",\n text: \"responseText\"\n },\n\n // List of data converters\n // 1) key format is \"source_type destination_type\" (a single space in-between)\n // 2) the catchall symbol \"*\" can be used for source_type\n converters: {\n\n // Convert anything to text\n \"* text\": window.String,\n\n // Text to html (true = no transformation)\n \"text html\": true,\n\n // Evaluate text as a json expression\n \"text json\": jQuery.parseJSON,\n\n // Parse text as xml\n \"text xml\": jQuery.parseXML\n },\n\n // For options that shouldn't be deep extended:\n // you can add your own custom options here if\n // and when you create one that shouldn't be\n // deep extended (see ajaxExtend)\n flatOptions: {\n context: true,\n url: true\n }\n },\n\n ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),\n ajaxTransport: addToPrefiltersOrTransports( transports ),\n\n // Main method\n ajax: function( url, options ) {\n\n // If url is an object, simulate pre-1.5 signature\n if ( typeof url === \"object\" ) {\n options = url;\n url = undefined;\n }\n\n // Force options to be an object\n options = options || {};\n\n var // ifModified key\n ifModifiedKey,\n // Response headers\n responseHeadersString,\n responseHeaders,\n // transport\n transport,\n // timeout handle\n timeoutTimer,\n // Cross-domain detection vars\n parts,\n // To know if global events are to be dispatched\n fireGlobals,\n // Loop variable\n i,\n // Create the final options object\n s = jQuery.ajaxSetup( {}, options ),\n // Callbacks context\n callbackContext = s.context || s,\n // Context for global events\n // It's the callbackContext if one was provided in the options\n // and if it's a DOM node or a jQuery collection\n globalEventContext = callbackContext !== s &&\n ( callbackContext.nodeType || callbackContext instanceof jQuery ) ?\n jQuery( callbackContext ) : jQuery.event,\n // Deferreds\n deferred = jQuery.Deferred(),\n completeDeferred = jQuery.Callbacks( \"once memory\" ),\n // Status-dependent callbacks\n statusCode = s.statusCode || {},\n // Headers (they are sent all at once)\n requestHeaders = {},\n requestHeadersNames = {},\n // The jqXHR state\n state = 0,\n // Default abort message\n strAbort = \"canceled\",\n // Fake xhr\n jqXHR = {\n\n readyState: 0,\n\n // Caches the header\n setRequestHeader: function( name, value ) {\n if ( !state ) {\n var lname = name.toLowerCase();\n name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;\n requestHeaders[ name ] = value;\n }\n return this;\n },\n\n // Raw string\n getAllResponseHeaders: function() {\n return state === 2 ? responseHeadersString : null;\n },\n\n // Builds headers hashtable if needed\n getResponseHeader: function( key ) {\n var match;\n if ( state === 2 ) {\n if ( !responseHeaders ) {\n responseHeaders = {};\n while( ( match = rheaders.exec( responseHeadersString ) ) ) {\n responseHeaders[ match[1].toLowerCase() ] = match[ 2 ];\n }\n }\n match = responseHeaders[ key.toLowerCase() ];\n }\n return match === undefined ? null : match;\n },\n\n // Overrides response content-type header\n overrideMimeType: function( type ) {\n if ( !state ) {\n s.mimeType = type;\n }\n return this;\n },\n\n // Cancel the request\n abort: function( statusText ) {\n statusText = statusText || strAbort;\n if ( transport ) {\n transport.abort( statusText );\n }\n done( 0, statusText );\n return this;\n }\n };\n\n // Callback for when everything is done\n // It is defined here because jslint complains if it is declared\n // at the end of the function (which would be more logical and readable)\n function done( status, nativeStatusText, responses, headers ) {\n var isSuccess, success, error, response, modified,\n statusText = nativeStatusText;\n\n // Called once\n if ( state === 2 ) {\n return;\n }\n\n // State is \"done\" now\n state = 2;\n\n // Clear timeout if it exists\n if ( timeoutTimer ) {\n clearTimeout( timeoutTimer );\n }\n\n // Dereference transport for early garbage collection\n // (no matter how long the jqXHR object will be used)\n transport = undefined;\n\n // Cache response headers\n responseHeadersString = headers || \"\";\n\n // Set readyState\n jqXHR.readyState = status > 0 ? 4 : 0;\n\n // Get response data\n if ( responses ) {\n response = ajaxHandleResponses( s, jqXHR, responses );\n }\n\n // If successful, handle type chaining\n if ( status >= 200 && status < 300 || status === 304 ) {\n\n // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.\n if ( s.ifModified ) {\n\n modified = jqXHR.getResponseHeader(\"Last-Modified\");\n if ( modified ) {\n jQuery.lastModified[ ifModifiedKey ] = modified;\n }\n modified = jqXHR.getResponseHeader(\"Etag\");\n if ( modified ) {\n jQuery.etag[ ifModifiedKey ] = modified;\n }\n }\n\n // If not modified\n if ( status === 304 ) {\n\n statusText = \"notmodified\";\n isSuccess = true;\n\n // If we have data\n } else {\n\n isSuccess = ajaxConvert( s, response );\n statusText = isSuccess.state;\n success = isSuccess.data;\n error = isSuccess.error;\n isSuccess = !error;\n }\n } else {\n // We extract error from statusText\n // then normalize statusText and status for non-aborts\n error = statusText;\n if ( !statusText || status ) {\n statusText = \"error\";\n if ( status < 0 ) {\n status = 0;\n }\n }\n }\n\n // Set data for the fake xhr object\n jqXHR.status = status;\n jqXHR.statusText = ( nativeStatusText || statusText ) + \"\";\n\n // Success/Error\n if ( isSuccess ) {\n deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );\n } else {\n deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );\n }\n\n // Status-dependent callbacks\n jqXHR.statusCode( statusCode );\n statusCode = undefined;\n\n if ( fireGlobals ) {\n globalEventContext.trigger( \"ajax\" + ( isSuccess ? \"Success\" : \"Error\" ),\n [ jqXHR, s, isSuccess ? success : error ] );\n }\n\n // Complete\n completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );\n\n if ( fireGlobals ) {\n globalEventContext.trigger( \"ajaxComplete\", [ jqXHR, s ] );\n // Handle the global AJAX counter\n if ( !( --jQuery.active ) ) {\n jQuery.event.trigger( \"ajaxStop\" );\n }\n }\n }\n\n // Attach deferreds\n deferred.promise( jqXHR );\n jqXHR.success = jqXHR.done;\n jqXHR.error = jqXHR.fail;\n jqXHR.complete = completeDeferred.add;\n\n // Status-dependent callbacks\n jqXHR.statusCode = function( map ) {\n if ( map ) {\n var tmp;\n if ( state < 2 ) {\n for ( tmp in map ) {\n statusCode[ tmp ] = [ statusCode[tmp], map[tmp] ];\n }\n } else {\n tmp = map[ jqXHR.status ];\n jqXHR.always( tmp );\n }\n }\n return this;\n };\n\n // Remove hash character (#7531: and string promotion)\n // Add protocol if not provided (#5866: IE7 issue with protocol-less urls)\n // We also use the url parameter if available\n s.url = ( ( url || s.url ) + \"\" ).replace( rhash, \"\" ).replace( rprotocol, ajaxLocParts[ 1 ] + \"//\" );\n\n // Extract dataTypes list\n s.dataTypes = jQuery.trim( s.dataType || \"*\" ).toLowerCase().split( core_rspace );\n\n // A cross-domain request is in order when we have a protocol:host:port mismatch\n if ( s.crossDomain == null ) {\n parts = rurl.exec( s.url.toLowerCase() );\n s.crossDomain = !!( parts &&\n ( parts[ 1 ] !== ajaxLocParts[ 1 ] || parts[ 2 ] !== ajaxLocParts[ 2 ] ||\n ( parts[ 3 ] || ( parts[ 1 ] === \"http:\" ? 80 : 443 ) ) !=\n ( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === \"http:\" ? 80 : 443 ) ) )\n );\n }\n\n // Convert data if not already a string\n if ( s.data && s.processData && typeof s.data !== \"string\" ) {\n s.data = jQuery.param( s.data, s.traditional );\n }\n\n // Apply prefilters\n inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );\n\n // If request was aborted inside a prefilter, stop there\n if ( state === 2 ) {\n return jqXHR;\n }\n\n // We can fire global events as of now if asked to\n fireGlobals = s.global;\n\n // Uppercase the type\n s.type = s.type.toUpperCase();\n\n // Determine if request has content\n s.hasContent = !rnoContent.test( s.type );\n\n // Watch for a new set of requests\n if ( fireGlobals && jQuery.active++ === 0 ) {\n jQuery.event.trigger( \"ajaxStart\" );\n }\n\n // More options handling for requests with no content\n if ( !s.hasContent ) {\n\n // If data is available, append data to url\n if ( s.data ) {\n s.url += ( rquery.test( s.url ) ? \"&\" : \"?\" ) + s.data;\n // #9682: remove data so that it's not used in an eventual retry\n delete s.data;\n }\n\n // Get ifModifiedKey before adding the anti-cache parameter\n ifModifiedKey = s.url;\n\n // Add anti-cache in url if needed\n if ( s.cache === false ) {\n\n var ts = jQuery.now(),\n // try replacing _= if it is there\n ret = s.url.replace( rts, \"$1_=\" + ts );\n\n // if nothing was replaced, add timestamp to the end\n s.url = ret + ( ( ret === s.url ) ? ( rquery.test( s.url ) ? \"&\" : \"?\" ) + \"_=\" + ts : \"\" );\n }\n }\n\n // Set the correct header, if data is being sent\n if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {\n jqXHR.setRequestHeader( \"Content-Type\", s.contentType );\n }\n\n // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.\n if ( s.ifModified ) {\n ifModifiedKey = ifModifiedKey || s.url;\n if ( jQuery.lastModified[ ifModifiedKey ] ) {\n jqXHR.setRequestHeader( \"If-Modified-Since\", jQuery.lastModified[ ifModifiedKey ] );\n }\n if ( jQuery.etag[ ifModifiedKey ] ) {\n jqXHR.setRequestHeader( \"If-None-Match\", jQuery.etag[ ifModifiedKey ] );\n }\n }\n\n // Set the Accepts header for the server, depending on the dataType\n jqXHR.setRequestHeader(\n \"Accept\",\n s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ?\n s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== \"*\" ? \", \" + allTypes + \"; q=0.01\" : \"\" ) :\n s.accepts[ \"*\" ]\n );\n\n // Check for headers option\n for ( i in s.headers ) {\n jqXHR.setRequestHeader( i, s.headers[ i ] );\n }\n\n // Allow custom headers/mimetypes and early abort\n if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {\n // Abort if not done already and return\n return jqXHR.abort();\n\n }\n\n // aborting is no longer a cancellation\n strAbort = \"abort\";\n\n // Install callbacks on deferreds\n for ( i in { success: 1, error: 1, complete: 1 } ) {\n jqXHR[ i ]( s[ i ] );\n }\n\n // Get transport\n transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );\n\n // If no transport, we auto-abort\n if ( !transport ) {\n done( -1, \"No Transport\" );\n } else {\n jqXHR.readyState = 1;\n // Send global event\n if ( fireGlobals ) {\n globalEventContext.trigger( \"ajaxSend\", [ jqXHR, s ] );\n }\n // Timeout\n if ( s.async && s.timeout > 0 ) {\n timeoutTimer = setTimeout( function(){\n jqXHR.abort( \"timeout\" );\n }, s.timeout );\n }\n\n try {\n state = 1;\n transport.send( requestHeaders, done );\n } catch (e) {\n // Propagate exception as error if not done\n if ( state < 2 ) {\n done( -1, e );\n // Simply rethrow otherwise\n } else {\n throw e;\n }\n }\n }\n\n return jqXHR;\n },\n\n // Counter for holding the number of active queries\n active: 0,\n\n // Last-Modified header cache for next request\n lastModified: {},\n etag: {}\n\n});\n\n/* Handles responses to an ajax request:\n * - sets all responseXXX fields accordingly\n * - finds the right dataType (mediates between content-type and expected dataType)\n * - returns the corresponding response\n */\nfunction ajaxHandleResponses( s, jqXHR, responses ) {\n\n var ct, type, finalDataType, firstDataType,\n contents = s.contents,\n dataTypes = s.dataTypes,\n responseFields = s.responseFields;\n\n // Fill responseXXX fields\n for ( type in responseFields ) {\n if ( type in responses ) {\n jqXHR[ responseFields[type] ] = responses[ type ];\n }\n }\n\n // Remove auto dataType and get content-type in the process\n while( dataTypes[ 0 ] === \"*\" ) {\n dataTypes.shift();\n if ( ct === undefined ) {\n ct = s.mimeType || jqXHR.getResponseHeader( \"content-type\" );\n }\n }\n\n // Check if we're dealing with a known content-type\n if ( ct ) {\n for ( type in contents ) {\n if ( contents[ type ] && contents[ type ].test( ct ) ) {\n dataTypes.unshift( type );\n break;\n }\n }\n }\n\n // Check to see if we have a response for the expected dataType\n if ( dataTypes[ 0 ] in responses ) {\n finalDataType = dataTypes[ 0 ];\n } else {\n // Try convertible dataTypes\n for ( type in responses ) {\n if ( !dataTypes[ 0 ] || s.converters[ type + \" \" + dataTypes[0] ] ) {\n finalDataType = type;\n break;\n }\n if ( !firstDataType ) {\n firstDataType = type;\n }\n }\n // Or just use first one\n finalDataType = finalDataType || firstDataType;\n }\n\n // If we found a dataType\n // We add the dataType to the list if needed\n // and return the corresponding response\n if ( finalDataType ) {\n if ( finalDataType !== dataTypes[ 0 ] ) {\n dataTypes.unshift( finalDataType );\n }\n return responses[ finalDataType ];\n }\n}\n\n// Chain conversions given the request and the original response\nfunction ajaxConvert( s, response ) {\n\n var conv, conv2, current, tmp,\n // Work with a copy of dataTypes in case we need to modify it for conversion\n dataTypes = s.dataTypes.slice(),\n prev = dataTypes[ 0 ],\n converters = {},\n i = 0;\n\n // Apply the dataFilter if provided\n if ( s.dataFilter ) {\n response = s.dataFilter( response, s.dataType );\n }\n\n // Create converters map with lowercased keys\n if ( dataTypes[ 1 ] ) {\n for ( conv in s.converters ) {\n converters[ conv.toLowerCase() ] = s.converters[ conv ];\n }\n }\n\n // Convert to each sequential dataType, tolerating list modification\n for ( ; (current = dataTypes[++i]); ) {\n\n // There's only work to do if current dataType is non-auto\n if ( current !== \"*\" ) {\n\n // Convert response if prev dataType is non-auto and differs from current\n if ( prev !== \"*\" && prev !== current ) {\n\n // Seek a direct converter\n conv = converters[ prev + \" \" + current ] || converters[ \"* \" + current ];\n\n // If none found, seek a pair\n if ( !conv ) {\n for ( conv2 in converters ) {\n\n // If conv2 outputs current\n tmp = conv2.split(\" \");\n if ( tmp[ 1 ] === current ) {\n\n // If prev can be converted to accepted input\n conv = converters[ prev + \" \" + tmp[ 0 ] ] ||\n converters[ \"* \" + tmp[ 0 ] ];\n if ( conv ) {\n // Condense equivalence converters\n if ( conv === true ) {\n conv = converters[ conv2 ];\n\n // Otherwise, insert the intermediate dataType\n } else if ( converters[ conv2 ] !== true ) {\n current = tmp[ 0 ];\n dataTypes.splice( i--, 0, current );\n }\n\n break;\n }\n }\n }\n }\n\n // Apply converter (if not an equivalence)\n if ( conv !== true ) {\n\n // Unless errors are allowed to bubble, catch and return them\n if ( conv && s[\"throws\"] ) {\n response = conv( response );\n } else {\n try {\n response = conv( response );\n } catch ( e ) {\n return { state: \"parsererror\", error: conv ? e : \"No conversion from \" + prev + \" to \" + current };\n }\n }\n }\n }\n\n // Update prev for next iteration\n prev = current;\n }\n }\n\n return { state: \"success\", data: response };\n}\nvar oldCallbacks = [],\n rquestion = /\\?/,\n rjsonp = /(=)\\?(?=&|$)|\\?\\?/,\n nonce = jQuery.now();\n\n// Default jsonp settings\njQuery.ajaxSetup({\n jsonp: \"callback\",\n jsonpCallback: function() {\n var callback = oldCallbacks.pop() || ( jQuery.expando + \"_\" + ( nonce++ ) );\n this[ callback ] = true;\n return callback;\n }\n});\n\n// Detect, normalize options and install callbacks for jsonp requests\njQuery.ajaxPrefilter( \"json jsonp\", function( s, originalSettings, jqXHR ) {\n\n var callbackName, overwritten, responseContainer,\n data = s.data,\n url = s.url,\n hasCallback = s.jsonp !== false,\n replaceInUrl = hasCallback && rjsonp.test( url ),\n replaceInData = hasCallback && !replaceInUrl && typeof data === \"string\" &&\n !( s.contentType || \"\" ).indexOf(\"application/x-www-form-urlencoded\") &&\n rjsonp.test( data );\n\n // Handle iff the expected data type is \"jsonp\" or we have a parameter to set\n if ( s.dataTypes[ 0 ] === \"jsonp\" || replaceInUrl || replaceInData ) {\n\n // Get callback name, remembering preexisting value associated with it\n callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?\n s.jsonpCallback() :\n s.jsonpCallback;\n overwritten = window[ callbackName ];\n\n // Insert callback into url or form data\n if ( replaceInUrl ) {\n s.url = url.replace( rjsonp, \"$1\" + callbackName );\n } else if ( replaceInData ) {\n s.data = data.replace( rjsonp, \"$1\" + callbackName );\n } else if ( hasCallback ) {\n s.url += ( rquestion.test( url ) ? \"&\" : \"?\" ) + s.jsonp + \"=\" + callbackName;\n }\n\n // Use data converter to retrieve json after script execution\n s.converters[\"script json\"] = function() {\n if ( !responseContainer ) {\n jQuery.error( callbackName + \" was not called\" );\n }\n return responseContainer[ 0 ];\n };\n\n // force json dataType\n s.dataTypes[ 0 ] = \"json\";\n\n // Install callback\n window[ callbackName ] = function() {\n responseContainer = arguments;\n };\n\n // Clean-up function (fires after converters)\n jqXHR.always(function() {\n // Restore preexisting value\n window[ callbackName ] = overwritten;\n\n // Save back as free\n if ( s[ callbackName ] ) {\n // make sure that re-using the options doesn't screw things around\n s.jsonpCallback = originalSettings.jsonpCallback;\n\n // save the callback name for future use\n oldCallbacks.push( callbackName );\n }\n\n // Call if it was a function and we have a response\n if ( responseContainer && jQuery.isFunction( overwritten ) ) {\n overwritten( responseContainer[ 0 ] );\n }\n\n responseContainer = overwritten = undefined;\n });\n\n // Delegate to script\n return \"script\";\n }\n});\n// Install script dataType\njQuery.ajaxSetup({\n accepts: {\n script: \"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript\"\n },\n contents: {\n script: /javascript|ecmascript/\n },\n converters: {\n \"text script\": function( text ) {\n jQuery.globalEval( text );\n return text;\n }\n }\n});\n\n// Handle cache's special case and global\njQuery.ajaxPrefilter( \"script\", function( s ) {\n if ( s.cache === undefined ) {\n s.cache = false;\n }\n if ( s.crossDomain ) {\n s.type = \"GET\";\n s.global = false;\n }\n});\n\n// Bind script tag hack transport\njQuery.ajaxTransport( \"script\", function(s) {\n\n // This transport only deals with cross domain requests\n if ( s.crossDomain ) {\n\n var script,\n head = document.head || document.getElementsByTagName( \"head\" )[0] || document.documentElement;\n\n return {\n\n send: function( _, callback ) {\n\n script = document.createElement( \"script\" );\n\n script.async = \"async\";\n\n if ( s.scriptCharset ) {\n script.charset = s.scriptCharset;\n }\n\n script.src = s.url;\n\n // Attach handlers for all browsers\n script.onload = script.onreadystatechange = function( _, isAbort ) {\n\n if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) {\n\n // Handle memory leak in IE\n script.onload = script.onreadystatechange = null;\n\n // Remove the script\n if ( head && script.parentNode ) {\n head.removeChild( script );\n }\n\n // Dereference the script\n script = undefined;\n\n // Callback if not abort\n if ( !isAbort ) {\n callback( 200, \"success\" );\n }\n }\n };\n // Use insertBefore instead of appendChild to circumvent an IE6 bug.\n // This arises when a base node is used (#2709 and #4378).\n head.insertBefore( script, head.firstChild );\n },\n\n abort: function() {\n if ( script ) {\n script.onload( 0, 1 );\n }\n }\n };\n }\n});\nvar xhrCallbacks,\n // #5280: Internet Explorer will keep connections alive if we don't abort on unload\n xhrOnUnloadAbort = window.ActiveXObject ? function() {\n // Abort all pending requests\n for ( var key in xhrCallbacks ) {\n xhrCallbacks[ key ]( 0, 1 );\n }\n } : false,\n xhrId = 0;\n\n// Functions to create xhrs\nfunction createStandardXHR() {\n try {\n return new window.XMLHttpRequest();\n } catch( e ) {}\n}\n\nfunction createActiveXHR() {\n try {\n return new window.ActiveXObject( \"Microsoft.XMLHTTP\" );\n } catch( e ) {}\n}\n\n// Create the request object\n// (This is still attached to ajaxSettings for backward compatibility)\njQuery.ajaxSettings.xhr = window.ActiveXObject ?\n /* Microsoft failed to properly\n * implement the XMLHttpRequest in IE7 (can't request local files),\n * so we use the ActiveXObject when it is available\n * Additionally XMLHttpRequest can be disabled in IE7/IE8 so\n * we need a fallback.\n */\n function() {\n return !this.isLocal && createStandardXHR() || createActiveXHR();\n } :\n // For all other browsers, use the standard XMLHttpRequest object\n createStandardXHR;\n\n// Determine support properties\n(function( xhr ) {\n jQuery.extend( jQuery.support, {\n ajax: !!xhr,\n cors: !!xhr && ( \"withCredentials\" in xhr )\n });\n})( jQuery.ajaxSettings.xhr() );\n\n// Create transport if the browser can provide an xhr\nif ( jQuery.support.ajax ) {\n\n jQuery.ajaxTransport(function( s ) {\n // Cross domain only allowed if supported through XMLHttpRequest\n if ( !s.crossDomain || jQuery.support.cors ) {\n\n var callback;\n\n return {\n send: function( headers, complete ) {\n\n // Get a new xhr\n var handle, i,\n xhr = s.xhr();\n\n // Open the socket\n // Passing null username, generates a login popup on Opera (#2865)\n if ( s.username ) {\n xhr.open( s.type, s.url, s.async, s.username, s.password );\n } else {\n xhr.open( s.type, s.url, s.async );\n }\n\n // Apply custom fields if provided\n if ( s.xhrFields ) {\n for ( i in s.xhrFields ) {\n xhr[ i ] = s.xhrFields[ i ];\n }\n }\n\n // Override mime type if needed\n if ( s.mimeType && xhr.overrideMimeType ) {\n xhr.overrideMimeType( s.mimeType );\n }\n\n // X-Requested-With header\n // For cross-domain requests, seeing as conditions for a preflight are\n // akin to a jigsaw puzzle, we simply never set it to be sure.\n // (it can always be set on a per-request basis or even using ajaxSetup)\n // For same-domain requests, won't change header if already provided.\n if ( !s.crossDomain && !headers[\"X-Requested-With\"] ) {\n headers[ \"X-Requested-With\" ] = \"XMLHttpRequest\";\n }\n\n // Need an extra try/catch for cross domain requests in Firefox 3\n try {\n for ( i in headers ) {\n xhr.setRequestHeader( i, headers[ i ] );\n }\n } catch( _ ) {}\n\n // Do send the request\n // This may raise an exception which is actually\n // handled in jQuery.ajax (so no try/catch here)\n xhr.send( ( s.hasContent && s.data ) || null );\n\n // Listener\n callback = function( _, isAbort ) {\n\n var status,\n statusText,\n responseHeaders,\n responses,\n xml;\n\n // Firefox throws exceptions when accessing properties\n // of an xhr when a network error occurred\n // http://helpful.knobs-dials.com/index.php/Component_returned_failure_code:_0x80040111_(NS_ERROR_NOT_AVAILABLE)\n try {\n\n // Was never called and is aborted or complete\n if ( callback && ( isAbort || xhr.readyState === 4 ) ) {\n\n // Only called once\n callback = undefined;\n\n // Do not keep as active anymore\n if ( handle ) {\n xhr.onreadystatechange = jQuery.noop;\n if ( xhrOnUnloadAbort ) {\n delete xhrCallbacks[ handle ];\n }\n }\n\n // If it's an abort\n if ( isAbort ) {\n // Abort it manually if needed\n if ( xhr.readyState !== 4 ) {\n xhr.abort();\n }\n } else {\n status = xhr.status;\n responseHeaders = xhr.getAllResponseHeaders();\n responses = {};\n xml = xhr.responseXML;\n\n // Construct response list\n if ( xml && xml.documentElement /* #4958 */ ) {\n responses.xml = xml;\n }\n\n // When requesting binary data, IE6-9 will throw an exception\n // on any attempt to access responseText (#11426)\n try {\n responses.text = xhr.responseText;\n } catch( e ) {\n }\n\n // Firefox throws an exception when accessing\n // statusText for faulty cross-domain requests\n try {\n statusText = xhr.statusText;\n } catch( e ) {\n // We normalize with Webkit giving an empty statusText\n statusText = \"\";\n }\n\n // Filter status for non standard behaviors\n\n // If the request is local and we have data: assume a success\n // (success with no data won't get notified, that's the best we\n // can do given current implementations)\n if ( !status && s.isLocal && !s.crossDomain ) {\n status = responses.text ? 200 : 404;\n // IE - #1450: sometimes returns 1223 when it should be 204\n } else if ( status === 1223 ) {\n status = 204;\n }\n }\n }\n } catch( firefoxAccessException ) {\n if ( !isAbort ) {\n complete( -1, firefoxAccessException );\n }\n }\n\n // Call complete if needed\n if ( responses ) {\n complete( status, statusText, responses, responseHeaders );\n }\n };\n\n if ( !s.async ) {\n // if we're in sync mode we fire the callback\n callback();\n } else if ( xhr.readyState === 4 ) {\n // (IE6 & IE7) if it's in cache and has been\n // retrieved directly we need to fire the callback\n setTimeout( callback, 0 );\n } else {\n handle = ++xhrId;\n if ( xhrOnUnloadAbort ) {\n // Create the active xhrs callbacks list if needed\n // and attach the unload handler\n if ( !xhrCallbacks ) {\n xhrCallbacks = {};\n jQuery( window ).unload( xhrOnUnloadAbort );\n }\n // Add to list of active xhrs callbacks\n xhrCallbacks[ handle ] = callback;\n }\n xhr.onreadystatechange = callback;\n }\n },\n\n abort: function() {\n if ( callback ) {\n callback(0,1);\n }\n }\n };\n }\n });\n}\nvar fxNow, timerId,\n rfxtypes = /^(?:toggle|show|hide)$/,\n rfxnum = new RegExp( \"^(?:([-+])=|)(\" + core_pnum + \")([a-z%]*)$\", \"i\" ),\n rrun = /queueHooks$/,\n animationPrefilters = [ defaultPrefilter ],\n tweeners = {\n \"*\": [function( prop, value ) {\n var end, unit,\n tween = this.createTween( prop, value ),\n parts = rfxnum.exec( value ),\n target = tween.cur(),\n start = +target || 0,\n scale = 1,\n maxIterations = 20;\n\n if ( parts ) {\n end = +parts[2];\n unit = parts[3] || ( jQuery.cssNumber[ prop ] ? \"\" : \"px\" );\n\n // We need to compute starting value\n if ( unit !== \"px\" && start ) {\n // Iteratively approximate from a nonzero starting point\n // Prefer the current property, because this process will be trivial if it uses the same units\n // Fallback to end or a simple constant\n start = jQuery.css( tween.elem, prop, true ) || end || 1;\n\n do {\n // If previous iteration zeroed out, double until we get *something*\n // Use a string for doubling factor so we don't accidentally see scale as unchanged below\n scale = scale || \".5\";\n\n // Adjust and apply\n start = start / scale;\n jQuery.style( tween.elem, prop, start + unit );\n\n // Update scale, tolerating zero or NaN from tween.cur()\n // And breaking the loop if scale is unchanged or perfect, or if we've just had enough\n } while ( scale !== (scale = tween.cur() / target) && scale !== 1 && --maxIterations );\n }\n\n tween.unit = unit;\n tween.start = start;\n // If a +=/-= token was provided, we're doing a relative animation\n tween.end = parts[1] ? start + ( parts[1] + 1 ) * end : end;\n }\n return tween;\n }]\n };\n\n// Animations created synchronously will run synchronously\nfunction createFxNow() {\n setTimeout(function() {\n fxNow = undefined;\n }, 0 );\n return ( fxNow = jQuery.now() );\n}\n\nfunction createTweens( animation, props ) {\n jQuery.each( props, function( prop, value ) {\n var collection = ( tweeners[ prop ] || [] ).concat( tweeners[ \"*\" ] ),\n index = 0,\n length = collection.length;\n for ( ; index < length; index++ ) {\n if ( collection[ index ].call( animation, prop, value ) ) {\n\n // we're done with this property\n return;\n }\n }\n });\n}\n\nfunction Animation( elem, properties, options ) {\n var result,\n index = 0,\n tweenerIndex = 0,\n length = animationPrefilters.length,\n deferred = jQuery.Deferred().always( function() {\n // don't match elem in the :animated selector\n delete tick.elem;\n }),\n tick = function() {\n var currentTime = fxNow || createFxNow(),\n remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),\n // archaic crash bug won't allow us to use 1 - ( 0.5 || 0 ) (#12497)\n temp = remaining / animation.duration || 0,\n percent = 1 - temp,\n index = 0,\n length = animation.tweens.length;\n\n for ( ; index < length ; index++ ) {\n animation.tweens[ index ].run( percent );\n }\n\n deferred.notifyWith( elem, [ animation, percent, remaining ]);\n\n if ( percent < 1 && length ) {\n return remaining;\n } else {\n deferred.resolveWith( elem, [ animation ] );\n return false;\n }\n },\n animation = deferred.promise({\n elem: elem,\n props: jQuery.extend( {}, properties ),\n opts: jQuery.extend( true, { specialEasing: {} }, options ),\n originalProperties: properties,\n originalOptions: options,\n startTime: fxNow || createFxNow(),\n duration: options.duration,\n tweens: [],\n createTween: function( prop, end, easing ) {\n var tween = jQuery.Tween( elem, animation.opts, prop, end,\n animation.opts.specialEasing[ prop ] || animation.opts.easing );\n animation.tweens.push( tween );\n return tween;\n },\n stop: function( gotoEnd ) {\n var index = 0,\n // if we are going to the end, we want to run all the tweens\n // otherwise we skip this part\n length = gotoEnd ? animation.tweens.length : 0;\n\n for ( ; index < length ; index++ ) {\n animation.tweens[ index ].run( 1 );\n }\n\n // resolve when we played the last frame\n // otherwise, reject\n if ( gotoEnd ) {\n deferred.resolveWith( elem, [ animation, gotoEnd ] );\n } else {\n deferred.rejectWith( elem, [ animation, gotoEnd ] );\n }\n return this;\n }\n }),\n props = animation.props;\n\n propFilter( props, animation.opts.specialEasing );\n\n for ( ; index < length ; index++ ) {\n result = animationPrefilters[ index ].call( animation, elem, props, animation.opts );\n if ( result ) {\n return result;\n }\n }\n\n createTweens( animation, props );\n\n if ( jQuery.isFunction( animation.opts.start ) ) {\n animation.opts.start.call( elem, animation );\n }\n\n jQuery.fx.timer(\n jQuery.extend( tick, {\n anim: animation,\n queue: animation.opts.queue,\n elem: elem\n })\n );\n\n // attach callbacks from options\n return animation.progress( animation.opts.progress )\n .done( animation.opts.done, animation.opts.complete )\n .fail( animation.opts.fail )\n .always( animation.opts.always );\n}\n\nfunction propFilter( props, specialEasing ) {\n var index, name, easing, value, hooks;\n\n // camelCase, specialEasing and expand cssHook pass\n for ( index in props ) {\n name = jQuery.camelCase( index );\n easing = specialEasing[ name ];\n value = props[ index ];\n if ( jQuery.isArray( value ) ) {\n easing = value[ 1 ];\n value = props[ index ] = value[ 0 ];\n }\n\n if ( index !== name ) {\n props[ name ] = value;\n delete props[ index ];\n }\n\n hooks = jQuery.cssHooks[ name ];\n if ( hooks && \"expand\" in hooks ) {\n value = hooks.expand( value );\n delete props[ name ];\n\n // not quite $.extend, this wont overwrite keys already present.\n // also - reusing 'index' from above because we have the correct \"name\"\n for ( index in value ) {\n if ( !( index in props ) ) {\n props[ index ] = value[ index ];\n specialEasing[ index ] = easing;\n }\n }\n } else {\n specialEasing[ name ] = easing;\n }\n }\n}\n\njQuery.Animation = jQuery.extend( Animation, {\n\n tweener: function( props, callback ) {\n if ( jQuery.isFunction( props ) ) {\n callback = props;\n props = [ \"*\" ];\n } else {\n props = props.split(\" \");\n }\n\n var prop,\n index = 0,\n length = props.length;\n\n for ( ; index < length ; index++ ) {\n prop = props[ index ];\n tweeners[ prop ] = tweeners[ prop ] || [];\n tweeners[ prop ].unshift( callback );\n }\n },\n\n prefilter: function( callback, prepend ) {\n if ( prepend ) {\n animationPrefilters.unshift( callback );\n } else {\n animationPrefilters.push( callback );\n }\n }\n});\n\nfunction defaultPrefilter( elem, props, opts ) {\n var index, prop, value, length, dataShow, toggle, tween, hooks, oldfire,\n anim = this,\n style = elem.style,\n orig = {},\n handled = [],\n hidden = elem.nodeType && isHidden( elem );\n\n // handle queue: false promises\n if ( !opts.queue ) {\n hooks = jQuery._queueHooks( elem, \"fx\" );\n if ( hooks.unqueued == null ) {\n hooks.unqueued = 0;\n oldfire = hooks.empty.fire;\n hooks.empty.fire = function() {\n if ( !hooks.unqueued ) {\n oldfire();\n }\n };\n }\n hooks.unqueued++;\n\n anim.always(function() {\n // doing this makes sure that the complete handler will be called\n // before this completes\n anim.always(function() {\n hooks.unqueued--;\n if ( !jQuery.queue( elem, \"fx\" ).length ) {\n hooks.empty.fire();\n }\n });\n });\n }\n\n // height/width overflow pass\n if ( elem.nodeType === 1 && ( \"height\" in props || \"width\" in props ) ) {\n // Make sure that nothing sneaks out\n // Record all 3 overflow attributes because IE does not\n // change the overflow attribute when overflowX and\n // overflowY are set to the same value\n opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];\n\n // Set display property to inline-block for height/width\n // animations on inline elements that are having width/height animated\n if ( jQuery.css( elem, \"display\" ) === \"inline\" &&\n jQuery.css( elem, \"float\" ) === \"none\" ) {\n\n // inline-level elements accept inline-block;\n // block-level elements need to be inline with layout\n if ( !jQuery.support.inlineBlockNeedsLayout || css_defaultDisplay( elem.nodeName ) === \"inline\" ) {\n style.display = \"inline-block\";\n\n } else {\n style.zoom = 1;\n }\n }\n }\n\n if ( opts.overflow ) {\n style.overflow = \"hidden\";\n if ( !jQuery.support.shrinkWrapBlocks ) {\n anim.done(function() {\n style.overflow = opts.overflow[ 0 ];\n style.overflowX = opts.overflow[ 1 ];\n style.overflowY = opts.overflow[ 2 ];\n });\n }\n }\n\n\n // show/hide pass\n for ( index in props ) {\n value = props[ index ];\n if ( rfxtypes.exec( value ) ) {\n delete props[ index ];\n toggle = toggle || value === \"toggle\";\n if ( value === ( hidden ? \"hide\" : \"show\" ) ) {\n continue;\n }\n handled.push( index );\n }\n }\n\n length = handled.length;\n if ( length ) {\n dataShow = jQuery._data( elem, \"fxshow\" ) || jQuery._data( elem, \"fxshow\", {} );\n if ( \"hidden\" in dataShow ) {\n hidden = dataShow.hidden;\n }\n\n // store state if its toggle - enables .stop().toggle() to \"reverse\"\n if ( toggle ) {\n dataShow.hidden = !hidden;\n }\n if ( hidden ) {\n jQuery( elem ).show();\n } else {\n anim.done(function() {\n jQuery( elem ).hide();\n });\n }\n anim.done(function() {\n var prop;\n jQuery.removeData( elem, \"fxshow\", true );\n for ( prop in orig ) {\n jQuery.style( elem, prop, orig[ prop ] );\n }\n });\n for ( index = 0 ; index < length ; index++ ) {\n prop = handled[ index ];\n tween = anim.createTween( prop, hidden ? dataShow[ prop ] : 0 );\n orig[ prop ] = dataShow[ prop ] || jQuery.style( elem, prop );\n\n if ( !( prop in dataShow ) ) {\n dataShow[ prop ] = tween.start;\n if ( hidden ) {\n tween.end = tween.start;\n tween.start = prop === \"width\" || prop === \"height\" ? 1 : 0;\n }\n }\n }\n }\n}\n\nfunction Tween( elem, options, prop, end, easing ) {\n return new Tween.prototype.init( elem, options, prop, end, easing );\n}\njQuery.Tween = Tween;\n\nTween.prototype = {\n constructor: Tween,\n init: function( elem, options, prop, end, easing, unit ) {\n this.elem = elem;\n this.prop = prop;\n this.easing = easing || \"swing\";\n this.options = options;\n this.start = this.now = this.cur();\n this.end = end;\n this.unit = unit || ( jQuery.cssNumber[ prop ] ? \"\" : \"px\" );\n },\n cur: function() {\n var hooks = Tween.propHooks[ this.prop ];\n\n return hooks && hooks.get ?\n hooks.get( this ) :\n Tween.propHooks._default.get( this );\n },\n run: function( percent ) {\n var eased,\n hooks = Tween.propHooks[ this.prop ];\n\n if ( this.options.duration ) {\n this.pos = eased = jQuery.easing[ this.easing ](\n percent, this.options.duration * percent, 0, 1, this.options.duration\n );\n } else {\n this.pos = eased = percent;\n }\n this.now = ( this.end - this.start ) * eased + this.start;\n\n if ( this.options.step ) {\n this.options.step.call( this.elem, this.now, this );\n }\n\n if ( hooks && hooks.set ) {\n hooks.set( this );\n } else {\n Tween.propHooks._default.set( this );\n }\n return this;\n }\n};\n\nTween.prototype.init.prototype = Tween.prototype;\n\nTween.propHooks = {\n _default: {\n get: function( tween ) {\n var result;\n\n if ( tween.elem[ tween.prop ] != null &&\n (!tween.elem.style || tween.elem.style[ tween.prop ] == null) ) {\n return tween.elem[ tween.prop ];\n }\n\n // passing any value as a 4th parameter to .css will automatically\n // attempt a parseFloat and fallback to a string if the parse fails\n // so, simple values such as \"10px\" are parsed to Float.\n // complex values such as \"rotate(1rad)\" are returned as is.\n result = jQuery.css( tween.elem, tween.prop, false, \"\" );\n // Empty strings, null, undefined and \"auto\" are converted to 0.\n return !result || result === \"auto\" ? 0 : result;\n },\n set: function( tween ) {\n // use step hook for back compat - use cssHook if its there - use .style if its\n // available and use plain properties where available\n if ( jQuery.fx.step[ tween.prop ] ) {\n jQuery.fx.step[ tween.prop ]( tween );\n } else if ( tween.elem.style && ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || jQuery.cssHooks[ tween.prop ] ) ) {\n jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );\n } else {\n tween.elem[ tween.prop ] = tween.now;\n }\n }\n }\n};\n\n// Remove in 2.0 - this supports IE8's panic based approach\n// to setting things on disconnected nodes\n\nTween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {\n set: function( tween ) {\n if ( tween.elem.nodeType && tween.elem.parentNode ) {\n tween.elem[ tween.prop ] = tween.now;\n }\n }\n};\n\njQuery.each([ \"toggle\", \"show\", \"hide\" ], function( i, name ) {\n var cssFn = jQuery.fn[ name ];\n jQuery.fn[ name ] = function( speed, easing, callback ) {\n return speed == null || typeof speed === \"boolean\" ||\n // special check for .toggle( handler, handler, ... )\n ( !i && jQuery.isFunction( speed ) && jQuery.isFunction( easing ) ) ?\n cssFn.apply( this, arguments ) :\n this.animate( genFx( name, true ), speed, easing, callback );\n };\n});\n\njQuery.fn.extend({\n fadeTo: function( speed, to, easing, callback ) {\n\n // show any hidden elements after setting opacity to 0\n return this.filter( isHidden ).css( \"opacity\", 0 ).show()\n\n // animate to the value specified\n .end().animate({ opacity: to }, speed, easing, callback );\n },\n animate: function( prop, speed, easing, callback ) {\n var empty = jQuery.isEmptyObject( prop ),\n optall = jQuery.speed( speed, easing, callback ),\n doAnimation = function() {\n // Operate on a copy of prop so per-property easing won't be lost\n var anim = Animation( this, jQuery.extend( {}, prop ), optall );\n\n // Empty animations resolve immediately\n if ( empty ) {\n anim.stop( true );\n }\n };\n\n return empty || optall.queue === false ?\n this.each( doAnimation ) :\n this.queue( optall.queue, doAnimation );\n },\n stop: function( type, clearQueue, gotoEnd ) {\n var stopQueue = function( hooks ) {\n var stop = hooks.stop;\n delete hooks.stop;\n stop( gotoEnd );\n };\n\n if ( typeof type !== \"string\" ) {\n gotoEnd = clearQueue;\n clearQueue = type;\n type = undefined;\n }\n if ( clearQueue && type !== false ) {\n this.queue( type || \"fx\", [] );\n }\n\n return this.each(function() {\n var dequeue = true,\n index = type != null && type + \"queueHooks\",\n timers = jQuery.timers,\n data = jQuery._data( this );\n\n if ( index ) {\n if ( data[ index ] && data[ index ].stop ) {\n stopQueue( data[ index ] );\n }\n } else {\n for ( index in data ) {\n if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {\n stopQueue( data[ index ] );\n }\n }\n }\n\n for ( index = timers.length; index--; ) {\n if ( timers[ index ].elem === this && (type == null || timers[ index ].queue === type) ) {\n timers[ index ].anim.stop( gotoEnd );\n dequeue = false;\n timers.splice( index, 1 );\n }\n }\n\n // start the next in the queue if the last step wasn't forced\n // timers currently will call their complete callbacks, which will dequeue\n // but only if they were gotoEnd\n if ( dequeue || !gotoEnd ) {\n jQuery.dequeue( this, type );\n }\n });\n }\n});\n\n// Generate parameters to create a standard animation\nfunction genFx( type, includeWidth ) {\n var which,\n attrs = { height: type },\n i = 0;\n\n // if we include width, step value is 1 to do all cssExpand values,\n // if we don't include width, step value is 2 to skip over Left and Right\n includeWidth = includeWidth? 1 : 0;\n for( ; i < 4 ; i += 2 - includeWidth ) {\n which = cssExpand[ i ];\n attrs[ \"margin\" + which ] = attrs[ \"padding\" + which ] = type;\n }\n\n if ( includeWidth ) {\n attrs.opacity = attrs.width = type;\n }\n\n return attrs;\n}\n\n// Generate shortcuts for custom animations\njQuery.each({\n slideDown: genFx(\"show\"),\n slideUp: genFx(\"hide\"),\n slideToggle: genFx(\"toggle\"),\n fadeIn: { opacity: \"show\" },\n fadeOut: { opacity: \"hide\" },\n fadeToggle: { opacity: \"toggle\" }\n}, function( name, props ) {\n jQuery.fn[ name ] = function( speed, easing, callback ) {\n return this.animate( props, speed, easing, callback );\n };\n});\n\njQuery.speed = function( speed, easing, fn ) {\n var opt = speed && typeof speed === \"object\" ? jQuery.extend( {}, speed ) : {\n complete: fn || !fn && easing ||\n jQuery.isFunction( speed ) && speed,\n duration: speed,\n easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing\n };\n\n opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === \"number\" ? opt.duration :\n opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;\n\n // normalize opt.queue - true/undefined/null -> \"fx\"\n if ( opt.queue == null || opt.queue === true ) {\n opt.queue = \"fx\";\n }\n\n // Queueing\n opt.old = opt.complete;\n\n opt.complete = function() {\n if ( jQuery.isFunction( opt.old ) ) {\n opt.old.call( this );\n }\n\n if ( opt.queue ) {\n jQuery.dequeue( this, opt.queue );\n }\n };\n\n return opt;\n};\n\njQuery.easing = {\n linear: function( p ) {\n return p;\n },\n swing: function( p ) {\n return 0.5 - Math.cos( p*Math.PI ) / 2;\n }\n};\n\njQuery.timers = [];\njQuery.fx = Tween.prototype.init;\njQuery.fx.tick = function() {\n var timer,\n timers = jQuery.timers,\n i = 0;\n\n fxNow = jQuery.now();\n\n for ( ; i < timers.length; i++ ) {\n timer = timers[ i ];\n // Checks the timer has not already been removed\n if ( !timer() && timers[ i ] === timer ) {\n timers.splice( i--, 1 );\n }\n }\n\n if ( !timers.length ) {\n jQuery.fx.stop();\n }\n fxNow = undefined;\n};\n\njQuery.fx.timer = function( timer ) {\n if ( timer() && jQuery.timers.push( timer ) && !timerId ) {\n timerId = setInterval( jQuery.fx.tick, jQuery.fx.interval );\n }\n};\n\njQuery.fx.interval = 13;\n\njQuery.fx.stop = function() {\n clearInterval( timerId );\n timerId = null;\n};\n\njQuery.fx.speeds = {\n slow: 600,\n fast: 200,\n // Default speed\n _default: 400\n};\n\n// Back Compat <1.8 extension point\njQuery.fx.step = {};\n\nif ( jQuery.expr && jQuery.expr.filters ) {\n jQuery.expr.filters.animated = function( elem ) {\n return jQuery.grep(jQuery.timers, function( fn ) {\n return elem === fn.elem;\n }).length;\n };\n}\nvar rroot = /^(?:body|html)$/i;\n\njQuery.fn.offset = function( options ) {\n if ( arguments.length ) {\n return options === undefined ?\n this :\n this.each(function( i ) {\n jQuery.offset.setOffset( this, options, i );\n });\n }\n\n var docElem, body, win, clientTop, clientLeft, scrollTop, scrollLeft,\n box = { top: 0, left: 0 },\n elem = this[ 0 ],\n doc = elem && elem.ownerDocument;\n\n if ( !doc ) {\n return;\n }\n\n if ( (body = doc.body) === elem ) {\n return jQuery.offset.bodyOffset( elem );\n }\n\n docElem = doc.documentElement;\n\n // Make sure it's not a disconnected DOM node\n if ( !jQuery.contains( docElem, elem ) ) {\n return box;\n }\n\n // If we don't have gBCR, just use 0,0 rather than error\n // BlackBerry 5, iOS 3 (original iPhone)\n if ( typeof elem.getBoundingClientRect !== \"undefined\" ) {\n box = elem.getBoundingClientRect();\n }\n win = getWindow( doc );\n clientTop = docElem.clientTop || body.clientTop || 0;\n clientLeft = docElem.clientLeft || body.clientLeft || 0;\n scrollTop = win.pageYOffset || docElem.scrollTop;\n scrollLeft = win.pageXOffset || docElem.scrollLeft;\n return {\n top: box.top + scrollTop - clientTop,\n left: box.left + scrollLeft - clientLeft\n };\n};\n\njQuery.offset = {\n\n bodyOffset: function( body ) {\n var top = body.offsetTop,\n left = body.offsetLeft;\n\n if ( jQuery.support.doesNotIncludeMarginInBodyOffset ) {\n top += parseFloat( jQuery.css(body, \"marginTop\") ) || 0;\n left += parseFloat( jQuery.css(body, \"marginLeft\") ) || 0;\n }\n\n return { top: top, left: left };\n },\n\n setOffset: function( elem, options, i ) {\n var position = jQuery.css( elem, \"position\" );\n\n // set position first, in-case top/left are set even on static elem\n if ( position === \"static\" ) {\n elem.style.position = \"relative\";\n }\n\n var curElem = jQuery( elem ),\n curOffset = curElem.offset(),\n curCSSTop = jQuery.css( elem, \"top\" ),\n curCSSLeft = jQuery.css( elem, \"left\" ),\n calculatePosition = ( position === \"absolute\" || position === \"fixed\" ) && jQuery.inArray(\"auto\", [curCSSTop, curCSSLeft]) > -1,\n props = {}, curPosition = {}, curTop, curLeft;\n\n // need to be able to calculate position if either top or left is auto and position is either absolute or fixed\n if ( calculatePosition ) {\n curPosition = curElem.position();\n curTop = curPosition.top;\n curLeft = curPosition.left;\n } else {\n curTop = parseFloat( curCSSTop ) || 0;\n curLeft = parseFloat( curCSSLeft ) || 0;\n }\n\n if ( jQuery.isFunction( options ) ) {\n options = options.call( elem, i, curOffset );\n }\n\n if ( options.top != null ) {\n props.top = ( options.top - curOffset.top ) + curTop;\n }\n if ( options.left != null ) {\n props.left = ( options.left - curOffset.left ) + curLeft;\n }\n\n if ( \"using\" in options ) {\n options.using.call( elem, props );\n } else {\n curElem.css( props );\n }\n }\n};\n\n\njQuery.fn.extend({\n\n position: function() {\n if ( !this[0] ) {\n return;\n }\n\n var elem = this[0],\n\n // Get *real* offsetParent\n offsetParent = this.offsetParent(),\n\n // Get correct offsets\n offset = this.offset(),\n parentOffset = rroot.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset();\n\n // Subtract element margins\n // note: when an element has margin: auto the offsetLeft and marginLeft\n // are the same in Safari causing offset.left to incorrectly be 0\n offset.top -= parseFloat( jQuery.css(elem, \"marginTop\") ) || 0;\n offset.left -= parseFloat( jQuery.css(elem, \"marginLeft\") ) || 0;\n\n // Add offsetParent borders\n parentOffset.top += parseFloat( jQuery.css(offsetParent[0], \"borderTopWidth\") ) || 0;\n parentOffset.left += parseFloat( jQuery.css(offsetParent[0], \"borderLeftWidth\") ) || 0;\n\n // Subtract the two offsets\n return {\n top: offset.top - parentOffset.top,\n left: offset.left - parentOffset.left\n };\n },\n\n offsetParent: function() {\n return this.map(function() {\n var offsetParent = this.offsetParent || document.body;\n while ( offsetParent && (!rroot.test(offsetParent.nodeName) && jQuery.css(offsetParent, \"position\") === \"static\") ) {\n offsetParent = offsetParent.offsetParent;\n }\n return offsetParent || document.body;\n });\n }\n});\n\n\n// Create scrollLeft and scrollTop methods\njQuery.each( {scrollLeft: \"pageXOffset\", scrollTop: \"pageYOffset\"}, function( method, prop ) {\n var top = /Y/.test( prop );\n\n jQuery.fn[ method ] = function( val ) {\n return jQuery.access( this, function( elem, method, val ) {\n var win = getWindow( elem );\n\n if ( val === undefined ) {\n return win ? (prop in win) ? win[ prop ] :\n win.document.documentElement[ method ] :\n elem[ method ];\n }\n\n if ( win ) {\n win.scrollTo(\n !top ? val : jQuery( win ).scrollLeft(),\n top ? val : jQuery( win ).scrollTop()\n );\n\n } else {\n elem[ method ] = val;\n }\n }, method, val, arguments.length, null );\n };\n});\n\nfunction getWindow( elem ) {\n return jQuery.isWindow( elem ) ?\n elem :\n elem.nodeType === 9 ?\n elem.defaultView || elem.parentWindow :\n false;\n}\n// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods\njQuery.each( { Height: \"height\", Width: \"width\" }, function( name, type ) {\n jQuery.each( { padding: \"inner\" + name, content: type, \"\": \"outer\" + name }, function( defaultExtra, funcName ) {\n // margin is only for outerHeight, outerWidth\n jQuery.fn[ funcName ] = function( margin, value ) {\n var chainable = arguments.length && ( defaultExtra || typeof margin !== \"boolean\" ),\n extra = defaultExtra || ( margin === true || value === true ? \"margin\" : \"border\" );\n\n return jQuery.access( this, function( elem, type, value ) {\n var doc;\n\n if ( jQuery.isWindow( elem ) ) {\n // As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there\n // isn't a whole lot we can do. See pull request at this URL for discussion:\n // https://github.com/jquery/jquery/pull/764\n return elem.document.documentElement[ \"client\" + name ];\n }\n\n // Get document width or height\n if ( elem.nodeType === 9 ) {\n doc = elem.documentElement;\n\n // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height], whichever is greatest\n // unfortunately, this causes bug #3838 in IE6/8 only, but there is currently no good, small way to fix it.\n return Math.max(\n elem.body[ \"scroll\" + name ], doc[ \"scroll\" + name ],\n elem.body[ \"offset\" + name ], doc[ \"offset\" + name ],\n doc[ \"client\" + name ]\n );\n }\n\n return value === undefined ?\n // Get width or height on the element, requesting but not forcing parseFloat\n jQuery.css( elem, type, value, extra ) :\n\n // Set width or height on the element\n jQuery.style( elem, type, value, extra );\n }, type, chainable ? margin : undefined, chainable, null );\n };\n });\n});\n// Expose jQuery to the global object\nwindow.jQuery = window.$ = jQuery;\n\n// Expose jQuery as an AMD module, but only for AMD loaders that\n// understand the issues with loading multiple versions of jQuery\n// in a page that all might call define(). The loader will indicate\n// they have special allowances for multiple jQuery versions by\n// specifying define.amd.jQuery = true. Register as a named module,\n// since jQuery can be concatenated with other files that may use define,\n// but not use a proper concatenation script that understands anonymous\n// AMD modules. A named AMD is safest and most robust way to register.\n// Lowercase jquery is used because AMD module names are derived from\n// file names, and jQuery is normally delivered in a lowercase file name.\n// Do this after creating the global so that if an AMD module wants to call\n// noConflict to hide this version of jQuery, it will work.\nif ( typeof define === \"function\" && define.amd && define.amd.jQuery ) {\n define( \"jquery\", [], function () { return jQuery; } );\n}\n\n})( window );", - "settings": - { - "buffer_size": 287804, - "line_ending": "Unix", - "name": "/*!" - } - }, - { - "file": "test/integration/test-submit.js", - "settings": - { - "buffer_size": 3638, - "line_ending": "Unix" - } - }, - { - "file": "test/integration/test-submit-custom.js", - "settings": - { - "buffer_size": 3684, - "line_ending": "Unix" - } - }, - { - "file": "test/integration/test-http-response.js", - "settings": - { - "buffer_size": 3109, - "line_ending": "Unix" - } - }, - { - "file": "Readme.md", - "settings": - { - "buffer_size": 2774, - "line_ending": "Unix" - } - }, - { - "contents": "var CRLF = '\\r\\n';\nvar form = new FormData();\n\nvar options = {\n header: CRLF + '--' + form.getBoundary() + CRLF + 'X-Custom-Header: 123' + CRLF + CRLF,\n knownLength: 1\n};\n\nform.append('my_buffer', buffer, options);\n\nform.submit('http://example.com/', function(err, res) {\n if (err) throw err;\n console.log('Done');\n});", - "settings": - { - "buffer_size": 322, - "line_ending": "Unix" - } - }, - { - "file": "test/run.js", - "settings": - { - "buffer_size": 121, - "line_ending": "Unix" - } - } - ], - "build_system": "", - "command_palette": - { - "height": 87.0, - "selected_items": - [ - [ - "Package Control: in", - "Package Control: Install Package" - ], - [ - "Package Control: ins", - "Package Control: Install Package" - ], - [ - "ins", - "Package Control: Install Package" - ], - [ - "insta", - "Package Control: Install Package" - ] - ], - "width": 467.0 - }, - "console": - { - "height": 125.0 - }, - "distraction_free": - { - "menu_visible": true, - "show_minimap": false, - "show_open_files": false, - "show_tabs": false, - "side_bar_visible": false, - "status_bar_visible": false - }, - "file_history": - [ - "/Users/alexi/Dropbox/Projects/node-form-data/test/integration/test-http-respone.js", - "/Users/alexi/Dropbox/Projects/node-form-data/test/run.js", - "/Users/alexi/Dropbox/Projects/libereco.ia.gs/sftp-config-alt.json", - "/Users/alexi/Desktop/test/file.txt", - "/Users/alexi/Desktop/stuff/kodak/web.js", - "/Users/alexi/Desktop/test/test1.js", - "/Users/alexi/Desktop/test/spdy.js", - "/Users/alexi/Dropbox/Projects/libereco.ia.gs/bin/echo.js", - "/Users/alexi/Dropbox/Projects/libereco.ia.gs/static/test.html", - "/Users/alexi/Dropbox/Projects/libereco.ia.gs/bin/passthrough_stream.js", - "/Users/alexi/Dropbox/Projects/libereco.ia.gs/node_modules/request/main.js", - "/Users/alexi/Dropbox/Projects/libereco.ia.gs/node_modules/request/tests/test-pipes.js", - "/Users/alexi/Dropbox/Projects/libereco.ia.gs/static/a/main.js", - "/Users/alexi/Dropbox/Projects/libereco.ia.gs/node_modules/flickr/lib/flickr.js", - "/Users/alexi/Dropbox/Projects/libereco.ia.gs/node_modules/socket.io/lib/socket.io.js", - "/var/folders/xn/475pdrpd72n4s6gdh4y_c2dm0000gn/T/sublime-sftp-browse-1342313240/mapped/var/www/libereco.ia.gs/node_modules/oauth/lib/oauth.js", - "/Users/alexi/Dropbox/Projects/libereco.ia.gs/node_modules/flickr/node_modules/oauth/lib/oauth.js", - "/Users/alexi/Dropbox/Projects/libereco.ia.gs/node_modules/flickr/index.js", - "/Users/alexi/Dropbox/Projects/libereco.ia.gs/node_modules/socket.io/index.js", - "/Users/alexi/Dropbox/Projects/libereco.ia.gs/sftp-config.json", - "/Users/alexi/Dropbox/Projects/libereco.ia.gs/public/index.html", - "/Users/alexi/Desktop/kodak/dns.js", - "/Users/alexi/Dropbox/Projects/500.ia.gs/htdocs/s/fonts.css", - "/Users/alexi/Dropbox/Projects/ia.gs/sftp-config.json", - "/Users/alexi/Downloads/fabric_plaid.png", - "/Users/alexi/Library/Application Support/Sublime Text 2/Packages/Default/Global.sublime-settings", - "/Users/alexi/Dropbox/Projects/ia.gs/node_modules/director/lib/director/router.js", - "/Users/alexi/Dropbox/Projects/ia.gs/web/e/404.html", - "/Users/alexi/Dropbox/Projects/ia.gs/web/e/500.html", - "/Users/alexi/Dropbox/Projects/ia.gs/node_modules/director/lib/director/http/index.js", - "/Users/alexi/Library/Application Support/Sublime Text 2/Packages/SFTP/SFTP.sublime-settings", - "/Users/alexi/Library/Application Support/Sublime Text 2/Packages/SFTP/Default (OSX).sublime-keymap", - "/Users/alexi/Sites/new/sftp-config.json", - "/Users/alexi/Sites/new/polarbear.css", - "/Users/alexi/Library/Application Support/Sublime Text 2/Packages/User/Base File.sublime-settings", - "/Users/alexi/Library/Application Support/Sublime Text 2/Packages/Default/Base File.sublime-settings", - "/Users/alexi/Sites/new/include/Controllers/Home/HomepageController.php" - ], - "find": - { - "height": 35.0 - }, - "find_in_files": - { - "height": 0.0, - "where_history": - [ - "" - ] - }, - "find_state": - { - "case_sensitive": false, - "find_history": - [ - "readable", - "argument", - "mikeal", - "return;", - "throw arguments[1]", - "arguments[1]", - "throw arguments", - "throw arguments[1]", - "path", - "conso", - "isStreamLike", - "parseUrl", - "stream", - "node.js", - "stream", - "http://libereco.ia.gs/", - "flickr_message_nopro", - "auth:done", - "con", - "console", - "photos", - "isReadStream", - "Buffer", - "Bufer", - "multipart", - "sig", - "api", - "api_", - "api_sig", - "writeFile", - "googledoodle.png", - "attachment", - "_write", - "fs", - "mime", - "_putOrPost", - "_performSecureRequest", - "8034", - "try", - "paramsToQueryString", - "_executeOAuthAPIRequest", - "oauth_client", - "_createClient", - "authorization", - "body", - "_performSecureRequest", - "query", - "io.", - ".listen", - "io", - "config", - "set", - "console", - "'next'", - "console", - "_asyncEverySeries", - "runlist", - "function", - "async", - "local", - "Find schools", - "What's up" - ], - "highlight": true, - "in_selection": false, - "preserve_case": false, - "regex": false, - "replace_history": - [ - ], - "reverse": false, - "show_context": true, - "use_buffer2": true, - "whole_word": false, - "wrap": true - }, - "groups": - [ - { - "selected": 1, - "sheets": - [ - { - "buffer": 0, - "file": "test/integration/test-pipe.js", - "settings": - { - "buffer_size": 3625, - "regions": - { - }, - "selection": - [ - [ - 654, - 673 - ] - ], - "settings": - { - "function_name_status_row": 18, - "incomplete_sync": null, - "remote_loading": false, - "synced": false, - "syntax": "Packages/JavaScript/JavaScript.tmLanguage" - }, - "translation.x": 0.0, - "translation.y": 238.0, - "zoom_level": 1.0 - }, - "type": "text" - }, - { - "buffer": 1, - "file": "package.json", - "settings": - { - "buffer_size": 673, - "regions": - { - }, - "selection": - [ - [ - 282, - 282 - ] - ], - "settings": - { - "function_name_status_row": 4, - "incomplete_sync": null, - "remote_loading": false, - "synced": false, - "syntax": "Packages/JavaScript/JSON.tmLanguage" - }, - "translation.x": 0.0, - "translation.y": 0.0, - "zoom_level": 1.0 - }, - "type": "text" - }, - { - "buffer": 2, - "file": "lib/form_data.js", - "settings": - { - "buffer_size": 7510, - "regions": - { - }, - "selection": - [ - [ - 1940, - 1940 - ] - ], - "settings": - { - "function_name_status_row": 65, - "incomplete_sync": null, - "remote_loading": false, - "synced": false, - "syntax": "Packages/JavaScript/JavaScript.tmLanguage" - }, - "translation.x": 0.0, - "translation.y": 658.0, - "zoom_level": 1.0 - }, - "type": "text" - }, - { - "buffer": 3, - "settings": - { - "buffer_size": 287804, - "regions": - { - }, - "selection": - [ - [ - 8273, - 8279 - ] - ], - "settings": - { - "auto_name": "/*!", - "function_name_status_row": 290, - "incomplete_sync": null, - "remote_loading": false, - "synced": false, - "syntax": "Packages/JavaScript/JavaScript.tmLanguage" - }, - "translation.x": 0.0, - "translation.y": 5683.0, - "zoom_level": 1.0 - }, - "type": "text" - }, - { - "buffer": 4, - "file": "test/integration/test-submit.js", - "settings": - { - "buffer_size": 3638, - "regions": - { - }, - "selection": - [ - [ - 3556, - 3556 - ] - ], - "settings": - { - "function_name_status_row": 111, - "incomplete_sync": null, - "remote_loading": false, - "synced": false, - "syntax": "Packages/JavaScript/JavaScript.tmLanguage" - }, - "translation.x": 0.0, - "translation.y": 1200.0, - "zoom_level": 1.0 - }, - "type": "text" - }, - { - "buffer": 5, - "file": "test/integration/test-submit-custom.js", - "settings": - { - "buffer_size": 3684, - "regions": - { - }, - "selection": - [ - [ - 3449, - 3449 - ] - ], - "settings": - { - "function_name_status_row": 104, - "incomplete_sync": null, - "remote_loading": false, - "synced": false, - "syntax": "Packages/JavaScript/JavaScript.tmLanguage" - }, - "translation.x": 0.0, - "translation.y": 1268.0, - "zoom_level": 1.0 - }, - "type": "text" - }, - { - "buffer": 6, - "file": "test/integration/test-http-response.js", - "settings": - { - "buffer_size": 3109, - "regions": - { - }, - "selection": - [ - [ - 2156, - 2156 - ] - ], - "settings": - { - "function_name_status_row": 88, - "incomplete_sync": null, - "remote_loading": false, - "synced": false, - "syntax": "Packages/JavaScript/JavaScript.tmLanguage" - }, - "translation.x": 0.0, - "translation.y": 59.0, - "zoom_level": 1.0 - }, - "type": "text" - }, - { - "buffer": 7, - "file": "Readme.md", - "settings": - { - "buffer_size": 2774, - "regions": - { - }, - "selection": - [ - [ - 0, - 0 - ] - ], - "settings": - { - "function_name_status_row": 0, - "incomplete_sync": null, - "remote_loading": false, - "synced": false, - "syntax": "Packages/Markdown/Markdown.tmLanguage" - }, - "translation.x": 0.0, - "translation.y": 996.0, - "zoom_level": 1.0 - }, - "type": "text" - }, - { - "buffer": 8, - "settings": - { - "buffer_size": 322, - "regions": - { - }, - "selection": - [ - [ - 0, - 322 - ] - ], - "settings": - { - "function_name_status_row": 0, - "incomplete_sync": null, - "remote_loading": false, - "synced": false, - "syntax": "Packages/JavaScript/JavaScript.tmLanguage" - }, - "translation.x": 0.0, - "translation.y": 0.0, - "zoom_level": 1.0 - }, - "type": "text" - }, - { - "buffer": 9, - "file": "test/run.js", - "settings": - { - "buffer_size": 121, - "regions": - { - }, - "selection": - [ - [ - 76, - 76 - ] - ], - "settings": - { - "function_name_status_row": 4, - "incomplete_sync": null, - "remote_loading": false, - "synced": false, - "syntax": "Packages/JavaScript/JavaScript.tmLanguage" - }, - "translation.x": 0.0, - "translation.y": 0.0, - "zoom_level": 1.0 - }, - "type": "text" - } - ] - } - ], - "incremental_find": - { - "height": 0.0 - }, - "input": - { - "height": 31.0 - }, - "layout": - { - "cells": - [ - [ - 0, - 0, - 1, - 1 - ] - ], - "cols": - [ - 0.0, - 1.0 - ], - "rows": - [ - 0.0, - 1.0 - ] - }, - "menu_visible": true, - "output.sftp": - { - "height": 108.0 - }, - "replace": - { - "height": 0.0 - }, - "save_all_on_build": true, - "select_file": - { - "height": 0.0, - "selected_items": - [ - [ - "homepagecon", - "include/Controllers/Home/HomepageController.php" - ], - [ - "polar", - "polarbear.css" - ], - [ - "homepageco", - "include/Controllers/Home/HomepageController.php" - ], - [ - "homepage.js", - "include/js/application/homepage/homepage.js" - ] - ], - "width": 0.0 - }, - "select_project": - { - "height": 0.0, - "selected_items": - [ - ], - "width": 0.0 - }, - "show_minimap": true, - "show_open_files": true, - "show_tabs": true, - "side_bar_visible": true, - "side_bar_width": 250.0, - "status_bar_visible": true -} diff --git a/deps/npm/node_modules/request/node_modules/form-data/node_modules/async/package.json b/deps/npm/node_modules/request/node_modules/form-data/node_modules/async/package.json index 578f9d02640..379c42c2fb8 100644 --- a/deps/npm/node_modules/request/node_modules/form-data/node_modules/async/package.json +++ b/deps/npm/node_modules/request/node_modules/form-data/node_modules/async/package.json @@ -38,5 +38,5 @@ "readme": "# Async.js\n\nAsync is a utility module which provides straight-forward, powerful functions\nfor working with asynchronous JavaScript. Although originally designed for\nuse with [node.js](http://nodejs.org), it can also be used directly in the\nbrowser. Also supports [component](https://github.com/component/component).\n\nAsync provides around 20 functions that include the usual 'functional'\nsuspects (map, reduce, filter, each…) as well as some common patterns\nfor asynchronous control flow (parallel, series, waterfall…). All these\nfunctions assume you follow the node.js convention of providing a single\ncallback as the last argument of your async function.\n\n\n## Quick Examples\n\n```javascript\nasync.map(['file1','file2','file3'], fs.stat, function(err, results){\n // results is now an array of stats for each file\n});\n\nasync.filter(['file1','file2','file3'], fs.exists, function(results){\n // results now equals an array of the existing files\n});\n\nasync.parallel([\n function(){ ... },\n function(){ ... }\n], callback);\n\nasync.series([\n function(){ ... },\n function(){ ... }\n]);\n```\n\nThere are many more functions available so take a look at the docs below for a\nfull list. This module aims to be comprehensive, so if you feel anything is\nmissing please create a GitHub issue for it.\n\n## Common Pitfalls\n\n### Binding a context to an iterator\n\nThis section is really about bind, not about async. If you are wondering how to\nmake async execute your iterators in a given context, or are confused as to why\na method of another library isn't working as an iterator, study this example:\n\n```js\n// Here is a simple object with an (unnecessarily roundabout) squaring method\nvar AsyncSquaringLibrary = {\n squareExponent: 2,\n square: function(number, callback){ \n var result = Math.pow(number, this.squareExponent);\n setTimeout(function(){\n callback(null, result);\n }, 200);\n }\n};\n\nasync.map([1, 2, 3], AsyncSquaringLibrary.square, function(err, result){\n // result is [NaN, NaN, NaN]\n // This fails because the `this.squareExponent` expression in the square\n // function is not evaluated in the context of AsyncSquaringLibrary, and is\n // therefore undefined.\n});\n\nasync.map([1, 2, 3], AsyncSquaringLibrary.square.bind(AsyncSquaringLibrary), function(err, result){\n // result is [1, 4, 9]\n // With the help of bind we can attach a context to the iterator before\n // passing it to async. Now the square function will be executed in its \n // 'home' AsyncSquaringLibrary context and the value of `this.squareExponent`\n // will be as expected.\n});\n```\n\n## Download\n\nThe source is available for download from\n[GitHub](http://github.com/caolan/async).\nAlternatively, you can install using Node Package Manager (npm):\n\n npm install async\n\n__Development:__ [async.js](https://github.com/caolan/async/raw/master/lib/async.js) - 29.6kb Uncompressed\n\n## In the Browser\n\nSo far it's been tested in IE6, IE7, IE8, FF3.6 and Chrome 5. Usage:\n\n```html\n<script type=\"text/javascript\" src=\"async.js\"></script>\n<script type=\"text/javascript\">\n\n async.map(data, asyncProcess, function(err, results){\n alert(results);\n });\n\n</script>\n```\n\n## Documentation\n\n### Collections\n\n* [each](#each)\n* [map](#map)\n* [filter](#filter)\n* [reject](#reject)\n* [reduce](#reduce)\n* [detect](#detect)\n* [sortBy](#sortBy)\n* [some](#some)\n* [every](#every)\n* [concat](#concat)\n\n### Control Flow\n\n* [series](#series)\n* [parallel](#parallel)\n* [whilst](#whilst)\n* [doWhilst](#doWhilst)\n* [until](#until)\n* [doUntil](#doUntil)\n* [forever](#forever)\n* [waterfall](#waterfall)\n* [compose](#compose)\n* [applyEach](#applyEach)\n* [queue](#queue)\n* [cargo](#cargo)\n* [auto](#auto)\n* [iterator](#iterator)\n* [apply](#apply)\n* [nextTick](#nextTick)\n* [times](#times)\n* [timesSeries](#timesSeries)\n\n### Utils\n\n* [memoize](#memoize)\n* [unmemoize](#unmemoize)\n* [log](#log)\n* [dir](#dir)\n* [noConflict](#noConflict)\n\n\n## Collections\n\n<a name=\"forEach\" />\n<a name=\"each\" />\n### each(arr, iterator, callback)\n\nApplies an iterator function to each item in an array, in parallel.\nThe iterator is called with an item from the list and a callback for when it\nhas finished. If the iterator passes an error to this callback, the main\ncallback for the each function is immediately called with the error.\n\nNote, that since this function applies the iterator to each item in parallel\nthere is no guarantee that the iterator functions will complete in order.\n\n__Arguments__\n\n* arr - An array to iterate over.\n* iterator(item, callback) - A function to apply to each item in the array.\n The iterator is passed a callback(err) which must be called once it has \n completed. If no error has occured, the callback should be run without \n arguments or with an explicit null argument.\n* callback(err) - A callback which is called after all the iterator functions\n have finished, or an error has occurred.\n\n__Example__\n\n```js\n// assuming openFiles is an array of file names and saveFile is a function\n// to save the modified contents of that file:\n\nasync.each(openFiles, saveFile, function(err){\n // if any of the saves produced an error, err would equal that error\n});\n```\n\n---------------------------------------\n\n<a name=\"forEachSeries\" />\n<a name=\"eachSeries\" />\n### eachSeries(arr, iterator, callback)\n\nThe same as each only the iterator is applied to each item in the array in\nseries. The next iterator is only called once the current one has completed\nprocessing. This means the iterator functions will complete in order.\n\n\n---------------------------------------\n\n<a name=\"forEachLimit\" />\n<a name=\"eachLimit\" />\n### eachLimit(arr, limit, iterator, callback)\n\nThe same as each only no more than \"limit\" iterators will be simultaneously \nrunning at any time.\n\nNote that the items are not processed in batches, so there is no guarantee that\n the first \"limit\" iterator functions will complete before any others are \nstarted.\n\n__Arguments__\n\n* arr - An array to iterate over.\n* limit - The maximum number of iterators to run at any time.\n* iterator(item, callback) - A function to apply to each item in the array.\n The iterator is passed a callback(err) which must be called once it has \n completed. If no error has occured, the callback should be run without \n arguments or with an explicit null argument.\n* callback(err) - A callback which is called after all the iterator functions\n have finished, or an error has occurred.\n\n__Example__\n\n```js\n// Assume documents is an array of JSON objects and requestApi is a\n// function that interacts with a rate-limited REST api.\n\nasync.eachLimit(documents, 20, requestApi, function(err){\n // if any of the saves produced an error, err would equal that error\n});\n```\n\n---------------------------------------\n\n<a name=\"map\" />\n### map(arr, iterator, callback)\n\nProduces a new array of values by mapping each value in the given array through\nthe iterator function. The iterator is called with an item from the array and a\ncallback for when it has finished processing. The callback takes 2 arguments, \nan error and the transformed item from the array. If the iterator passes an\nerror to this callback, the main callback for the map function is immediately\ncalled with the error.\n\nNote, that since this function applies the iterator to each item in parallel\nthere is no guarantee that the iterator functions will complete in order, however\nthe results array will be in the same order as the original array.\n\n__Arguments__\n\n* arr - An array to iterate over.\n* iterator(item, callback) - A function to apply to each item in the array.\n The iterator is passed a callback(err, transformed) which must be called once \n it has completed with an error (which can be null) and a transformed item.\n* callback(err, results) - A callback which is called after all the iterator\n functions have finished, or an error has occurred. Results is an array of the\n transformed items from the original array.\n\n__Example__\n\n```js\nasync.map(['file1','file2','file3'], fs.stat, function(err, results){\n // results is now an array of stats for each file\n});\n```\n\n---------------------------------------\n\n<a name=\"mapSeries\" />\n### mapSeries(arr, iterator, callback)\n\nThe same as map only the iterator is applied to each item in the array in\nseries. The next iterator is only called once the current one has completed\nprocessing. The results array will be in the same order as the original.\n\n\n---------------------------------------\n\n<a name=\"mapLimit\" />\n### mapLimit(arr, limit, iterator, callback)\n\nThe same as map only no more than \"limit\" iterators will be simultaneously \nrunning at any time.\n\nNote that the items are not processed in batches, so there is no guarantee that\n the first \"limit\" iterator functions will complete before any others are \nstarted.\n\n__Arguments__\n\n* arr - An array to iterate over.\n* limit - The maximum number of iterators to run at any time.\n* iterator(item, callback) - A function to apply to each item in the array.\n The iterator is passed a callback(err, transformed) which must be called once \n it has completed with an error (which can be null) and a transformed item.\n* callback(err, results) - A callback which is called after all the iterator\n functions have finished, or an error has occurred. Results is an array of the\n transformed items from the original array.\n\n__Example__\n\n```js\nasync.map(['file1','file2','file3'], 1, fs.stat, function(err, results){\n // results is now an array of stats for each file\n});\n```\n\n---------------------------------------\n\n<a name=\"filter\" />\n### filter(arr, iterator, callback)\n\n__Alias:__ select\n\nReturns a new array of all the values which pass an async truth test.\n_The callback for each iterator call only accepts a single argument of true or\nfalse, it does not accept an error argument first!_ This is in-line with the\nway node libraries work with truth tests like fs.exists. This operation is\nperformed in parallel, but the results array will be in the same order as the\noriginal.\n\n__Arguments__\n\n* arr - An array to iterate over.\n* iterator(item, callback) - A truth test to apply to each item in the array.\n The iterator is passed a callback(truthValue) which must be called with a \n boolean argument once it has completed.\n* callback(results) - A callback which is called after all the iterator\n functions have finished.\n\n__Example__\n\n```js\nasync.filter(['file1','file2','file3'], fs.exists, function(results){\n // results now equals an array of the existing files\n});\n```\n\n---------------------------------------\n\n<a name=\"filterSeries\" />\n### filterSeries(arr, iterator, callback)\n\n__alias:__ selectSeries\n\nThe same as filter only the iterator is applied to each item in the array in\nseries. The next iterator is only called once the current one has completed\nprocessing. The results array will be in the same order as the original.\n\n---------------------------------------\n\n<a name=\"reject\" />\n### reject(arr, iterator, callback)\n\nThe opposite of filter. Removes values that pass an async truth test.\n\n---------------------------------------\n\n<a name=\"rejectSeries\" />\n### rejectSeries(arr, iterator, callback)\n\nThe same as reject, only the iterator is applied to each item in the array\nin series.\n\n\n---------------------------------------\n\n<a name=\"reduce\" />\n### reduce(arr, memo, iterator, callback)\n\n__aliases:__ inject, foldl\n\nReduces a list of values into a single value using an async iterator to return\neach successive step. Memo is the initial state of the reduction. This\nfunction only operates in series. For performance reasons, it may make sense to\nsplit a call to this function into a parallel map, then use the normal\nArray.prototype.reduce on the results. This function is for situations where\neach step in the reduction needs to be async, if you can get the data before\nreducing it then it's probably a good idea to do so.\n\n__Arguments__\n\n* arr - An array to iterate over.\n* memo - The initial state of the reduction.\n* iterator(memo, item, callback) - A function applied to each item in the\n array to produce the next step in the reduction. The iterator is passed a\n callback(err, reduction) which accepts an optional error as its first \n argument, and the state of the reduction as the second. If an error is \n passed to the callback, the reduction is stopped and the main callback is \n immediately called with the error.\n* callback(err, result) - A callback which is called after all the iterator\n functions have finished. Result is the reduced value.\n\n__Example__\n\n```js\nasync.reduce([1,2,3], 0, function(memo, item, callback){\n // pointless async:\n process.nextTick(function(){\n callback(null, memo + item)\n });\n}, function(err, result){\n // result is now equal to the last value of memo, which is 6\n});\n```\n\n---------------------------------------\n\n<a name=\"reduceRight\" />\n### reduceRight(arr, memo, iterator, callback)\n\n__Alias:__ foldr\n\nSame as reduce, only operates on the items in the array in reverse order.\n\n\n---------------------------------------\n\n<a name=\"detect\" />\n### detect(arr, iterator, callback)\n\nReturns the first value in a list that passes an async truth test. The\niterator is applied in parallel, meaning the first iterator to return true will\nfire the detect callback with that result. That means the result might not be\nthe first item in the original array (in terms of order) that passes the test.\n\nIf order within the original array is important then look at detectSeries.\n\n__Arguments__\n\n* arr - An array to iterate over.\n* iterator(item, callback) - A truth test to apply to each item in the array.\n The iterator is passed a callback(truthValue) which must be called with a \n boolean argument once it has completed.\n* callback(result) - A callback which is called as soon as any iterator returns\n true, or after all the iterator functions have finished. Result will be\n the first item in the array that passes the truth test (iterator) or the\n value undefined if none passed.\n\n__Example__\n\n```js\nasync.detect(['file1','file2','file3'], fs.exists, function(result){\n // result now equals the first file in the list that exists\n});\n```\n\n---------------------------------------\n\n<a name=\"detectSeries\" />\n### detectSeries(arr, iterator, callback)\n\nThe same as detect, only the iterator is applied to each item in the array\nin series. This means the result is always the first in the original array (in\nterms of array order) that passes the truth test.\n\n\n---------------------------------------\n\n<a name=\"sortBy\" />\n### sortBy(arr, iterator, callback)\n\nSorts a list by the results of running each value through an async iterator.\n\n__Arguments__\n\n* arr - An array to iterate over.\n* iterator(item, callback) - A function to apply to each item in the array.\n The iterator is passed a callback(err, sortValue) which must be called once it\n has completed with an error (which can be null) and a value to use as the sort\n criteria.\n* callback(err, results) - A callback which is called after all the iterator\n functions have finished, or an error has occurred. Results is the items from\n the original array sorted by the values returned by the iterator calls.\n\n__Example__\n\n```js\nasync.sortBy(['file1','file2','file3'], function(file, callback){\n fs.stat(file, function(err, stats){\n callback(err, stats.mtime);\n });\n}, function(err, results){\n // results is now the original array of files sorted by\n // modified date\n});\n```\n\n---------------------------------------\n\n<a name=\"some\" />\n### some(arr, iterator, callback)\n\n__Alias:__ any\n\nReturns true if at least one element in the array satisfies an async test.\n_The callback for each iterator call only accepts a single argument of true or\nfalse, it does not accept an error argument first!_ This is in-line with the\nway node libraries work with truth tests like fs.exists. Once any iterator\ncall returns true, the main callback is immediately called.\n\n__Arguments__\n\n* arr - An array to iterate over.\n* iterator(item, callback) - A truth test to apply to each item in the array.\n The iterator is passed a callback(truthValue) which must be called with a \n boolean argument once it has completed.\n* callback(result) - A callback which is called as soon as any iterator returns\n true, or after all the iterator functions have finished. Result will be\n either true or false depending on the values of the async tests.\n\n__Example__\n\n```js\nasync.some(['file1','file2','file3'], fs.exists, function(result){\n // if result is true then at least one of the files exists\n});\n```\n\n---------------------------------------\n\n<a name=\"every\" />\n### every(arr, iterator, callback)\n\n__Alias:__ all\n\nReturns true if every element in the array satisfies an async test.\n_The callback for each iterator call only accepts a single argument of true or\nfalse, it does not accept an error argument first!_ This is in-line with the\nway node libraries work with truth tests like fs.exists.\n\n__Arguments__\n\n* arr - An array to iterate over.\n* iterator(item, callback) - A truth test to apply to each item in the array.\n The iterator is passed a callback(truthValue) which must be called with a \n boolean argument once it has completed.\n* callback(result) - A callback which is called after all the iterator\n functions have finished. Result will be either true or false depending on\n the values of the async tests.\n\n__Example__\n\n```js\nasync.every(['file1','file2','file3'], fs.exists, function(result){\n // if result is true then every file exists\n});\n```\n\n---------------------------------------\n\n<a name=\"concat\" />\n### concat(arr, iterator, callback)\n\nApplies an iterator to each item in a list, concatenating the results. Returns the\nconcatenated list. The iterators are called in parallel, and the results are\nconcatenated as they return. There is no guarantee that the results array will\nbe returned in the original order of the arguments passed to the iterator function.\n\n__Arguments__\n\n* arr - An array to iterate over\n* iterator(item, callback) - A function to apply to each item in the array.\n The iterator is passed a callback(err, results) which must be called once it \n has completed with an error (which can be null) and an array of results.\n* callback(err, results) - A callback which is called after all the iterator\n functions have finished, or an error has occurred. Results is an array containing\n the concatenated results of the iterator function.\n\n__Example__\n\n```js\nasync.concat(['dir1','dir2','dir3'], fs.readdir, function(err, files){\n // files is now a list of filenames that exist in the 3 directories\n});\n```\n\n---------------------------------------\n\n<a name=\"concatSeries\" />\n### concatSeries(arr, iterator, callback)\n\nSame as async.concat, but executes in series instead of parallel.\n\n\n## Control Flow\n\n<a name=\"series\" />\n### series(tasks, [callback])\n\nRun an array of functions in series, each one running once the previous\nfunction has completed. If any functions in the series pass an error to its\ncallback, no more functions are run and the callback for the series is\nimmediately called with the value of the error. Once the tasks have completed,\nthe results are passed to the final callback as an array.\n\nIt is also possible to use an object instead of an array. Each property will be\nrun as a function and the results will be passed to the final callback as an object\ninstead of an array. This can be a more readable way of handling results from\nasync.series.\n\n\n__Arguments__\n\n* tasks - An array or object containing functions to run, each function is passed\n a callback(err, result) it must call on completion with an error (which can\n be null) and an optional result value.\n* callback(err, results) - An optional callback to run once all the functions\n have completed. This function gets a results array (or object) containing all \n the result arguments passed to the task callbacks.\n\n__Example__\n\n```js\nasync.series([\n function(callback){\n // do some stuff ...\n callback(null, 'one');\n },\n function(callback){\n // do some more stuff ...\n callback(null, 'two');\n }\n],\n// optional callback\nfunction(err, results){\n // results is now equal to ['one', 'two']\n});\n\n\n// an example using an object instead of an array\nasync.series({\n one: function(callback){\n setTimeout(function(){\n callback(null, 1);\n }, 200);\n },\n two: function(callback){\n setTimeout(function(){\n callback(null, 2);\n }, 100);\n }\n},\nfunction(err, results) {\n // results is now equal to: {one: 1, two: 2}\n});\n```\n\n---------------------------------------\n\n<a name=\"parallel\" />\n### parallel(tasks, [callback])\n\nRun an array of functions in parallel, without waiting until the previous\nfunction has completed. If any of the functions pass an error to its\ncallback, the main callback is immediately called with the value of the error.\nOnce the tasks have completed, the results are passed to the final callback as an\narray.\n\nIt is also possible to use an object instead of an array. Each property will be\nrun as a function and the results will be passed to the final callback as an object\ninstead of an array. This can be a more readable way of handling results from\nasync.parallel.\n\n\n__Arguments__\n\n* tasks - An array or object containing functions to run, each function is passed \n a callback(err, result) it must call on completion with an error (which can\n be null) and an optional result value.\n* callback(err, results) - An optional callback to run once all the functions\n have completed. This function gets a results array (or object) containing all \n the result arguments passed to the task callbacks.\n\n__Example__\n\n```js\nasync.parallel([\n function(callback){\n setTimeout(function(){\n callback(null, 'one');\n }, 200);\n },\n function(callback){\n setTimeout(function(){\n callback(null, 'two');\n }, 100);\n }\n],\n// optional callback\nfunction(err, results){\n // the results array will equal ['one','two'] even though\n // the second function had a shorter timeout.\n});\n\n\n// an example using an object instead of an array\nasync.parallel({\n one: function(callback){\n setTimeout(function(){\n callback(null, 1);\n }, 200);\n },\n two: function(callback){\n setTimeout(function(){\n callback(null, 2);\n }, 100);\n }\n},\nfunction(err, results) {\n // results is now equals to: {one: 1, two: 2}\n});\n```\n\n---------------------------------------\n\n<a name=\"parallel\" />\n### parallelLimit(tasks, limit, [callback])\n\nThe same as parallel only the tasks are executed in parallel with a maximum of \"limit\" \ntasks executing at any time.\n\nNote that the tasks are not executed in batches, so there is no guarantee that \nthe first \"limit\" tasks will complete before any others are started.\n\n__Arguments__\n\n* tasks - An array or object containing functions to run, each function is passed \n a callback(err, result) it must call on completion with an error (which can\n be null) and an optional result value.\n* limit - The maximum number of tasks to run at any time.\n* callback(err, results) - An optional callback to run once all the functions\n have completed. This function gets a results array (or object) containing all \n the result arguments passed to the task callbacks.\n\n---------------------------------------\n\n<a name=\"whilst\" />\n### whilst(test, fn, callback)\n\nRepeatedly call fn, while test returns true. Calls the callback when stopped,\nor an error occurs.\n\n__Arguments__\n\n* test() - synchronous truth test to perform before each execution of fn.\n* fn(callback) - A function to call each time the test passes. The function is\n passed a callback(err) which must be called once it has completed with an \n optional error argument.\n* callback(err) - A callback which is called after the test fails and repeated\n execution of fn has stopped.\n\n__Example__\n\n```js\nvar count = 0;\n\nasync.whilst(\n function () { return count < 5; },\n function (callback) {\n count++;\n setTimeout(callback, 1000);\n },\n function (err) {\n // 5 seconds have passed\n }\n);\n```\n\n---------------------------------------\n\n<a name=\"doWhilst\" />\n### doWhilst(fn, test, callback)\n\nThe post check version of whilst. To reflect the difference in the order of operations `test` and `fn` arguments are switched. `doWhilst` is to `whilst` as `do while` is to `while` in plain JavaScript.\n\n---------------------------------------\n\n<a name=\"until\" />\n### until(test, fn, callback)\n\nRepeatedly call fn, until test returns true. Calls the callback when stopped,\nor an error occurs.\n\nThe inverse of async.whilst.\n\n---------------------------------------\n\n<a name=\"doUntil\" />\n### doUntil(fn, test, callback)\n\nLike doWhilst except the test is inverted. Note the argument ordering differs from `until`.\n\n---------------------------------------\n\n<a name=\"forever\" />\n### forever(fn, callback)\n\nCalls the asynchronous function 'fn' repeatedly, in series, indefinitely.\nIf an error is passed to fn's callback then 'callback' is called with the\nerror, otherwise it will never be called.\n\n---------------------------------------\n\n<a name=\"waterfall\" />\n### waterfall(tasks, [callback])\n\nRuns an array of functions in series, each passing their results to the next in\nthe array. However, if any of the functions pass an error to the callback, the\nnext function is not executed and the main callback is immediately called with\nthe error.\n\n__Arguments__\n\n* tasks - An array of functions to run, each function is passed a \n callback(err, result1, result2, ...) it must call on completion. The first\n argument is an error (which can be null) and any further arguments will be \n passed as arguments in order to the next task.\n* callback(err, [results]) - An optional callback to run once all the functions\n have completed. This will be passed the results of the last task's callback.\n\n\n\n__Example__\n\n```js\nasync.waterfall([\n function(callback){\n callback(null, 'one', 'two');\n },\n function(arg1, arg2, callback){\n callback(null, 'three');\n },\n function(arg1, callback){\n // arg1 now equals 'three'\n callback(null, 'done');\n }\n], function (err, result) {\n // result now equals 'done' \n});\n```\n\n---------------------------------------\n<a name=\"compose\" />\n### compose(fn1, fn2...)\n\nCreates a function which is a composition of the passed asynchronous\nfunctions. Each function consumes the return value of the function that\nfollows. Composing functions f(), g() and h() would produce the result of\nf(g(h())), only this version uses callbacks to obtain the return values.\n\nEach function is executed with the `this` binding of the composed function.\n\n__Arguments__\n\n* functions... - the asynchronous functions to compose\n\n\n__Example__\n\n```js\nfunction add1(n, callback) {\n setTimeout(function () {\n callback(null, n + 1);\n }, 10);\n}\n\nfunction mul3(n, callback) {\n setTimeout(function () {\n callback(null, n * 3);\n }, 10);\n}\n\nvar add1mul3 = async.compose(mul3, add1);\n\nadd1mul3(4, function (err, result) {\n // result now equals 15\n});\n```\n\n---------------------------------------\n<a name=\"applyEach\" />\n### applyEach(fns, args..., callback)\n\nApplies the provided arguments to each function in the array, calling the\ncallback after all functions have completed. If you only provide the first\nargument then it will return a function which lets you pass in the\narguments as if it were a single function call.\n\n__Arguments__\n\n* fns - the asynchronous functions to all call with the same arguments\n* args... - any number of separate arguments to pass to the function\n* callback - the final argument should be the callback, called when all\n functions have completed processing\n\n\n__Example__\n\n```js\nasync.applyEach([enableSearch, updateSchema], 'bucket', callback);\n\n// partial application example:\nasync.each(\n buckets,\n async.applyEach([enableSearch, updateSchema]),\n callback\n);\n```\n\n---------------------------------------\n\n<a name=\"applyEachSeries\" />\n### applyEachSeries(arr, iterator, callback)\n\nThe same as applyEach only the functions are applied in series.\n\n---------------------------------------\n\n<a name=\"queue\" />\n### queue(worker, concurrency)\n\nCreates a queue object with the specified concurrency. Tasks added to the\nqueue will be processed in parallel (up to the concurrency limit). If all\nworkers are in progress, the task is queued until one is available. Once\na worker has completed a task, the task's callback is called.\n\n__Arguments__\n\n* worker(task, callback) - An asynchronous function for processing a queued\n task, which must call its callback(err) argument when finished, with an \n optional error as an argument.\n* concurrency - An integer for determining how many worker functions should be\n run in parallel.\n\n__Queue objects__\n\nThe queue object returned by this function has the following properties and\nmethods:\n\n* length() - a function returning the number of items waiting to be processed.\n* concurrency - an integer for determining how many worker functions should be\n run in parallel. This property can be changed after a queue is created to\n alter the concurrency on-the-fly.\n* push(task, [callback]) - add a new task to the queue, the callback is called\n once the worker has finished processing the task.\n instead of a single task, an array of tasks can be submitted. the respective callback is used for every task in the list.\n* unshift(task, [callback]) - add a new task to the front of the queue.\n* saturated - a callback that is called when the queue length hits the concurrency and further tasks will be queued\n* empty - a callback that is called when the last item from the queue is given to a worker\n* drain - a callback that is called when the last item from the queue has returned from the worker\n\n__Example__\n\n```js\n// create a queue object with concurrency 2\n\nvar q = async.queue(function (task, callback) {\n console.log('hello ' + task.name);\n callback();\n}, 2);\n\n\n// assign a callback\nq.drain = function() {\n console.log('all items have been processed');\n}\n\n// add some items to the queue\n\nq.push({name: 'foo'}, function (err) {\n console.log('finished processing foo');\n});\nq.push({name: 'bar'}, function (err) {\n console.log('finished processing bar');\n});\n\n// add some items to the queue (batch-wise)\n\nq.push([{name: 'baz'},{name: 'bay'},{name: 'bax'}], function (err) {\n console.log('finished processing bar');\n});\n\n// add some items to the front of the queue\n\nq.unshift({name: 'bar'}, function (err) {\n console.log('finished processing bar');\n});\n```\n\n---------------------------------------\n\n<a name=\"cargo\" />\n### cargo(worker, [payload])\n\nCreates a cargo object with the specified payload. Tasks added to the\ncargo will be processed altogether (up to the payload limit). If the\nworker is in progress, the task is queued until it is available. Once\nthe worker has completed some tasks, each callback of those tasks is called.\n\n__Arguments__\n\n* worker(tasks, callback) - An asynchronous function for processing an array of\n queued tasks, which must call its callback(err) argument when finished, with \n an optional error as an argument.\n* payload - An optional integer for determining how many tasks should be\n processed per round; if omitted, the default is unlimited.\n\n__Cargo objects__\n\nThe cargo object returned by this function has the following properties and\nmethods:\n\n* length() - a function returning the number of items waiting to be processed.\n* payload - an integer for determining how many tasks should be\n process per round. This property can be changed after a cargo is created to\n alter the payload on-the-fly.\n* push(task, [callback]) - add a new task to the queue, the callback is called\n once the worker has finished processing the task.\n instead of a single task, an array of tasks can be submitted. the respective callback is used for every task in the list.\n* saturated - a callback that is called when the queue length hits the concurrency and further tasks will be queued\n* empty - a callback that is called when the last item from the queue is given to a worker\n* drain - a callback that is called when the last item from the queue has returned from the worker\n\n__Example__\n\n```js\n// create a cargo object with payload 2\n\nvar cargo = async.cargo(function (tasks, callback) {\n for(var i=0; i<tasks.length; i++){\n console.log('hello ' + tasks[i].name);\n }\n callback();\n}, 2);\n\n\n// add some items\n\ncargo.push({name: 'foo'}, function (err) {\n console.log('finished processing foo');\n});\ncargo.push({name: 'bar'}, function (err) {\n console.log('finished processing bar');\n});\ncargo.push({name: 'baz'}, function (err) {\n console.log('finished processing baz');\n});\n```\n\n---------------------------------------\n\n<a name=\"auto\" />\n### auto(tasks, [callback])\n\nDetermines the best order for running functions based on their requirements.\nEach function can optionally depend on other functions being completed first,\nand each function is run as soon as its requirements are satisfied. If any of\nthe functions pass an error to their callback, that function will not complete\n(so any other functions depending on it will not run) and the main callback\nwill be called immediately with the error. Functions also receive an object\ncontaining the results of functions which have completed so far.\n\nNote, all functions are called with a results object as a second argument, \nso it is unsafe to pass functions in the tasks object which cannot handle the\nextra argument. For example, this snippet of code:\n\n```js\nasync.auto({\n readData: async.apply(fs.readFile, 'data.txt', 'utf-8');\n}, callback);\n```\n\nwill have the effect of calling readFile with the results object as the last\nargument, which will fail:\n\n```js\nfs.readFile('data.txt', 'utf-8', cb, {});\n```\n\nInstead, wrap the call to readFile in a function which does not forward the \nresults object:\n\n```js\nasync.auto({\n readData: function(cb, results){\n fs.readFile('data.txt', 'utf-8', cb);\n }\n}, callback);\n```\n\n__Arguments__\n\n* tasks - An object literal containing named functions or an array of\n requirements, with the function itself the last item in the array. The key\n used for each function or array is used when specifying requirements. The \n function receives two arguments: (1) a callback(err, result) which must be \n called when finished, passing an error (which can be null) and the result of \n the function's execution, and (2) a results object, containing the results of\n the previously executed functions.\n* callback(err, results) - An optional callback which is called when all the\n tasks have been completed. The callback will receive an error as an argument\n if any tasks pass an error to their callback. Results will always be passed\n\tbut if an error occurred, no other tasks will be performed, and the results\n\tobject will only contain partial results.\n \n\n__Example__\n\n```js\nasync.auto({\n get_data: function(callback){\n // async code to get some data\n },\n make_folder: function(callback){\n // async code to create a directory to store a file in\n // this is run at the same time as getting the data\n },\n write_file: ['get_data', 'make_folder', function(callback){\n // once there is some data and the directory exists,\n // write the data to a file in the directory\n callback(null, filename);\n }],\n email_link: ['write_file', function(callback, results){\n // once the file is written let's email a link to it...\n // results.write_file contains the filename returned by write_file.\n }]\n});\n```\n\nThis is a fairly trivial example, but to do this using the basic parallel and\nseries functions would look like this:\n\n```js\nasync.parallel([\n function(callback){\n // async code to get some data\n },\n function(callback){\n // async code to create a directory to store a file in\n // this is run at the same time as getting the data\n }\n],\nfunction(err, results){\n async.series([\n function(callback){\n // once there is some data and the directory exists,\n // write the data to a file in the directory\n },\n function(callback){\n // once the file is written let's email a link to it...\n }\n ]);\n});\n```\n\nFor a complicated series of async tasks using the auto function makes adding\nnew tasks much easier and makes the code more readable.\n\n\n---------------------------------------\n\n<a name=\"iterator\" />\n### iterator(tasks)\n\nCreates an iterator function which calls the next function in the array,\nreturning a continuation to call the next one after that. It's also possible to\n'peek' the next iterator by doing iterator.next().\n\nThis function is used internally by the async module but can be useful when\nyou want to manually control the flow of functions in series.\n\n__Arguments__\n\n* tasks - An array of functions to run.\n\n__Example__\n\n```js\nvar iterator = async.iterator([\n function(){ sys.p('one'); },\n function(){ sys.p('two'); },\n function(){ sys.p('three'); }\n]);\n\nnode> var iterator2 = iterator();\n'one'\nnode> var iterator3 = iterator2();\n'two'\nnode> iterator3();\n'three'\nnode> var nextfn = iterator2.next();\nnode> nextfn();\n'three'\n```\n\n---------------------------------------\n\n<a name=\"apply\" />\n### apply(function, arguments..)\n\nCreates a continuation function with some arguments already applied, a useful\nshorthand when combined with other control flow functions. Any arguments\npassed to the returned function are added to the arguments originally passed\nto apply.\n\n__Arguments__\n\n* function - The function you want to eventually apply all arguments to.\n* arguments... - Any number of arguments to automatically apply when the\n continuation is called.\n\n__Example__\n\n```js\n// using apply\n\nasync.parallel([\n async.apply(fs.writeFile, 'testfile1', 'test1'),\n async.apply(fs.writeFile, 'testfile2', 'test2'),\n]);\n\n\n// the same process without using apply\n\nasync.parallel([\n function(callback){\n fs.writeFile('testfile1', 'test1', callback);\n },\n function(callback){\n fs.writeFile('testfile2', 'test2', callback);\n }\n]);\n```\n\nIt's possible to pass any number of additional arguments when calling the\ncontinuation:\n\n```js\nnode> var fn = async.apply(sys.puts, 'one');\nnode> fn('two', 'three');\none\ntwo\nthree\n```\n\n---------------------------------------\n\n<a name=\"nextTick\" />\n### nextTick(callback)\n\nCalls the callback on a later loop around the event loop. In node.js this just\ncalls process.nextTick, in the browser it falls back to setImmediate(callback)\nif available, otherwise setTimeout(callback, 0), which means other higher priority\nevents may precede the execution of the callback.\n\nThis is used internally for browser-compatibility purposes.\n\n__Arguments__\n\n* callback - The function to call on a later loop around the event loop.\n\n__Example__\n\n```js\nvar call_order = [];\nasync.nextTick(function(){\n call_order.push('two');\n // call_order now equals ['one','two']\n});\ncall_order.push('one')\n```\n\n<a name=\"times\" />\n### times(n, callback)\n\nCalls the callback n times and accumulates results in the same manner\nyou would use with async.map.\n\n__Arguments__\n\n* n - The number of times to run the function.\n* callback - The function to call n times.\n\n__Example__\n\n```js\n// Pretend this is some complicated async factory\nvar createUser = function(id, callback) {\n callback(null, {\n id: 'user' + id\n })\n}\n// generate 5 users\nasync.times(5, function(n, next){\n createUser(n, function(err, user) {\n next(err, user)\n })\n}, function(err, users) {\n // we should now have 5 users\n});\n```\n\n<a name=\"timesSeries\" />\n### timesSeries(n, callback)\n\nThe same as times only the iterator is applied to each item in the array in\nseries. The next iterator is only called once the current one has completed\nprocessing. The results array will be in the same order as the original.\n\n\n## Utils\n\n<a name=\"memoize\" />\n### memoize(fn, [hasher])\n\nCaches the results of an async function. When creating a hash to store function\nresults against, the callback is omitted from the hash and an optional hash\nfunction can be used.\n\nThe cache of results is exposed as the `memo` property of the function returned\nby `memoize`.\n\n__Arguments__\n\n* fn - the function you to proxy and cache results from.\n* hasher - an optional function for generating a custom hash for storing\n results, it has all the arguments applied to it apart from the callback, and\n must be synchronous.\n\n__Example__\n\n```js\nvar slow_fn = function (name, callback) {\n // do something\n callback(null, result);\n};\nvar fn = async.memoize(slow_fn);\n\n// fn can now be used as if it were slow_fn\nfn('some name', function () {\n // callback\n});\n```\n\n<a name=\"unmemoize\" />\n### unmemoize(fn)\n\nUndoes a memoized function, reverting it to the original, unmemoized\nform. Comes handy in tests.\n\n__Arguments__\n\n* fn - the memoized function\n\n<a name=\"log\" />\n### log(function, arguments)\n\nLogs the result of an async function to the console. Only works in node.js or\nin browsers that support console.log and console.error (such as FF and Chrome).\nIf multiple arguments are returned from the async function, console.log is\ncalled on each argument in order.\n\n__Arguments__\n\n* function - The function you want to eventually apply all arguments to.\n* arguments... - Any number of arguments to apply to the function.\n\n__Example__\n\n```js\nvar hello = function(name, callback){\n setTimeout(function(){\n callback(null, 'hello ' + name);\n }, 1000);\n};\n```\n```js\nnode> async.log(hello, 'world');\n'hello world'\n```\n\n---------------------------------------\n\n<a name=\"dir\" />\n### dir(function, arguments)\n\nLogs the result of an async function to the console using console.dir to\ndisplay the properties of the resulting object. Only works in node.js or\nin browsers that support console.dir and console.error (such as FF and Chrome).\nIf multiple arguments are returned from the async function, console.dir is\ncalled on each argument in order.\n\n__Arguments__\n\n* function - The function you want to eventually apply all arguments to.\n* arguments... - Any number of arguments to apply to the function.\n\n__Example__\n\n```js\nvar hello = function(name, callback){\n setTimeout(function(){\n callback(null, {hello: name});\n }, 1000);\n};\n```\n```js\nnode> async.dir(hello, 'world');\n{hello: 'world'}\n```\n\n---------------------------------------\n\n<a name=\"noConflict\" />\n### noConflict()\n\nChanges the value of async back to its original value, returning a reference to the\nasync object.\n", "readmeFilename": "README.md", "_id": "async@0.2.9", - "_from": "async@~0.2.7" + "_from": "async@~0.2.9" } diff --git a/deps/npm/node_modules/request/node_modules/form-data/package.json b/deps/npm/node_modules/request/node_modules/form-data/package.json index 48236848166..79fb6ef3da7 100644 --- a/deps/npm/node_modules/request/node_modules/form-data/package.json +++ b/deps/npm/node_modules/request/node_modules/form-data/package.json @@ -5,8 +5,8 @@ "url": "http://debuggable.com/" }, "name": "form-data", - "description": "A module to create readable `\"multipart/form-data\"` streams. Can be used to submit forms and file uploads to other web applications.", - "version": "0.0.8", + "description": "A module to create readable \"multipart/form-data\" streams. Can be used to submit forms and file uploads to other web applications.", + "version": "0.1.0", "repository": { "type": "git", "url": "git://github.com/felixge/node-form-data.git" @@ -20,20 +20,20 @@ }, "dependencies": { "combined-stream": "~0.0.4", - "mime": "~1.2.2", - "async": "~0.2.7" + "mime": "~1.2.9", + "async": "~0.2.9" }, "devDependencies": { - "fake": "~0.2.1", + "fake": "~0.2.2", "far": "~0.0.7", - "formidable": "~1.0.13", - "request": "~2.16.6" + "formidable": "~1.0.14", + "request": "~2.22.0" }, - "readme": "# Form-Data [![Build Status](https://travis-ci.org/alexindigo/node-form-data.png?branch=master)](https://travis-ci.org/alexindigo/node-form-data)\n\nA module to create readable `\"multipart/form-data\"` streams. Can be used to\nsubmit forms and file uploads to other web applications.\n\nThe API of this module is inspired by the\n[XMLHttpRequest-2 FormData Interface][xhr2-fd].\n\n[xhr2-fd]: http://dev.w3.org/2006/webapi/XMLHttpRequest-2/Overview.html#the-formdata-interface\n\n## Install\n\n```\nnpm install form-data\n```\n\n## Usage\n\nIn this example we are constructing a form with 3 fields that contain a string,\na buffer and a file stream.\n\n``` javascript\nvar FormData = require('form-data');\nvar fs = require('fs');\n\nvar form = new FormData();\nform.append('my_field', 'my value');\nform.append('my_buffer', new Buffer(10));\nform.append('my_file', fs.createReadStream('/foo/bar.jpg'));\n```\n\nAlso you can use http-response stream:\n\n``` javascript\nvar FormData = require('form-data');\nvar http = require('http');\n\nvar form = new FormData();\n\nhttp.request('http://nodejs.org/images/logo.png', function(response) {\n form.append('my_field', 'my value');\n form.append('my_buffer', new Buffer(10));\n form.append('my_logo', response);\n});\n```\n\nOr @mikeal's request stream:\n\n``` javascript\nvar FormData = require('form-data');\nvar request = require('request');\n\nvar form = new FormData();\n\nform.append('my_field', 'my value');\nform.append('my_buffer', new Buffer(10));\nform.append('my_logo', request('http://nodejs.org/images/logo.png'));\n```\n\nIn order to submit this form to a web application, you can use node's http\nclient interface:\n\n``` javascript\nvar http = require('http');\n\nvar request = http.request({\n method: 'post',\n host: 'example.org',\n path: '/upload',\n headers: form.getHeaders()\n});\n\nform.pipe(request);\n\nrequest.on('response', function(res) {\n console.log(res.statusCode);\n});\n```\n\nOr if you would prefer the `'Content-Length'` header to be set for you:\n\n``` javascript\nform.submit('example.org/upload', function(err, res) {\n console.log(res.statusCode);\n});\n```\n\nTo use custom headers and pre-known length in parts:\n\n``` javascript\nvar CRLF = '\\r\\n';\nvar form = new FormData();\n\nvar options = {\n header: CRLF + '--' + form.getBoundary() + CRLF + 'X-Custom-Header: 123' + CRLF + CRLF,\n knownLength: 1\n};\n\nform.append('my_buffer', buffer, options);\n\nform.submit('http://example.com/', function(err, res) {\n if (err) throw err;\n console.log('Done');\n});\n```\n\nForm-Data can recognize and fetch all the required information from common types of streams (fs.readStream, http.response and mikeal's request), for some other types of streams you'd need to provide \"file\"-related information manually:\n\n``` javascript\nsomeModule.stream(function(err, stdout, stderr) {\n if (err) throw err;\n\n var form = new FormData();\n\n form.append('file', stdout, {\n filename: 'unicycle.jpg',\n contentType: 'image/jpg',\n knownLength: 19806\n });\n\n form.submit('http://example.com/', function(err, res) {\n if (err) throw err;\n console.log('Done');\n });\n});\n```\n\nFor edge cases, like POST request to URL with query string or to pass HTTP auth credentials, object can be passed to `form.submit()` as first parameter:\n\n``` javascript\nform.submit({\n host: 'example.com',\n path: '/probably.php?extra=params',\n auth: 'username:password'\n}, function(err, res) {\n console.log(res.statusCode);\n});\n```\n\n## TODO\n\n- Add new streams (0.10) support and try really hard not to break it for 0.8.x.\n\n## License\n\nForm-Data is licensed under the MIT license.\n", + "readme": "# Form-Data [![Build Status](https://travis-ci.org/felixge/node-form-data.png?branch=master)](https://travis-ci.org/felixge/node-form-data) [![Dependency Status](https://gemnasium.com/felixge/node-form-data.png)](https://gemnasium.com/felixge/node-form-data)\n\nA module to create readable ```\"multipart/form-data\"``` streams. Can be used to submit forms and file uploads to other web applications.\n\nThe API of this module is inspired by the [XMLHttpRequest-2 FormData Interface][xhr2-fd].\n\n[xhr2-fd]: http://dev.w3.org/2006/webapi/XMLHttpRequest-2/Overview.html#the-formdata-interface\n\n## Install\n\n```\nnpm install form-data\n```\n\n## Usage\n\nIn this example we are constructing a form with 3 fields that contain a string,\na buffer and a file stream.\n\n``` javascript\nvar FormData = require('form-data');\nvar fs = require('fs');\n\nvar form = new FormData();\nform.append('my_field', 'my value');\nform.append('my_buffer', new Buffer(10));\nform.append('my_file', fs.createReadStream('/foo/bar.jpg'));\n```\n\nAlso you can use http-response stream:\n\n``` javascript\nvar FormData = require('form-data');\nvar http = require('http');\n\nvar form = new FormData();\n\nhttp.request('http://nodejs.org/images/logo.png', function(response) {\n form.append('my_field', 'my value');\n form.append('my_buffer', new Buffer(10));\n form.append('my_logo', response);\n});\n```\n\nOr @mikeal's request stream:\n\n``` javascript\nvar FormData = require('form-data');\nvar request = require('request');\n\nvar form = new FormData();\n\nform.append('my_field', 'my value');\nform.append('my_buffer', new Buffer(10));\nform.append('my_logo', request('http://nodejs.org/images/logo.png'));\n```\n\nIn order to submit this form to a web application, you can use node's http\nclient interface:\n\n``` javascript\nvar http = require('http');\n\nvar request = http.request({\n method: 'post',\n host: 'example.org',\n path: '/upload',\n headers: form.getHeaders()\n});\n\nform.pipe(request);\n\nrequest.on('response', function(res) {\n console.log(res.statusCode);\n});\n```\n\nOr if you would prefer the `'Content-Length'` header to be set for you:\n\n``` javascript\nform.submit('example.org/upload', function(err, res) {\n console.log(res.statusCode);\n});\n```\n\nTo use custom headers and pre-known length in parts:\n\n``` javascript\nvar CRLF = '\\r\\n';\nvar form = new FormData();\n\nvar options = {\n header: CRLF + '--' + form.getBoundary() + CRLF + 'X-Custom-Header: 123' + CRLF + CRLF,\n knownLength: 1\n};\n\nform.append('my_buffer', buffer, options);\n\nform.submit('http://example.com/', function(err, res) {\n if (err) throw err;\n console.log('Done');\n});\n```\n\nForm-Data can recognize and fetch all the required information from common types of streams (fs.readStream, http.response and mikeal's request), for some other types of streams you'd need to provide \"file\"-related information manually:\n\n``` javascript\nsomeModule.stream(function(err, stdout, stderr) {\n if (err) throw err;\n\n var form = new FormData();\n\n form.append('file', stdout, {\n filename: 'unicycle.jpg',\n contentType: 'image/jpg',\n knownLength: 19806\n });\n\n form.submit('http://example.com/', function(err, res) {\n if (err) throw err;\n console.log('Done');\n });\n});\n```\n\nFor edge cases, like POST request to URL with query string or to pass HTTP auth credentials, object can be passed to `form.submit()` as first parameter:\n\n``` javascript\nform.submit({\n host: 'example.com',\n path: '/probably.php?extra=params',\n auth: 'username:password'\n}, function(err, res) {\n console.log(res.statusCode);\n});\n```\n\n## Notes\n\n- ```getLengthSync()``` method DOESN'T calculate length for streams, use ```knownLength``` options as workaround.\n\n## TODO\n\n- Add new streams (0.10) support and try really hard not to break it for 0.8.x.\n\n## License\n\nForm-Data is licensed under the MIT license.\n", "readmeFilename": "Readme.md", "bugs": { "url": "https://github.com/felixge/node-form-data/issues" }, - "_id": "form-data@0.0.8", - "_from": "form-data@0.0.8" + "_id": "form-data@0.1.0", + "_from": "form-data@~0.1.0" } diff --git a/deps/npm/node_modules/request/node_modules/form-data/sftp-config.json b/deps/npm/node_modules/request/node_modules/form-data/sftp-config.json deleted file mode 100644 index ad9ed2623d5..00000000000 --- a/deps/npm/node_modules/request/node_modules/form-data/sftp-config.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - // The tab key will cycle through the settings when first created - // Visit http://wbond.net/sublime_packages/sftp/settings for help - - // sftp, ftp or ftps - "type": "sftp", - - "save_before_upload": true, - "upload_on_save": true, - "sync_down_on_open": false, - "sync_skip_deletes": false, - "confirm_downloads": false, - "confirm_sync": true, - "confirm_overwrite_newer": false, - - "host": "amber.exposeapp.com", - "user": "alex", - //"password": "password", - //"port": "22", - - "remote_path": "/var/www/_playground/form-data/", - "ignore_regexes": [ - "node_modules", - "\\.sublime-(project|workspace)", "sftp-config(-alt\\d?)?\\.json", - "sftp-settings\\.json", "/venv/", "\\.svn", "\\.hg", "\\.git", - "\\.bzr", "_darcs", "CVS", "\\.DS_Store", "Thumbs\\.db", "desktop\\.ini" - ], - //"file_permissions": "664", - //"dir_permissions": "775", - - //"extra_list_connections": 0, - - "connect_timeout": 30, - //"keepalive": 120, - //"ftp_passive_mode": true, - //"ssh_key_file": "~/.ssh/id_rsa", - //"sftp_flags": ["-F", "/path/to/ssh_config"], - - //"preserve_modification_times": false, - //"remote_time_offset_in_hours": 0, - //"remote_encoding": "utf-8", - //"remote_locale": "C", -} diff --git a/deps/npm/node_modules/request/node_modules/form-data/test/common.js b/deps/npm/node_modules/request/node_modules/form-data/test/common.js deleted file mode 100644 index 8a26482e1ea..00000000000 --- a/deps/npm/node_modules/request/node_modules/form-data/test/common.js +++ /dev/null @@ -1,14 +0,0 @@ -var common = module.exports; -var path = require('path'); - -var rootDir = path.join(__dirname, '..'); -common.dir = { - lib: rootDir + '/lib', - fixture: rootDir + '/test/fixture', - tmp: rootDir + '/test/tmp', -}; - -common.assert = require('assert'); -common.fake = require('fake'); - -common.port = 8432; diff --git a/deps/npm/node_modules/request/node_modules/form-data/test/fixture/bacon.txt b/deps/npm/node_modules/request/node_modules/form-data/test/fixture/bacon.txt deleted file mode 100644 index 9804bbdc63c..00000000000 --- a/deps/npm/node_modules/request/node_modules/form-data/test/fixture/bacon.txt +++ /dev/null @@ -1 +0,0 @@ -Bacon is delicious. diff --git a/deps/npm/node_modules/request/node_modules/form-data/test/fixture/unicycle.jpg b/deps/npm/node_modules/request/node_modules/form-data/test/fixture/unicycle.jpg Binary files differdeleted file mode 100644 index 7cea4dd71dc..00000000000 --- a/deps/npm/node_modules/request/node_modules/form-data/test/fixture/unicycle.jpg +++ /dev/null diff --git a/deps/npm/node_modules/request/node_modules/form-data/test/integration/test-custom-filename.js b/deps/npm/node_modules/request/node_modules/form-data/test/integration/test-custom-filename.js deleted file mode 100644 index 05f3fc036ef..00000000000 --- a/deps/npm/node_modules/request/node_modules/form-data/test/integration/test-custom-filename.js +++ /dev/null @@ -1,52 +0,0 @@ -/* -test custom filename and content-type: -re: https://github.com/felixge/node-form-data/issues/29 -*/ - -var common = require('../common'); -var assert = common.assert; -var http = require('http'); -var fs = require('fs'); - -var FormData = require(common.dir.lib + '/form_data'); -var IncomingForm = require('formidable').IncomingForm; - -var options = { - filename: 'test.png', - contentType: 'image/gif' -}; - -var server = http.createServer(function(req, res) { - - var form = new IncomingForm({uploadDir: common.dir.tmp}); - - form.parse(req); - - form - .on('file', function(name, file) { - assert.strictEqual(name, 'my_file'); - assert.strictEqual(file.name, options.filename); - assert.strictEqual(file.type, options.contentType); - }) - .on('end', function() { - res.writeHead(200); - res.end('done'); - }); -}); - - -server.listen(common.port, function() { - var form = new FormData(); - - form.append('my_file', fs.createReadStream(common.dir.fixture + '/unicycle.jpg'), options); - - form.submit('http://localhost:' + common.port + '/', function(err, res) { - if (err) { - throw err; - } - - assert.strictEqual(res.statusCode, 200); - server.close(); - }); - -}); diff --git a/deps/npm/node_modules/request/node_modules/form-data/test/integration/test-custom-headers.js b/deps/npm/node_modules/request/node_modules/form-data/test/integration/test-custom-headers.js deleted file mode 100644 index 1c9b6adad56..00000000000 --- a/deps/npm/node_modules/request/node_modules/form-data/test/integration/test-custom-headers.js +++ /dev/null @@ -1,75 +0,0 @@ -/* -test custom headers, added in pull request: -https://github.com/felixge/node-form-data/pull/17 -*/ - -var common = require('../common'); -var assert = common.assert; -var http = require('http'); - -var FormData = require(common.dir.lib + '/form_data'); - -var CRLF = '\r\n'; - -var testHeader = 'X-Test-Fake: 123'; - -var expectedLength; - - -var server = http.createServer(function(req, res) { - var data = ''; - req.setEncoding('utf8'); - - req.on('data', function(d) { - data += d; - }); - - req.on('end', function() { - assert.ok( data.indexOf( testHeader ) != -1 ); - - // content-length would be 1000+ w/actual buffer size, - // but smaller w/overridden size. - assert.ok( typeof req.headers['content-length'] !== 'undefined' ); - assert.equal(req.headers['content-length'], expectedLength); - - res.writeHead(200); - res.end('done'); - }); -}); - - -server.listen(common.port, function() { - var form = new FormData(); - - var options = { - header: - CRLF + '--' + form.getBoundary() + CRLF + - testHeader + - CRLF + CRLF, - - // override content-length, - // much lower than actual buffer size (1000) - knownLength: 1 - }; - - var bufferData = []; - for (var z = 0; z < 1000; z++) { - bufferData.push(1); - } - var buffer = new Buffer(bufferData); - - form.append('my_buffer', buffer, options); - - // (available to req handler) - expectedLength = form._lastBoundary().length + form._overheadLength + options.knownLength; - - form.submit('http://localhost:' + common.port + '/', function(err, res) { - if (err) { - throw err; - } - - assert.strictEqual(res.statusCode, 200); - server.close(); - }); - -}); diff --git a/deps/npm/node_modules/request/node_modules/form-data/test/integration/test-form-get-length.js b/deps/npm/node_modules/request/node_modules/form-data/test/integration/test-form-get-length.js deleted file mode 100644 index 44d3b4dc276..00000000000 --- a/deps/npm/node_modules/request/node_modules/form-data/test/integration/test-form-get-length.js +++ /dev/null @@ -1,93 +0,0 @@ -var common = require('../common'); -var assert = common.assert; -var FormData = require(common.dir.lib + '/form_data'); -var fake = require('fake').create(); -var fs = require('fs'); - -(function testEmptyForm() { - var form = new FormData(); - var callback = fake.callback(arguments.callee.name + '-getLength'); - var calls = fake.expectAnytime(callback, [null, 0]).calls; - - form.getLength(callback); - - // Make sure our response is async - assert.strictEqual(calls.length, 0); -})(); - -(function testUtf8String() { - var FIELD = 'my_field'; - var VALUE = 'May the € be with you'; - - var form = new FormData(); - form.append(FIELD, VALUE); - var callback = fake.callback(arguments.callee.name + '-getLength'); - - var expectedLength = - form._overheadLength + - Buffer.byteLength(VALUE) + - form._lastBoundary().length; - - fake.expectAnytime(callback, [null, expectedLength]); - form.getLength(callback); -})(); - -(function testBuffer() { - var FIELD = 'my_field'; - var VALUE = new Buffer(23); - - var form = new FormData(); - form.append(FIELD, VALUE); - var callback = fake.callback(arguments.callee.name + '-getLength'); - - var expectedLength = - form._overheadLength + - VALUE.length + - form._lastBoundary().length; - - fake.expectAnytime(callback, [null, expectedLength]); - form.getLength(callback); -})(); - - -(function testStringFileBufferFile() { - var fields = [ - { - name: 'my_field', - value: 'Test 123', - }, - { - name: 'my_image', - value: fs.createReadStream(common.dir.fixture + '/unicycle.jpg'), - }, - { - name: 'my_buffer', - value: new Buffer('123'), - }, - { - name: 'my_txt', - value: fs.createReadStream(common.dir.fixture + '/bacon.txt'), - }, - ]; - - var form = new FormData(); - var expectedLength = 0; - - fields.forEach(function(field) { - form.append(field.name, field.value); - if (field.value.path) { - var stat = fs.statSync(field.value.path); - expectedLength += stat.size; - } else { - expectedLength += field.value.length; - } - }); - - expectedLength += form._overheadLength + form._lastBoundary().length; - - var callback = fake.callback(arguments.callee.name + '-getLength'); - fake.expectAnytime(callback, [null, expectedLength]); - form.getLength(callback); -})(); - - diff --git a/deps/npm/node_modules/request/node_modules/form-data/test/integration/test-get-boundary.js b/deps/npm/node_modules/request/node_modules/form-data/test/integration/test-get-boundary.js deleted file mode 100644 index 6dc2fb2bdde..00000000000 --- a/deps/npm/node_modules/request/node_modules/form-data/test/integration/test-get-boundary.js +++ /dev/null @@ -1,18 +0,0 @@ -var common = require('../common'); -var assert = common.assert; - -var FormData = require(common.dir.lib + '/form_data'); - -(function testOneBoundaryPerForm() { - var form = new FormData(); - var boundary = form.getBoundary(); - - assert.equal(boundary, form.getBoundary()); - assert.equal(boundary.length, 50); -})(); - -(function testUniqueBoundaryPerForm() { - var formA = new FormData(); - var formB = new FormData(); - assert.notEqual(formA.getBoundary(), formB.getBoundary()); -})(); diff --git a/deps/npm/node_modules/request/node_modules/form-data/test/integration/test-http-response.js b/deps/npm/node_modules/request/node_modules/form-data/test/integration/test-http-response.js deleted file mode 100644 index bebb26b35f4..00000000000 --- a/deps/npm/node_modules/request/node_modules/form-data/test/integration/test-http-response.js +++ /dev/null @@ -1,83 +0,0 @@ -var common = require('../common'); -var assert = common.assert; -var http = require('http'); -var path = require('path'); -var mime = require('mime'); -var request = require('request'); -var parseUrl = require('url').parse; -var fs = require('fs'); -var FormData = require(common.dir.lib + '/form_data'); -var IncomingForm = require('formidable').IncomingForm; - -var remoteFile = 'http://nodejs.org/images/logo.png'; - -var FIELDS; -var server; - -var parsedUrl = parseUrl(remoteFile) - , options = { - method: 'get', - port: parsedUrl.port || 80, - path: parsedUrl.pathname, - host: parsedUrl.hostname - } - ; - -http.request(options, function(res) { - - FIELDS = [ - {name: 'my_field', value: 'my_value'}, - {name: 'my_buffer', value: new Buffer([1, 2, 3])}, - {name: 'remote_file', value: res } - ]; - - var form = new FormData(); - FIELDS.forEach(function(field) { - form.append(field.name, field.value); - }); - - server.listen(common.port, function() { - - form.submit('http://localhost:' + common.port + '/', function(err, res) { - - if (err) { - throw err; - } - - assert.strictEqual(res.statusCode, 200); - server.close(); - }); - - }); - -}).end(); - -server = http.createServer(function(req, res) { - - var form = new IncomingForm({uploadDir: common.dir.tmp}); - - form.parse(req); - - form - .on('field', function(name, value) { - var field = FIELDS.shift(); - assert.strictEqual(name, field.name); - assert.strictEqual(value, field.value+''); - }) - .on('file', function(name, file) { - var field = FIELDS.shift(); - assert.strictEqual(name, field.name); - // http response doesn't have path property - assert.strictEqual(file.name, path.basename(field.value.path || remoteFile)); - assert.strictEqual(file.type, mime.lookup(file.name)); - }) - .on('end', function() { - res.writeHead(200); - res.end('done'); - }); -}); - - -process.on('exit', function() { - assert.strictEqual(FIELDS.length, 0); -}); diff --git a/deps/npm/node_modules/request/node_modules/form-data/test/integration/test-pipe.js b/deps/npm/node_modules/request/node_modules/form-data/test/integration/test-pipe.js deleted file mode 100644 index a9264f92ebc..00000000000 --- a/deps/npm/node_modules/request/node_modules/form-data/test/integration/test-pipe.js +++ /dev/null @@ -1,73 +0,0 @@ -var common = require('../common'); -var assert = common.assert; -var http = require('http'); -var path = require('path'); -var mime = require('mime'); -var request = require('request'); -var fs = require('fs'); -var FormData = require(common.dir.lib + '/form_data'); -var IncomingForm = require('formidable').IncomingForm; - -var remoteFile = 'http://nodejs.org/images/logo.png'; - -// wrap non simple values into function -// just to deal with ReadStream "autostart" -// Can't wait for 0.10 -var FIELDS = [ - {name: 'my_field', value: 'my_value'}, - {name: 'my_buffer', value: function(){ return new Buffer([1, 2, 3])} }, - {name: 'my_file', value: function(){ return fs.createReadStream(common.dir.fixture + '/unicycle.jpg')} }, - {name: 'remote_file', value: function(){ return request(remoteFile)} } -]; - -var server = http.createServer(function(req, res) { - - var form = new IncomingForm({uploadDir: common.dir.tmp}); - - form.parse(req); - - form - .on('field', function(name, value) { - var field = FIELDS.shift(); - assert.strictEqual(name, field.name); - assert.strictEqual(value, field.value+''); - }) - .on('file', function(name, file) { - var field = FIELDS.shift(); - assert.strictEqual(name, field.name); - assert.strictEqual(file.name, path.basename(field.value.path)); - assert.strictEqual(file.type, mime.lookup(file.name)); - }) - .on('end', function() { - res.writeHead(200); - res.end('done'); - }); -}); - -server.listen(common.port, function() { - var form = new FormData(); - FIELDS.forEach(function(field) { - // important to append ReadStreams within the same tick - if ((typeof field.value == 'function')) { - field.value = field.value(); - } - form.append(field.name, field.value); - }); - - var request = http.request({ - method: 'post', - port: common.port, - path: '/upload', - headers: form.getHeaders() - }); - - form.pipe(request); - - request.on('response', function(res) { - server.close(); - }); -}); - -process.on('exit', function() { - assert.strictEqual(FIELDS.length, 0); -}); diff --git a/deps/npm/node_modules/request/node_modules/form-data/test/integration/test-submit-custom.js b/deps/npm/node_modules/request/node_modules/form-data/test/integration/test-submit-custom.js deleted file mode 100644 index f0d8f088cd6..00000000000 --- a/deps/npm/node_modules/request/node_modules/form-data/test/integration/test-submit-custom.js +++ /dev/null @@ -1,77 +0,0 @@ -var common = require('../common'); -var assert = common.assert; -var http = require('http'); -var path = require('path'); -var mime = require('mime'); -var request = require('request'); -var fs = require('fs'); -var FormData = require(common.dir.lib + '/form_data'); -var IncomingForm = require('formidable').IncomingForm; - -var remoteFile = 'http://nodejs.org/images/logo.png'; - -// wrap non simple values into function -// just to deal with ReadStream "autostart" -// Can't wait for 0.10 -var FIELDS = [ - {name: 'my_field', value: 'my_value'}, - {name: 'my_buffer', value: function(){ return new Buffer([1, 2, 3])} }, - {name: 'my_file', value: function(){ return fs.createReadStream(common.dir.fixture + '/unicycle.jpg')} }, - {name: 'remote_file', value: function(){ return request(remoteFile)} } -]; - -var server = http.createServer(function(req, res) { - - var form = new IncomingForm({uploadDir: common.dir.tmp}); - - form.parse(req); - - form - .on('field', function(name, value) { - var field = FIELDS.shift(); - assert.strictEqual(name, field.name); - assert.strictEqual(value, field.value+''); - }) - .on('file', function(name, file) { - var field = FIELDS.shift(); - assert.strictEqual(name, field.name); - assert.strictEqual(file.name, path.basename(field.value.path)); - assert.strictEqual(file.type, mime.lookup(file.name)); - }) - .on('end', function() { - res.writeHead(200); - res.end('done'); - }); -}); - -server.listen(common.port, function() { - - var form = new FormData(); - - FIELDS.forEach(function(field) { - // important to append ReadStreams within the same tick - if ((typeof field.value == 'function')) { - field.value = field.value(); - } - form.append(field.name, field.value); - }); - - // custom params object passed to submit - form.submit({ - port: common.port, - path: '/' - }, function(err, res) { - - if (err) { - throw err; - } - - assert.strictEqual(res.statusCode, 200); - server.close(); - }); - -}); - -process.on('exit', function() { - assert.strictEqual(FIELDS.length, 0); -}); diff --git a/deps/npm/node_modules/request/node_modules/form-data/test/integration/test-submit.js b/deps/npm/node_modules/request/node_modules/form-data/test/integration/test-submit.js deleted file mode 100644 index f90cc7f285b..00000000000 --- a/deps/npm/node_modules/request/node_modules/form-data/test/integration/test-submit.js +++ /dev/null @@ -1,73 +0,0 @@ -var common = require('../common'); -var assert = common.assert; -var http = require('http'); -var path = require('path'); -var mime = require('mime'); -var request = require('request'); -var fs = require('fs'); -var FormData = require(common.dir.lib + '/form_data'); -var IncomingForm = require('formidable').IncomingForm; - -var remoteFile = 'http://nodejs.org/images/logo.png'; - -// wrap non simple values into function -// just to deal with ReadStream "autostart" -// Can't wait for 0.10 -var FIELDS = [ - {name: 'my_field', value: 'my_value'}, - {name: 'my_buffer', value: function(){ return new Buffer([1, 2, 3])} }, - {name: 'my_file', value: function(){ return fs.createReadStream(common.dir.fixture + '/unicycle.jpg')} }, - {name: 'remote_file', value: function(){ return request(remoteFile)} } -]; - -var server = http.createServer(function(req, res) { - - var form = new IncomingForm({uploadDir: common.dir.tmp}); - - form.parse(req); - - form - .on('field', function(name, value) { - var field = FIELDS.shift(); - assert.strictEqual(name, field.name); - assert.strictEqual(value, field.value+''); - }) - .on('file', function(name, file) { - var field = FIELDS.shift(); - assert.strictEqual(name, field.name); - assert.strictEqual(file.name, path.basename(field.value.path)); - assert.strictEqual(file.type, mime.lookup(file.name)); - }) - .on('end', function() { - res.writeHead(200); - res.end('done'); - }); -}); - -server.listen(common.port, function() { - - var form = new FormData(); - - FIELDS.forEach(function(field) { - // important to append ReadStreams within the same tick - if ((typeof field.value == 'function')) { - field.value = field.value(); - } - form.append(field.name, field.value); - }); - - form.submit('http://localhost:' + common.port + '/', function(err, res) { - - if (err) { - throw err; - } - - assert.strictEqual(res.statusCode, 200); - server.close(); - }); - -}); - -process.on('exit', function() { - assert.strictEqual(FIELDS.length, 0); -}); diff --git a/deps/npm/node_modules/request/node_modules/form-data/test/run.js b/deps/npm/node_modules/request/node_modules/form-data/test/run.js deleted file mode 100755 index 0bb8e822414..00000000000 --- a/deps/npm/node_modules/request/node_modules/form-data/test/run.js +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/env node -var far = require('far').create(); - -far.add(__dirname); -far.include(/test-.*\.js$/); - -far.execute(); diff --git a/deps/npm/node_modules/request/node_modules/hawk/Makefile b/deps/npm/node_modules/request/node_modules/hawk/Makefile index 9e7138c2a6f..5f339bf3474 100755 --- a/deps/npm/node_modules/request/node_modules/hawk/Makefile +++ b/deps/npm/node_modules/request/node_modules/hawk/Makefile @@ -1,11 +1,10 @@ test: - @./node_modules/.bin/lab + @node node_modules/lab/bin/lab test-cov: - @./node_modules/.bin/lab -r threshold -t 100 + @node node_modules/lab/bin/lab -r threshold -t 100 test-cov-html: - @./node_modules/.bin/lab -r html -o coverage.html + @node node_modules/lab/bin/lab -r html -o coverage.html complexity: - @./node_modules/.bin/cr -o complexity.md -f markdown lib + @node node_modules/complexity-report/src/cli.js -o complexity.md -f markdown lib .PHONY: test test-cov test-cov-html complexity - diff --git a/deps/npm/node_modules/request/node_modules/hawk/README.md b/deps/npm/node_modules/request/node_modules/hawk/README.md index 97458fb8527..010bac6d01a 100755 --- a/deps/npm/node_modules/request/node_modules/hawk/README.md +++ b/deps/npm/node_modules/request/node_modules/hawk/README.md @@ -1,620 +1,627 @@ -![hawk Logo](https://raw.github.com/hueniverse/hawk/master/images/hawk.png)
-
-<img align="right" src="https://raw.github.com/hueniverse/hawk/master/images/logo.png" /> **Hawk** is an HTTP authentication scheme using a message authentication code (MAC) algorithm to provide partial
-HTTP request cryptographic verification. For more complex use cases such as access delegation, see [Oz](https://github.com/hueniverse/oz).
-
-Current version: **0.13**
-
-[![Build Status](https://secure.travis-ci.org/hueniverse/hawk.png)](http://travis-ci.org/hueniverse/hawk)
-
-# Table of Content
-
-- [**Introduction**](#introduction)
- - [Replay Protection](#replay-protection)
- - [Usage Example](#usage-example)
- - [Protocol Example](#protocol-example)
- - [Payload Validation](#payload-validation)
- - [Response Payload Validation](#response-payload-validation)
- - [Browser Support and Considerations](#browser-support-and-considerations)
-<p></p>
-- [**Single URI Authorization**](#single-uri-authorization)
- - [Usage Example](#bewit-usage-example)
-<p></p>
-- [**Security Considerations**](#security-considerations)
- - [MAC Keys Transmission](#mac-keys-transmission)
- - [Confidentiality of Requests](#confidentiality-of-requests)
- - [Spoofing by Counterfeit Servers](#spoofing-by-counterfeit-servers)
- - [Plaintext Storage of Credentials](#plaintext-storage-of-credentials)
- - [Entropy of Keys](#entropy-of-keys)
- - [Coverage Limitations](#coverage-limitations)
- - [Future Time Manipulation](#future-time-manipulation)
- - [Client Clock Poisoning](#client-clock-poisoning)
- - [Bewit Limitations](#bewit-limitations)
-<p></p>
-- [**Frequently Asked Questions**](#frequently-asked-questions)
-<p></p>
-- [**Acknowledgements**](#acknowledgements)
-
-# Introduction
-
-**Hawk** is an HTTP authentication scheme providing mechanisms for making authenticated HTTP requests with
-partial cryptographic verification of the request and response, covering the HTTP method, request URI, host,
-and optionally the request payload.
-
-Similar to the HTTP [Digest access authentication schemes](http://www.ietf.org/rfc/rfc2617.txt), **Hawk** uses a set of
-client credentials which include an identifier (e.g. username) and key (e.g. password). Likewise, just as with the Digest scheme,
-the key is never included in authenticated requests. Instead, it is used to calculate a request MAC value which is
-included in its place.
-
-However, **Hawk** has several differences from Digest. In particular, while both use a nonce to limit the possibility of
-replay attacks, in **Hawk** the client generates the nonce and uses it in combination with a timestamp, leading to less
-"chattiness" (interaction with the server).
-
-Also unlike Digest, this scheme is not intended to protect the key itself (the password in Digest) because
-the client and server must both have access to the key material in the clear.
-
-The primary design goals of this scheme are to:
-* simplify and improve HTTP authentication for services that are unwilling or unable to deploy TLS for all resources,
-* secure credentials against leakage (e.g., when the client uses some form of dynamic configuration to determine where
- to send an authenticated request), and
-* avoid the exposure of credentials sent to a malicious server over an unauthenticated secure channel due to client
- failure to validate the server's identity as part of its TLS handshake.
-
-In addition, **Hawk** supports a method for granting third-parties temporary access to individual resources using
-a query parameter called _bewit_ (in falconry, a leather strap used to attach a tracking device to the leg of a hawk).
-
-The **Hawk** scheme requires the establishment of a shared symmetric key between the client and the server,
-which is beyond the scope of this module. Typically, the shared credentials are established via an initial
-TLS-protected phase or derived from some other shared confidential information available to both the client
-and the server.
-
-
-## Replay Protection
-
-Without replay protection, an attacker can use a compromised (but otherwise valid and authenticated) request more
-than once, gaining access to a protected resource. To mitigate this, clients include both a nonce and a timestamp when
-making requests. This gives the server enough information to prevent replay attacks.
-
-The nonce is generated by the client, and is a string unique across all requests with the same timestamp and
-key identifier combination.
-
-The timestamp enables the server to restrict the validity period of the credentials where requests occuring afterwards
-are rejected. It also removes the need for the server to retain an unbounded number of nonce values for future checks.
-By default, **Hawk** uses a time window of 1 minute to allow for time skew between the client and server (which in
-practice translates to a maximum of 2 minutes as the skew can be positive or negative).
-
-Using a timestamp requires the client's clock to be in sync with the server's clock. **Hawk** requires both the client
-clock and the server clock to use NTP to ensure synchronization. However, given the limitations of some client types
-(e.g. browsers) to deploy NTP, the server provides the client with its current time (in seconds precision) in response
-to a bad timestamp.
-
-There is no expectation that the client will adjust its system clock to match the server (in fact, this would be a
-potential attack vector). Instead, the client only uses the server's time to calculate an offset used only
-for communications with that particular server. The protocol rewards clients with synchronized clocks by reducing
-the number of round trips required to authenticate the first request.
-
-
-## Usage Example
-
-Server code:
-
-```javascript
-var Http = require('http');
-var Hawk = require('hawk');
-
-
-// Credentials lookup function
-
-var credentialsFunc = function (id, callback) {
-
- var credentials = {
- key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn',
- algorithm: 'sha256',
- user: 'Steve'
- };
-
- return callback(null, credentials);
-};
-
-// Create HTTP server
-
-var handler = function (req, res) {
-
- // Authenticate incoming request
-
- Hawk.server.authenticate(req, credentialsFunc, {}, function (err, credentials, artifacts) {
-
- // Prepare response
-
- var payload = (!err ? 'Hello ' + credentials.user + ' ' + artifacts.ext : 'Shoosh!');
- var headers = { 'Content-Type': 'text/plain' };
-
- // Generate Server-Authorization response header
-
- var header = Hawk.server.header(credentials, artifacts, { payload: payload, contentType: headers['Content-Type'] });
- headers['Server-Authorization'] = header;
-
- // Send the response back
-
- res.writeHead(!err ? 200 : 401, headers);
- res.end(payload);
- });
-};
-
-// Start server
-
-Http.createServer(handler).listen(8000, 'example.com');
-```
-
-Client code:
-
-```javascript
-var Request = require('request');
-var Hawk = require('hawk');
-
-
-// Client credentials
-
-var credentials = {
- id: 'dh37fgj492je',
- key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn',
- algorithm: 'sha256'
-}
-
-// Request options
-
-var requestOptions = {
- uri: 'http://example.com:8000/resource/1?b=1&a=2',
- method: 'GET',
- headers: {}
-};
-
-// Generate Authorization request header
-
-var header = Hawk.client.header('http://example.com:8000/resource/1?b=1&a=2', 'GET', { credentials: credentials, ext: 'some-app-data' });
-requestOptions.headers.Authorization = header.field;
-
-// Send authenticated request
-
-Request(requestOptions, function (error, response, body) {
-
- // Authenticate the server's response
-
- var isValid = Hawk.client.authenticate(response, credentials, header.artifacts, { payload: body });
-
- // Output results
-
- console.log(response.statusCode + ': ' + body + (isValid ? ' (valid)' : ' (invalid)'));
-});
-```
-
-**Hawk** utilized the [**SNTP**](https://github.com/hueniverse/sntp) module for time sync management. By default, the local
-machine time is used. To automatically retrieve and synchronice the clock within the application, use the SNTP 'start()' method.
-
-```javascript
-Hawk.sntp.start();
-```
-
-
-## Protocol Example
-
-The client attempts to access a protected resource without authentication, sending the following HTTP request to
-the resource server:
-
-```
-GET /resource/1?b=1&a=2 HTTP/1.1
-Host: example.com:8000
-```
-
-The resource server returns an authentication challenge.
-
-```
-HTTP/1.1 401 Unauthorized
-WWW-Authenticate: Hawk
-```
-
-The client has previously obtained a set of **Hawk** credentials for accessing resources on the "http://example.com/"
-server. The **Hawk** credentials issued to the client include the following attributes:
-
-* Key identifier: dh37fgj492je
-* Key: werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn
-* Algorithm: sha256
-
-The client generates the authentication header by calculating a timestamp (e.g. the number of seconds since January 1,
-1970 00:00:00 GMT), generating a nonce, and constructing the normalized request string (each value followed by a newline
-character):
-
-```
-hawk.1.header
-1353832234
-j4h3g2
-GET
-/resource?a=1&b=2
-example.com
-8000
-
-some-app-ext-data
-
-```
-
-The request MAC is calculated using HMAC with the specified hash algorithm "sha256" and the key over the normalized request string.
-The result is base64-encoded to produce the request MAC:
-
-```
-6R4rV5iE+NPoym+WwjeHzjAGXUtLNIxmo1vpMofpLAE=
-```
-
-The client includes the **Hawk** key identifier, timestamp, nonce, application specific data, and request MAC with the request using
-the HTTP `Authorization` request header field:
-
-```
-GET /resource/1?b=1&a=2 HTTP/1.1
-Host: example.com:8000
-Authorization: Hawk id="dh37fgj492je", ts="1353832234", nonce="j4h3g2", ext="some-app-ext-data", mac="6R4rV5iE+NPoym+WwjeHzjAGXUtLNIxmo1vpMofpLAE="
-```
-
-The server validates the request by calculating the request MAC again based on the request received and verifies the validity
-and scope of the **Hawk** credentials. If valid, the server responds with the requested resource.
-
-
-### Payload Validation
-
-**Hawk** provides optional payload validation. When generating the authentication header, the client calculates a payload hash
-using the specified hash algorithm. The hash is calculated over the concatenated value of (each followed by a newline character):
-* `hawk.1.payload`
-* the content-type in lowercase, without any parameters (e.g. `application/json`)
-* the request payload prior to any content encoding (the exact representation requirements should be specified by the server for payloads other than simple single-part ascii to ensure interoperability)
-
-For example:
-
-* Payload: `Thank you for flying Hawk`
-* Content Type: `text/plain`
-* Hash (sha256): `Yi9LfIIFRtBEPt74PVmbTF/xVAwPn7ub15ePICfgnuY=`
-
-Results in the following input to the payload hash function (newline terminated values):
-
-```
-hawk.1.payload
-text/plain
-Thank you for flying Hawk
-
-```
-
-Which produces the following hash value:
-
-```
-Yi9LfIIFRtBEPt74PVmbTF/xVAwPn7ub15ePICfgnuY=
-```
-
-The client constructs the normalized request string (newline terminated values):
-
-```
-hawk.1.header
-1353832234
-j4h3g2
-POST
-/resource?a=1&b=2
-example.com
-8000
-Yi9LfIIFRtBEPt74PVmbTF/xVAwPn7ub15ePICfgnuY=
-some-app-ext-data
-
-```
-
-Then calculates the request MAC and includes the **Hawk** key identifier, timestamp, nonce, payload hash, application specific data,
-and request MAC, with the request using the HTTP `Authorization` request header field:
-
-```
-POST /resource/1 HTTP/1.1
-Host: example.com:8000
-Authorization: Hawk id="dh37fgj492je", ts="1353832234", nonce="j4h3g2", hash="Yi9LfIIFRtBEPt74PVmbTF/xVAwPn7ub15ePICfgnuY=", ext="some-app-ext-data", mac="aSe1DERmZuRl3pI36/9BdZmnErTw3sNzOOAUlfeKjVw="
-```
-
-It is up to the server if and when it validates the payload for any given request, based solely on it's security policy
-and the nature of the data included.
-
-If the payload is available at the time of authentication, the server uses the hash value provided by the client to construct
-the normalized string and validates the MAC. If the MAC is valid, the server calculates the payload hash and compares the value
-with the provided payload hash in the header. In many cases, checking the MAC first is faster than calculating the payload hash.
-
-However, if the payload is not available at authentication time (e.g. too large to fit in memory, streamed elsewhere, or processed
-at a different stage in the application), the server may choose to defer payload validation for later by retaining the hash value
-provided by the client after validating the MAC.
-
-It is important to note that MAC validation does not mean the hash value provided by the client is valid, only that the value
-included in the header was not modified. Without calculating the payload hash on the server and comparing it to the value provided
-by the client, the payload may be modified by an attacker.
-
-
-## Response Payload Validation
-
-**Hawk** provides partial response payload validation. The server includes the `Server-Authorization` response header which enables the
-client to authenticate the response and ensure it is talking to the right server. **Hawk** defines the HTTP `Server-Authorization` header
-as a response header using the exact same syntax as the `Authorization` request header field.
-
-The header is contructed using the same process as the client's request header. The server uses the same credentials and other
-artifacts provided by the client to constructs the normalized request string. The `ext` and `hash` values are replaced with
-new values based on the server response. The rest as identical to those used by the client.
-
-The result MAC digest is included with the optional `hash` and `ext` values:
-
-```
-Server-Authorization: Hawk mac="XIJRsMl/4oL+nn+vKoeVZPdCHXB4yJkNnBbTbHFZUYE=", hash="f9cDF/TDm7TkYRLnGwRMfeDzT6LixQVLvrIKhh0vgmM=", ext="response-specific"
-```
-
-
-## Browser Support and Considerations
-
-A browser script is provided for including using a `<script>` tag in [lib/browser.js](/lib/browser.js).
-
-**Hawk** relies on the _Server-Authorization_ and _WWW-Authenticate_ headers in its response to communicate with the client.
-Therefore, in case of CORS requests, it is important to consider sending _Access-Control-Expose-Headers_ with the value
-_"WWW-Authenticate, Server-Authorization"_ on each response from your server. As explained in the
-[specifications](http://www.w3.org/TR/cors/#access-control-expose-headers-response-header), it will indicate that these headers
-can safely be accessed by the client (using getResponseHeader() on the XmlHttpRequest object). Otherwise you will be met with a
-["simple response header"](http://www.w3.org/TR/cors/#simple-response-header) which excludes these fields and would prevent the
-Hawk client from authenticating the requests.You can read more about the why and how in this
-[article](http://www.html5rocks.com/en/tutorials/cors/#toc-adding-cors-support-to-the-server)
-
-
-# Single URI Authorization
-
-There are cases in which limited and short-term access to a protected resource is granted to a third party which does not
-have access to the shared credentials. For example, displaying a protected image on a web page accessed by anyone. **Hawk**
-provides limited support for such URIs in the form of a _bewit_ - a URI query parameter appended to the request URI which contains
-the necessary credentials to authenticate the request.
-
-Because of the significant security risks involved in issuing such access, bewit usage is purposely limited only to GET requests
-and for a finite period of time. Both the client and server can issue bewit credentials, however, the server should not use the same
-credentials as the client to maintain clear traceability as to who issued which credentials.
-
-In order to simplify implementation, bewit credentials do not support single-use policy and can be replayed multiple times within
-the granted access timeframe.
-
-
-## Bewit Usage Example
-
-Server code:
-
-```javascript
-var Http = require('http');
-var Hawk = require('hawk');
-
-
-// Credentials lookup function
-
-var credentialsFunc = function (id, callback) {
-
- var credentials = {
- key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn',
- algorithm: 'sha256'
- };
-
- return callback(null, credentials);
-};
-
-// Create HTTP server
-
-var handler = function (req, res) {
-
- Hawk.uri.authenticate(req, credentialsFunc, {}, function (err, credentials, attributes) {
-
- res.writeHead(!err ? 200 : 401, { 'Content-Type': 'text/plain' });
- res.end(!err ? 'Access granted' : 'Shoosh!');
- });
-};
-
-Http.createServer(handler).listen(8000, 'example.com');
-```
-
-Bewit code generation:
-
-```javascript
-var Request = require('request');
-var Hawk = require('hawk');
-
-
-// Client credentials
-
-var credentials = {
- id: 'dh37fgj492je',
- key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn',
- algorithm: 'sha256'
-}
-
-// Generate bewit
-
-var duration = 60 * 5; // 5 Minutes
-var bewit = Hawk.uri.getBewit('http://example.com:8080/resource/1?b=1&a=2', { credentials: credentials, ttlSec: duration, ext: 'some-app-data' });
-var uri = 'http://example.com:8000/resource/1?b=1&a=2' + '&bewit=' + bewit;
-```
-
-
-# Security Considerations
-
-The greatest sources of security risks are usually found not in **Hawk** but in the policies and procedures surrounding its use.
-Implementers are strongly encouraged to assess how this module addresses their security requirements. This section includes
-an incomplete list of security considerations that must be reviewed and understood before deploying **Hawk** on the server.
-Many of the protections provided in **Hawk** depends on whether and how they are used.
-
-### MAC Keys Transmission
-
-**Hawk** does not provide any mechanism for obtaining or transmitting the set of shared credentials required. Any mechanism used
-to obtain **Hawk** credentials must ensure that these transmissions are protected using transport-layer mechanisms such as TLS.
-
-### Confidentiality of Requests
-
-While **Hawk** provides a mechanism for verifying the integrity of HTTP requests, it provides no guarantee of request
-confidentiality. Unless other precautions are taken, eavesdroppers will have full access to the request content. Servers should
-carefully consider the types of data likely to be sent as part of such requests, and employ transport-layer security mechanisms
-to protect sensitive resources.
-
-### Spoofing by Counterfeit Servers
-
-**Hawk** provides limited verification of the server authenticity. When receiving a response back from the server, the server
-may choose to include a response `Server-Authorization` header which the client can use to verify the response. However, it is up to
-the server to determine when such measure is included, to up to the client to enforce that policy.
-
-A hostile party could take advantage of this by intercepting the client's requests and returning misleading or otherwise
-incorrect responses. Service providers should consider such attacks when developing services using this protocol, and should
-require transport-layer security for any requests where the authenticity of the resource server or of server responses is an issue.
-
-### Plaintext Storage of Credentials
-
-The **Hawk** key functions the same way passwords do in traditional authentication systems. In order to compute the request MAC,
-the server must have access to the key in plaintext form. This is in contrast, for example, to modern operating systems, which
-store only a one-way hash of user credentials.
-
-If an attacker were to gain access to these keys - or worse, to the server's database of all such keys - he or she would be able
-to perform any action on behalf of any resource owner. Accordingly, it is critical that servers protect these keys from unauthorized
-access.
-
-### Entropy of Keys
-
-Unless a transport-layer security protocol is used, eavesdroppers will have full access to authenticated requests and request
-MAC values, and will thus be able to mount offline brute-force attacks to recover the key used. Servers should be careful to
-assign keys which are long enough, and random enough, to resist such attacks for at least the length of time that the **Hawk**
-credentials are valid.
-
-For example, if the credentials are valid for two weeks, servers should ensure that it is not possible to mount a brute force
-attack that recovers the key in less than two weeks. Of course, servers are urged to err on the side of caution, and use the
-longest key reasonable.
-
-It is equally important that the pseudo-random number generator (PRNG) used to generate these keys be of sufficiently high
-quality. Many PRNG implementations generate number sequences that may appear to be random, but which nevertheless exhibit
-patterns or other weaknesses which make cryptanalysis or brute force attacks easier. Implementers should be careful to use
-cryptographically secure PRNGs to avoid these problems.
-
-### Coverage Limitations
-
-The request MAC only covers the HTTP `Host` header and optionally the `Content-Type` header. It does not cover any other headers
-which can often affect how the request body is interpreted by the server. If the server behavior is influenced by the presence
-or value of such headers, an attacker can manipulate the request headers without being detected. Implementers should use the
-`ext` feature to pass application-specific information via the `Authorization` header which is protected by the request MAC.
-
-The response authentication, when performed, only covers the response payload, content-type, and the request information
-provided by the client in it's request (method, resource, timestamp, nonce, etc.). It does not cover the HTTP status code or
-any other response header field (e.g. Location) which can affect the client's behaviour.
-
-### Future Time Manipulation
-
-The protocol relies on a clock sync between the client and server. To accomplish this, the server informs the client of its
-current time when an invalid timestamp is received.
-
-If an attacker is able to manipulate this information and cause the client to use an incorrect time, it would be able to cause
-the client to generate authenticated requests using time in the future. Such requests will fail when sent by the client, and will
-not likely leave a trace on the server (given the common implementation of nonce, if at all enforced). The attacker will then
-be able to replay the request at the correct time without detection.
-
-The client must only use the time information provided by the server if:
-* it was delivered over a TLS connection and the server identity has been verified, or
-* the `tsm` MAC digest calculated using the same client credentials over the timestamp has been verified.
-
-### Client Clock Poisoning
-
-When receiving a request with a bad timestamp, the server provides the client with its current time. The client must never use
-the time received from the server to adjust its own clock, and must only use it to calculate an offset for communicating with
-that particular server.
-
-### Bewit Limitations
-
-Special care must be taken when issuing bewit credentials to third parties. Bewit credentials are valid until expiration and cannot
-be revoked or limited without using other means. Whatever resource they grant access to will be completely exposed to anyone with
-access to the bewit credentials which act as bearer credentials for that particular resource. While bewit usage is limited to GET
-requests only and therefore cannot be used to perform transactions or change server state, it can still be used to expose private
-and sensitive information.
-
-
-# Frequently Asked Questions
-
-### Where is the protocol specification?
-
-If you are looking for some prose explaining how all this works, **this is it**. **Hawk** is being developed as an open source
-project instead of a standard. In other words, the [code](/hueniverse/hawk/tree/master/lib) is the specification. Not sure about
-something? Open an issue!
-
-### Is it done?
-
-At if version 0.10.0, **Hawk** is feature-complete. However, until this module reaches version 1.0.0 it is considered experimental
-and is likely to change. This also means your feedback and contribution are very welcome. Feel free to open issues with questions
-and suggestions.
-
-### Where can I find **Hawk** implementations in other languages?
-
-**Hawk**'s only reference implementation is provided in JavaScript as a node.js module. However, others are actively porting it to other
-platforms. There is already a [PHP](https://github.com/alexbilbie/PHP-Hawk),
-[.NET](https://github.com/pcibraro/hawknet), and [JAVA](https://github.com/wealdtech/hawk) libraries available. The full list
-is maintained [here](https://github.com/hueniverse/hawk/issues?labels=port). Please add an issue if you are working on another
-port. A cross-platform test-suite is in the works.
-
-### Why isn't the algorithm part of the challenge or dynamically negotiated?
-
-The algorithm used is closely related to the key issued as different algorithms require different key sizes (and other
-requirements). While some keys can be used for multiple algorithm, the protocol is designed to closely bind the key and algorithm
-together as part of the issued credentials.
-
-### Why is Host and Content-Type the only headers covered by the request MAC?
-
-It is really hard to include other headers. Headers can be changed by proxies and other intermediaries and there is no
-well-established way to normalize them. Many platforms change the case of header field names and values. The only
-straight-forward solution is to include the headers in some blob (say, base64 encoded JSON) and include that with the request,
-an approach taken by JWT and other such formats. However, that design violates the HTTP header boundaries, repeats information,
-and introduces other security issues because firewalls will not be aware of these "hidden" headers. In addition, any information
-repeated must be compared to the duplicated information in the header and therefore only moves the problem elsewhere.
-
-### Why not just use HTTP Digest?
-
-Digest requires pre-negotiation to establish a nonce. This means you can't just make a request - you must first send
-a protocol handshake to the server. This pattern has become unacceptable for most web services, especially mobile
-where extra round-trip are costly.
-
-### Why bother with all this nonce and timestamp business?
-
-**Hawk** is an attempt to find a reasonable, practical compromise between security and usability. OAuth 1.0 got timestamp
-and nonces halfway right but failed when it came to scalability and consistent developer experience. **Hawk** addresses
-it by requiring the client to sync its clock, but provides it with tools to accomplish it.
-
-In general, replay protection is a matter of application-specific threat model. It is less of an issue on a TLS-protected
-system where the clients are implemented using best practices and are under the control of the server. Instead of dropping
-replay protection, **Hawk** offers a required time window and an optional nonce verification. Together, it provides developers
-with the ability to decide how to enforce their security policy without impacting the client's implementation.
-
-### What are `app` and `dlg` in the authorization header and normalized mac string?
-
-The original motivation for **Hawk** was to replace the OAuth 1.0 use cases. This included both a simple client-server mode which
-this module is specifically designed for, and a delegated access mode which is being developed separately in
-[Oz](https://github.com/hueniverse/oz). In addition to the **Hawk** use cases, Oz requires another attribute: the application id `app`.
-This provides binding between the credentials and the application in a way that prevents an attacker from tricking an application
-to use credentials issued to someone else. It also has an optional 'delegated-by' attribute `dlg` which is the application id of the
-application the credentials were directly issued to. The goal of these two additions is to allow Oz to utilize **Hawk** directly,
-but with the additional security of delegated credentials.
-
-### What is the purpose of the static strings used in each normalized MAC input?
-
-When calculating a hash or MAC, a static prefix (tag) is added. The prefix is used to prevent MAC values from being
-used or reused for a purpose other than what they were created for (i.e. prevents switching MAC values between a request,
-response, and a bewit use cases). It also protects against expliots created after a potential change in how the protocol
-creates the normalized string. For example, if a future version would switch the order of nonce and timestamp, it
-can create an exploit opportunity for cases where the nonce is similar in format to a timestamp.
-
-### Does **Hawk** have anything to do with OAuth?
-
-Short answer: no.
-
-**Hawk** was originally proposed as the OAuth MAC Token specification. However, the OAuth working group in its consistent
-incompetence failed to produce a final, usable solution to address one of the most popular use cases of OAuth 1.0 - using it
-to authenticate simple client-server transactions (i.e. two-legged). As you can guess, the OAuth working group is still hard
-at work to produce more garbage.
-
-**Hawk** provides a simple HTTP authentication scheme for making client-server requests. It does not address the OAuth use case
-of delegating access to a third party. If you are looking for an OAuth alternative, check out [Oz](https://github.com/hueniverse/oz).
-
-
-# Acknowledgements
-
-**Hawk** is a derivative work of the [HTTP MAC Authentication Scheme](http://tools.ietf.org/html/draft-hammer-oauth-v2-mac-token-05) proposal
-co-authored by Ben Adida, Adam Barth, and Eran Hammer, which in turn was based on the OAuth 1.0 community specification.
-
-Special thanks to Ben Laurie for his always insightful feedback and advice.
-
-The **Hawk** logo was created by [Chris Carrasco](http://chriscarrasco.com).
+![hawk Logo](https://raw.github.com/hueniverse/hawk/master/images/hawk.png) + +<img align="right" src="https://raw.github.com/hueniverse/hawk/master/images/logo.png" /> **Hawk** is an HTTP authentication scheme using a message authentication code (MAC) algorithm to provide partial +HTTP request cryptographic verification. For more complex use cases such as access delegation, see [Oz](https://github.com/hueniverse/oz). + +Current version: **1.0** + +[![Build Status](https://secure.travis-ci.org/hueniverse/hawk.png)](http://travis-ci.org/hueniverse/hawk) + +# Table of Content + +- [**Introduction**](#introduction) + - [Replay Protection](#replay-protection) + - [Usage Example](#usage-example) + - [Protocol Example](#protocol-example) + - [Payload Validation](#payload-validation) + - [Response Payload Validation](#response-payload-validation) + - [Browser Support and Considerations](#browser-support-and-considerations) +<p></p> +- [**Single URI Authorization**](#single-uri-authorization) + - [Usage Example](#bewit-usage-example) +<p></p> +- [**Security Considerations**](#security-considerations) + - [MAC Keys Transmission](#mac-keys-transmission) + - [Confidentiality of Requests](#confidentiality-of-requests) + - [Spoofing by Counterfeit Servers](#spoofing-by-counterfeit-servers) + - [Plaintext Storage of Credentials](#plaintext-storage-of-credentials) + - [Entropy of Keys](#entropy-of-keys) + - [Coverage Limitations](#coverage-limitations) + - [Future Time Manipulation](#future-time-manipulation) + - [Client Clock Poisoning](#client-clock-poisoning) + - [Bewit Limitations](#bewit-limitations) + - [Host Header Forgery](#host-header-forgery) +<p></p> +- [**Frequently Asked Questions**](#frequently-asked-questions) +<p></p> +- [**Acknowledgements**](#acknowledgements) + +# Introduction + +**Hawk** is an HTTP authentication scheme providing mechanisms for making authenticated HTTP requests with +partial cryptographic verification of the request and response, covering the HTTP method, request URI, host, +and optionally the request payload. + +Similar to the HTTP [Digest access authentication schemes](http://www.ietf.org/rfc/rfc2617.txt), **Hawk** uses a set of +client credentials which include an identifier (e.g. username) and key (e.g. password). Likewise, just as with the Digest scheme, +the key is never included in authenticated requests. Instead, it is used to calculate a request MAC value which is +included in its place. + +However, **Hawk** has several differences from Digest. In particular, while both use a nonce to limit the possibility of +replay attacks, in **Hawk** the client generates the nonce and uses it in combination with a timestamp, leading to less +"chattiness" (interaction with the server). + +Also unlike Digest, this scheme is not intended to protect the key itself (the password in Digest) because +the client and server must both have access to the key material in the clear. + +The primary design goals of this scheme are to: +* simplify and improve HTTP authentication for services that are unwilling or unable to deploy TLS for all resources, +* secure credentials against leakage (e.g., when the client uses some form of dynamic configuration to determine where + to send an authenticated request), and +* avoid the exposure of credentials sent to a malicious server over an unauthenticated secure channel due to client + failure to validate the server's identity as part of its TLS handshake. + +In addition, **Hawk** supports a method for granting third-parties temporary access to individual resources using +a query parameter called _bewit_ (in falconry, a leather strap used to attach a tracking device to the leg of a hawk). + +The **Hawk** scheme requires the establishment of a shared symmetric key between the client and the server, +which is beyond the scope of this module. Typically, the shared credentials are established via an initial +TLS-protected phase or derived from some other shared confidential information available to both the client +and the server. + + +## Replay Protection + +Without replay protection, an attacker can use a compromised (but otherwise valid and authenticated) request more +than once, gaining access to a protected resource. To mitigate this, clients include both a nonce and a timestamp when +making requests. This gives the server enough information to prevent replay attacks. + +The nonce is generated by the client, and is a string unique across all requests with the same timestamp and +key identifier combination. + +The timestamp enables the server to restrict the validity period of the credentials where requests occuring afterwards +are rejected. It also removes the need for the server to retain an unbounded number of nonce values for future checks. +By default, **Hawk** uses a time window of 1 minute to allow for time skew between the client and server (which in +practice translates to a maximum of 2 minutes as the skew can be positive or negative). + +Using a timestamp requires the client's clock to be in sync with the server's clock. **Hawk** requires both the client +clock and the server clock to use NTP to ensure synchronization. However, given the limitations of some client types +(e.g. browsers) to deploy NTP, the server provides the client with its current time (in seconds precision) in response +to a bad timestamp. + +There is no expectation that the client will adjust its system clock to match the server (in fact, this would be a +potential attack vector). Instead, the client only uses the server's time to calculate an offset used only +for communications with that particular server. The protocol rewards clients with synchronized clocks by reducing +the number of round trips required to authenticate the first request. + + +## Usage Example + +Server code: + +```javascript +var Http = require('http'); +var Hawk = require('hawk'); + + +// Credentials lookup function + +var credentialsFunc = function (id, callback) { + + var credentials = { + key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn', + algorithm: 'sha256', + user: 'Steve' + }; + + return callback(null, credentials); +}; + +// Create HTTP server + +var handler = function (req, res) { + + // Authenticate incoming request + + Hawk.server.authenticate(req, credentialsFunc, {}, function (err, credentials, artifacts) { + + // Prepare response + + var payload = (!err ? 'Hello ' + credentials.user + ' ' + artifacts.ext : 'Shoosh!'); + var headers = { 'Content-Type': 'text/plain' }; + + // Generate Server-Authorization response header + + var header = Hawk.server.header(credentials, artifacts, { payload: payload, contentType: headers['Content-Type'] }); + headers['Server-Authorization'] = header; + + // Send the response back + + res.writeHead(!err ? 200 : 401, headers); + res.end(payload); + }); +}; + +// Start server + +Http.createServer(handler).listen(8000, 'example.com'); +``` + +Client code: + +```javascript +var Request = require('request'); +var Hawk = require('hawk'); + + +// Client credentials + +var credentials = { + id: 'dh37fgj492je', + key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn', + algorithm: 'sha256' +} + +// Request options + +var requestOptions = { + uri: 'http://example.com:8000/resource/1?b=1&a=2', + method: 'GET', + headers: {} +}; + +// Generate Authorization request header + +var header = Hawk.client.header('http://example.com:8000/resource/1?b=1&a=2', 'GET', { credentials: credentials, ext: 'some-app-data' }); +requestOptions.headers.Authorization = header.field; + +// Send authenticated request + +Request(requestOptions, function (error, response, body) { + + // Authenticate the server's response + + var isValid = Hawk.client.authenticate(response, credentials, header.artifacts, { payload: body }); + + // Output results + + console.log(response.statusCode + ': ' + body + (isValid ? ' (valid)' : ' (invalid)')); +}); +``` + +**Hawk** utilized the [**SNTP**](https://github.com/hueniverse/sntp) module for time sync management. By default, the local +machine time is used. To automatically retrieve and synchronice the clock within the application, use the SNTP 'start()' method. + +```javascript +Hawk.sntp.start(); +``` + + +## Protocol Example + +The client attempts to access a protected resource without authentication, sending the following HTTP request to +the resource server: + +``` +GET /resource/1?b=1&a=2 HTTP/1.1 +Host: example.com:8000 +``` + +The resource server returns an authentication challenge. + +``` +HTTP/1.1 401 Unauthorized +WWW-Authenticate: Hawk +``` + +The client has previously obtained a set of **Hawk** credentials for accessing resources on the "http://example.com/" +server. The **Hawk** credentials issued to the client include the following attributes: + +* Key identifier: dh37fgj492je +* Key: werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn +* Algorithm: sha256 + +The client generates the authentication header by calculating a timestamp (e.g. the number of seconds since January 1, +1970 00:00:00 GMT), generating a nonce, and constructing the normalized request string (each value followed by a newline +character): + +``` +hawk.1.header +1353832234 +j4h3g2 +GET +/resource/1?b=1&a=2 +example.com +8000 + +some-app-ext-data + +``` + +The request MAC is calculated using HMAC with the specified hash algorithm "sha256" and the key over the normalized request string. +The result is base64-encoded to produce the request MAC: + +``` +6R4rV5iE+NPoym+WwjeHzjAGXUtLNIxmo1vpMofpLAE= +``` + +The client includes the **Hawk** key identifier, timestamp, nonce, application specific data, and request MAC with the request using +the HTTP `Authorization` request header field: + +``` +GET /resource/1?b=1&a=2 HTTP/1.1 +Host: example.com:8000 +Authorization: Hawk id="dh37fgj492je", ts="1353832234", nonce="j4h3g2", ext="some-app-ext-data", mac="6R4rV5iE+NPoym+WwjeHzjAGXUtLNIxmo1vpMofpLAE=" +``` + +The server validates the request by calculating the request MAC again based on the request received and verifies the validity +and scope of the **Hawk** credentials. If valid, the server responds with the requested resource. + + +### Payload Validation + +**Hawk** provides optional payload validation. When generating the authentication header, the client calculates a payload hash +using the specified hash algorithm. The hash is calculated over the concatenated value of (each followed by a newline character): +* `hawk.1.payload` +* the content-type in lowercase, without any parameters (e.g. `application/json`) +* the request payload prior to any content encoding (the exact representation requirements should be specified by the server for payloads other than simple single-part ascii to ensure interoperability) + +For example: + +* Payload: `Thank you for flying Hawk` +* Content Type: `text/plain` +* Hash (sha256): `Yi9LfIIFRtBEPt74PVmbTF/xVAwPn7ub15ePICfgnuY=` + +Results in the following input to the payload hash function (newline terminated values): + +``` +hawk.1.payload +text/plain +Thank you for flying Hawk + +``` + +Which produces the following hash value: + +``` +Yi9LfIIFRtBEPt74PVmbTF/xVAwPn7ub15ePICfgnuY= +``` + +The client constructs the normalized request string (newline terminated values): + +``` +hawk.1.header +1353832234 +j4h3g2 +POST +/resource/1?a=1&b=2 +example.com +8000 +Yi9LfIIFRtBEPt74PVmbTF/xVAwPn7ub15ePICfgnuY= +some-app-ext-data + +``` + +Then calculates the request MAC and includes the **Hawk** key identifier, timestamp, nonce, payload hash, application specific data, +and request MAC, with the request using the HTTP `Authorization` request header field: + +``` +POST /resource/1?a=1&b=2 HTTP/1.1 +Host: example.com:8000 +Authorization: Hawk id="dh37fgj492je", ts="1353832234", nonce="j4h3g2", hash="Yi9LfIIFRtBEPt74PVmbTF/xVAwPn7ub15ePICfgnuY=", ext="some-app-ext-data", mac="aSe1DERmZuRl3pI36/9BdZmnErTw3sNzOOAUlfeKjVw=" +``` + +It is up to the server if and when it validates the payload for any given request, based solely on it's security policy +and the nature of the data included. + +If the payload is available at the time of authentication, the server uses the hash value provided by the client to construct +the normalized string and validates the MAC. If the MAC is valid, the server calculates the payload hash and compares the value +with the provided payload hash in the header. In many cases, checking the MAC first is faster than calculating the payload hash. + +However, if the payload is not available at authentication time (e.g. too large to fit in memory, streamed elsewhere, or processed +at a different stage in the application), the server may choose to defer payload validation for later by retaining the hash value +provided by the client after validating the MAC. + +It is important to note that MAC validation does not mean the hash value provided by the client is valid, only that the value +included in the header was not modified. Without calculating the payload hash on the server and comparing it to the value provided +by the client, the payload may be modified by an attacker. + + +## Response Payload Validation + +**Hawk** provides partial response payload validation. The server includes the `Server-Authorization` response header which enables the +client to authenticate the response and ensure it is talking to the right server. **Hawk** defines the HTTP `Server-Authorization` header +as a response header using the exact same syntax as the `Authorization` request header field. + +The header is contructed using the same process as the client's request header. The server uses the same credentials and other +artifacts provided by the client to constructs the normalized request string. The `ext` and `hash` values are replaced with +new values based on the server response. The rest as identical to those used by the client. + +The result MAC digest is included with the optional `hash` and `ext` values: + +``` +Server-Authorization: Hawk mac="XIJRsMl/4oL+nn+vKoeVZPdCHXB4yJkNnBbTbHFZUYE=", hash="f9cDF/TDm7TkYRLnGwRMfeDzT6LixQVLvrIKhh0vgmM=", ext="response-specific" +``` + + +## Browser Support and Considerations + +A browser script is provided for including using a `<script>` tag in [lib/browser.js](/lib/browser.js). + +**Hawk** relies on the _Server-Authorization_ and _WWW-Authenticate_ headers in its response to communicate with the client. +Therefore, in case of CORS requests, it is important to consider sending _Access-Control-Expose-Headers_ with the value +_"WWW-Authenticate, Server-Authorization"_ on each response from your server. As explained in the +[specifications](http://www.w3.org/TR/cors/#access-control-expose-headers-response-header), it will indicate that these headers +can safely be accessed by the client (using getResponseHeader() on the XmlHttpRequest object). Otherwise you will be met with a +["simple response header"](http://www.w3.org/TR/cors/#simple-response-header) which excludes these fields and would prevent the +Hawk client from authenticating the requests.You can read more about the why and how in this +[article](http://www.html5rocks.com/en/tutorials/cors/#toc-adding-cors-support-to-the-server) + + +# Single URI Authorization + +There are cases in which limited and short-term access to a protected resource is granted to a third party which does not +have access to the shared credentials. For example, displaying a protected image on a web page accessed by anyone. **Hawk** +provides limited support for such URIs in the form of a _bewit_ - a URI query parameter appended to the request URI which contains +the necessary credentials to authenticate the request. + +Because of the significant security risks involved in issuing such access, bewit usage is purposely limited only to GET requests +and for a finite period of time. Both the client and server can issue bewit credentials, however, the server should not use the same +credentials as the client to maintain clear traceability as to who issued which credentials. + +In order to simplify implementation, bewit credentials do not support single-use policy and can be replayed multiple times within +the granted access timeframe. + + +## Bewit Usage Example + +Server code: + +```javascript +var Http = require('http'); +var Hawk = require('hawk'); + + +// Credentials lookup function + +var credentialsFunc = function (id, callback) { + + var credentials = { + key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn', + algorithm: 'sha256' + }; + + return callback(null, credentials); +}; + +// Create HTTP server + +var handler = function (req, res) { + + Hawk.uri.authenticate(req, credentialsFunc, {}, function (err, credentials, attributes) { + + res.writeHead(!err ? 200 : 401, { 'Content-Type': 'text/plain' }); + res.end(!err ? 'Access granted' : 'Shoosh!'); + }); +}; + +Http.createServer(handler).listen(8000, 'example.com'); +``` + +Bewit code generation: + +```javascript +var Request = require('request'); +var Hawk = require('hawk'); + + +// Client credentials + +var credentials = { + id: 'dh37fgj492je', + key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn', + algorithm: 'sha256' +} + +// Generate bewit + +var duration = 60 * 5; // 5 Minutes +var bewit = Hawk.uri.getBewit('http://example.com:8080/resource/1?b=1&a=2', { credentials: credentials, ttlSec: duration, ext: 'some-app-data' }); +var uri = 'http://example.com:8000/resource/1?b=1&a=2' + '&bewit=' + bewit; +``` + + +# Security Considerations + +The greatest sources of security risks are usually found not in **Hawk** but in the policies and procedures surrounding its use. +Implementers are strongly encouraged to assess how this module addresses their security requirements. This section includes +an incomplete list of security considerations that must be reviewed and understood before deploying **Hawk** on the server. +Many of the protections provided in **Hawk** depends on whether and how they are used. + +### MAC Keys Transmission + +**Hawk** does not provide any mechanism for obtaining or transmitting the set of shared credentials required. Any mechanism used +to obtain **Hawk** credentials must ensure that these transmissions are protected using transport-layer mechanisms such as TLS. + +### Confidentiality of Requests + +While **Hawk** provides a mechanism for verifying the integrity of HTTP requests, it provides no guarantee of request +confidentiality. Unless other precautions are taken, eavesdroppers will have full access to the request content. Servers should +carefully consider the types of data likely to be sent as part of such requests, and employ transport-layer security mechanisms +to protect sensitive resources. + +### Spoofing by Counterfeit Servers + +**Hawk** provides limited verification of the server authenticity. When receiving a response back from the server, the server +may choose to include a response `Server-Authorization` header which the client can use to verify the response. However, it is up to +the server to determine when such measure is included, to up to the client to enforce that policy. + +A hostile party could take advantage of this by intercepting the client's requests and returning misleading or otherwise +incorrect responses. Service providers should consider such attacks when developing services using this protocol, and should +require transport-layer security for any requests where the authenticity of the resource server or of server responses is an issue. + +### Plaintext Storage of Credentials + +The **Hawk** key functions the same way passwords do in traditional authentication systems. In order to compute the request MAC, +the server must have access to the key in plaintext form. This is in contrast, for example, to modern operating systems, which +store only a one-way hash of user credentials. + +If an attacker were to gain access to these keys - or worse, to the server's database of all such keys - he or she would be able +to perform any action on behalf of any resource owner. Accordingly, it is critical that servers protect these keys from unauthorized +access. + +### Entropy of Keys + +Unless a transport-layer security protocol is used, eavesdroppers will have full access to authenticated requests and request +MAC values, and will thus be able to mount offline brute-force attacks to recover the key used. Servers should be careful to +assign keys which are long enough, and random enough, to resist such attacks for at least the length of time that the **Hawk** +credentials are valid. + +For example, if the credentials are valid for two weeks, servers should ensure that it is not possible to mount a brute force +attack that recovers the key in less than two weeks. Of course, servers are urged to err on the side of caution, and use the +longest key reasonable. + +It is equally important that the pseudo-random number generator (PRNG) used to generate these keys be of sufficiently high +quality. Many PRNG implementations generate number sequences that may appear to be random, but which nevertheless exhibit +patterns or other weaknesses which make cryptanalysis or brute force attacks easier. Implementers should be careful to use +cryptographically secure PRNGs to avoid these problems. + +### Coverage Limitations + +The request MAC only covers the HTTP `Host` header and optionally the `Content-Type` header. It does not cover any other headers +which can often affect how the request body is interpreted by the server. If the server behavior is influenced by the presence +or value of such headers, an attacker can manipulate the request headers without being detected. Implementers should use the +`ext` feature to pass application-specific information via the `Authorization` header which is protected by the request MAC. + +The response authentication, when performed, only covers the response payload, content-type, and the request information +provided by the client in it's request (method, resource, timestamp, nonce, etc.). It does not cover the HTTP status code or +any other response header field (e.g. Location) which can affect the client's behaviour. + +### Future Time Manipulation + +The protocol relies on a clock sync between the client and server. To accomplish this, the server informs the client of its +current time when an invalid timestamp is received. + +If an attacker is able to manipulate this information and cause the client to use an incorrect time, it would be able to cause +the client to generate authenticated requests using time in the future. Such requests will fail when sent by the client, and will +not likely leave a trace on the server (given the common implementation of nonce, if at all enforced). The attacker will then +be able to replay the request at the correct time without detection. + +The client must only use the time information provided by the server if: +* it was delivered over a TLS connection and the server identity has been verified, or +* the `tsm` MAC digest calculated using the same client credentials over the timestamp has been verified. + +### Client Clock Poisoning + +When receiving a request with a bad timestamp, the server provides the client with its current time. The client must never use +the time received from the server to adjust its own clock, and must only use it to calculate an offset for communicating with +that particular server. + +### Bewit Limitations + +Special care must be taken when issuing bewit credentials to third parties. Bewit credentials are valid until expiration and cannot +be revoked or limited without using other means. Whatever resource they grant access to will be completely exposed to anyone with +access to the bewit credentials which act as bearer credentials for that particular resource. While bewit usage is limited to GET +requests only and therefore cannot be used to perform transactions or change server state, it can still be used to expose private +and sensitive information. + +### Host Header Forgery + +Hawk validates the incoming request MAC against the incoming HTTP Host header. However, unless the optional `host` and `port` +options are used with `server.authenticate()`, a malicous client can mint new host names pointing to the server's IP address and +use that to craft an attack by sending a valid request that's meant for another hostname than the one used by the server. Server +implementors must manually verify that the host header received matches their expectation (or use the options mentioned above). + +# Frequently Asked Questions + +### Where is the protocol specification? + +If you are looking for some prose explaining how all this works, **this is it**. **Hawk** is being developed as an open source +project instead of a standard. In other words, the [code](/hueniverse/hawk/tree/master/lib) is the specification. Not sure about +something? Open an issue! + +### Is it done? + +At if version 0.10.0, **Hawk** is feature-complete. However, until this module reaches version 1.0.0 it is considered experimental +and is likely to change. This also means your feedback and contribution are very welcome. Feel free to open issues with questions +and suggestions. + +### Where can I find **Hawk** implementations in other languages? + +**Hawk**'s only reference implementation is provided in JavaScript as a node.js module. However, others are actively porting it to other +platforms. There is already a [PHP](https://github.com/alexbilbie/PHP-Hawk), +[.NET](https://github.com/pcibraro/hawknet), and [JAVA](https://github.com/wealdtech/hawk) libraries available. The full list +is maintained [here](https://github.com/hueniverse/hawk/issues?labels=port). Please add an issue if you are working on another +port. A cross-platform test-suite is in the works. + +### Why isn't the algorithm part of the challenge or dynamically negotiated? + +The algorithm used is closely related to the key issued as different algorithms require different key sizes (and other +requirements). While some keys can be used for multiple algorithm, the protocol is designed to closely bind the key and algorithm +together as part of the issued credentials. + +### Why is Host and Content-Type the only headers covered by the request MAC? + +It is really hard to include other headers. Headers can be changed by proxies and other intermediaries and there is no +well-established way to normalize them. Many platforms change the case of header field names and values. The only +straight-forward solution is to include the headers in some blob (say, base64 encoded JSON) and include that with the request, +an approach taken by JWT and other such formats. However, that design violates the HTTP header boundaries, repeats information, +and introduces other security issues because firewalls will not be aware of these "hidden" headers. In addition, any information +repeated must be compared to the duplicated information in the header and therefore only moves the problem elsewhere. + +### Why not just use HTTP Digest? + +Digest requires pre-negotiation to establish a nonce. This means you can't just make a request - you must first send +a protocol handshake to the server. This pattern has become unacceptable for most web services, especially mobile +where extra round-trip are costly. + +### Why bother with all this nonce and timestamp business? + +**Hawk** is an attempt to find a reasonable, practical compromise between security and usability. OAuth 1.0 got timestamp +and nonces halfway right but failed when it came to scalability and consistent developer experience. **Hawk** addresses +it by requiring the client to sync its clock, but provides it with tools to accomplish it. + +In general, replay protection is a matter of application-specific threat model. It is less of an issue on a TLS-protected +system where the clients are implemented using best practices and are under the control of the server. Instead of dropping +replay protection, **Hawk** offers a required time window and an optional nonce verification. Together, it provides developers +with the ability to decide how to enforce their security policy without impacting the client's implementation. + +### What are `app` and `dlg` in the authorization header and normalized mac string? + +The original motivation for **Hawk** was to replace the OAuth 1.0 use cases. This included both a simple client-server mode which +this module is specifically designed for, and a delegated access mode which is being developed separately in +[Oz](https://github.com/hueniverse/oz). In addition to the **Hawk** use cases, Oz requires another attribute: the application id `app`. +This provides binding between the credentials and the application in a way that prevents an attacker from tricking an application +to use credentials issued to someone else. It also has an optional 'delegated-by' attribute `dlg` which is the application id of the +application the credentials were directly issued to. The goal of these two additions is to allow Oz to utilize **Hawk** directly, +but with the additional security of delegated credentials. + +### What is the purpose of the static strings used in each normalized MAC input? + +When calculating a hash or MAC, a static prefix (tag) is added. The prefix is used to prevent MAC values from being +used or reused for a purpose other than what they were created for (i.e. prevents switching MAC values between a request, +response, and a bewit use cases). It also protects against expliots created after a potential change in how the protocol +creates the normalized string. For example, if a future version would switch the order of nonce and timestamp, it +can create an exploit opportunity for cases where the nonce is similar in format to a timestamp. + +### Does **Hawk** have anything to do with OAuth? + +Short answer: no. + +**Hawk** was originally proposed as the OAuth MAC Token specification. However, the OAuth working group in its consistent +incompetence failed to produce a final, usable solution to address one of the most popular use cases of OAuth 1.0 - using it +to authenticate simple client-server transactions (i.e. two-legged). As you can guess, the OAuth working group is still hard +at work to produce more garbage. + +**Hawk** provides a simple HTTP authentication scheme for making client-server requests. It does not address the OAuth use case +of delegating access to a third party. If you are looking for an OAuth alternative, check out [Oz](https://github.com/hueniverse/oz). + + +# Acknowledgements + +**Hawk** is a derivative work of the [HTTP MAC Authentication Scheme](http://tools.ietf.org/html/draft-hammer-oauth-v2-mac-token-05) proposal +co-authored by Ben Adida, Adam Barth, and Eran Hammer, which in turn was based on the OAuth 1.0 community specification. + +Special thanks to Ben Laurie for his always insightful feedback and advice. + +The **Hawk** logo was created by [Chris Carrasco](http://chriscarrasco.com). diff --git a/deps/npm/node_modules/request/node_modules/hawk/lib/browser.js b/deps/npm/node_modules/request/node_modules/hawk/lib/browser.js index 6eeb2b15e7f..27494f23f94 100755 --- a/deps/npm/node_modules/request/node_modules/hawk/lib/browser.js +++ b/deps/npm/node_modules/request/node_modules/hawk/lib/browser.js @@ -1,430 +1,485 @@ -/*
- HTTP Hawk Authentication Scheme
- Copyright (c) 2012-2013, Eran Hammer <eran@hueniverse.com>
- MIT Licensed
-*/
-
-
-// Declare namespace
-
-var hawk = {};
-
-
-// Export if used as a module
-
-if (typeof module !== "undefined" && module.exports) {
- module.exports = hawk;
-}
-
-// Generate an Authorization header for a given request
-
-/*
- uri: 'http://example.com/resource?a=b'
- method: HTTP verb (e.g. 'GET', 'POST')
- options: {
-
- // Required
-
- credentials: {
- id: 'dh37fgj492je',
- key: 'aoijedoaijsdlaksjdl',
- algorithm: 'sha256' // 'sha1', 'sha256'
- },
-
- // Optional
-
- ext: 'application-specific', // Application specific data sent via the ext attribute
- timestamp: Date.now() / 1000, // A pre-calculated timestamp in seconds
- nonce: '2334f34f', // A pre-generated nonce
- localtimeOffsetMsec: 400, // Time offset to sync with server time (ignored if timestamp provided)
- payload: '{"some":"payload"}', // UTF-8 encoded string for body hash generation (ignored if hash provided)
- contentType: 'application/json', // Payload content-type (ignored if hash provided)
- hash: 'U4MKKSmiVxk37JCCrAVIjV=', // Pre-calculated payload hash
- app: '24s23423f34dx', // Oz application id
- dlg: '234sz34tww3sd' // Oz delegated-by application id
- }
-*/
-
-hawk.client = {
-
- header: function (uri, method, options) {
-
- var result = {
- field: '',
- artifacts: {}
- };
-
- // Validate inputs
-
- if (!uri || (typeof uri !== 'string' && typeof uri !== 'object') ||
- !method || typeof method !== 'string' ||
- !options || typeof options !== 'object') {
-
- return result;
- }
-
- // Application time
-
- var timestamp = options.timestamp || Math.floor((hawk.utils.now() + (options.localtimeOffsetMsec || 0)) / 1000)
-
- // Validate credentials
-
- var credentials = options.credentials;
- if (!credentials ||
- !credentials.id ||
- !credentials.key ||
- !credentials.algorithm) {
-
- // Invalid credential object
- return result;
- }
-
- if (hawk.crypto.algorithms.indexOf(credentials.algorithm) === -1) {
- return result;
- }
-
- // Parse URI
-
- if (typeof uri === 'string') {
- uri = hawk.utils.parseUri(uri);
- }
-
- // Calculate signature
-
- var artifacts = {
- ts: timestamp,
- nonce: options.nonce || hawk.utils.randomString(6),
- method: method,
- resource: uri.relative,
- host: uri.hostname,
- port: uri.port,
- hash: options.hash,
- ext: options.ext,
- app: options.app,
- dlg: options.dlg
- };
-
- result.artifacts = artifacts;
-
- // Calculate payload hash
-
- if (!artifacts.hash &&
- options.hasOwnProperty('payload')) {
-
- artifacts.hash = hawk.crypto.calculatePayloadHash(options.payload, credentials.algorithm, options.contentType);
- }
-
- var mac = hawk.crypto.calculateMac('header', credentials, artifacts);
-
- // Construct header
-
- var hasExt = artifacts.ext !== null && artifacts.ext !== undefined && artifacts.ext !== ''; // Other falsey values allowed
- var header = 'Hawk id="' + credentials.id +
- '", ts="' + artifacts.ts +
- '", nonce="' + artifacts.nonce +
- (artifacts.hash ? '", hash="' + artifacts.hash : '') +
- (hasExt ? '", ext="' + hawk.utils.escapeHeaderAttribute(artifacts.ext) : '') +
- '", mac="' + mac + '"';
-
- if (artifacts.app) {
- header += ', app="' + artifacts.app +
- (artifacts.dlg ? '", dlg="' + artifacts.dlg : '') + '"';
- }
-
- result.field = header;
-
- return result;
- },
-
-
- // Validate server response
-
- /*
- request: object created via 'new XMLHttpRequest()' after response received
- artifacts: object recieved from header().artifacts
- options: {
- payload: optional payload received
- required: specifies if a Server-Authorization header is required. Defaults to 'false'
- }
- */
-
- authenticate: function (request, credentials, artifacts, options) {
-
- options = options || {};
-
- if (request.getResponseHeader('www-authenticate')) {
-
- // Parse HTTP WWW-Authenticate header
-
- var attributes = hawk.utils.parseAuthorizationHeader(request.getResponseHeader('www-authenticate'), ['ts', 'tsm', 'error']);
- if (!attributes) {
- return false;
- }
-
- if (attributes.ts) {
- var tsm = hawk.crypto.calculateTsMac(attributes.ts, credentials);
- if (tsm !== attributes.tsm) {
- return false;
- }
-
- hawk.utils.setNtpOffset(attributes.ts - Math.floor(Date.now() / 1000)); // Keep offset at 1 second precision
- }
- }
-
- // Parse HTTP Server-Authorization header
-
- if (!request.getResponseHeader('server-authorization') &&
- !options.required) {
-
- return true;
- }
-
- var attributes = hawk.utils.parseAuthorizationHeader(request.getResponseHeader('server-authorization'), ['mac', 'ext', 'hash']);
- if (!attributes) {
- return false;
- }
-
- var modArtifacts = {
- ts: artifacts.ts,
- nonce: artifacts.nonce,
- method: artifacts.method,
- resource: artifacts.resource,
- host: artifacts.host,
- port: artifacts.port,
- hash: attributes.hash,
- ext: attributes.ext,
- app: artifacts.app,
- dlg: artifacts.dlg
- };
-
- var mac = hawk.crypto.calculateMac('response', credentials, modArtifacts);
- if (mac !== attributes.mac) {
- return false;
- }
-
- if (!options.hasOwnProperty('payload')) {
- return true;
- }
-
- if (!attributes.hash) {
- return false;
- }
-
- var calculatedHash = hawk.crypto.calculatePayloadHash(options.payload, credentials.algorithm, request.getResponseHeader('content-type'));
- return (calculatedHash === attributes.hash);
- }
-};
-
-
-hawk.crypto = {
-
- headerVersion: '1',
-
- algorithms: ['sha1', 'sha256'],
-
- calculateMac: function (type, credentials, options) {
-
- var normalized = hawk.crypto.generateNormalizedString(type, options);
-
- var hmac = CryptoJS['Hmac' + credentials.algorithm.toUpperCase()](normalized, credentials.key);
- return hmac.toString(CryptoJS.enc.Base64);
- },
-
- generateNormalizedString: function (type, options) {
-
- var normalized = 'hawk.' + hawk.crypto.headerVersion + '.' + type + '\n' +
- options.ts + '\n' +
- options.nonce + '\n' +
- options.method.toUpperCase() + '\n' +
- options.resource + '\n' +
- options.host.toLowerCase() + '\n' +
- options.port + '\n' +
- (options.hash || '') + '\n';
-
- if (options.ext) {
- normalized += options.ext.replace('\\', '\\\\').replace('\n', '\\n');
- }
-
- normalized += '\n';
-
- if (options.app) {
- normalized += options.app + '\n' +
- (options.dlg || '') + '\n';
- }
-
- return normalized;
- },
-
- calculatePayloadHash: function (payload, algorithm, contentType) {
-
- var hash = CryptoJS.algo[algorithm.toUpperCase()].create();
- hash.update('hawk.' + hawk.crypto.headerVersion + '.payload\n');
- hash.update(hawk.utils.parseContentType(contentType) + '\n');
- hash.update(payload || '');
- hash.update('\n');
- return hash.finalize().toString(CryptoJS.enc.Base64);
- },
-
- calculateTsMac: function (ts, credentials) {
-
- var hash = CryptoJS['Hmac' + credentials.algorithm.toUpperCase()]('hawk.' + hawk.crypto.headerVersion + '.ts\n' + ts + '\n', credentials.key);
- return hash.toString(CryptoJS.enc.Base64);
- }
-};
-
-
-hawk.utils = {
-
- storage: { // localStorage compatible interface
- _cache: {},
- setItem: function (key, value) {
-
- hawk.utils.storage._cache[key] = value;
- },
- getItem: function (key) {
-
- return hawk.utils.storage._cache[key];
- }
- },
-
- setStorage: function (storage) {
-
- var ntpOffset = hawk.utils.getNtpOffset() || 0;
- hawk.utils.storage = storage;
- hawk.utils.setNtpOffset(ntpOffset);
- },
-
- setNtpOffset: function (offset) {
-
- hawk.utils.storage.setItem('hawk_ntp_offset', offset);
- },
-
- getNtpOffset: function () {
-
- return parseInt(hawk.utils.storage.getItem('hawk_ntp_offset') || '0', 10);
- },
-
- now: function () {
-
- return Date.now() + hawk.utils.getNtpOffset();
- },
-
- escapeHeaderAttribute: function (attribute) {
-
- return attribute.replace(/\\/g, '\\\\').replace(/\"/g, '\\"');
- },
-
- parseContentType: function (header) {
-
- if (!header) {
- return '';
- }
-
- return header.split(';')[0].trim().toLowerCase();
- },
-
- parseAuthorizationHeader: function (header, keys) {
-
- if (!header) {
- return null;
- }
-
- var headerParts = header.match(/^(\w+)(?:\s+(.*))?$/); // Header: scheme[ something]
- if (!headerParts) {
- return null;
- }
-
- var scheme = headerParts[1];
- if (scheme.toLowerCase() !== 'hawk') {
- return null;
- }
-
- var attributesString = headerParts[2];
- if (!attributesString) {
- return null;
- }
-
- var attributes = {};
- var verify = attributesString.replace(/(\w+)="([^"\\]*)"\s*(?:,\s*|$)/g, function ($0, $1, $2) {
-
- // Check valid attribute names
-
- if (keys.indexOf($1) === -1) {
- return;
- }
-
- // Allowed attribute value characters: !#$%&'()*+,-./:;<=>?@[]^_`{|}~ and space, a-z, A-Z, 0-9
-
- if ($2.match(/^[ \w\!#\$%&'\(\)\*\+,\-\.\/\:;<\=>\?@\[\]\^`\{\|\}~]+$/) === null) {
- return;
- }
-
- // Check for duplicates
-
- if (attributes.hasOwnProperty($1)) {
- return;
- }
-
- attributes[$1] = $2;
- return '';
- });
-
- if (verify !== '') {
- return null;
- }
-
- return attributes;
- },
-
- randomString: function (size) {
-
- var randomSource = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
- var len = randomSource.length;
-
- var result = [];
- for (var i = 0; i < size; ++i) {
- result[i] = randomSource[Math.floor(Math.random() * len)];
- }
-
- return result.join('');
- },
-
- parseUri: function (input) {
-
- // Based on: parseURI 1.2.2
- // http://blog.stevenlevithan.com/archives/parseuri
- // (c) Steven Levithan <stevenlevithan.com>
- // MIT License
-
- var keys = ['source', 'protocol', 'authority', 'userInfo', 'user', 'password', 'hostname', 'port', 'resource', 'relative', 'pathname', 'directory', 'file', 'query', 'fragment'];
-
- var uriRegex = /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?(((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?)(?:#(.*))?)/;
- var uriByNumber = uriRegex.exec(input);
- var uri = {};
-
- var i = 15;
- while (i--) {
- uri[keys[i]] = uriByNumber[i] || '';
- }
-
- if (uri.port === null ||
- uri.port === '') {
-
- uri.port = (uri.protocol.toLowerCase() === 'http' ? '80' : (uri.protocol.toLowerCase() === 'https' ? '443' : ''));
- }
-
- return uri;
- }
-};
-
-
-// Based on: Crypto-JS v3.1.2
-// Copyright (c) 2009-2013, Jeff Mott. All rights reserved.
-// http://code.google.com/p/crypto-js/
-// http://code.google.com/p/crypto-js/wiki/License
-
-var CryptoJS=CryptoJS||function(h,r){var k={},l=k.lib={},n=function(){},f=l.Base={extend:function(a){n.prototype=this;var b=new n;a&&b.mixIn(a);b.hasOwnProperty("init")||(b.init=function(){b.$super.init.apply(this,arguments)});b.init.prototype=b;b.$super=this;return b},create:function(){var a=this.extend();a.init.apply(a,arguments);return a},init:function(){},mixIn:function(a){for(var b in a)a.hasOwnProperty(b)&&(this[b]=a[b]);a.hasOwnProperty("toString")&&(this.toString=a.toString)},clone:function(){return this.init.prototype.extend(this)}},j=l.WordArray=f.extend({init:function(a,b){a=this.words=a||[];this.sigBytes=b!=r?b:4*a.length},toString:function(a){return(a||s).stringify(this)},concat:function(a){var b=this.words,d=a.words,c=this.sigBytes;a=a.sigBytes;this.clamp();if(c%4)for(var e=0;e<a;e++)b[c+e>>>2]|=(d[e>>>2]>>>24-8*(e%4)&255)<<24-8*((c+e)%4);else if(65535<d.length)for(e=0;e<a;e+=4)b[c+e>>>2]=d[e>>>2];else b.push.apply(b,d);this.sigBytes+=a;return this},clamp:function(){var a=this.words,b=this.sigBytes;a[b>>>2]&=4294967295<<32-8*(b%4);a.length=h.ceil(b/4)},clone:function(){var a=f.clone.call(this);a.words=this.words.slice(0);return a},random:function(a){for(var b=[],d=0;d<a;d+=4)b.push(4294967296*h.random()|0);return new j.init(b,a)}}),m=k.enc={},s=m.Hex={stringify:function(a){var b=a.words;a=a.sigBytes;for(var d=[],c=0;c<a;c++){var e=b[c>>>2]>>>24-8*(c%4)&255;d.push((e>>>4).toString(16));d.push((e&15).toString(16))}return d.join("")},parse:function(a){for(var b=a.length,d=[],c=0;c<b;c+=2)d[c>>>3]|=parseInt(a.substr(c,2),16)<<24-4*(c%8);return new j.init(d,b/2)}},p=m.Latin1={stringify:function(a){var b=a.words;a=a.sigBytes;for(var d=[],c=0;c<a;c++)d.push(String.fromCharCode(b[c>>>2]>>>24-8*(c%4)&255));return d.join("")},parse:function(a){for(var b=a.length,d=[],c=0;c<b;c++)d[c>>>2]|=(a.charCodeAt(c)&255)<<24-8*(c%4);return new j.init(d,b)}},t=m.Utf8={stringify:function(a){try{return decodeURIComponent(escape(p.stringify(a)))}catch(b){throw Error("Malformed UTF-8 data");}},parse:function(a){return p.parse(unescape(encodeURIComponent(a)))}},q=l.BufferedBlockAlgorithm=f.extend({reset:function(){this._data=new j.init;this._nDataBytes=0},_append:function(a){"string"==typeof a&&(a=t.parse(a));this._data.concat(a);this._nDataBytes+=a.sigBytes},_process:function(a){var b=this._data,d=b.words,c=b.sigBytes,e=this.blockSize,f=c/(4*e),f=a?h.ceil(f):h.max((f|0)-this._minBufferSize,0);a=f*e;c=h.min(4*a,c);if(a){for(var g=0;g<a;g+=e)this._doProcessBlock(d,g);g=d.splice(0,a);b.sigBytes-=c}return new j.init(g,c)},clone:function(){var a=f.clone.call(this);a._data=this._data.clone();return a},_minBufferSize:0});l.Hasher=q.extend({cfg:f.extend(),init:function(a){this.cfg=this.cfg.extend(a);this.reset()},reset:function(){q.reset.call(this);this._doReset()},update:function(a){this._append(a);this._process();return this},finalize:function(a){a&&this._append(a);return this._doFinalize()},blockSize:16,_createHelper:function(a){return function(b,d){return(new a.init(d)).finalize(b)}},_createHmacHelper:function(a){return function(b,d){return(new u.HMAC.init(a,d)).finalize(b)}}});var u=k.algo={};return k}(Math);
-(function () { var k = CryptoJS, b = k.lib, m = b.WordArray, l = b.Hasher, d = [], b = k.algo.SHA1 = l.extend({ _doReset: function () { this._hash = new m.init([1732584193, 4023233417, 2562383102, 271733878, 3285377520]) }, _doProcessBlock: function (n, p) { for (var a = this._hash.words, e = a[0], f = a[1], h = a[2], j = a[3], b = a[4], c = 0; 80 > c; c++) { if (16 > c) d[c] = n[p + c] | 0; else { var g = d[c - 3] ^ d[c - 8] ^ d[c - 14] ^ d[c - 16]; d[c] = g << 1 | g >>> 31 } g = (e << 5 | e >>> 27) + b + d[c]; g = 20 > c ? g + ((f & h | ~f & j) + 1518500249) : 40 > c ? g + ((f ^ h ^ j) + 1859775393) : 60 > c ? g + ((f & h | f & j | h & j) - 1894007588) : g + ((f ^ h ^ j) - 899497514); b = j; j = h; h = f << 30 | f >>> 2; f = e; e = g } a[0] = a[0] + e | 0; a[1] = a[1] + f | 0; a[2] = a[2] + h | 0; a[3] = a[3] + j | 0; a[4] = a[4] + b | 0 }, _doFinalize: function () { var b = this._data, d = b.words, a = 8 * this._nDataBytes, e = 8 * b.sigBytes; d[e >>> 5] |= 128 << 24 - e % 32; d[(e + 64 >>> 9 << 4) + 14] = Math.floor(a / 4294967296); d[(e + 64 >>> 9 << 4) + 15] = a; b.sigBytes = 4 * d.length; this._process(); return this._hash }, clone: function () { var b = l.clone.call(this); b._hash = this._hash.clone(); return b } }); k.SHA1 = l._createHelper(b); k.HmacSHA1 = l._createHmacHelper(b) })();
-(function (k) { for (var g = CryptoJS, h = g.lib, v = h.WordArray, j = h.Hasher, h = g.algo, s = [], t = [], u = function (q) { return 4294967296 * (q - (q | 0)) | 0 }, l = 2, b = 0; 64 > b;) { var d; a: { d = l; for (var w = k.sqrt(d), r = 2; r <= w; r++) if (!(d % r)) { d = !1; break a } d = !0 } d && (8 > b && (s[b] = u(k.pow(l, 0.5))), t[b] = u(k.pow(l, 1 / 3)), b++); l++ } var n = [], h = h.SHA256 = j.extend({ _doReset: function () { this._hash = new v.init(s.slice(0)) }, _doProcessBlock: function (q, h) { for (var a = this._hash.words, c = a[0], d = a[1], b = a[2], k = a[3], f = a[4], g = a[5], j = a[6], l = a[7], e = 0; 64 > e; e++) { if (16 > e) n[e] = q[h + e] | 0; else { var m = n[e - 15], p = n[e - 2]; n[e] = ((m << 25 | m >>> 7) ^ (m << 14 | m >>> 18) ^ m >>> 3) + n[e - 7] + ((p << 15 | p >>> 17) ^ (p << 13 | p >>> 19) ^ p >>> 10) + n[e - 16] } m = l + ((f << 26 | f >>> 6) ^ (f << 21 | f >>> 11) ^ (f << 7 | f >>> 25)) + (f & g ^ ~f & j) + t[e] + n[e]; p = ((c << 30 | c >>> 2) ^ (c << 19 | c >>> 13) ^ (c << 10 | c >>> 22)) + (c & d ^ c & b ^ d & b); l = j; j = g; g = f; f = k + m | 0; k = b; b = d; d = c; c = m + p | 0 } a[0] = a[0] + c | 0; a[1] = a[1] + d | 0; a[2] = a[2] + b | 0; a[3] = a[3] + k | 0; a[4] = a[4] + f | 0; a[5] = a[5] + g | 0; a[6] = a[6] + j | 0; a[7] = a[7] + l | 0 }, _doFinalize: function () { var d = this._data, b = d.words, a = 8 * this._nDataBytes, c = 8 * d.sigBytes; b[c >>> 5] |= 128 << 24 - c % 32; b[(c + 64 >>> 9 << 4) + 14] = k.floor(a / 4294967296); b[(c + 64 >>> 9 << 4) + 15] = a; d.sigBytes = 4 * b.length; this._process(); return this._hash }, clone: function () { var b = j.clone.call(this); b._hash = this._hash.clone(); return b } }); g.SHA256 = j._createHelper(h); g.HmacSHA256 = j._createHmacHelper(h) })(Math);
-(function(){var c=CryptoJS,k=c.enc.Utf8;c.algo.HMAC=c.lib.Base.extend({init:function(a,b){a=this._hasher=new a.init;"string"==typeof b&&(b=k.parse(b));var c=a.blockSize,e=4*c;b.sigBytes>e&&(b=a.finalize(b));b.clamp();for(var f=this._oKey=b.clone(),g=this._iKey=b.clone(),h=f.words,j=g.words,d=0;d<c;d++)h[d]^=1549556828,j[d]^=909522486;f.sigBytes=g.sigBytes=e;this.reset()},reset:function(){var a=this._hasher;a.reset();a.update(this._iKey)},update:function(a){this._hasher.update(a);return this},finalize:function(a){var b=this._hasher;a=b.finalize(a);b.reset();return b.finalize(this._oKey.clone().concat(a))}})})();
-(function(){var h=CryptoJS,j=h.lib.WordArray;h.enc.Base64={stringify:function(b){var e=b.words,f=b.sigBytes,c=this._map;b.clamp();b=[];for(var a=0;a<f;a+=3)for(var d=(e[a>>>2]>>>24-8*(a%4)&255)<<16|(e[a+1>>>2]>>>24-8*((a+1)%4)&255)<<8|e[a+2>>>2]>>>24-8*((a+2)%4)&255,g=0;4>g&&a+0.75*g<f;g++)b.push(c.charAt(d>>>6*(3-g)&63));if(e=c.charAt(64))for(;b.length%4;)b.push(e);return b.join("")},parse:function(b){var e=b.length,f=this._map,c=f.charAt(64);c&&(c=b.indexOf(c),-1!=c&&(e=c));for(var c=[],a=0,d=0;d<e;d++)if(d%4){var g=f.indexOf(b.charAt(d-1))<<2*(d%4),h=f.indexOf(b.charAt(d))>>>6-2*(d%4);c[a>>>2]|=(g|h)<<24-8*(a%4);a++}return j.create(c,a)},_map:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="}})();
+/* + HTTP Hawk Authentication Scheme + Copyright (c) 2012-2013, Eran Hammer <eran@hueniverse.com> + MIT Licensed +*/ + + +// Declare namespace + +var hawk = {}; + + +// Export if used as a module + +if (typeof module !== "undefined" && module.exports) { + module.exports = hawk; +} + +hawk.client = { + + // Generate an Authorization header for a given request + + /* + uri: 'http://example.com/resource?a=b' + method: HTTP verb (e.g. 'GET', 'POST') + options: { + + // Required + + credentials: { + id: 'dh37fgj492je', + key: 'aoijedoaijsdlaksjdl', + algorithm: 'sha256' // 'sha1', 'sha256' + }, + + // Optional + + ext: 'application-specific', // Application specific data sent via the ext attribute + timestamp: Date.now() / 1000, // A pre-calculated timestamp in seconds + nonce: '2334f34f', // A pre-generated nonce + localtimeOffsetMsec: 400, // Time offset to sync with server time (ignored if timestamp provided) + payload: '{"some":"payload"}', // UTF-8 encoded string for body hash generation (ignored if hash provided) + contentType: 'application/json', // Payload content-type (ignored if hash provided) + hash: 'U4MKKSmiVxk37JCCrAVIjV=', // Pre-calculated payload hash + app: '24s23423f34dx', // Oz application id + dlg: '234sz34tww3sd' // Oz delegated-by application id + } + */ + + header: function (uri, method, options) { + + var result = { + field: '', + artifacts: {} + }; + + // Validate inputs + + if (!uri || (typeof uri !== 'string' && typeof uri !== 'object') || + !method || typeof method !== 'string' || + !options || typeof options !== 'object') { + + return result; + } + + // Application time + + var timestamp = options.timestamp || Math.floor((hawk.utils.now() + (options.localtimeOffsetMsec || 0)) / 1000) + + // Validate credentials + + var credentials = options.credentials; + if (!credentials || + !credentials.id || + !credentials.key || + !credentials.algorithm) { + + // Invalid credential object + return result; + } + + if (hawk.crypto.algorithms.indexOf(credentials.algorithm) === -1) { + return result; + } + + // Parse URI + + if (typeof uri === 'string') { + uri = hawk.utils.parseUri(uri); + } + + // Calculate signature + + var artifacts = { + ts: timestamp, + nonce: options.nonce || hawk.utils.randomString(6), + method: method, + resource: uri.relative, + host: uri.hostname, + port: uri.port, + hash: options.hash, + ext: options.ext, + app: options.app, + dlg: options.dlg + }; + + result.artifacts = artifacts; + + // Calculate payload hash + + if (!artifacts.hash && + options.hasOwnProperty('payload')) { + + artifacts.hash = hawk.crypto.calculatePayloadHash(options.payload, credentials.algorithm, options.contentType); + } + + var mac = hawk.crypto.calculateMac('header', credentials, artifacts); + + // Construct header + + var hasExt = artifacts.ext !== null && artifacts.ext !== undefined && artifacts.ext !== ''; // Other falsey values allowed + var header = 'Hawk id="' + credentials.id + + '", ts="' + artifacts.ts + + '", nonce="' + artifacts.nonce + + (artifacts.hash ? '", hash="' + artifacts.hash : '') + + (hasExt ? '", ext="' + hawk.utils.escapeHeaderAttribute(artifacts.ext) : '') + + '", mac="' + mac + '"'; + + if (artifacts.app) { + header += ', app="' + artifacts.app + + (artifacts.dlg ? '", dlg="' + artifacts.dlg : '') + '"'; + } + + result.field = header; + + return result; + }, + + + // Validate server response + + /* + request: object created via 'new XMLHttpRequest()' after response received + artifacts: object recieved from header().artifacts + options: { + payload: optional payload received + required: specifies if a Server-Authorization header is required. Defaults to 'false' + } + */ + + authenticate: function (request, credentials, artifacts, options) { + + options = options || {}; + + if (request.getResponseHeader('www-authenticate')) { + + // Parse HTTP WWW-Authenticate header + + var attributes = hawk.utils.parseAuthorizationHeader(request.getResponseHeader('www-authenticate'), ['ts', 'tsm', 'error']); + if (!attributes) { + return false; + } + + if (attributes.ts) { + var tsm = hawk.crypto.calculateTsMac(attributes.ts, credentials); + if (tsm !== attributes.tsm) { + return false; + } + + hawk.utils.setNtpOffset(attributes.ts - Math.floor(Date.now() / 1000)); // Keep offset at 1 second precision + } + } + + // Parse HTTP Server-Authorization header + + if (!request.getResponseHeader('server-authorization') && + !options.required) { + + return true; + } + + var attributes = hawk.utils.parseAuthorizationHeader(request.getResponseHeader('server-authorization'), ['mac', 'ext', 'hash']); + if (!attributes) { + return false; + } + + var modArtifacts = { + ts: artifacts.ts, + nonce: artifacts.nonce, + method: artifacts.method, + resource: artifacts.resource, + host: artifacts.host, + port: artifacts.port, + hash: attributes.hash, + ext: attributes.ext, + app: artifacts.app, + dlg: artifacts.dlg + }; + + var mac = hawk.crypto.calculateMac('response', credentials, modArtifacts); + if (mac !== attributes.mac) { + return false; + } + + if (!options.hasOwnProperty('payload')) { + return true; + } + + if (!attributes.hash) { + return false; + } + + var calculatedHash = hawk.crypto.calculatePayloadHash(options.payload, credentials.algorithm, request.getResponseHeader('content-type')); + return (calculatedHash === attributes.hash); + }, + + message: function (host, port, message, options) { + + // Validate inputs + + if (!host || typeof host !== 'string' || + !port || typeof port !== 'number' || + message === null || message === undefined || typeof message !== 'string' || + !options || typeof options !== 'object') { + + return null; + } + + // Application time + + var timestamp = options.timestamp || Math.floor((hawk.utils.now() + (options.localtimeOffsetMsec || 0)) / 1000) + + // Validate credentials + + var credentials = options.credentials; + if (!credentials || + !credentials.id || + !credentials.key || + !credentials.algorithm) { + + // Invalid credential object + return null; + } + + if (hawk.crypto.algorithms.indexOf(credentials.algorithm) === -1) { + return null; + } + + // Calculate signature + + var artifacts = { + ts: timestamp, + nonce: options.nonce || hawk.utils.randomString(6), + host: host, + port: port, + hash: hawk.crypto.calculatePayloadHash(message, credentials.algorithm) + }; + + // Construct authorization + + var result = { + id: credentials.id, + ts: artifacts.ts, + nonce: artifacts.nonce, + hash: artifacts.hash, + mac: hawk.crypto.calculateMac('message', credentials, artifacts) + }; + + return result; + } +}; + + +hawk.crypto = { + + headerVersion: '1', + + algorithms: ['sha1', 'sha256'], + + calculateMac: function (type, credentials, options) { + + var normalized = hawk.crypto.generateNormalizedString(type, options); + + var hmac = CryptoJS['Hmac' + credentials.algorithm.toUpperCase()](normalized, credentials.key); + return hmac.toString(CryptoJS.enc.Base64); + }, + + generateNormalizedString: function (type, options) { + + var normalized = 'hawk.' + hawk.crypto.headerVersion + '.' + type + '\n' + + options.ts + '\n' + + options.nonce + '\n' + + (options.method || '').toUpperCase() + '\n' + + (options.resource || '') + '\n' + + options.host.toLowerCase() + '\n' + + options.port + '\n' + + (options.hash || '') + '\n'; + + if (options.ext) { + normalized += options.ext.replace('\\', '\\\\').replace('\n', '\\n'); + } + + normalized += '\n'; + + if (options.app) { + normalized += options.app + '\n' + + (options.dlg || '') + '\n'; + } + + return normalized; + }, + + calculatePayloadHash: function (payload, algorithm, contentType) { + + var hash = CryptoJS.algo[algorithm.toUpperCase()].create(); + hash.update('hawk.' + hawk.crypto.headerVersion + '.payload\n'); + hash.update(hawk.utils.parseContentType(contentType) + '\n'); + hash.update(payload || ''); + hash.update('\n'); + return hash.finalize().toString(CryptoJS.enc.Base64); + }, + + calculateTsMac: function (ts, credentials) { + + var hash = CryptoJS['Hmac' + credentials.algorithm.toUpperCase()]('hawk.' + hawk.crypto.headerVersion + '.ts\n' + ts + '\n', credentials.key); + return hash.toString(CryptoJS.enc.Base64); + } +}; + + +hawk.utils = { + + storage: { // localStorage compatible interface + _cache: {}, + setItem: function (key, value) { + + hawk.utils.storage._cache[key] = value; + }, + getItem: function (key) { + + return hawk.utils.storage._cache[key]; + } + }, + + setStorage: function (storage) { + + var ntpOffset = hawk.utils.getNtpOffset() || 0; + hawk.utils.storage = storage; + hawk.utils.setNtpOffset(ntpOffset); + }, + + setNtpOffset: function (offset) { + + hawk.utils.storage.setItem('hawk_ntp_offset', offset); + }, + + getNtpOffset: function () { + + return parseInt(hawk.utils.storage.getItem('hawk_ntp_offset') || '0', 10); + }, + + now: function () { + + return Date.now() + hawk.utils.getNtpOffset(); + }, + + escapeHeaderAttribute: function (attribute) { + + return attribute.replace(/\\/g, '\\\\').replace(/\"/g, '\\"'); + }, + + parseContentType: function (header) { + + if (!header) { + return ''; + } + + return header.split(';')[0].trim().toLowerCase(); + }, + + parseAuthorizationHeader: function (header, keys) { + + if (!header) { + return null; + } + + var headerParts = header.match(/^(\w+)(?:\s+(.*))?$/); // Header: scheme[ something] + if (!headerParts) { + return null; + } + + var scheme = headerParts[1]; + if (scheme.toLowerCase() !== 'hawk') { + return null; + } + + var attributesString = headerParts[2]; + if (!attributesString) { + return null; + } + + var attributes = {}; + var verify = attributesString.replace(/(\w+)="([^"\\]*)"\s*(?:,\s*|$)/g, function ($0, $1, $2) { + + // Check valid attribute names + + if (keys.indexOf($1) === -1) { + return; + } + + // Allowed attribute value characters: !#$%&'()*+,-./:;<=>?@[]^_`{|}~ and space, a-z, A-Z, 0-9 + + if ($2.match(/^[ \w\!#\$%&'\(\)\*\+,\-\.\/\:;<\=>\?@\[\]\^`\{\|\}~]+$/) === null) { + return; + } + + // Check for duplicates + + if (attributes.hasOwnProperty($1)) { + return; + } + + attributes[$1] = $2; + return ''; + }); + + if (verify !== '') { + return null; + } + + return attributes; + }, + + randomString: function (size) { + + var randomSource = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; + var len = randomSource.length; + + var result = []; + for (var i = 0; i < size; ++i) { + result[i] = randomSource[Math.floor(Math.random() * len)]; + } + + return result.join(''); + }, + + parseUri: function (input) { + + // Based on: parseURI 1.2.2 + // http://blog.stevenlevithan.com/archives/parseuri + // (c) Steven Levithan <stevenlevithan.com> + // MIT License + + var keys = ['source', 'protocol', 'authority', 'userInfo', 'user', 'password', 'hostname', 'port', 'resource', 'relative', 'pathname', 'directory', 'file', 'query', 'fragment']; + + var uriRegex = /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?(((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?)(?:#(.*))?)/; + var uriByNumber = uriRegex.exec(input); + var uri = {}; + + var i = 15; + while (i--) { + uri[keys[i]] = uriByNumber[i] || ''; + } + + if (uri.port === null || + uri.port === '') { + + uri.port = (uri.protocol.toLowerCase() === 'http' ? '80' : (uri.protocol.toLowerCase() === 'https' ? '443' : '')); + } + + return uri; + } +}; + + +// Based on: Crypto-JS v3.1.2 +// Copyright (c) 2009-2013, Jeff Mott. All rights reserved. +// http://code.google.com/p/crypto-js/ +// http://code.google.com/p/crypto-js/wiki/License + +var CryptoJS=CryptoJS||function(h,r){var k={},l=k.lib={},n=function(){},f=l.Base={extend:function(a){n.prototype=this;var b=new n;a&&b.mixIn(a);b.hasOwnProperty("init")||(b.init=function(){b.$super.init.apply(this,arguments)});b.init.prototype=b;b.$super=this;return b},create:function(){var a=this.extend();a.init.apply(a,arguments);return a},init:function(){},mixIn:function(a){for(var b in a)a.hasOwnProperty(b)&&(this[b]=a[b]);a.hasOwnProperty("toString")&&(this.toString=a.toString)},clone:function(){return this.init.prototype.extend(this)}},j=l.WordArray=f.extend({init:function(a,b){a=this.words=a||[];this.sigBytes=b!=r?b:4*a.length},toString:function(a){return(a||s).stringify(this)},concat:function(a){var b=this.words,d=a.words,c=this.sigBytes;a=a.sigBytes;this.clamp();if(c%4)for(var e=0;e<a;e++)b[c+e>>>2]|=(d[e>>>2]>>>24-8*(e%4)&255)<<24-8*((c+e)%4);else if(65535<d.length)for(e=0;e<a;e+=4)b[c+e>>>2]=d[e>>>2];else b.push.apply(b,d);this.sigBytes+=a;return this},clamp:function(){var a=this.words,b=this.sigBytes;a[b>>>2]&=4294967295<<32-8*(b%4);a.length=h.ceil(b/4)},clone:function(){var a=f.clone.call(this);a.words=this.words.slice(0);return a},random:function(a){for(var b=[],d=0;d<a;d+=4)b.push(4294967296*h.random()|0);return new j.init(b,a)}}),m=k.enc={},s=m.Hex={stringify:function(a){var b=a.words;a=a.sigBytes;for(var d=[],c=0;c<a;c++){var e=b[c>>>2]>>>24-8*(c%4)&255;d.push((e>>>4).toString(16));d.push((e&15).toString(16))}return d.join("")},parse:function(a){for(var b=a.length,d=[],c=0;c<b;c+=2)d[c>>>3]|=parseInt(a.substr(c,2),16)<<24-4*(c%8);return new j.init(d,b/2)}},p=m.Latin1={stringify:function(a){var b=a.words;a=a.sigBytes;for(var d=[],c=0;c<a;c++)d.push(String.fromCharCode(b[c>>>2]>>>24-8*(c%4)&255));return d.join("")},parse:function(a){for(var b=a.length,d=[],c=0;c<b;c++)d[c>>>2]|=(a.charCodeAt(c)&255)<<24-8*(c%4);return new j.init(d,b)}},t=m.Utf8={stringify:function(a){try{return decodeURIComponent(escape(p.stringify(a)))}catch(b){throw Error("Malformed UTF-8 data");}},parse:function(a){return p.parse(unescape(encodeURIComponent(a)))}},q=l.BufferedBlockAlgorithm=f.extend({reset:function(){this._data=new j.init;this._nDataBytes=0},_append:function(a){"string"==typeof a&&(a=t.parse(a));this._data.concat(a);this._nDataBytes+=a.sigBytes},_process:function(a){var b=this._data,d=b.words,c=b.sigBytes,e=this.blockSize,f=c/(4*e),f=a?h.ceil(f):h.max((f|0)-this._minBufferSize,0);a=f*e;c=h.min(4*a,c);if(a){for(var g=0;g<a;g+=e)this._doProcessBlock(d,g);g=d.splice(0,a);b.sigBytes-=c}return new j.init(g,c)},clone:function(){var a=f.clone.call(this);a._data=this._data.clone();return a},_minBufferSize:0});l.Hasher=q.extend({cfg:f.extend(),init:function(a){this.cfg=this.cfg.extend(a);this.reset()},reset:function(){q.reset.call(this);this._doReset()},update:function(a){this._append(a);this._process();return this},finalize:function(a){a&&this._append(a);return this._doFinalize()},blockSize:16,_createHelper:function(a){return function(b,d){return(new a.init(d)).finalize(b)}},_createHmacHelper:function(a){return function(b,d){return(new u.HMAC.init(a,d)).finalize(b)}}});var u=k.algo={};return k}(Math); +(function () { var k = CryptoJS, b = k.lib, m = b.WordArray, l = b.Hasher, d = [], b = k.algo.SHA1 = l.extend({ _doReset: function () { this._hash = new m.init([1732584193, 4023233417, 2562383102, 271733878, 3285377520]) }, _doProcessBlock: function (n, p) { for (var a = this._hash.words, e = a[0], f = a[1], h = a[2], j = a[3], b = a[4], c = 0; 80 > c; c++) { if (16 > c) d[c] = n[p + c] | 0; else { var g = d[c - 3] ^ d[c - 8] ^ d[c - 14] ^ d[c - 16]; d[c] = g << 1 | g >>> 31 } g = (e << 5 | e >>> 27) + b + d[c]; g = 20 > c ? g + ((f & h | ~f & j) + 1518500249) : 40 > c ? g + ((f ^ h ^ j) + 1859775393) : 60 > c ? g + ((f & h | f & j | h & j) - 1894007588) : g + ((f ^ h ^ j) - 899497514); b = j; j = h; h = f << 30 | f >>> 2; f = e; e = g } a[0] = a[0] + e | 0; a[1] = a[1] + f | 0; a[2] = a[2] + h | 0; a[3] = a[3] + j | 0; a[4] = a[4] + b | 0 }, _doFinalize: function () { var b = this._data, d = b.words, a = 8 * this._nDataBytes, e = 8 * b.sigBytes; d[e >>> 5] |= 128 << 24 - e % 32; d[(e + 64 >>> 9 << 4) + 14] = Math.floor(a / 4294967296); d[(e + 64 >>> 9 << 4) + 15] = a; b.sigBytes = 4 * d.length; this._process(); return this._hash }, clone: function () { var b = l.clone.call(this); b._hash = this._hash.clone(); return b } }); k.SHA1 = l._createHelper(b); k.HmacSHA1 = l._createHmacHelper(b) })(); +(function (k) { for (var g = CryptoJS, h = g.lib, v = h.WordArray, j = h.Hasher, h = g.algo, s = [], t = [], u = function (q) { return 4294967296 * (q - (q | 0)) | 0 }, l = 2, b = 0; 64 > b;) { var d; a: { d = l; for (var w = k.sqrt(d), r = 2; r <= w; r++) if (!(d % r)) { d = !1; break a } d = !0 } d && (8 > b && (s[b] = u(k.pow(l, 0.5))), t[b] = u(k.pow(l, 1 / 3)), b++); l++ } var n = [], h = h.SHA256 = j.extend({ _doReset: function () { this._hash = new v.init(s.slice(0)) }, _doProcessBlock: function (q, h) { for (var a = this._hash.words, c = a[0], d = a[1], b = a[2], k = a[3], f = a[4], g = a[5], j = a[6], l = a[7], e = 0; 64 > e; e++) { if (16 > e) n[e] = q[h + e] | 0; else { var m = n[e - 15], p = n[e - 2]; n[e] = ((m << 25 | m >>> 7) ^ (m << 14 | m >>> 18) ^ m >>> 3) + n[e - 7] + ((p << 15 | p >>> 17) ^ (p << 13 | p >>> 19) ^ p >>> 10) + n[e - 16] } m = l + ((f << 26 | f >>> 6) ^ (f << 21 | f >>> 11) ^ (f << 7 | f >>> 25)) + (f & g ^ ~f & j) + t[e] + n[e]; p = ((c << 30 | c >>> 2) ^ (c << 19 | c >>> 13) ^ (c << 10 | c >>> 22)) + (c & d ^ c & b ^ d & b); l = j; j = g; g = f; f = k + m | 0; k = b; b = d; d = c; c = m + p | 0 } a[0] = a[0] + c | 0; a[1] = a[1] + d | 0; a[2] = a[2] + b | 0; a[3] = a[3] + k | 0; a[4] = a[4] + f | 0; a[5] = a[5] + g | 0; a[6] = a[6] + j | 0; a[7] = a[7] + l | 0 }, _doFinalize: function () { var d = this._data, b = d.words, a = 8 * this._nDataBytes, c = 8 * d.sigBytes; b[c >>> 5] |= 128 << 24 - c % 32; b[(c + 64 >>> 9 << 4) + 14] = k.floor(a / 4294967296); b[(c + 64 >>> 9 << 4) + 15] = a; d.sigBytes = 4 * b.length; this._process(); return this._hash }, clone: function () { var b = j.clone.call(this); b._hash = this._hash.clone(); return b } }); g.SHA256 = j._createHelper(h); g.HmacSHA256 = j._createHmacHelper(h) })(Math); +(function(){var c=CryptoJS,k=c.enc.Utf8;c.algo.HMAC=c.lib.Base.extend({init:function(a,b){a=this._hasher=new a.init;"string"==typeof b&&(b=k.parse(b));var c=a.blockSize,e=4*c;b.sigBytes>e&&(b=a.finalize(b));b.clamp();for(var f=this._oKey=b.clone(),g=this._iKey=b.clone(),h=f.words,j=g.words,d=0;d<c;d++)h[d]^=1549556828,j[d]^=909522486;f.sigBytes=g.sigBytes=e;this.reset()},reset:function(){var a=this._hasher;a.reset();a.update(this._iKey)},update:function(a){this._hasher.update(a);return this},finalize:function(a){var b=this._hasher;a=b.finalize(a);b.reset();return b.finalize(this._oKey.clone().concat(a))}})})(); +(function(){var h=CryptoJS,j=h.lib.WordArray;h.enc.Base64={stringify:function(b){var e=b.words,f=b.sigBytes,c=this._map;b.clamp();b=[];for(var a=0;a<f;a+=3)for(var d=(e[a>>>2]>>>24-8*(a%4)&255)<<16|(e[a+1>>>2]>>>24-8*((a+1)%4)&255)<<8|e[a+2>>>2]>>>24-8*((a+2)%4)&255,g=0;4>g&&a+0.75*g<f;g++)b.push(c.charAt(d>>>6*(3-g)&63));if(e=c.charAt(64))for(;b.length%4;)b.push(e);return b.join("")},parse:function(b){var e=b.length,f=this._map,c=f.charAt(64);c&&(c=b.indexOf(c),-1!=c&&(e=c));for(var c=[],a=0,d=0;d<e;d++)if(d%4){var g=f.indexOf(b.charAt(d-1))<<2*(d%4),h=f.indexOf(b.charAt(d))>>>6-2*(d%4);c[a>>>2]|=(g|h)<<24-8*(a%4);a++}return j.create(c,a)},_map:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="}})(); diff --git a/deps/npm/node_modules/request/node_modules/hawk/lib/client.js b/deps/npm/node_modules/request/node_modules/hawk/lib/client.js index 8b5bad566fb..41984582a29 100755 --- a/deps/npm/node_modules/request/node_modules/hawk/lib/client.js +++ b/deps/npm/node_modules/request/node_modules/hawk/lib/client.js @@ -1,285 +1,367 @@ -// Load modules
-
-var Url = require('url');
-var Hoek = require('hoek');
-var Cryptiles = require('cryptiles');
-var Crypto = require('./crypto');
-var Utils = require('./utils');
-
-
-// Declare internals
-
-var internals = {};
-
-
-// Generate an Authorization header for a given request
-
-/*
- uri: 'http://example.com/resource?a=b' or object from Url.parse()
- method: HTTP verb (e.g. 'GET', 'POST')
- options: {
-
- // Required
-
- credentials: {
- id: 'dh37fgj492je',
- key: 'aoijedoaijsdlaksjdl',
- algorithm: 'sha256' // 'sha1', 'sha256'
- },
-
- // Optional
-
- ext: 'application-specific', // Application specific data sent via the ext attribute
- timestamp: Date.now(), // A pre-calculated timestamp
- nonce: '2334f34f', // A pre-generated nonce
- localtimeOffsetMsec: 400, // Time offset to sync with server time (ignored if timestamp provided)
- payload: '{"some":"payload"}', // UTF-8 encoded string for body hash generation (ignored if hash provided)
- contentType: 'application/json', // Payload content-type (ignored if hash provided)
- hash: 'U4MKKSmiVxk37JCCrAVIjV=', // Pre-calculated payload hash
- app: '24s23423f34dx', // Oz application id
- dlg: '234sz34tww3sd' // Oz delegated-by application id
- }
-*/
-
-exports.header = function (uri, method, options) {
-
- var result = {
- field: '',
- artifacts: {}
- };
-
- // Validate inputs
-
- if (!uri || (typeof uri !== 'string' && typeof uri !== 'object') ||
- !method || typeof method !== 'string' ||
- !options || typeof options !== 'object') {
-
- return result;
- }
-
- // Application time
-
- var timestamp = options.timestamp || Math.floor((Utils.now() + (options.localtimeOffsetMsec || 0)) / 1000)
-
- // Validate credentials
-
- var credentials = options.credentials;
- if (!credentials ||
- !credentials.id ||
- !credentials.key ||
- !credentials.algorithm) {
-
- // Invalid credential object
- return result;
- }
-
- if (Crypto.algorithms.indexOf(credentials.algorithm) === -1) {
- return result;
- }
-
- // Parse URI
-
- if (typeof uri === 'string') {
- uri = Url.parse(uri);
- }
-
- // Calculate signature
-
- var artifacts = {
- ts: timestamp,
- nonce: options.nonce || Cryptiles.randomString(6),
- method: method,
- resource: uri.pathname + (uri.search || ''), // Maintain trailing '?'
- host: uri.hostname,
- port: uri.port || (uri.protocol === 'http:' ? 80 : 443),
- hash: options.hash,
- ext: options.ext,
- app: options.app,
- dlg: options.dlg
- };
-
- result.artifacts = artifacts;
-
- // Calculate payload hash
-
- if (!artifacts.hash &&
- options.hasOwnProperty('payload')) {
-
- artifacts.hash = Crypto.calculatePayloadHash(options.payload, credentials.algorithm, options.contentType);
- }
-
- var mac = Crypto.calculateMac('header', credentials, artifacts);
-
- // Construct header
-
- var hasExt = artifacts.ext !== null && artifacts.ext !== undefined && artifacts.ext !== ''; // Other falsey values allowed
- var header = 'Hawk id="' + credentials.id +
- '", ts="' + artifacts.ts +
- '", nonce="' + artifacts.nonce +
- (artifacts.hash ? '", hash="' + artifacts.hash : '') +
- (hasExt ? '", ext="' + Utils.escapeHeaderAttribute(artifacts.ext) : '') +
- '", mac="' + mac + '"';
-
- if (artifacts.app) {
- header += ', app="' + artifacts.app +
- (artifacts.dlg ? '", dlg="' + artifacts.dlg : '') + '"';
- }
-
- result.field = header;
-
- return result;
-};
-
-
-// Validate server response
-
-/*
- res: node's response object
- artifacts: object recieved from header().artifacts
- options: {
- payload: optional payload received
- required: specifies if a Server-Authorization header is required. Defaults to 'false'
- }
-*/
-
-exports.authenticate = function (res, credentials, artifacts, options) {
-
- artifacts = Hoek.clone(artifacts);
- options = options || {};
-
- if (res.headers['www-authenticate']) {
-
- // Parse HTTP WWW-Authenticate header
-
- var attributes = Utils.parseAuthorizationHeader(res.headers['www-authenticate'], ['ts', 'tsm', 'error']);
- if (attributes instanceof Error) {
- return false;
- }
-
- if (attributes.ts) {
- var tsm = Crypto.calculateTsMac(attributes.ts, credentials);
- if (tsm !== attributes.tsm) {
- return false;
- }
- }
- }
-
- // Parse HTTP Server-Authorization header
-
- if (!res.headers['server-authorization'] &&
- !options.required) {
-
- return true;
- }
-
- var attributes = Utils.parseAuthorizationHeader(res.headers['server-authorization'], ['mac', 'ext', 'hash']);
- if (attributes instanceof Error) {
- return false;
- }
-
- artifacts.ext = attributes.ext;
- artifacts.hash = attributes.hash;
-
- var mac = Crypto.calculateMac('response', credentials, artifacts);
- if (mac !== attributes.mac) {
- return false;
- }
-
- if (!options.hasOwnProperty('payload')) {
- return true;
- }
-
- if (!attributes.hash) {
- return false;
- }
-
- var calculatedHash = Crypto.calculatePayloadHash(options.payload, credentials.algorithm, res.headers['content-type']);
- return (calculatedHash === attributes.hash);
-};
-
-
-// Generate a bewit value for a given URI
-
-/*
- * credentials is an object with the following keys: 'id, 'key', 'algorithm'.
- * options is an object with the following optional keys: 'ext', 'localtimeOffsetMsec'
- */
-/*
- uri: 'http://example.com/resource?a=b' or object from Url.parse()
- options: {
-
- // Required
-
- credentials: {
- id: 'dh37fgj492je',
- key: 'aoijedoaijsdlaksjdl',
- algorithm: 'sha256' // 'sha1', 'sha256'
- },
- ttlSec: 60 * 60, // TTL in seconds
-
- // Optional
-
- ext: 'application-specific', // Application specific data sent via the ext attribute
- localtimeOffsetMsec: 400 // Time offset to sync with server time
- };
-*/
-
-exports.getBewit = function (uri, options) {
-
- // Validate inputs
-
- if (!uri ||
- (typeof uri !== 'string' && typeof uri !== 'object') ||
- !options ||
- typeof options !== 'object' ||
- !options.ttlSec) {
-
- return '';
- }
-
- options.ext = (options.ext === null || options.ext === undefined ? '' : options.ext); // Zero is valid value
-
- // Application time
-
- var now = Utils.now() + (options.localtimeOffsetMsec || 0);
-
- // Validate credentials
-
- var credentials = options.credentials;
- if (!credentials ||
- !credentials.id ||
- !credentials.key ||
- !credentials.algorithm) {
-
- return '';
- }
-
- if (Crypto.algorithms.indexOf(credentials.algorithm) === -1) {
- return '';
- }
-
- // Parse URI
-
- if (typeof uri === 'string') {
- uri = Url.parse(uri);
- }
-
- // Calculate signature
-
- var exp = Math.floor(now / 1000) + options.ttlSec;
- var mac = Crypto.calculateMac('bewit', credentials, {
- ts: exp,
- nonce: '',
- method: 'GET',
- resource: uri.pathname + (uri.search || ''), // Maintain trailing '?'
- host: uri.hostname,
- port: uri.port || (uri.protocol === 'http:' ? 80 : 443),
- ext: options.ext
- });
-
- // Construct bewit: id\exp\mac\ext
-
- var bewit = credentials.id + '\\' + exp + '\\' + mac + '\\' + options.ext;
- return Utils.base64urlEncode(bewit);
-};
-
+// Load modules + +var Url = require('url'); +var Hoek = require('hoek'); +var Cryptiles = require('cryptiles'); +var Crypto = require('./crypto'); +var Utils = require('./utils'); + + +// Declare internals + +var internals = {}; + + +// Generate an Authorization header for a given request + +/* + uri: 'http://example.com/resource?a=b' or object from Url.parse() + method: HTTP verb (e.g. 'GET', 'POST') + options: { + + // Required + + credentials: { + id: 'dh37fgj492je', + key: 'aoijedoaijsdlaksjdl', + algorithm: 'sha256' // 'sha1', 'sha256' + }, + + // Optional + + ext: 'application-specific', // Application specific data sent via the ext attribute + timestamp: Date.now(), // A pre-calculated timestamp + nonce: '2334f34f', // A pre-generated nonce + localtimeOffsetMsec: 400, // Time offset to sync with server time (ignored if timestamp provided) + payload: '{"some":"payload"}', // UTF-8 encoded string for body hash generation (ignored if hash provided) + contentType: 'application/json', // Payload content-type (ignored if hash provided) + hash: 'U4MKKSmiVxk37JCCrAVIjV=', // Pre-calculated payload hash + app: '24s23423f34dx', // Oz application id + dlg: '234sz34tww3sd' // Oz delegated-by application id + } +*/ + +exports.header = function (uri, method, options) { + + var result = { + field: '', + artifacts: {} + }; + + // Validate inputs + + if (!uri || (typeof uri !== 'string' && typeof uri !== 'object') || + !method || typeof method !== 'string' || + !options || typeof options !== 'object') { + + return result; + } + + // Application time + + var timestamp = options.timestamp || Math.floor((Utils.now() + (options.localtimeOffsetMsec || 0)) / 1000) + + // Validate credentials + + var credentials = options.credentials; + if (!credentials || + !credentials.id || + !credentials.key || + !credentials.algorithm) { + + // Invalid credential object + return result; + } + + if (Crypto.algorithms.indexOf(credentials.algorithm) === -1) { + return result; + } + + // Parse URI + + if (typeof uri === 'string') { + uri = Url.parse(uri); + } + + // Calculate signature + + var artifacts = { + ts: timestamp, + nonce: options.nonce || Cryptiles.randomString(6), + method: method, + resource: uri.pathname + (uri.search || ''), // Maintain trailing '?' + host: uri.hostname, + port: uri.port || (uri.protocol === 'http:' ? 80 : 443), + hash: options.hash, + ext: options.ext, + app: options.app, + dlg: options.dlg + }; + + result.artifacts = artifacts; + + // Calculate payload hash + + if (!artifacts.hash && + options.hasOwnProperty('payload')) { + + artifacts.hash = Crypto.calculatePayloadHash(options.payload, credentials.algorithm, options.contentType); + } + + var mac = Crypto.calculateMac('header', credentials, artifacts); + + // Construct header + + var hasExt = artifacts.ext !== null && artifacts.ext !== undefined && artifacts.ext !== ''; // Other falsey values allowed + var header = 'Hawk id="' + credentials.id + + '", ts="' + artifacts.ts + + '", nonce="' + artifacts.nonce + + (artifacts.hash ? '", hash="' + artifacts.hash : '') + + (hasExt ? '", ext="' + Utils.escapeHeaderAttribute(artifacts.ext) : '') + + '", mac="' + mac + '"'; + + if (artifacts.app) { + header += ', app="' + artifacts.app + + (artifacts.dlg ? '", dlg="' + artifacts.dlg : '') + '"'; + } + + result.field = header; + + return result; +}; + + +// Validate server response + +/* + res: node's response object + artifacts: object recieved from header().artifacts + options: { + payload: optional payload received + required: specifies if a Server-Authorization header is required. Defaults to 'false' + } +*/ + +exports.authenticate = function (res, credentials, artifacts, options) { + + artifacts = Hoek.clone(artifacts); + options = options || {}; + + if (res.headers['www-authenticate']) { + + // Parse HTTP WWW-Authenticate header + + var attributes = Utils.parseAuthorizationHeader(res.headers['www-authenticate'], ['ts', 'tsm', 'error']); + if (attributes instanceof Error) { + return false; + } + + if (attributes.ts) { + var tsm = Crypto.calculateTsMac(attributes.ts, credentials); + if (tsm !== attributes.tsm) { + return false; + } + } + } + + // Parse HTTP Server-Authorization header + + if (!res.headers['server-authorization'] && + !options.required) { + + return true; + } + + var attributes = Utils.parseAuthorizationHeader(res.headers['server-authorization'], ['mac', 'ext', 'hash']); + if (attributes instanceof Error) { + return false; + } + + artifacts.ext = attributes.ext; + artifacts.hash = attributes.hash; + + var mac = Crypto.calculateMac('response', credentials, artifacts); + if (mac !== attributes.mac) { + return false; + } + + if (!options.hasOwnProperty('payload')) { + return true; + } + + if (!attributes.hash) { + return false; + } + + var calculatedHash = Crypto.calculatePayloadHash(options.payload, credentials.algorithm, res.headers['content-type']); + return (calculatedHash === attributes.hash); +}; + + +// Generate a bewit value for a given URI + +/* + * credentials is an object with the following keys: 'id, 'key', 'algorithm'. + * options is an object with the following optional keys: 'ext', 'localtimeOffsetMsec' + */ +/* + uri: 'http://example.com/resource?a=b' or object from Url.parse() + options: { + + // Required + + credentials: { + id: 'dh37fgj492je', + key: 'aoijedoaijsdlaksjdl', + algorithm: 'sha256' // 'sha1', 'sha256' + }, + ttlSec: 60 * 60, // TTL in seconds + + // Optional + + ext: 'application-specific', // Application specific data sent via the ext attribute + localtimeOffsetMsec: 400 // Time offset to sync with server time + }; +*/ + +exports.getBewit = function (uri, options) { + + // Validate inputs + + if (!uri || + (typeof uri !== 'string' && typeof uri !== 'object') || + !options || + typeof options !== 'object' || + !options.ttlSec) { + + return ''; + } + + options.ext = (options.ext === null || options.ext === undefined ? '' : options.ext); // Zero is valid value + + // Application time + + var now = Utils.now() + (options.localtimeOffsetMsec || 0); + + // Validate credentials + + var credentials = options.credentials; + if (!credentials || + !credentials.id || + !credentials.key || + !credentials.algorithm) { + + return ''; + } + + if (Crypto.algorithms.indexOf(credentials.algorithm) === -1) { + return ''; + } + + // Parse URI + + if (typeof uri === 'string') { + uri = Url.parse(uri); + } + + // Calculate signature + + var exp = Math.floor(now / 1000) + options.ttlSec; + var mac = Crypto.calculateMac('bewit', credentials, { + ts: exp, + nonce: '', + method: 'GET', + resource: uri.pathname + (uri.search || ''), // Maintain trailing '?' + host: uri.hostname, + port: uri.port || (uri.protocol === 'http:' ? 80 : 443), + ext: options.ext + }); + + // Construct bewit: id\exp\mac\ext + + var bewit = credentials.id + '\\' + exp + '\\' + mac + '\\' + options.ext; + return Utils.base64urlEncode(bewit); +}; + + +// Generate an authorization string for a message + +/* + host: 'example.com', + port: 8000, + message: '{"some":"payload"}', // UTF-8 encoded string for body hash generation + options: { + + // Required + + credentials: { + id: 'dh37fgj492je', + key: 'aoijedoaijsdlaksjdl', + algorithm: 'sha256' // 'sha1', 'sha256' + }, + + // Optional + + timestamp: Date.now(), // A pre-calculated timestamp + nonce: '2334f34f', // A pre-generated nonce + localtimeOffsetMsec: 400, // Time offset to sync with server time (ignored if timestamp provided) + } +*/ + +exports.message = function (host, port, message, options) { + + // Validate inputs + + if (!host || typeof host !== 'string' || + !port || typeof port !== 'number' || + message === null || message === undefined || typeof message !== 'string' || + !options || typeof options !== 'object') { + + return null; + } + + // Application time + + var timestamp = options.timestamp || Math.floor((Utils.now() + (options.localtimeOffsetMsec || 0)) / 1000) + + // Validate credentials + + var credentials = options.credentials; + if (!credentials || + !credentials.id || + !credentials.key || + !credentials.algorithm) { + + // Invalid credential object + return null; + } + + if (Crypto.algorithms.indexOf(credentials.algorithm) === -1) { + return null; + } + + // Calculate signature + + var artifacts = { + ts: timestamp, + nonce: options.nonce || Cryptiles.randomString(6), + host: host, + port: port, + hash: Crypto.calculatePayloadHash(message, credentials.algorithm) + }; + + // Construct authorization + + var result = { + id: credentials.id, + ts: artifacts.ts, + nonce: artifacts.nonce, + hash: artifacts.hash, + mac: Crypto.calculateMac('message', credentials, artifacts) + }; + + return result; +}; + + + diff --git a/deps/npm/node_modules/request/node_modules/hawk/lib/crypto.js b/deps/npm/node_modules/request/node_modules/hawk/lib/crypto.js index 2f0b1d148f4..150340a3364 100755 --- a/deps/npm/node_modules/request/node_modules/hawk/lib/crypto.js +++ b/deps/npm/node_modules/request/node_modules/hawk/lib/crypto.js @@ -1,111 +1,111 @@ -// Load modules
-
-var Crypto = require('crypto');
-var Url = require('url');
-var Utils = require('./utils');
-
-
-// Declare internals
-
-var internals = {};
-
-
-// MAC normalization format version
-
-exports.headerVersion = '1'; // Prevent comparison of mac values generated with different normalized string formats
-
-
-// Supported HMAC algorithms
-
-exports.algorithms = ['sha1', 'sha256'];
-
-
-// Calculate the request MAC
-
-/*
- type: 'header', // 'header', 'bewit', 'response'
- credentials: {
- key: 'aoijedoaijsdlaksjdl',
- algorithm: 'sha256' // 'sha1', 'sha256'
- },
- options: {
- method: 'GET',
- resource: '/resource?a=1&b=2',
- host: 'example.com',
- port: 8080,
- ts: 1357718381034,
- nonce: 'd3d345f',
- hash: 'U4MKKSmiVxk37JCCrAVIjV/OhB3y+NdwoCr6RShbVkE=',
- ext: 'app-specific-data',
- app: 'hf48hd83qwkj', // Application id (Oz)
- dlg: 'd8djwekds9cj' // Delegated by application id (Oz), requires options.app
- }
-*/
-
-exports.calculateMac = function (type, credentials, options) {
-
- var normalized = exports.generateNormalizedString(type, options);
-
- var hmac = Crypto.createHmac(credentials.algorithm, credentials.key).update(normalized);
- var digest = hmac.digest('base64');
- return digest;
-};
-
-
-exports.generateNormalizedString = function (type, options) {
-
- var normalized = 'hawk.' + exports.headerVersion + '.' + type + '\n' +
- options.ts + '\n' +
- options.nonce + '\n' +
- options.method.toUpperCase() + '\n' +
- options.resource + '\n' +
- options.host.toLowerCase() + '\n' +
- options.port + '\n' +
- (options.hash || '') + '\n';
-
- if (options.ext) {
- normalized += options.ext.replace('\\', '\\\\').replace('\n', '\\n');
- }
-
- normalized += '\n';
-
- if (options.app) {
- normalized += options.app + '\n' +
- (options.dlg || '') + '\n';
- }
-
- return normalized;
-};
-
-
-exports.calculatePayloadHash = function (payload, algorithm, contentType) {
-
- var hash = exports.initializePayloadHash(algorithm, contentType);
- hash.update(payload || '');
- return exports.finalizePayloadHash(hash);
-};
-
-
-exports.initializePayloadHash = function (algorithm, contentType) {
-
- var hash = Crypto.createHash(algorithm);
- hash.update('hawk.' + exports.headerVersion + '.payload\n');
- hash.update(Utils.parseContentType(contentType) + '\n');
- return hash;
-};
-
-
-exports.finalizePayloadHash = function (hash) {
-
- hash.update('\n');
- return hash.digest('base64');
-};
-
-
-exports.calculateTsMac = function (ts, credentials) {
-
- var hmac = Crypto.createHmac(credentials.algorithm, credentials.key);
- hmac.update('hawk.' + exports.headerVersion + '.ts\n' + ts + '\n');
- return hmac.digest('base64');
-};
-
+// Load modules + +var Crypto = require('crypto'); +var Url = require('url'); +var Utils = require('./utils'); + + +// Declare internals + +var internals = {}; + + +// MAC normalization format version + +exports.headerVersion = '1'; // Prevent comparison of mac values generated with different normalized string formats + + +// Supported HMAC algorithms + +exports.algorithms = ['sha1', 'sha256']; + + +// Calculate the request MAC + +/* + type: 'header', // 'header', 'bewit', 'response' + credentials: { + key: 'aoijedoaijsdlaksjdl', + algorithm: 'sha256' // 'sha1', 'sha256' + }, + options: { + method: 'GET', + resource: '/resource?a=1&b=2', + host: 'example.com', + port: 8080, + ts: 1357718381034, + nonce: 'd3d345f', + hash: 'U4MKKSmiVxk37JCCrAVIjV/OhB3y+NdwoCr6RShbVkE=', + ext: 'app-specific-data', + app: 'hf48hd83qwkj', // Application id (Oz) + dlg: 'd8djwekds9cj' // Delegated by application id (Oz), requires options.app + } +*/ + +exports.calculateMac = function (type, credentials, options) { + + var normalized = exports.generateNormalizedString(type, options); + + var hmac = Crypto.createHmac(credentials.algorithm, credentials.key).update(normalized); + var digest = hmac.digest('base64'); + return digest; +}; + + +exports.generateNormalizedString = function (type, options) { + + var normalized = 'hawk.' + exports.headerVersion + '.' + type + '\n' + + options.ts + '\n' + + options.nonce + '\n' + + (options.method || '').toUpperCase() + '\n' + + (options.resource || '') + '\n' + + options.host.toLowerCase() + '\n' + + options.port + '\n' + + (options.hash || '') + '\n'; + + if (options.ext) { + normalized += options.ext.replace('\\', '\\\\').replace('\n', '\\n'); + } + + normalized += '\n'; + + if (options.app) { + normalized += options.app + '\n' + + (options.dlg || '') + '\n'; + } + + return normalized; +}; + + +exports.calculatePayloadHash = function (payload, algorithm, contentType) { + + var hash = exports.initializePayloadHash(algorithm, contentType); + hash.update(payload || ''); + return exports.finalizePayloadHash(hash); +}; + + +exports.initializePayloadHash = function (algorithm, contentType) { + + var hash = Crypto.createHash(algorithm); + hash.update('hawk.' + exports.headerVersion + '.payload\n'); + hash.update(Utils.parseContentType(contentType) + '\n'); + return hash; +}; + + +exports.finalizePayloadHash = function (hash) { + + hash.update('\n'); + return hash.digest('base64'); +}; + + +exports.calculateTsMac = function (ts, credentials) { + + var hmac = Crypto.createHmac(credentials.algorithm, credentials.key); + hmac.update('hawk.' + exports.headerVersion + '.ts\n' + ts + '\n'); + return hmac.digest('base64'); +}; + diff --git a/deps/npm/node_modules/request/node_modules/hawk/lib/index.js b/deps/npm/node_modules/request/node_modules/hawk/lib/index.js index 5c90e33fe1f..1d713cb61af 100755 --- a/deps/npm/node_modules/request/node_modules/hawk/lib/index.js +++ b/deps/npm/node_modules/request/node_modules/hawk/lib/index.js @@ -1,15 +1,15 @@ -// Export sub-modules
-
-exports.error = exports.Error = require('boom');
-exports.sntp = require('sntp');
-exports.server = require('./server');
-exports.client = require('./client');
-exports.crypto = require('./crypto');
-exports.utils = require('./utils');
-
-exports.uri = {
- authenticate: exports.server.authenticateBewit,
- getBewit: exports.client.getBewit
-};
-
-
+// Export sub-modules + +exports.error = exports.Error = require('boom'); +exports.sntp = require('sntp'); +exports.server = require('./server'); +exports.client = require('./client'); +exports.crypto = require('./crypto'); +exports.utils = require('./utils'); + +exports.uri = { + authenticate: exports.server.authenticateBewit, + getBewit: exports.client.getBewit +}; + + diff --git a/deps/npm/node_modules/request/node_modules/hawk/lib/server.js b/deps/npm/node_modules/request/node_modules/hawk/lib/server.js index ec9ce0d4c73..478c47b3975 100755 --- a/deps/npm/node_modules/request/node_modules/hawk/lib/server.js +++ b/deps/npm/node_modules/request/node_modules/hawk/lib/server.js @@ -1,424 +1,524 @@ -// Load modules
-
-var Boom = require('boom');
-var Hoek = require('hoek');
-var Cryptiles = require('cryptiles');
-var Crypto = require('./crypto');
-var Utils = require('./utils');
-
-
-// Declare internals
-
-var internals = {};
-
-
-// Hawk authentication
-
-/*
- req: node's HTTP request object or an object as follows:
-
- var request = {
- method: 'GET',
- url: '/resource/4?a=1&b=2',
- host: 'example.com',
- port: 8080,
- authorization: 'Hawk id="dh37fgj492je", ts="1353832234", nonce="j4h3g2", ext="some-app-ext-data", mac="6R4rV5iE+NPoym+WwjeHzjAGXUtLNIxmo1vpMofpLAE="'
- };
-
- credentialsFunc: required function to lookup the set of Hawk credentials based on the provided credentials id.
- The credentials include the MAC key, MAC algorithm, and other attributes (such as username)
- needed by the application. This function is the equivalent of verifying the username and
- password in Basic authentication.
-
- var credentialsFunc = function (id, callback) {
-
- // Lookup credentials in database
- db.lookup(id, function (err, item) {
-
- if (err || !item) {
- return callback(err);
- }
-
- var credentials = {
- // Required
- key: item.key,
- algorithm: item.algorithm,
- // Application specific
- user: item.user
- };
-
- return callback(null, credentials);
- });
- };
-
- options: {
-
- hostHeaderName: optional header field name, used to override the default 'Host' header when used
- behind a cache of a proxy. Apache2 changes the value of the 'Host' header while preserving
- the original (which is what the module must verify) in the 'x-forwarded-host' header field.
- Only used when passed a node Http.ServerRequest object.
-
- nonceFunc: optional nonce validation function. The function signature is function(nonce, ts, callback)
- where 'callback' must be called using the signature function(err).
-
- timestampSkewSec: optional number of seconds of permitted clock skew for incoming timestamps. Defaults to 60 seconds.
- Provides a +/- skew which means actual allowed window is double the number of seconds.
-
- localtimeOffsetMsec: optional local clock time offset express in a number of milliseconds (positive or negative).
- Defaults to 0.
-
- payload: optional payload for validation. The client calculates the hash value and includes it via the 'hash'
- header attribute. The server always ensures the value provided has been included in the request
- MAC. When this option is provided, it validates the hash value itself. Validation is done by calculating
- a hash value over the entire payload (assuming it has already be normalized to the same format and
- encoding used by the client to calculate the hash on request). If the payload is not available at the time
- of authentication, the authenticatePayload() method can be used by passing it the credentials and
- attributes.hash returned in the authenticate callback.
- }
-
- callback: function (err, credentials, artifacts) { }
- */
-
-exports.authenticate = function (req, credentialsFunc, options, callback) {
-
- callback = Utils.nextTick(callback);
-
- // Default options
-
- options.nonceFunc = options.nonceFunc || function (nonce, ts, nonceCallback) { return nonceCallback(); }; // No validation
- options.timestampSkewSec = options.timestampSkewSec || 60; // 60 seconds
-
- // Application time
-
- var now = Utils.now() + (options.localtimeOffsetMsec || 0); // Measure now before any other processing
-
- // Convert node Http request object to a request configuration object
-
- var request = Utils.parseRequest(req, options);
- if (request instanceof Error) {
- return callback(Boom.badRequest(request.message));
- }
-
- // Parse HTTP Authorization header
-
- var attributes = Utils.parseAuthorizationHeader(request.authorization);
- if (attributes instanceof Error) {
- return callback(attributes);
- }
-
- // Construct artifacts container
-
- var artifacts = {
- method: request.method,
- host: request.host,
- port: request.port,
- resource: request.url,
- ts: attributes.ts,
- nonce: attributes.nonce,
- hash: attributes.hash,
- ext: attributes.ext,
- app: attributes.app,
- dlg: attributes.dlg,
- mac: attributes.mac,
- id: attributes.id
- };
-
- // Verify required header attributes
-
- if (!attributes.id ||
- !attributes.ts ||
- !attributes.nonce ||
- !attributes.mac) {
-
- return callback(Boom.badRequest('Missing attributes'), null, artifacts);
- }
-
- // Fetch Hawk credentials
-
- credentialsFunc(attributes.id, function (err, credentials) {
-
- if (err) {
- return callback(err, credentials || null, artifacts);
- }
-
- if (!credentials) {
- return callback(Boom.unauthorized('Unknown credentials', 'Hawk'), null, artifacts);
- }
-
- if (!credentials.key ||
- !credentials.algorithm) {
-
- return callback(Boom.internal('Invalid credentials'), credentials, artifacts);
- }
-
- if (Crypto.algorithms.indexOf(credentials.algorithm) === -1) {
- return callback(Boom.internal('Unknown algorithm'), credentials, artifacts);
- }
-
- // Calculate MAC
-
- var mac = Crypto.calculateMac('header', credentials, artifacts);
- if (!Cryptiles.fixedTimeComparison(mac, attributes.mac)) {
- return callback(Boom.unauthorized('Bad mac', 'Hawk'), credentials, artifacts);
- }
-
- // Check payload hash
-
- if (options.payload !== null &&
- options.payload !== undefined) { // '' is valid
-
- if (!attributes.hash) {
- return callback(Boom.unauthorized('Missing required payload hash', 'Hawk'), credentials, artifacts);
- }
-
- var hash = Crypto.calculatePayloadHash(options.payload, credentials.algorithm, request.contentType);
- if (!Cryptiles.fixedTimeComparison(hash, attributes.hash)) {
- return callback(Boom.unauthorized('Bad payload hash', 'Hawk'), credentials, artifacts);
- }
- }
-
- // Check nonce
-
- options.nonceFunc(attributes.nonce, attributes.ts, function (err) {
-
- if (err) {
- return callback(Boom.unauthorized('Invalid nonce', 'Hawk'), credentials, artifacts);
- }
-
- // Check timestamp staleness
-
- if (Math.abs((attributes.ts * 1000) - now) > (options.timestampSkewSec * 1000)) {
- var fresh = Math.floor((Utils.now() + (options.localtimeOffsetMsec || 0)) / 1000); // Get fresh now
- var tsm = Crypto.calculateTsMac(fresh, credentials);
- return callback(Boom.unauthorized('Stale timestamp', 'Hawk', { ts: fresh, tsm: tsm }), credentials, artifacts);
- }
-
- // Successful authentication
-
- return callback(null, credentials, artifacts);
- });
- });
-};
-
-
-// Authenticate payload hash - used when payload cannot be provided during authenticate()
-
-/*
- payload: raw request payload
- credentials: from authenticate callback
- artifacts: from authenticate callback
- contentType: req.headers['content-type']
-*/
-
-exports.authenticatePayload = function (payload, credentials, artifacts, contentType) {
-
- var calculatedHash = Crypto.calculatePayloadHash(payload, credentials.algorithm, contentType);
- return Cryptiles.fixedTimeComparison(calculatedHash, artifacts.hash);
-};
-
-
-// Generate a Server-Authorization header for a given response
-
-/*
- credentials: {}, // Object received from authenticate()
- artifacts: {} // Object received from authenticate(); 'mac', 'hash', and 'ext' - ignored
- options: {
- ext: 'application-specific', // Application specific data sent via the ext attribute
- payload: '{"some":"payload"}', // UTF-8 encoded string for body hash generation (ignored if hash provided)
- contentType: 'application/json', // Payload content-type (ignored if hash provided)
- hash: 'U4MKKSmiVxk37JCCrAVIjV=' // Pre-calculated payload hash
- }
-*/
-
-exports.header = function (credentials, artifacts, options) {
-
- // Prepare inputs
-
- options = options || {};
-
- if (!artifacts ||
- typeof artifacts !== 'object' ||
- typeof options !== 'object') {
-
- return '';
- }
-
- artifacts = Hoek.clone(artifacts);
- delete artifacts.mac;
- artifacts.hash = options.hash;
- artifacts.ext = options.ext;
-
- // Validate credentials
-
- if (!credentials ||
- !credentials.key ||
- !credentials.algorithm) {
-
- // Invalid credential object
- return '';
- }
-
- if (Crypto.algorithms.indexOf(credentials.algorithm) === -1) {
- return '';
- }
-
- // Calculate payload hash
-
- if (!artifacts.hash &&
- options.hasOwnProperty('payload')) {
-
- artifacts.hash = Crypto.calculatePayloadHash(options.payload, credentials.algorithm, options.contentType);
- }
-
- var mac = Crypto.calculateMac('response', credentials, artifacts);
-
- // Construct header
-
- var header = 'Hawk mac="' + mac + '"' +
- (artifacts.hash ? ', hash="' + artifacts.hash + '"' : '');
-
- if (artifacts.ext !== null &&
- artifacts.ext !== undefined &&
- artifacts.ext !== '') { // Other falsey values allowed
-
- header += ', ext="' + Utils.escapeHeaderAttribute(artifacts.ext) + '"';
- }
-
- return header;
-};
-
-
-/*
- * Arguments and options are the same as index.js with the exception that the only supported options are:
- * 'hostHeaderName', 'localtimeOffsetMsec'
- */
-
-exports.authenticateBewit = function (req, credentialsFunc, options, callback) {
-
- callback = Utils.nextTick(callback);
-
- // Application time
-
- var now = Utils.now() + (options.localtimeOffsetMsec || 0);
-
- // Convert node Http request object to a request configuration object
-
- var request = Utils.parseRequest(req, options);
- if (request instanceof Error) {
- return callback(Boom.badRequest(request.message));
- }
-
- // Extract bewit
-
- // 1 2 3 4
- var resource = request.url.match(/^(\/.*)([\?&])bewit\=([^&$]*)(?:&(.+))?$/);
- if (!resource) {
- return callback(Boom.unauthorized(null, 'Hawk'));
- }
-
- // Bewit not empty
-
- if (!resource[3]) {
- return callback(Boom.unauthorized('Empty bewit', 'Hawk'));
- }
-
- // Verify method is GET
-
- if (request.method !== 'GET' &&
- request.method !== 'HEAD') {
-
- return callback(Boom.unauthorized('Invalid method', 'Hawk'));
- }
-
- // No other authentication
-
- if (request.authorization) {
- return callback(Boom.badRequest('Multiple authentications', 'Hawk'));
- }
-
- // Parse bewit
-
- var bewitString = Utils.base64urlDecode(resource[3]);
- if (bewitString instanceof Error) {
- return callback(Boom.badRequest('Invalid bewit encoding'));
- }
-
- // Bewit format: id\exp\mac\ext ('\' is used because it is a reserved header attribute character)
-
- var bewitParts = bewitString.split('\\');
- if (!bewitParts ||
- bewitParts.length !== 4) {
-
- return callback(Boom.badRequest('Invalid bewit structure'));
- }
-
- var bewit = {
- id: bewitParts[0],
- exp: parseInt(bewitParts[1], 10),
- mac: bewitParts[2],
- ext: bewitParts[3] || ''
- };
-
- if (!bewit.id ||
- !bewit.exp ||
- !bewit.mac) {
-
- return callback(Boom.badRequest('Missing bewit attributes'));
- }
-
- // Construct URL without bewit
-
- var url = resource[1];
- if (resource[4]) {
- url += resource[2] + resource[4];
- }
-
- // Check expiration
-
- if (bewit.exp * 1000 <= now) {
- return callback(Boom.unauthorized('Access expired', 'Hawk'), null, bewit);
- }
-
- // Fetch Hawk credentials
-
- credentialsFunc(bewit.id, function (err, credentials) {
-
- if (err) {
- return callback(err, credentials || null, bewit.ext);
- }
-
- if (!credentials) {
- return callback(Boom.unauthorized('Unknown credentials', 'Hawk'), null, bewit);
- }
-
- if (!credentials.key ||
- !credentials.algorithm) {
-
- return callback(Boom.internal('Invalid credentials'), credentials, bewit);
- }
-
- if (Crypto.algorithms.indexOf(credentials.algorithm) === -1) {
- return callback(Boom.internal('Unknown algorithm'), credentials, bewit);
- }
-
- // Calculate MAC
-
- var mac = Crypto.calculateMac('bewit', credentials, {
- ts: bewit.exp,
- nonce: '',
- method: 'GET',
- resource: url,
- host: request.host,
- port: request.port,
- ext: bewit.ext
- });
-
- if (!Cryptiles.fixedTimeComparison(mac, bewit.mac)) {
- return callback(Boom.unauthorized('Bad mac', 'Hawk'), credentials, bewit);
- }
-
- // Successful authentication
-
- return callback(null, credentials, bewit);
- });
-};
+// Load modules + +var Boom = require('boom'); +var Hoek = require('hoek'); +var Cryptiles = require('cryptiles'); +var Crypto = require('./crypto'); +var Utils = require('./utils'); + + +// Declare internals + +var internals = {}; + + +// Hawk authentication + +/* + req: node's HTTP request object or an object as follows: + + var request = { + method: 'GET', + url: '/resource/4?a=1&b=2', + host: 'example.com', + port: 8080, + authorization: 'Hawk id="dh37fgj492je", ts="1353832234", nonce="j4h3g2", ext="some-app-ext-data", mac="6R4rV5iE+NPoym+WwjeHzjAGXUtLNIxmo1vpMofpLAE="' + }; + + credentialsFunc: required function to lookup the set of Hawk credentials based on the provided credentials id. + The credentials include the MAC key, MAC algorithm, and other attributes (such as username) + needed by the application. This function is the equivalent of verifying the username and + password in Basic authentication. + + var credentialsFunc = function (id, callback) { + + // Lookup credentials in database + db.lookup(id, function (err, item) { + + if (err || !item) { + return callback(err); + } + + var credentials = { + // Required + key: item.key, + algorithm: item.algorithm, + // Application specific + user: item.user + }; + + return callback(null, credentials); + }); + }; + + options: { + + hostHeaderName: optional header field name, used to override the default 'Host' header when used + behind a cache of a proxy. Apache2 changes the value of the 'Host' header while preserving + the original (which is what the module must verify) in the 'x-forwarded-host' header field. + Only used when passed a node Http.ServerRequest object. + + nonceFunc: optional nonce validation function. The function signature is function(nonce, ts, callback) + where 'callback' must be called using the signature function(err). + + timestampSkewSec: optional number of seconds of permitted clock skew for incoming timestamps. Defaults to 60 seconds. + Provides a +/- skew which means actual allowed window is double the number of seconds. + + localtimeOffsetMsec: optional local clock time offset express in a number of milliseconds (positive or negative). + Defaults to 0. + + payload: optional payload for validation. The client calculates the hash value and includes it via the 'hash' + header attribute. The server always ensures the value provided has been included in the request + MAC. When this option is provided, it validates the hash value itself. Validation is done by calculating + a hash value over the entire payload (assuming it has already be normalized to the same format and + encoding used by the client to calculate the hash on request). If the payload is not available at the time + of authentication, the authenticatePayload() method can be used by passing it the credentials and + attributes.hash returned in the authenticate callback. + + host: optional host name override. Only used when passed a node request object. + port: optional port override. Only used when passed a node request object. + } + + callback: function (err, credentials, artifacts) { } + */ + +exports.authenticate = function (req, credentialsFunc, options, callback) { + + callback = Utils.nextTick(callback); + + // Default options + + options.nonceFunc = options.nonceFunc || function (nonce, ts, nonceCallback) { return nonceCallback(); }; // No validation + options.timestampSkewSec = options.timestampSkewSec || 60; // 60 seconds + + // Application time + + var now = Utils.now() + (options.localtimeOffsetMsec || 0); // Measure now before any other processing + + // Convert node Http request object to a request configuration object + + var request = Utils.parseRequest(req, options); + if (request instanceof Error) { + return callback(Boom.badRequest(request.message)); + } + + // Parse HTTP Authorization header + + var attributes = Utils.parseAuthorizationHeader(request.authorization); + if (attributes instanceof Error) { + return callback(attributes); + } + + // Construct artifacts container + + var artifacts = { + method: request.method, + host: request.host, + port: request.port, + resource: request.url, + ts: attributes.ts, + nonce: attributes.nonce, + hash: attributes.hash, + ext: attributes.ext, + app: attributes.app, + dlg: attributes.dlg, + mac: attributes.mac, + id: attributes.id + }; + + // Verify required header attributes + + if (!attributes.id || + !attributes.ts || + !attributes.nonce || + !attributes.mac) { + + return callback(Boom.badRequest('Missing attributes'), null, artifacts); + } + + // Fetch Hawk credentials + + credentialsFunc(attributes.id, function (err, credentials) { + + if (err) { + return callback(err, credentials || null, artifacts); + } + + if (!credentials) { + return callback(Boom.unauthorized('Unknown credentials', 'Hawk'), null, artifacts); + } + + if (!credentials.key || + !credentials.algorithm) { + + return callback(Boom.internal('Invalid credentials'), credentials, artifacts); + } + + if (Crypto.algorithms.indexOf(credentials.algorithm) === -1) { + return callback(Boom.internal('Unknown algorithm'), credentials, artifacts); + } + + // Calculate MAC + + var mac = Crypto.calculateMac('header', credentials, artifacts); + if (!Cryptiles.fixedTimeComparison(mac, attributes.mac)) { + return callback(Boom.unauthorized('Bad mac', 'Hawk'), credentials, artifacts); + } + + // Check payload hash + + if (options.payload !== null && + options.payload !== undefined) { // '' is valid + + if (!attributes.hash) { + return callback(Boom.unauthorized('Missing required payload hash', 'Hawk'), credentials, artifacts); + } + + var hash = Crypto.calculatePayloadHash(options.payload, credentials.algorithm, request.contentType); + if (!Cryptiles.fixedTimeComparison(hash, attributes.hash)) { + return callback(Boom.unauthorized('Bad payload hash', 'Hawk'), credentials, artifacts); + } + } + + // Check nonce + + options.nonceFunc(attributes.nonce, attributes.ts, function (err) { + + if (err) { + return callback(Boom.unauthorized('Invalid nonce', 'Hawk'), credentials, artifacts); + } + + // Check timestamp staleness + + if (Math.abs((attributes.ts * 1000) - now) > (options.timestampSkewSec * 1000)) { + var fresh = Math.floor((Utils.now() + (options.localtimeOffsetMsec || 0)) / 1000); // Get fresh now + var tsm = Crypto.calculateTsMac(fresh, credentials); + return callback(Boom.unauthorized('Stale timestamp', 'Hawk', { ts: fresh, tsm: tsm }), credentials, artifacts); + } + + // Successful authentication + + return callback(null, credentials, artifacts); + }); + }); +}; + + +// Authenticate payload hash - used when payload cannot be provided during authenticate() + +/* + payload: raw request payload + credentials: from authenticate callback + artifacts: from authenticate callback + contentType: req.headers['content-type'] +*/ + +exports.authenticatePayload = function (payload, credentials, artifacts, contentType) { + + var calculatedHash = Crypto.calculatePayloadHash(payload, credentials.algorithm, contentType); + return Cryptiles.fixedTimeComparison(calculatedHash, artifacts.hash); +}; + + +// Generate a Server-Authorization header for a given response + +/* + credentials: {}, // Object received from authenticate() + artifacts: {} // Object received from authenticate(); 'mac', 'hash', and 'ext' - ignored + options: { + ext: 'application-specific', // Application specific data sent via the ext attribute + payload: '{"some":"payload"}', // UTF-8 encoded string for body hash generation (ignored if hash provided) + contentType: 'application/json', // Payload content-type (ignored if hash provided) + hash: 'U4MKKSmiVxk37JCCrAVIjV=' // Pre-calculated payload hash + } +*/ + +exports.header = function (credentials, artifacts, options) { + + // Prepare inputs + + options = options || {}; + + if (!artifacts || + typeof artifacts !== 'object' || + typeof options !== 'object') { + + return ''; + } + + artifacts = Hoek.clone(artifacts); + delete artifacts.mac; + artifacts.hash = options.hash; + artifacts.ext = options.ext; + + // Validate credentials + + if (!credentials || + !credentials.key || + !credentials.algorithm) { + + // Invalid credential object + return ''; + } + + if (Crypto.algorithms.indexOf(credentials.algorithm) === -1) { + return ''; + } + + // Calculate payload hash + + if (!artifacts.hash && + options.hasOwnProperty('payload')) { + + artifacts.hash = Crypto.calculatePayloadHash(options.payload, credentials.algorithm, options.contentType); + } + + var mac = Crypto.calculateMac('response', credentials, artifacts); + + // Construct header + + var header = 'Hawk mac="' + mac + '"' + + (artifacts.hash ? ', hash="' + artifacts.hash + '"' : ''); + + if (artifacts.ext !== null && + artifacts.ext !== undefined && + artifacts.ext !== '') { // Other falsey values allowed + + header += ', ext="' + Utils.escapeHeaderAttribute(artifacts.ext) + '"'; + } + + return header; +}; + + +/* + * Arguments and options are the same as authenticate() with the exception that the only supported options are: + * 'hostHeaderName', 'localtimeOffsetMsec', 'host', 'port' + */ + +exports.authenticateBewit = function (req, credentialsFunc, options, callback) { + + callback = Utils.nextTick(callback); + + // Application time + + var now = Utils.now() + (options.localtimeOffsetMsec || 0); + + // Convert node Http request object to a request configuration object + + var request = Utils.parseRequest(req, options); + if (request instanceof Error) { + return callback(Boom.badRequest(request.message)); + } + + // Extract bewit + + // 1 2 3 4 + var resource = request.url.match(/^(\/.*)([\?&])bewit\=([^&$]*)(?:&(.+))?$/); + if (!resource) { + return callback(Boom.unauthorized(null, 'Hawk')); + } + + // Bewit not empty + + if (!resource[3]) { + return callback(Boom.unauthorized('Empty bewit', 'Hawk')); + } + + // Verify method is GET + + if (request.method !== 'GET' && + request.method !== 'HEAD') { + + return callback(Boom.unauthorized('Invalid method', 'Hawk')); + } + + // No other authentication + + if (request.authorization) { + return callback(Boom.badRequest('Multiple authentications', 'Hawk')); + } + + // Parse bewit + + var bewitString = Utils.base64urlDecode(resource[3]); + if (bewitString instanceof Error) { + return callback(Boom.badRequest('Invalid bewit encoding')); + } + + // Bewit format: id\exp\mac\ext ('\' is used because it is a reserved header attribute character) + + var bewitParts = bewitString.split('\\'); + if (!bewitParts || + bewitParts.length !== 4) { + + return callback(Boom.badRequest('Invalid bewit structure')); + } + + var bewit = { + id: bewitParts[0], + exp: parseInt(bewitParts[1], 10), + mac: bewitParts[2], + ext: bewitParts[3] || '' + }; + + if (!bewit.id || + !bewit.exp || + !bewit.mac) { + + return callback(Boom.badRequest('Missing bewit attributes')); + } + + // Construct URL without bewit + + var url = resource[1]; + if (resource[4]) { + url += resource[2] + resource[4]; + } + + // Check expiration + + if (bewit.exp * 1000 <= now) { + return callback(Boom.unauthorized('Access expired', 'Hawk'), null, bewit); + } + + // Fetch Hawk credentials + + credentialsFunc(bewit.id, function (err, credentials) { + + if (err) { + return callback(err, credentials || null, bewit.ext); + } + + if (!credentials) { + return callback(Boom.unauthorized('Unknown credentials', 'Hawk'), null, bewit); + } + + if (!credentials.key || + !credentials.algorithm) { + + return callback(Boom.internal('Invalid credentials'), credentials, bewit); + } + + if (Crypto.algorithms.indexOf(credentials.algorithm) === -1) { + return callback(Boom.internal('Unknown algorithm'), credentials, bewit); + } + + // Calculate MAC + + var mac = Crypto.calculateMac('bewit', credentials, { + ts: bewit.exp, + nonce: '', + method: 'GET', + resource: url, + host: request.host, + port: request.port, + ext: bewit.ext + }); + + if (!Cryptiles.fixedTimeComparison(mac, bewit.mac)) { + return callback(Boom.unauthorized('Bad mac', 'Hawk'), credentials, bewit); + } + + // Successful authentication + + return callback(null, credentials, bewit); + }); +}; + + +/* + * options are the same as authenticate() with the exception that the only supported options are: + * 'nonceFunc', 'timestampSkewSec', 'localtimeOffsetMsec' + */ + +exports.authenticateMessage = function (host, port, message, authorization, credentialsFunc, options, callback) { + + callback = Utils.nextTick(callback); + + // Default options + + options.nonceFunc = options.nonceFunc || function (nonce, ts, nonceCallback) { return nonceCallback(); }; // No validation + options.timestampSkewSec = options.timestampSkewSec || 60; // 60 seconds + + // Application time + + var now = Utils.now() + (options.localtimeOffsetMsec || 0); // Measure now before any other processing + + // Validate authorization + + if (!authorization.id || + !authorization.ts || + !authorization.nonce || + !authorization.hash || + !authorization.mac) { + + return callback(Boom.badRequest('Invalid authorization')) + } + + // Fetch Hawk credentials + + credentialsFunc(authorization.id, function (err, credentials) { + + if (err) { + return callback(err, credentials || null); + } + + if (!credentials) { + return callback(Boom.unauthorized('Unknown credentials', 'Hawk')); + } + + if (!credentials.key || + !credentials.algorithm) { + + return callback(Boom.internal('Invalid credentials'), credentials); + } + + if (Crypto.algorithms.indexOf(credentials.algorithm) === -1) { + return callback(Boom.internal('Unknown algorithm'), credentials); + } + + // Construct artifacts container + + var artifacts = { + ts: authorization.ts, + nonce: authorization.nonce, + host: host, + port: port, + hash: authorization.hash + }; + + // Calculate MAC + + var mac = Crypto.calculateMac('message', credentials, artifacts); + if (!Cryptiles.fixedTimeComparison(mac, authorization.mac)) { + return callback(Boom.unauthorized('Bad mac', 'Hawk'), credentials); + } + + // Check payload hash + + var hash = Crypto.calculatePayloadHash(message, credentials.algorithm); + if (!Cryptiles.fixedTimeComparison(hash, authorization.hash)) { + return callback(Boom.unauthorized('Bad message hash', 'Hawk'), credentials); + } + + // Check nonce + + options.nonceFunc(authorization.nonce, authorization.ts, function (err) { + + if (err) { + return callback(Boom.unauthorized('Invalid nonce', 'Hawk'), credentials); + } + + // Check timestamp staleness + + if (Math.abs((authorization.ts * 1000) - now) > (options.timestampSkewSec * 1000)) { + return callback(Boom.unauthorized('Stale timestamp'), credentials); + } + + // Successful authentication + + return callback(null, credentials); + }); + }); +}; diff --git a/deps/npm/node_modules/request/node_modules/hawk/lib/utils.js b/deps/npm/node_modules/request/node_modules/hawk/lib/utils.js index 024adba1237..c8938fe8291 100755 --- a/deps/npm/node_modules/request/node_modules/hawk/lib/utils.js +++ b/deps/npm/node_modules/request/node_modules/hawk/lib/utils.js @@ -42,7 +42,14 @@ exports.parseHost = function (req, hostHeaderName) { return null; } - var hostHeaderRegex = /^(?:(?:\r\n)?[\t ])*([^:]+)(?::(\d+))?(?:(?:\r\n)?[\t ])*$/; // Does not support IPv6 + var hostHeaderRegex; + if (hostHeader[0] === '[') { + hostHeaderRegex = /^(?:(?:\r\n)?\s)*(\[[^\]]+\])(?::(\d+))?(?:(?:\r\n)?\s)*$/; // IPv6 + } + else { + hostHeaderRegex = /^(?:(?:\r\n)?\s)*([^:]+)(?::(\d+))?(?:(?:\r\n)?\s)*$/; // IPv4, hostname + } + var hostParts = hostHeader.match(hostHeaderRegex); if (!hostParts || @@ -78,19 +85,21 @@ exports.parseRequest = function (req, options) { if (!req.headers) { return req; } - + // Obtain host and port information - var host = exports.parseHost(req, options.hostHeaderName); - if (!host) { - return new Error('Invalid Host header'); + if (!options.host || !options.port) { + var host = exports.parseHost(req, options.hostHeaderName); + if (!host) { + return new Error('Invalid Host header'); + } } var request = { method: req.method, url: req.url, - host: host.name, - port: host.port, + host: options.host || host.name, + port: options.port || host.port, authorization: req.headers.authorization, contentType: req.headers['content-type'] || '' }; diff --git a/deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/.npmignore b/deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/.npmignore deleted file mode 100644 index 9966e5e637c..00000000000 --- a/deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/.npmignore +++ /dev/null @@ -1,18 +0,0 @@ -.idea
-*.iml
-npm-debug.log
-dump.rdb
-node_modules
-results.tap
-results.xml
-npm-shrinkwrap.json
-config.json
-.DS_Store
-*/.DS_Store
-*/*/.DS_Store
-._*
-*/._*
-*/*/._*
-coverage.*
-lib-cov
-complexity.md
diff --git a/deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/.travis.yml b/deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/.travis.yml deleted file mode 100755 index 40ca59eeebd..00000000000 --- a/deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/.travis.yml +++ /dev/null @@ -1,5 +0,0 @@ -language: node_js
-
-node_js:
- - 0.10
-
diff --git a/deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/LICENSE b/deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/LICENSE deleted file mode 100755 index 394adcff2ed..00000000000 --- a/deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/LICENSE +++ /dev/null @@ -1,33 +0,0 @@ -Copyright (c) 2011-2013, Walmart.
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- * Neither the name of Walmart nor the
- names of its contributors may be used to endorse or promote products
- derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL WALMART BE LIABLE FOR ANY
-DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-
- * * *
-
-
-Portions of this project were initially based on Postmile, Copyright (c) 2011, Yahoo Inc.
-Postmile is published at https://github.com/yahoo/postmile and its licensing terms are
-published at https://github.com/yahoo/postmile/blob/master/LICENSE.
-
diff --git a/deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/Makefile b/deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/Makefile deleted file mode 100755 index e605d6c049d..00000000000 --- a/deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -test:
- @node node_modules/lab/bin/lab
-test-cov:
- @node node_modules/lab/bin/lab -r threshold -t 100
-test-cov-html:
- @node node_modules/lab/bin/lab -r html -o coverage.html
-complexity:
- @node node_modules/complexity-report/src/cli.js -o complexity.md -f markdown lib
-
-.PHONY: test test-cov test-cov-html complexity
diff --git a/deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/README.md b/deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/README.md deleted file mode 100755 index ac64e2fda1f..00000000000 --- a/deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/README.md +++ /dev/null @@ -1,436 +0,0 @@ -<a href="https://github.com/spumko"><img src="https://raw.github.com/spumko/spumko/master/images/from.png" align="right" /></a>
-![hoek Logo](https://raw.github.com/spumko/hoek/master/images/hoek.png)
-
-General purpose node utilities
-
-[![Build Status](https://secure.travis-ci.org/spumko/hoek.png)](http://travis-ci.org/spumko/hoek)
-
-# Table of Contents
-
-* [Introduction](#introduction "Introduction")
-* [Object](#object "Object")
- * [clone](#cloneobj "clone")
- * [merge](#mergetarget-source-isnulloverride-ismergearrays "merge")
- * [applyToDefaults](#applytodefaultsdefaults-options "applyToDefaults")
- * [unique](#uniquearray-key "unique")
- * [mapToObject](#maptoobjectarray-key "mapToObject")
- * [intersect](#intersectarray1-array2 "intersect")
- * [matchKeys](#matchkeysobj-keys "matchKeys")
- * [flatten](#flattenarray-target "flatten")
- * [removeKeys](#removekeysobject-keys "removeKeys")
- * [reach](#reachobj-chain "reach")
- * [inheritAsync](#inheritasyncself-obj-keys "inheritAsync")
- * [rename](#renameobj-from-to "rename")
-* [Timer](#timer "Timer")
-* [Binary Encoding/Decoding](#binary "Binary Encoding/Decoding")
- * [base64urlEncode](#binary64urlEncodevalue "binary64urlEncode")
- * [base64urlDecode](#binary64urlDecodevalue "binary64urlDecode")
-* [Escaping Characters](#escaped "Escaping Characters")
- * [escapeHtml](#escapeHtmlstring "escapeHtml")
- * [escapeHeaderAttribute](#escapeHeaderAttributeattribute "escapeHeaderAttribute")
- * [escapeRegex](#escapeRegexstring "escapeRegex")
-* [Errors](#errors "Errors")
- * [assert](#assertmessage "assert")
- * [abort](#abortmessage "abort")
- * [displayStack](#displayStackslice "displayStack")
- * [callStack](#callStackslice "callStack")
- * [toss](#tosscondition "toss")
-* [Load files](#load-files "Load Files")
- * [loadPackage](#loadPackagedir "loadpackage")
- * [loadDirModules](#loadDirModulespath-excludefiles-target "loaddirmodules")
-
-
-
-# Introduction
-
-The *Hoek* general purpose node utilities library is used to aid in a variety of manners. It comes with useful methods for Arrays (clone, merge, applyToDefaults), Objects (removeKeys, copy), Asserting and more.
-
-For example, to use Hoek to set configuration with default options:
-```javascript
-var Hoek = require('hoek');
-
-var default = {url : "www.github.com", port : "8000", debug : true}
-
-var config = Hoek.applyToDefaults(default, {port : "3000", admin : true});
-
-// In this case, config would be { url: 'www.github.com', port: '3000', debug: true, admin: true }
-```
-
-Under each of the sections (such as Array), there are subsections which correspond to Hoek methods. Each subsection will explain how to use the corresponding method. In each js excerpt below, the var Hoek = require('hoek') is omitted for brevity.
-
-## Object
-
-Hoek provides several helpful methods for objects and arrays.
-
-### clone(obj)
-
-This method is used to clone an object or an array. A *deep copy* is made (duplicates everything, including values that are objects).
-
-```javascript
-
-var nestedObj = {
- w: /^something$/ig,
- x: {
- a: [1, 2, 3],
- b: 123456,
- c: new Date()
- },
- y: 'y',
- z: new Date()
- };
-
-var copy = Hoek.clone(nestedObj);
-
-copy.x.b = 100;
-
-console.log(copy.y) // results in 'y'
-console.log(nestedObj.x.b) // results in 123456
-console.log(copy.x.b) // results in 100
-```
-
-### merge(target, source, isNullOverride, isMergeArrays)
-isNullOverride, isMergeArrays default to true
-
-Merge all the properties of source into target, source wins in conflic, and by default null and undefined from source are applied
-
-
-```javascript
-
-var target = {a: 1, b : 2}
-var source = {a: 0, c: 5}
-var source2 = {a: null, c: 5}
-
-var targetArray = [1, 2, 3];
-var sourceArray = [4, 5];
-
-var newTarget = Hoek.merge(target, source); // results in {a: 0, b: 2, c: 5}
-newTarget = Hoek.merge(target, source2); // results in {a: null, b: 2, c: 5}
-newTarget = Hoek.merge(target, source2, false); // results in {a: 1, b: 2, c: 5}
-
-newTarget = Hoek.merge(targetArray, sourceArray) // results in [1, 2, 3, 4, 5]
-newTarget = Hoek.merge(targetArray, sourceArray, true, false) // results in [4, 5]
-
-
-
-
-```
-
-### applyToDefaults(defaults, options)
-
-Apply options to a copy of the defaults
-
-```javascript
-
-var defaults = {host: "localhost", port: 8000};
-var options = {port: 8080};
-
-var config = Hoek.applyToDefaults(defaults, options); // results in {host: "localhost", port: 8080};
-
-
-```
-
-### unique(array, key)
-
-Remove duplicate items from Array
-
-```javascript
-
-var array = [1, 2, 2, 3, 3, 4, 5, 6];
-
-var newArray = Hoek.unique(array); // results in [1,2,3,4,5,6];
-
-array = [{id: 1}, {id: 1}, {id: 2}];
-
-newArray = Hoek.unique(array, "id") // results in [{id: 1}, {id: 2}]
-
-```
-
-### mapToObject(array, key)
-
-Convert an Array into an Object
-
-```javascript
-
-var array = [1,2,3];
-var newObject = Hoek.mapToObject(array); // results in [{"1": true}, {"2": true}, {"3": true}]
-
-array = [{id: 1}, {id: 2}];
-newObject = Hoek.mapToObject(array, "id") // results in [{"id": 1}, {"id": 2}]
-
-```
-### intersect(array1, array2)
-
-Find the common unique items in two arrays
-
-```javascript
-
-var array1 = [1, 2, 3];
-var array2 = [1, 4, 5];
-
-var newArray = Hoek.intersect(array1, array2) // results in [1]
-
-```
-
-### matchKeys(obj, keys)
-
-Find which keys are present
-
-```javascript
-
-var obj = {a: 1, b: 2, c: 3};
-var keys = ["a", "e"];
-
-Hoek.matchKeys(obj, keys) // returns ["a"]
-
-```
-
-### flatten(array, target)
-
-Flatten an array
-
-```javascript
-
-var array = [1, 2, 3];
-var target = [4, 5];
-
-var flattenedArray = Hoek.flatten(array, target) // results in [4, 5, 1, 2, 3];
-
-```
-
-### removeKeys(object, keys)
-
-Remove keys
-
-```javascript
-
-var object = {a: 1, b: 2, c: 3, d: 4};
-
-var keys = ["a", "b"];
-
-Hoek.removeKeys(object, keys) // object is now {c: 3, d: 4}
-
-```
-
-### reach(obj, chain)
-
-Converts an object key chain string to reference
-
-```javascript
-
-var chain = 'a.b.c';
-var obj = {a : {b : { c : 1}}};
-
-Hoek.reach(obj, chain) // returns 1
-
-```
-
-### inheritAsync(self, obj, keys)
-
-Inherits a selected set of methods from an object, wrapping functions in asynchronous syntax and catching errors
-
-```javascript
-
-var targetFunc = function () { };
-
-var proto = {
- a: function () {
- return 'a!';
- },
- b: function () {
- return 'b!';
- },
- c: function () {
- throw new Error('c!');
- }
- };
-
-var keys = ['a', 'c'];
-
-Hoek.inheritAsync(targetFunc, proto, ['a', 'c']);
-
-var target = new targetFunc();
-
-target.a(function(err, result){console.log(result)} // returns 'a!'
-
-target.c(function(err, result){console.log(result)} // returns undefined
-
-target.b(function(err, result){console.log(result)} // gives error: Object [object Object] has no method 'b'
-
-```
-
-### rename(obj, from, to)
-
-Rename a key of an object
-
-```javascript
-
-var obj = {a : 1, b : 2};
-
-Hoek.rename(obj, "a", "c"); // obj is now {c : 1, b : 2}
-
-```
-
-
-# Timer
-
-A Timer object. Initializing a new timer object sets the ts to the number of milliseconds elapsed since 1 January 1970 00:00:00 UTC.
-
-```javascript
-
-
-example :
-
-
-var timerObj = new Hoek.Timer();
-console.log("Time is now: " + timerObj.ts)
-console.log("Elapsed time from initialization: " + timerObj.elapsed() + 'milliseconds')
-
-```
-
-# Binary Encoding/Decoding
-
-### base64urlEncode(value)
-
-Encodes value in Base64 or URL encoding
-
-### base64urlDecode(value)
-
-Decodes data in Base64 or URL encoding.
-# Escaping Characters
-
-Hoek provides convenient methods for escaping html characters. The escaped characters are as followed:
-
-```javascript
-
-internals.htmlEscaped = {
- '&': '&',
- '<': '<',
- '>': '>',
- '"': '"',
- "'": ''',
- '`': '`'
-};
-
-```
-
-### escapeHtml(string)
-
-```javascript
-
-var string = '<html> hey </html>';
-var escapedString = Hoek.escapeHtml(string); // returns <html> hey </html>
-
-```
-
-### escapeHeaderAttribute(attribute)
-
-Escape attribute value for use in HTTP header
-
-```javascript
-
-var a = Hoek.escapeHeaderAttribute('I said "go w\\o me"'); //returns I said \"go w\\o me\"
-
-
-```
-
-
-### escapeRegex(string)
-
-Escape string for Regex construction
-
-```javascript
-
-var a = Hoek.escapeRegex('4^f$s.4*5+-_?%=#!:@|~\\/`"(>)[<]d{}s,'); // returns 4\^f\$s\.4\*5\+\-_\?%\=#\!\:@\|~\\\/`"\(>\)\[<\]d\{\}s\,
-
-
-
-```
-
-# Errors
-
-### assert(message)
-
-```javascript
-
-var a = 1, b =2;
-
-Hoek.assert(a === b, 'a should equal b'); // ABORT: a should equal b
-
-```
-
-### abort(message)
-
-First checks if process.env.NODE_ENV === 'test', and if so, throws error message. Otherwise,
-displays most recent stack and then exits process.
-
-
-
-### displayStack(slice)
-
-Displays the trace stack
-
-```javascript
-
-var stack = Hoek.displayStack();
-console.log(stack) // returns something like:
-
-[ 'null (/Users/user/Desktop/hoek/test.js:4:18)',
- 'Module._compile (module.js:449:26)',
- 'Module._extensions..js (module.js:467:10)',
- 'Module.load (module.js:356:32)',
- 'Module._load (module.js:312:12)',
- 'Module.runMain (module.js:492:10)',
- 'startup.processNextTick.process._tickCallback (node.js:244:9)' ]
-
-```
-
-### callStack(slice)
-
-Returns a trace stack array.
-
-```javascript
-
-var stack = Hoek.callStack();
-console.log(stack) // returns something like:
-
-[ [ '/Users/user/Desktop/hoek/test.js', 4, 18, null, false ],
- [ 'module.js', 449, 26, 'Module._compile', false ],
- [ 'module.js', 467, 10, 'Module._extensions..js', false ],
- [ 'module.js', 356, 32, 'Module.load', false ],
- [ 'module.js', 312, 12, 'Module._load', false ],
- [ 'module.js', 492, 10, 'Module.runMain', false ],
- [ 'node.js',
- 244,
- 9,
- 'startup.processNextTick.process._tickCallback',
- false ] ]
-
-
-```
-
-### toss(condition)
-
-toss(condition /*, [message], callback */)
-
-Return an error as first argument of a callback
-
-
-# Load Files
-
-### loadPackage(dir)
-
-Load and parse package.json process root or given directory
-
-```javascript
-
-var pack = Hoek.loadPackage(); // pack.name === 'hoek'
-
-```
-
-### loadDirModules(path, excludeFiles, target)
-
-Loads modules from a given path; option to exclude files (array).
-
-
-
-
diff --git a/deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/images/hoek.png b/deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/images/hoek.png Binary files differdeleted file mode 100755 index 6ccfcb12be7..00000000000 --- a/deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/images/hoek.png +++ /dev/null diff --git a/deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/index.js b/deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/index.js deleted file mode 100755 index 4cc88b35877..00000000000 --- a/deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/index.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('./lib');
\ No newline at end of file diff --git a/deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/lib/escape.js b/deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/lib/escape.js deleted file mode 100755 index 666b3dc8206..00000000000 --- a/deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/lib/escape.js +++ /dev/null @@ -1,132 +0,0 @@ -// Declare internals
-
-var internals = {};
-
-
-exports.escapeJavaScript = function (input) {
-
- if (!input) {
- return '';
- }
-
- var escaped = '';
-
- for (var i = 0, il = input.length; i < il; ++i) {
-
- var charCode = input.charCodeAt(i);
-
- if (internals.isSafe(charCode)) {
- escaped += input[i];
- }
- else {
- escaped += internals.escapeJavaScriptChar(charCode);
- }
- }
-
- return escaped;
-};
-
-
-exports.escapeHtml = function (input) {
-
- if (!input) {
- return '';
- }
-
- var escaped = '';
-
- for (var i = 0, il = input.length; i < il; ++i) {
-
- var charCode = input.charCodeAt(i);
-
- if (internals.isSafe(charCode)) {
- escaped += input[i];
- }
- else {
- escaped += internals.escapeHtmlChar(charCode);
- }
- }
-
- return escaped;
-};
-
-
-internals.escapeJavaScriptChar = function (charCode) {
-
- if (charCode >= 256) {
- return '\\u' + internals.padLeft('' + charCode, 4);
- }
-
- var hexValue = new Buffer(String.fromCharCode(charCode), 'ascii').toString('hex');
- return '\\x' + internals.padLeft(hexValue, 2);
-};
-
-
-internals.escapeHtmlChar = function (charCode) {
-
- var namedEscape = internals.namedHtml[charCode];
- if (typeof namedEscape !== 'undefined') {
- return namedEscape;
- }
-
- if (charCode >= 256) {
- return '&#' + charCode + ';';
- }
-
- var hexValue = new Buffer(String.fromCharCode(charCode), 'ascii').toString('hex');
- return '&#x' + internals.padLeft(hexValue, 2) + ';';
-};
-
-
-internals.padLeft = function (str, len) {
-
- while (str.length < len) {
- str = '0' + str;
- }
-
- return str;
-};
-
-
-internals.isSafe = function (charCode) {
-
- return (typeof internals.safeCharCodes[charCode] !== 'undefined');
-};
-
-
-internals.namedHtml = {
- '38': '&',
- '60': '<',
- '62': '>',
- '34': '"',
- '160': ' ',
- '162': '¢',
- '163': '£',
- '164': '¤',
- '169': '©',
- '174': '®'
-};
-
-
-internals.safeCharCodes = (function () {
-
- var safe = {};
-
- for (var i = 32; i < 123; ++i) {
-
- if ((i >= 97 && i <= 122) || // a-z
- (i >= 65 && i <= 90) || // A-Z
- (i >= 48 && i <= 57) || // 0-9
- i === 32 || // space
- i === 46 || // .
- i === 44 || // ,
- i === 45 || // -
- i === 58 || // :
- i === 95) { // _
-
- safe[i] = null;
- }
- }
-
- return safe;
-}());
\ No newline at end of file diff --git a/deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/lib/index.js b/deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/lib/index.js deleted file mode 100755 index 806260d25eb..00000000000 --- a/deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/lib/index.js +++ /dev/null @@ -1,585 +0,0 @@ -// Load modules
-
-var Fs = require('fs');
-var Escape = require('./escape');
-
-
-// Declare internals
-
-var internals = {};
-
-
-// Clone object or array
-
-exports.clone = function (obj, seen) {
-
- if (typeof obj !== 'object' ||
- obj === null) {
-
- return obj;
- }
-
- seen = seen || { orig: [], copy: [] };
-
- var lookup = seen.orig.indexOf(obj);
- if (lookup !== -1) {
- return seen.copy[lookup];
- }
-
- var newObj = (obj instanceof Array) ? [] : {};
-
- seen.orig.push(obj);
- seen.copy.push(newObj);
-
- for (var i in obj) {
- if (obj.hasOwnProperty(i)) {
- if (obj[i] instanceof Buffer) {
- newObj[i] = new Buffer(obj[i]);
- }
- else if (obj[i] instanceof Date) {
- newObj[i] = new Date(obj[i].getTime());
- }
- else if (obj[i] instanceof RegExp) {
- var flags = '' + (obj[i].global ? 'g' : '') + (obj[i].ignoreCase ? 'i' : '') + (obj[i].multiline ? 'm' : '');
- newObj[i] = new RegExp(obj[i].source, flags);
- }
- else {
- newObj[i] = exports.clone(obj[i], seen);
- }
- }
- }
-
- return newObj;
-};
-
-
-// Merge all the properties of source into target, source wins in conflic, and by default null and undefined from source are applied
-
-exports.merge = function (target, source, isNullOverride /* = true */, isMergeArrays /* = true */) {
-
- exports.assert(target && typeof target == 'object', 'Invalid target value: must be an object');
- exports.assert(source === null || source === undefined || typeof source === 'object', 'Invalid source value: must be null, undefined, or an object');
-
- if (!source) {
- return target;
- }
-
- if (source instanceof Array) {
- exports.assert(target instanceof Array, 'Cannot merge array onto an object');
- if (isMergeArrays === false) { // isMergeArrays defaults to true
- target.length = 0; // Must not change target assignment
- }
-
- for (var i = 0, il = source.length; i < il; ++i) {
- target.push(source[i]);
- }
-
- return target;
- }
-
- var keys = Object.keys(source);
- for (var k = 0, kl = keys.length; k < kl; ++k) {
- var key = keys[k];
- var value = source[key];
- if (value &&
- typeof value === 'object') {
-
- if (!target[key] ||
- typeof target[key] !== 'object') {
-
- target[key] = exports.clone(value);
- }
- else {
- exports.merge(target[key], source[key], isNullOverride, isMergeArrays);
- }
- }
- else {
- if (value !== null && value !== undefined) { // Explicit to preserve empty strings
- target[key] = value;
- }
- else if (isNullOverride !== false) { // Defaults to true
- target[key] = value;
- }
- }
- }
-
- return target;
-};
-
-
-// Apply options to a copy of the defaults
-
-exports.applyToDefaults = function (defaults, options) {
-
- exports.assert(defaults && typeof defaults == 'object', 'Invalid defaults value: must be an object');
- exports.assert(!options || options === true || typeof options === 'object', 'Invalid options value: must be true, falsy or an object');
-
- if (!options) { // If no options, return null
- return null;
- }
-
- var copy = exports.clone(defaults);
-
- if (options === true) { // If options is set to true, use defaults
- return copy;
- }
-
- return exports.merge(copy, options, false, false);
-};
-
-
-// Remove duplicate items from array
-
-exports.unique = function (array, key) {
-
- var index = {};
- var result = [];
-
- for (var i = 0, il = array.length; i < il; ++i) {
- var id = (key ? array[i][key] : array[i]);
- if (index[id] !== true) {
-
- result.push(array[i]);
- index[id] = true;
- }
- }
-
- return result;
-};
-
-
-// Convert array into object
-
-exports.mapToObject = function (array, key) {
-
- if (!array) {
- return null;
- }
-
- var obj = {};
- for (var i = 0, il = array.length; i < il; ++i) {
- if (key) {
- if (array[i][key]) {
- obj[array[i][key]] = true;
- }
- }
- else {
- obj[array[i]] = true;
- }
- }
-
- return obj;
-};
-
-
-// Find the common unique items in two arrays
-
-exports.intersect = function (array1, array2, justFirst) {
-
- if (!array1 || !array2) {
- return [];
- }
-
- var common = [];
- var hash = (array1 instanceof Array ? exports.mapToObject(array1) : array1);
- var found = {};
- for (var i = 0, il = array2.length; i < il; ++i) {
- if (hash[array2[i]] && !found[array2[i]]) {
- if (justFirst) {
- return array2[i];
- }
-
- common.push(array2[i]);
- found[array2[i]] = true;
- }
- }
-
- return (justFirst ? null : common);
-};
-
-
-// Find which keys are present
-
-exports.matchKeys = function (obj, keys) {
-
- var matched = [];
- for (var i = 0, il = keys.length; i < il; ++i) {
- if (obj.hasOwnProperty(keys[i])) {
- matched.push(keys[i]);
- }
- }
- return matched;
-};
-
-
-// Flatten array
-
-exports.flatten = function (array, target) {
-
- var result = target || [];
-
- for (var i = 0, il = array.length; i < il; ++i) {
- if (Array.isArray(array[i])) {
- exports.flatten(array[i], result);
- }
- else {
- result.push(array[i]);
- }
- }
-
- return result;
-};
-
-
-// Remove keys
-
-exports.removeKeys = function (object, keys) {
-
- for (var i = 0, il = keys.length; i < il; i++) {
- delete object[keys[i]];
- }
-};
-
-
-// Convert an object key chain string ('a.b.c') to reference (object[a][b][c])
-
-exports.reach = function (obj, chain) {
-
- var path = chain.split('.');
- var ref = obj;
- for (var i = 0, il = path.length; i < il; ++i) {
- if (ref) {
- ref = ref[path[i]];
- }
- }
-
- return ref;
-};
-
-
-// Inherits a selected set of methods from an object, wrapping functions in asynchronous syntax and catching errors
-
-exports.inheritAsync = function (self, obj, keys) {
-
- keys = keys || null;
-
- for (var i in obj) {
- if (obj.hasOwnProperty(i)) {
- if (keys instanceof Array &&
- keys.indexOf(i) < 0) {
-
- continue;
- }
-
- self.prototype[i] = (function (fn) {
-
- return function (next) {
-
- var result = null;
- try {
- result = fn();
- }
- catch (err) {
- return next(err);
- }
-
- return next(null, result);
- };
- })(obj[i]);
- }
- }
-};
-
-
-exports.formatStack = function (stack) {
-
- var trace = [];
- for (var i = 0, il = stack.length; i < il; ++i) {
- var item = stack[i];
- trace.push([item.getFileName(), item.getLineNumber(), item.getColumnNumber(), item.getFunctionName(), item.isConstructor()]);
- }
-
- return trace;
-};
-
-
-exports.formatTrace = function (trace) {
-
- var display = [];
-
- for (var i = 0, il = trace.length; i < il; ++i) {
- var row = trace[i];
- display.push((row[4] ? 'new ' : '') + row[3] + ' (' + row[0] + ':' + row[1] + ':' + row[2] + ')');
- }
-
- return display;
-};
-
-
-exports.callStack = function (slice) {
-
- // http://code.google.com/p/v8/wiki/JavaScriptStackTraceApi
-
- var v8 = Error.prepareStackTrace;
- Error.prepareStackTrace = function (err, stack) {
-
- return stack;
- };
-
- var capture = {};
- Error.captureStackTrace(capture, arguments.callee);
- var stack = capture.stack;
-
- Error.prepareStackTrace = v8;
-
- var trace = exports.formatStack(stack);
-
- if (slice) {
- return trace.slice(slice);
- }
-
- return trace;
-};
-
-
-exports.displayStack = function (slice) {
-
- var trace = exports.callStack(slice === undefined ? 1 : slice + 1);
-
- return exports.formatTrace(trace);
-};
-
-
-exports.abortThrow = false;
-
-
-exports.abort = function (message, hideStack) {
-
- if (process.env.NODE_ENV === 'test' || exports.abortThrow === true) {
- throw new Error(message || 'Unknown error');
- }
-
- var stack = '';
- if (!hideStack) {
- stack = exports.displayStack(1).join('\n\t');
- }
- console.log('ABORT: ' + message + '\n\t' + stack);
- process.exit(1);
-};
-
-
-exports.assert = function (condition /*, msg1, msg2, msg3 */) {
-
- if (condition) {
- return;
- }
-
- var msgs = Array.prototype.slice.call(arguments, 1);
- msgs = msgs.map(function (msg) {
-
- return typeof msg === 'string' ? msg : msg instanceof Error ? msg.message : JSON.stringify(msg);
- });
- throw new Error(msgs.join(' ') || 'Unknown error');
-};
-
-
-exports.loadDirModules = function (path, excludeFiles, target) { // target(filename, name, capName)
-
- var exclude = {};
- for (var i = 0, il = excludeFiles.length; i < il; ++i) {
- exclude[excludeFiles[i] + '.js'] = true;
- }
-
- var files = Fs.readdirSync(path);
- for (i = 0, il = files.length; i < il; ++i) {
- var filename = files[i];
- if (/\.js$/.test(filename) &&
- !exclude[filename]) {
-
- var name = filename.substr(0, filename.lastIndexOf('.'));
- var capName = name.charAt(0).toUpperCase() + name.substr(1).toLowerCase();
-
- if (typeof target !== 'function') {
- target[capName] = require(path + '/' + name);
- }
- else {
- target(path + '/' + name, name, capName);
- }
- }
- }
-};
-
-
-exports.rename = function (obj, from, to) {
-
- obj[to] = obj[from];
- delete obj[from];
-};
-
-
-exports.Timer = function () {
-
- this.reset();
-};
-
-
-exports.Timer.prototype.reset = function () {
-
- this.ts = Date.now();
-};
-
-
-exports.Timer.prototype.elapsed = function () {
-
- return Date.now() - this.ts;
-};
-
-
-// Load and parse package.json process root or given directory
-
-exports.loadPackage = function (dir) {
-
- var result = {};
- var filepath = (dir || process.env.PWD) + '/package.json';
- if (Fs.existsSync(filepath)) {
- try {
- result = JSON.parse(Fs.readFileSync(filepath));
- }
- catch (e) { }
- }
-
- return result;
-};
-
-
-// Escape string for Regex construction
-
-exports.escapeRegex = function (string) {
-
- // Escape ^$.*+-?=!:|\/()[]{},
- return string.replace(/[\^\$\.\*\+\-\?\=\!\:\|\\\/\(\)\[\]\{\}\,]/g, '\\$&');
-};
-
-
-// Return an error as first argument of a callback
-
-exports.toss = function (condition /*, [message], next */) {
-
- var message = (arguments.length === 3 ? arguments[1] : '');
- var next = (arguments.length === 3 ? arguments[2] : arguments[1]);
-
- var err = (message instanceof Error ? message : (message ? new Error(message) : (condition instanceof Error ? condition : new Error())));
-
- if (condition instanceof Error ||
- !condition) {
-
- return next(err);
- }
-};
-
-
-// Base64url (RFC 4648) encode
-
-exports.base64urlEncode = function (value) {
-
- return (new Buffer(value, 'binary')).toString('base64').replace(/\+/g, '-').replace(/\//g, '_').replace(/\=/g, '');
-};
-
-
-// Base64url (RFC 4648) decode
-
-exports.base64urlDecode = function (encoded) {
-
- if (encoded &&
- !encoded.match(/^[\w\-]*$/)) {
-
- return new Error('Invalid character');
- }
-
- try {
- return (new Buffer(encoded.replace(/-/g, '+').replace(/:/g, '/'), 'base64')).toString('binary');
- }
- catch (err) {
- return err;
- }
-};
-
-
-// Escape attribute value for use in HTTP header
-
-exports.escapeHeaderAttribute = function (attribute) {
-
- // Allowed value characters: !#$%&'()*+,-./:;<=>?@[]^_`{|}~ and space, a-z, A-Z, 0-9, \, "
-
- exports.assert(attribute.match(/^[ \w\!#\$%&'\(\)\*\+,\-\.\/\:;<\=>\?@\[\]\^`\{\|\}~\"\\]*$/), 'Bad attribute value (' + attribute + ')');
-
- return attribute.replace(/\\/g, '\\\\').replace(/\"/g, '\\"'); // Escape quotes and slash
-};
-
-
-exports.escapeHtml = function (string) {
-
- return Escape.escapeHtml(string);
-};
-
-
-exports.escapeJavaScript = function (string) {
-
- return Escape.escapeJavaScript(string);
-};
-
-
-/*
-var event = {
- timestamp: now.getTime(),
- tags: ['tag'],
- data: { some: 'data' }
-};
-*/
-
-exports.consoleFunc = console.log;
-
-exports.printEvent = function (event) {
-
- var pad = function (value) {
-
- return (value < 10 ? '0' : '') + value;
- };
-
- var now = new Date(event.timestamp);
- var timestring = (now.getYear() - 100).toString() +
- pad(now.getMonth() + 1) +
- pad(now.getDate()) +
- '/' +
- pad(now.getHours()) +
- pad(now.getMinutes()) +
- pad(now.getSeconds()) +
- '.' +
- now.getMilliseconds();
-
- var data = event.data;
- if (typeof event.data !== 'string') {
- try {
- data = JSON.stringify(event.data);
- }
- catch (e) {
- data = 'JSON Error: ' + e.message;
- }
- }
-
- var output = timestring + ', ' + event.tags[0] + ', ' + data;
- exports.consoleFunc(output);
-};
-
-
-exports.nextTick = function (callback) {
-
- return function () {
-
- var args = arguments;
- process.nextTick(function () {
-
- callback.apply(null, args);
- });
- };
-};
diff --git a/deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/package.json b/deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/package.json deleted file mode 100755 index 152a5de7d85..00000000000 --- a/deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/package.json +++ /dev/null @@ -1,52 +0,0 @@ -{ - "name": "hoek", - "description": "General purpose node utilities", - "version": "0.9.1", - "author": { - "name": "Eran Hammer", - "email": "eran@hueniverse.com", - "url": "http://hueniverse.com" - }, - "contributors": [ - { - "name": "Van Nguyen", - "email": "the.gol.effect@gmail.com" - } - ], - "repository": { - "type": "git", - "url": "git://github.com/spumko/hoek" - }, - "main": "index", - "keywords": [ - "utilities" - ], - "engines": { - "node": ">=0.8.0" - }, - "dependencies": {}, - "devDependencies": { - "lab": "0.1.x", - "complexity-report": "0.x.x" - }, - "scripts": { - "test": "make test-cov" - }, - "licenses": [ - { - "type": "BSD", - "url": "http://github.com/spumko/hoek/raw/master/LICENSE" - } - ], - "readme": "<a href=\"https://github.com/spumko\"><img src=\"https://raw.github.com/spumko/spumko/master/images/from.png\" align=\"right\" /></a>\r\n![hoek Logo](https://raw.github.com/spumko/hoek/master/images/hoek.png)\r\n\r\nGeneral purpose node utilities\r\n\r\n[![Build Status](https://secure.travis-ci.org/spumko/hoek.png)](http://travis-ci.org/spumko/hoek)\r\n\r\n# Table of Contents\r\n\r\n* [Introduction](#introduction \"Introduction\")\r\n* [Object](#object \"Object\")\r\n * [clone](#cloneobj \"clone\")\r\n * [merge](#mergetarget-source-isnulloverride-ismergearrays \"merge\")\r\n * [applyToDefaults](#applytodefaultsdefaults-options \"applyToDefaults\")\r\n * [unique](#uniquearray-key \"unique\")\r\n * [mapToObject](#maptoobjectarray-key \"mapToObject\")\r\n * [intersect](#intersectarray1-array2 \"intersect\")\r\n * [matchKeys](#matchkeysobj-keys \"matchKeys\")\r\n * [flatten](#flattenarray-target \"flatten\")\r\n * [removeKeys](#removekeysobject-keys \"removeKeys\")\r\n * [reach](#reachobj-chain \"reach\")\r\n * [inheritAsync](#inheritasyncself-obj-keys \"inheritAsync\")\r\n * [rename](#renameobj-from-to \"rename\")\r\n* [Timer](#timer \"Timer\")\r\n* [Binary Encoding/Decoding](#binary \"Binary Encoding/Decoding\")\r\n * [base64urlEncode](#binary64urlEncodevalue \"binary64urlEncode\")\r\n * [base64urlDecode](#binary64urlDecodevalue \"binary64urlDecode\")\r\n* [Escaping Characters](#escaped \"Escaping Characters\")\r\n * [escapeHtml](#escapeHtmlstring \"escapeHtml\")\r\n * [escapeHeaderAttribute](#escapeHeaderAttributeattribute \"escapeHeaderAttribute\")\r\n * [escapeRegex](#escapeRegexstring \"escapeRegex\")\r\n* [Errors](#errors \"Errors\")\r\n * [assert](#assertmessage \"assert\")\r\n * [abort](#abortmessage \"abort\")\r\n * [displayStack](#displayStackslice \"displayStack\")\r\n * [callStack](#callStackslice \"callStack\")\r\n * [toss](#tosscondition \"toss\")\r\n* [Load files](#load-files \"Load Files\")\r\n * [loadPackage](#loadPackagedir \"loadpackage\")\r\n * [loadDirModules](#loadDirModulespath-excludefiles-target \"loaddirmodules\")\r\n\r\n\r\n\r\n# Introduction\r\n\r\nThe *Hoek* general purpose node utilities library is used to aid in a variety of manners. It comes with useful methods for Arrays (clone, merge, applyToDefaults), Objects (removeKeys, copy), Asserting and more. \r\n\r\nFor example, to use Hoek to set configuration with default options:\r\n```javascript\r\nvar Hoek = require('hoek');\r\n\r\nvar default = {url : \"www.github.com\", port : \"8000\", debug : true}\r\n\r\nvar config = Hoek.applyToDefaults(default, {port : \"3000\", admin : true});\r\n\r\n// In this case, config would be { url: 'www.github.com', port: '3000', debug: true, admin: true }\r\n```\r\n\r\nUnder each of the sections (such as Array), there are subsections which correspond to Hoek methods. Each subsection will explain how to use the corresponding method. In each js excerpt below, the var Hoek = require('hoek') is omitted for brevity.\r\n\r\n## Object\r\n\r\nHoek provides several helpful methods for objects and arrays.\r\n\r\n### clone(obj)\r\n\r\nThis method is used to clone an object or an array. A *deep copy* is made (duplicates everything, including values that are objects). \r\n\r\n```javascript\r\n\r\nvar nestedObj = {\r\n w: /^something$/ig,\r\n x: {\r\n a: [1, 2, 3],\r\n b: 123456,\r\n c: new Date()\r\n },\r\n y: 'y',\r\n z: new Date()\r\n };\r\n\r\nvar copy = Hoek.clone(nestedObj);\r\n\r\ncopy.x.b = 100;\r\n\r\nconsole.log(copy.y) // results in 'y'\r\nconsole.log(nestedObj.x.b) // results in 123456\r\nconsole.log(copy.x.b) // results in 100\r\n```\r\n\r\n### merge(target, source, isNullOverride, isMergeArrays)\r\nisNullOverride, isMergeArrays default to true\r\n\r\nMerge all the properties of source into target, source wins in conflic, and by default null and undefined from source are applied\r\n\r\n\r\n```javascript\r\n\r\nvar target = {a: 1, b : 2}\r\nvar source = {a: 0, c: 5}\r\nvar source2 = {a: null, c: 5}\r\n\r\nvar targetArray = [1, 2, 3];\r\nvar sourceArray = [4, 5];\r\n\r\nvar newTarget = Hoek.merge(target, source); // results in {a: 0, b: 2, c: 5}\r\nnewTarget = Hoek.merge(target, source2); // results in {a: null, b: 2, c: 5}\r\nnewTarget = Hoek.merge(target, source2, false); // results in {a: 1, b: 2, c: 5}\r\n\r\nnewTarget = Hoek.merge(targetArray, sourceArray) // results in [1, 2, 3, 4, 5]\r\nnewTarget = Hoek.merge(targetArray, sourceArray, true, false) // results in [4, 5]\r\n\r\n\r\n\r\n\r\n```\r\n\r\n### applyToDefaults(defaults, options)\r\n\r\nApply options to a copy of the defaults\r\n\r\n```javascript\r\n\r\nvar defaults = {host: \"localhost\", port: 8000};\r\nvar options = {port: 8080};\r\n\r\nvar config = Hoek.applyToDefaults(defaults, options); // results in {host: \"localhost\", port: 8080};\r\n\r\n\r\n```\r\n\r\n### unique(array, key)\r\n\r\nRemove duplicate items from Array\r\n\r\n```javascript\r\n\r\nvar array = [1, 2, 2, 3, 3, 4, 5, 6];\r\n\r\nvar newArray = Hoek.unique(array); // results in [1,2,3,4,5,6];\r\n\r\narray = [{id: 1}, {id: 1}, {id: 2}];\r\n\r\nnewArray = Hoek.unique(array, \"id\") // results in [{id: 1}, {id: 2}]\r\n\r\n```\r\n\r\n### mapToObject(array, key)\r\n\r\nConvert an Array into an Object\r\n\r\n```javascript\r\n\r\nvar array = [1,2,3];\r\nvar newObject = Hoek.mapToObject(array); // results in [{\"1\": true}, {\"2\": true}, {\"3\": true}]\r\n\r\narray = [{id: 1}, {id: 2}];\r\nnewObject = Hoek.mapToObject(array, \"id\") // results in [{\"id\": 1}, {\"id\": 2}]\r\n\r\n```\r\n### intersect(array1, array2)\r\n\r\nFind the common unique items in two arrays\r\n\r\n```javascript\r\n\r\nvar array1 = [1, 2, 3];\r\nvar array2 = [1, 4, 5];\r\n\r\nvar newArray = Hoek.intersect(array1, array2) // results in [1]\r\n\r\n```\r\n\r\n### matchKeys(obj, keys) \r\n\r\nFind which keys are present\r\n\r\n```javascript\r\n\r\nvar obj = {a: 1, b: 2, c: 3};\r\nvar keys = [\"a\", \"e\"];\r\n\r\nHoek.matchKeys(obj, keys) // returns [\"a\"]\r\n\r\n```\r\n\r\n### flatten(array, target)\r\n\r\nFlatten an array\r\n\r\n```javascript\r\n\r\nvar array = [1, 2, 3];\r\nvar target = [4, 5]; \r\n\r\nvar flattenedArray = Hoek.flatten(array, target) // results in [4, 5, 1, 2, 3];\r\n\r\n```\r\n\r\n### removeKeys(object, keys)\r\n\r\nRemove keys\r\n\r\n```javascript\r\n\r\nvar object = {a: 1, b: 2, c: 3, d: 4};\r\n\r\nvar keys = [\"a\", \"b\"];\r\n\r\nHoek.removeKeys(object, keys) // object is now {c: 3, d: 4}\r\n\r\n```\r\n\r\n### reach(obj, chain)\r\n\r\nConverts an object key chain string to reference\r\n\r\n```javascript\r\n\r\nvar chain = 'a.b.c';\r\nvar obj = {a : {b : { c : 1}}};\r\n\r\nHoek.reach(obj, chain) // returns 1\r\n\r\n```\r\n\r\n### inheritAsync(self, obj, keys) \r\n\r\nInherits a selected set of methods from an object, wrapping functions in asynchronous syntax and catching errors\r\n\r\n```javascript\r\n\r\nvar targetFunc = function () { };\r\n\r\nvar proto = {\r\n a: function () {\r\n return 'a!';\r\n },\r\n b: function () {\r\n return 'b!';\r\n },\r\n c: function () {\r\n throw new Error('c!');\r\n }\r\n };\r\n\r\nvar keys = ['a', 'c'];\r\n\r\nHoek.inheritAsync(targetFunc, proto, ['a', 'c']);\r\n\r\nvar target = new targetFunc();\r\n\r\ntarget.a(function(err, result){console.log(result)} // returns 'a!' \r\n\r\ntarget.c(function(err, result){console.log(result)} // returns undefined\r\n\r\ntarget.b(function(err, result){console.log(result)} // gives error: Object [object Object] has no method 'b'\r\n\r\n```\r\n\r\n### rename(obj, from, to)\r\n\r\nRename a key of an object\r\n\r\n```javascript\r\n\r\nvar obj = {a : 1, b : 2};\r\n\r\nHoek.rename(obj, \"a\", \"c\"); // obj is now {c : 1, b : 2}\r\n\r\n```\r\n\r\n\r\n# Timer\r\n\r\nA Timer object. Initializing a new timer object sets the ts to the number of milliseconds elapsed since 1 January 1970 00:00:00 UTC.\r\n\r\n```javascript\r\n\r\n\r\nexample : \r\n\r\n\r\nvar timerObj = new Hoek.Timer();\r\nconsole.log(\"Time is now: \" + timerObj.ts)\r\nconsole.log(\"Elapsed time from initialization: \" + timerObj.elapsed() + 'milliseconds')\r\n\r\n```\r\n\r\n# Binary Encoding/Decoding\r\n\r\n### base64urlEncode(value)\r\n\r\nEncodes value in Base64 or URL encoding\r\n\r\n### base64urlDecode(value)\r\n\r\nDecodes data in Base64 or URL encoding.\r\n# Escaping Characters\r\n\r\nHoek provides convenient methods for escaping html characters. The escaped characters are as followed:\r\n\r\n```javascript\r\n\r\ninternals.htmlEscaped = {\r\n '&': '&',\r\n '<': '<',\r\n '>': '>',\r\n '\"': '"',\r\n \"'\": ''',\r\n '`': '`'\r\n};\r\n\r\n```\r\n\r\n### escapeHtml(string)\r\n\r\n```javascript\r\n\r\nvar string = '<html> hey </html>';\r\nvar escapedString = Hoek.escapeHtml(string); // returns <html> hey </html>\r\n\r\n```\r\n\r\n### escapeHeaderAttribute(attribute)\r\n\r\nEscape attribute value for use in HTTP header\r\n\r\n```javascript\r\n\r\nvar a = Hoek.escapeHeaderAttribute('I said \"go w\\\\o me\"'); //returns I said \\\"go w\\\\o me\\\"\r\n\r\n\r\n```\r\n\r\n\r\n### escapeRegex(string)\r\n\r\nEscape string for Regex construction\r\n\r\n```javascript\r\n\r\nvar a = Hoek.escapeRegex('4^f$s.4*5+-_?%=#!:@|~\\\\/`\"(>)[<]d{}s,'); // returns 4\\^f\\$s\\.4\\*5\\+\\-_\\?%\\=#\\!\\:@\\|~\\\\\\/`\"\\(>\\)\\[<\\]d\\{\\}s\\,\r\n\r\n\r\n\r\n```\r\n\r\n# Errors\r\n\r\n### assert(message)\r\n\r\n```javascript\r\n\r\nvar a = 1, b =2;\r\n\r\nHoek.assert(a === b, 'a should equal b'); // ABORT: a should equal b\r\n\r\n```\r\n\r\n### abort(message)\r\n\r\nFirst checks if process.env.NODE_ENV === 'test', and if so, throws error message. Otherwise,\r\ndisplays most recent stack and then exits process.\r\n\r\n\r\n\r\n### displayStack(slice)\r\n\r\nDisplays the trace stack\r\n\r\n```javascript\r\n\r\nvar stack = Hoek.displayStack();\r\nconsole.log(stack) // returns something like:\r\n\r\n[ 'null (/Users/user/Desktop/hoek/test.js:4:18)',\r\n 'Module._compile (module.js:449:26)',\r\n 'Module._extensions..js (module.js:467:10)',\r\n 'Module.load (module.js:356:32)',\r\n 'Module._load (module.js:312:12)',\r\n 'Module.runMain (module.js:492:10)',\r\n 'startup.processNextTick.process._tickCallback (node.js:244:9)' ]\r\n\r\n```\r\n\r\n### callStack(slice)\r\n\r\nReturns a trace stack array.\r\n\r\n```javascript\r\n\r\nvar stack = Hoek.callStack();\r\nconsole.log(stack) // returns something like:\r\n\r\n[ [ '/Users/user/Desktop/hoek/test.js', 4, 18, null, false ],\r\n [ 'module.js', 449, 26, 'Module._compile', false ],\r\n [ 'module.js', 467, 10, 'Module._extensions..js', false ],\r\n [ 'module.js', 356, 32, 'Module.load', false ],\r\n [ 'module.js', 312, 12, 'Module._load', false ],\r\n [ 'module.js', 492, 10, 'Module.runMain', false ],\r\n [ 'node.js',\r\n 244,\r\n 9,\r\n 'startup.processNextTick.process._tickCallback',\r\n false ] ]\r\n\r\n\r\n```\r\n\r\n### toss(condition)\r\n\r\ntoss(condition /*, [message], callback */)\r\n\r\nReturn an error as first argument of a callback\r\n\r\n\r\n# Load Files\r\n\r\n### loadPackage(dir)\r\n\r\nLoad and parse package.json process root or given directory\r\n\r\n```javascript\r\n\r\nvar pack = Hoek.loadPackage(); // pack.name === 'hoek'\r\n\r\n```\r\n\r\n### loadDirModules(path, excludeFiles, target) \r\n\r\nLoads modules from a given path; option to exclude files (array).\r\n\r\n\r\n\r\n\r\n", - "readmeFilename": "README.md", - "bugs": { - "url": "https://github.com/spumko/hoek/issues" - }, - "_id": "hoek@0.9.1", - "dist": { - "shasum": "396f2118033eabc93ae5c2cd6ca75f0a89c03592" - }, - "_from": "hoek@0.9.x", - "_resolved": "https://registry.npmjs.org/hoek/-/hoek-0.9.1.tgz" -} diff --git a/deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/test/escaper.js b/deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/test/escaper.js deleted file mode 100644 index 4dddd77dc9d..00000000000 --- a/deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/test/escaper.js +++ /dev/null @@ -1,86 +0,0 @@ -// Load modules
-
-var Lab = require('lab');
-var Hoek = require('../lib');
-
-
-// Declare internals
-
-var internals = {};
-
-
-// Test shortcuts
-
-var expect = Lab.expect;
-var before = Lab.before;
-var after = Lab.after;
-var describe = Lab.experiment;
-var it = Lab.test;
-
-
-describe('Hoek', function () {
-
- describe('#escapeJavaScript', function () {
-
- it('encodes / characters', function (done) {
-
- var encoded = Hoek.escapeJavaScript('<script>alert(1)</script>');
- expect(encoded).to.equal('\\x3cscript\\x3ealert\\x281\\x29\\x3c\\x2fscript\\x3e');
- done();
- });
-
- it('encodes \' characters', function (done) {
-
- var encoded = Hoek.escapeJavaScript('something(\'param\')');
- expect(encoded).to.equal('something\\x28\\x27param\\x27\\x29');
- done();
- });
-
- it('encodes large unicode characters with the correct padding', function (done) {
-
- var encoded = Hoek.escapeJavaScript(String.fromCharCode(500) + String.fromCharCode(1000));
- expect(encoded).to.equal('\\u0500\\u1000');
- done();
- });
-
- it('doesn\'t throw an exception when passed null', function (done) {
-
- var encoded = Hoek.escapeJavaScript(null);
- expect(encoded).to.equal('');
- done();
- });
- });
-
- describe('#escapeHtml', function () {
-
- it('encodes / characters', function (done) {
-
- var encoded = Hoek.escapeHtml('<script>alert(1)</script>');
- expect(encoded).to.equal('<script>alert(1)</script>');
- done();
- });
-
- it('encodes < and > as named characters', function (done) {
-
- var encoded = Hoek.escapeHtml('<script><>');
- expect(encoded).to.equal('<script><>');
- done();
- });
-
- it('encodes large unicode characters', function (done) {
-
- var encoded = Hoek.escapeHtml(String.fromCharCode(500) + String.fromCharCode(1000));
- expect(encoded).to.equal('ǴϨ');
- done();
- });
-
- it('doesn\'t throw an exception when passed null', function (done) {
-
- var encoded = Hoek.escapeHtml(null);
- expect(encoded).to.equal('');
- done();
- });
- });
-});
-
-
diff --git a/deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/test/index.js b/deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/test/index.js deleted file mode 100755 index c40e3ad9a4a..00000000000 --- a/deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/test/index.js +++ /dev/null @@ -1,1078 +0,0 @@ -// Load modules
-
-var Lab = require('lab');
-var Hoek = require('../lib');
-
-
-// Declare internals
-
-var internals = {};
-
-
-// Test shortcuts
-
-var expect = Lab.expect;
-var before = Lab.before;
-var after = Lab.after;
-var describe = Lab.experiment;
-var it = Lab.test;
-
-
-describe('Hoek', function () {
-
- var nestedObj = {
- v: [7,8,9],
- w: /^something$/igm,
- x: {
- a: [1, 2, 3],
- b: 123456,
- c: new Date(),
- d: /hi/igm,
- e: /hello/
- },
- y: 'y',
- z: new Date()
- };
-
- var dupsArray = [nestedObj, { z: 'z' }, nestedObj];
- var reducedDupsArray = [nestedObj, { z: 'z' }];
-
- describe('#clone', function () {
-
- it('should clone a nested object', function (done) {
-
- var a = nestedObj;
- var b = Hoek.clone(a);
-
- expect(a).to.deep.equal(b);
- expect(a.z.getTime()).to.equal(b.z.getTime());
- done();
- });
-
- it('should clone a null object', function (done) {
-
- var b = Hoek.clone(null);
-
- expect(b).to.equal(null);
- done();
- });
-
- it('should not convert undefined properties to null', function (done) {
-
- var obj = { something: undefined };
- var b = Hoek.clone(obj);
-
- expect(typeof b.something).to.equal('undefined');
- done();
- });
-
- it('should not throw on circular reference', function (done) {
-
- var a = {};
- a.x = a;
-
- var test = (function () {
-
- var b = Hoek.clone(a);
- });
-
- expect(test).to.not.throw();
- done();
- });
-
- it('should properly clone circular reference', function (done) {
-
- var x = {
- 'z': new Date()
- };
- x.y = x;
-
- var b = Hoek.clone(x);
- expect(Object.keys(b.y)).to.deep.equal(Object.keys(x))
- expect(b.z).to.not.equal(x.z);
- expect(b.y).to.not.equal(x.y);
- expect(b.y.z).to.not.equal(x.y.z);
- expect(b.y).to.equal(b);
- expect(b.y.y.y.y).to.equal(b);
- done();
- });
-
- it('should properly clone deeply nested object', function (done) {
-
- var a = {
- x: {
- y: {
- a: [1, 2, 3],
- b: 123456,
- c: new Date(),
- d: /hi/igm,
- e: /hello/
- },
- }
- };
-
- var b = Hoek.clone(a);
-
- expect(a).to.deep.equal(b);
- expect(a.x.y.c.getTime()).to.equal(b.x.y.c.getTime());
- done();
- });
-
- it('should properly clone arrays', function (done) {
-
- var a = [1,2,3];
-
- var b = Hoek.clone(a);
-
- expect(a).to.deep.equal(b);
- done();
- });
-
- it('should perform actual copy for shallow keys (no pass by reference)', function (done) {
-
- var x = Hoek.clone(nestedObj);
- var y = Hoek.clone(nestedObj);
-
- // Date
- expect(x.z).to.not.equal(nestedObj.z);
- expect(x.z).to.not.equal(y.z);
-
- // Regex
- expect(x.w).to.not.equal(nestedObj.w);
- expect(x.w).to.not.equal(y.w);
-
- // Array
- expect(x.v).to.not.equal(nestedObj.v);
- expect(x.v).to.not.equal(y.v);
-
- // Immutable(s)
- x.y = 5;
- expect(x.y).to.not.equal(nestedObj.y);
- expect(x.y).to.not.equal(y.y);
-
- done();
- });
-
- it('should perform actual copy for deep keys (no pass by reference)', function (done) {
-
- var x = Hoek.clone(nestedObj);
- var y = Hoek.clone(nestedObj);
-
- expect(x.x.c).to.not.equal(nestedObj.x.c);
- expect(x.x.c).to.not.equal(y.x.c);
-
- expect(x.x.c.getTime()).to.equal(nestedObj.x.c.getTime());
- expect(x.x.c.getTime()).to.equal(y.x.c.getTime());
- done();
- });
-
- it('copies functions with properties', function (done) {
-
- var a = {
- x: function () { return 1; },
- y: {}
- };
- a.x.z = 'string in function';
- a.x.v = function () { return 2; };
- a.y.u = a.x;
-
- var b = Hoek.clone(a);
- expect(b.x()).to.equal(1);
- expect(b.x.v()).to.equal(2);
- expect(b.y.u).to.equal(b.x);
- expect(b.x.z).to.equal('string in function');
- done();
- });
-
- it('should copy a buffer', function(done){
- var tls = {
- key: new Buffer([1,2,3,4,5]),
- cert: new Buffer([1,2,3,4,5,6,10])
- }
-
- copiedTls = Hoek.clone(tls);
- expect(Buffer.isBuffer(copiedTls.key)).to.equal(true);
- expect(JSON.stringify(copiedTls.key)).to.equal(JSON.stringify(tls.key))
- expect(Buffer.isBuffer(copiedTls.cert)).to.equal(true);
- expect(JSON.stringify(copiedTls.cert)).to.equal(JSON.stringify(tls.cert))
- done();
- });
- });
-
- describe('#merge', function () {
-
- it('does not throw if source is null', function (done) {
-
- var a = {};
- var b = null;
- var c = null;
-
- expect(function () {
-
- c = Hoek.merge(a, b);
- }).to.not.throw();
-
- expect(c).to.equal(a);
- done();
- });
-
- it('does not throw if source is undefined', function (done) {
-
- var a = {};
- var b = undefined;
- var c = null;
-
- expect(function () {
-
- c = Hoek.merge(a, b);
- }).to.not.throw();
-
- expect(c).to.equal(a);
- done();
- });
-
- it('throws if source is not an object', function (done) {
-
- expect(function () {
-
- var a = {};
- var b = 0;
-
- Hoek.merge(a, b);
- }).to.throw('Invalid source value: must be null, undefined, or an object');
- done();
- });
-
- it('throws if target is not an object', function (done) {
-
- expect(function () {
-
- var a = 0;
- var b = {};
-
- Hoek.merge(a, b);
- }).to.throw('Invalid target value: must be an object');
- done();
- });
-
- it('throws if target is not an array and source is', function (done) {
-
- expect(function () {
-
- var a = {};
- var b = [1, 2];
-
- Hoek.merge(a, b);
- }).to.throw('Cannot merge array onto an object');
- done();
- });
-
- it('returns the same object when merging arrays', function (done) {
-
- var a = [];
- var b = [1, 2];
-
- expect(Hoek.merge(a, b)).to.equal(a);
- done();
- });
-
- it('should combine an empty object with a non-empty object', function (done) {
-
- var a = {};
- var b = nestedObj;
-
- var c = Hoek.merge(a, b);
- expect(a).to.deep.equal(b);
- expect(c).to.deep.equal(b);
- done();
- });
-
- it('should override values in target', function (done) {
-
- var a = { x: 1, y: 2, z: 3, v: 5, t: 'test', m: 'abc' };
- var b = { x: null, z: 4, v: 0, t: { u: 6 }, m: '123' };
-
- var c = Hoek.merge(a, b);
- expect(c.x).to.equal(null);
- expect(c.y).to.equal(2);
- expect(c.z).to.equal(4);
- expect(c.v).to.equal(0);
- expect(c.m).to.equal('123');
- expect(c.t).to.deep.equal({ u: 6 });
- done();
- });
-
- it('should override values in target (flip)', function (done) {
-
- var a = { x: 1, y: 2, z: 3, v: 5, t: 'test', m: 'abc' };
- var b = { x: null, z: 4, v: 0, t: { u: 6 }, m: '123' };
-
- var d = Hoek.merge(b, a);
- expect(d.x).to.equal(1);
- expect(d.y).to.equal(2);
- expect(d.z).to.equal(3);
- expect(d.v).to.equal(5);
- expect(d.m).to.equal('abc');
- expect(d.t).to.deep.equal('test');
- done();
- });
- });
-
- describe('#applyToDefaults', function () {
-
- var defaults = {
- a: 1,
- b: 2,
- c: {
- d: 3,
- e: [5, 6]
- },
- f: 6,
- g: 'test'
- };
-
- it('should return null if options is false', function (done) {
-
- var result = Hoek.applyToDefaults(defaults, false);
- expect(result).to.equal(null);
- done();
- });
-
- it('should return a copy of defaults if options is true', function (done) {
-
- var result = Hoek.applyToDefaults(defaults, true);
- expect(result).to.deep.equal(result);
- done();
- });
-
- it('should apply object to defaults', function (done) {
-
- var obj = {
- a: null,
- c: {
- e: [4]
- },
- f: 0,
- g: {
- h: 5
- }
- };
-
- var result = Hoek.applyToDefaults(defaults, obj);
- expect(result.c.e).to.deep.equal([4]);
- expect(result.a).to.equal(1);
- expect(result.b).to.equal(2);
- expect(result.f).to.equal(0);
- expect(result.g).to.deep.equal({ h: 5 });
- done();
- });
- });
-
- describe('#unique', function () {
-
- it('should ensure uniqueness within array of objects based on subkey', function (done) {
-
- var a = Hoek.unique(dupsArray, 'x');
- expect(a).to.deep.equal(reducedDupsArray);
- done();
- });
-
- it('removes duplicated without key', function (done) {
-
- expect(Hoek.unique([1, 2, 3, 4, 2, 1, 5])).to.deep.equal([1, 2, 3, 4, 5]);
- done();
- });
- });
-
- describe('#mapToObject', function () {
-
- it('should return null on null array', function (done) {
-
- var a = Hoek.mapToObject(null);
- expect(a).to.equal(null);
- done();
- });
-
- it('should convert basic array to existential object', function (done) {
-
- var keys = [1, 2, 3, 4];
- var a = Hoek.mapToObject(keys);
- for (var i in keys) {
- expect(a[keys[i]]).to.equal(true);
- }
- done();
- });
-
- it('should convert array of objects to existential object', function (done) {
-
- var keys = [{ x: 1 }, { x: 2 }, { x: 3 }];
- var subkey = 'x';
- var a = Hoek.mapToObject(keys, subkey);
- for (var i in keys) {
- expect(a[keys[i][subkey]]).to.equal(true);
- }
- done();
- });
- });
-
- describe('#intersect', function () {
-
- it('should return the common objects of two arrays', function (done) {
-
- var array1 = [1, 2, 3, 4, 4, 5, 5];
- var array2 = [5, 4, 5, 6, 7];
- var common = Hoek.intersect(array1, array2);
- expect(common.length).to.equal(2);
- done();
- });
-
- it('should return just the first common object of two arrays', function (done) {
-
- var array1 = [1, 2, 3, 4, 4, 5, 5];
- var array2 = [5, 4, 5, 6, 7];
- var common = Hoek.intersect(array1, array2, true);
- expect(common).to.equal(5);
- done();
- });
-
- it('should return an empty array if either input is null', function (done) {
-
- expect(Hoek.intersect([1], null).length).to.equal(0);
- expect(Hoek.intersect(null, [1]).length).to.equal(0);
- done();
- });
-
- it('should return the common objects of object and array', function (done) {
-
- var array1 = [1, 2, 3, 4, 4, 5, 5];
- var array2 = [5, 4, 5, 6, 7];
- var common = Hoek.intersect(Hoek.mapToObject(array1), array2);
- expect(common.length).to.equal(2);
- done();
- });
- });
-
- describe('#matchKeys', function () {
-
- it('should match the existing object keys', function (done) {
-
- var obj = {
- a: 1,
- b: 2,
- c: 3,
- d: null
- };
-
- expect(Hoek.matchKeys(obj, ['b', 'c', 'd', 'e'])).to.deep.equal(['b', 'c', 'd']);
- done();
- });
- });
-
- describe('#flatten', function () {
-
- it('should return a flat array', function (done) {
-
- var result = Hoek.flatten([1, 2, [3, 4, [5, 6], [7], 8], [9], [10, [11, 12]], 13]);
- expect(result.length).to.equal(13);
- expect(result).to.deep.equal([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]);
- done();
- });
- });
-
- describe('#removeKeys', function () {
-
- var objWithHiddenKeys = {
- location: {
- name: 'San Bruno'
- },
- company: {
- name: '@WalmartLabs'
- }
- };
-
- it('should delete params with definition\'s hide set to true', function (done) {
-
- var a = Hoek.removeKeys(objWithHiddenKeys, ['location']);
- expect(objWithHiddenKeys.location).to.not.exist;
- expect(objWithHiddenKeys.company).to.exist;
- done();
- });
- });
-
- describe('#reach', function () {
-
- var obj = {
- a: {
- b: {
- c: {
- d: 1,
- e: 2
- },
- f: 'hello'
- },
- g: {
- h: 3
- }
- },
- i: function () { }
- };
-
- it('returns a valid member', function (done) {
-
- expect(Hoek.reach(obj, 'a.b.c.d')).to.equal(1);
- done();
- });
-
- it('returns null on null object', function (done) {
-
- expect(Hoek.reach(null, 'a.b.c.d')).to.not.exist;
- done();
- });
-
- it('returns null on missing member', function (done) {
-
- expect(Hoek.reach(obj, 'a.b.c.d.x')).to.not.exist;
- done();
- });
-
- it('returns null on invalid member', function (done) {
-
- expect(Hoek.reach(obj, 'a.b.c.d-.x')).to.not.exist;
- done();
- });
-
- it('returns function member', function (done) {
-
- expect(typeof Hoek.reach(obj, 'i')).to.equal('function');
- done();
- });
- });
-
- describe('#inheritAsync', function () {
-
- it('should inherit selected methods and wrap in async call', function (done) {
-
- var proto = {
- a: function () {
- return 'a!';
- },
- b: function () {
- return 'b!';
- },
- c: function () {
- throw new Error('c!');
- }
- };
-
- var targetFunc = function () { };
- targetFunc.prototype.c = function () {
-
- return 'oops';
- };
-
- Hoek.inheritAsync(targetFunc, proto, ['a', 'c']);
- var target = new targetFunc();
-
- expect(typeof target.a).to.equal('function');
- expect(typeof target.c).to.equal('function');
- expect(target.b).to.not.exist;
-
- target.a(function (err, result) {
-
- expect(err).to.not.exist;
- expect(result).to.equal('a!');
-
- target.c(function (err, result) {
-
- expect(result).to.not.exist;
- expect(err.message).to.equal('c!');
- done();
- });
- });
- });
- });
-
- describe('#callStack', function () {
-
- it('should return the full call stack', function (done) {
-
- var stack = Hoek.callStack();
- expect(stack[0][0]).to.contain('index.js');
- expect(stack[0][2]).to.equal(30);
- done();
- });
- });
-
- describe('#displayStack ', function () {
-
- it('should return the full call stack for display', function (done) {
-
- var stack = Hoek.displayStack();
- expect(stack[0]).to.contain('test/index.js:');
- done();
- });
-
- it('should include constructor functions correctly', function (done) {
-
- var Something = function (next) {
-
- next();
- };
-
- var something = new Something(function () {
-
- var stack = Hoek.displayStack();
- expect(stack[1]).to.contain('new Something');
- done();
- });
- });
- });
-
- describe('#abort', function () {
-
- it('should exit process when not in test mode', function (done) {
-
- var env = process.env.NODE_ENV;
- var write = process.stdout.write;
- var exit = process.exit;
-
- process.env.NODE_ENV = 'nottatest';
- process.stdout.write = function () { };
- process.exit = function (state) {
-
- process.exit = exit;
- process.env.NODE_ENV = env;
- process.stdout.write = write;
-
- expect(state).to.equal(1);
- done();
- };
-
- Hoek.abort('Boom');
- });
-
- it('should throw when not in test mode and abortThrow is true', function (done) {
-
- var env = process.env.NODE_ENV;
- process.env.NODE_ENV = 'nottatest';
- Hoek.abortThrow = true;
-
- var fn = function () {
-
- Hoek.abort('my error message');
- };
-
- expect(fn).to.throw('my error message');
- Hoek.abortThrow = false;
- process.env.NODE_ENV = env;
-
- done();
- });
-
-
- it('should respect hideStack argument', function (done) {
-
- var env = process.env.NODE_ENV;
- var write = process.stdout.write;
- var exit = process.exit;
- var output = '';
-
- process.exit = function () { };
- process.env.NODE_ENV = '';
- process.stdout.write = function (message) {
-
- output = message;
- };
-
- Hoek.abort('my error message', true);
-
- process.env.NODE_ENV = env;
- process.stdout.write = write;
- process.exit = exit;
-
- expect(output).to.equal('ABORT: my error message\n\t\n');
-
- done();
- });
-
- it('should default to showing stack', function (done) {
-
- var env = process.env.NODE_ENV;
- var write = process.stdout.write;
- var exit = process.exit;
- var output = '';
-
- process.exit = function () { };
- process.env.NODE_ENV = '';
- process.stdout.write = function (message) {
-
- output = message;
- };
-
- Hoek.abort('my error message');
-
- process.env.NODE_ENV = env;
- process.stdout.write = write;
- process.exit = exit;
-
- expect(output).to.contain('index.js');
-
- done();
- });
- });
-
- describe('#assert', function () {
-
- it('should throw an Error when using assert in a test', function (done) {
-
- var fn = function () {
-
- Hoek.assert(false, 'my error message');
- };
-
- expect(fn).to.throw('my error message');
- done();
- });
-
- it('should throw an Error when using assert in a test with no message', function (done) {
-
- var fn = function () {
-
- Hoek.assert(false);
- };
-
- expect(fn).to.throw('Unknown error');
- done();
- });
-
- it('should throw an Error when using assert in a test with multipart message', function (done) {
-
- var fn = function () {
-
- Hoek.assert(false, 'This', 'is', 'my message');
- };
-
- expect(fn).to.throw('This is my message');
- done();
- });
-
- it('should throw an Error when using assert in a test with object message', function (done) {
-
- var fn = function () {
-
- Hoek.assert(false, 'This', 'is', { spinal: 'tap' });
- };
-
- expect(fn).to.throw('This is {"spinal":"tap"}');
- done();
- });
-
- it('should throw an Error when using assert in a test with error object message', function (done) {
-
- var fn = function () {
-
- Hoek.assert(false, new Error('This is spinal tap'));
- };
-
- expect(fn).to.throw('This is spinal tap');
- done();
- });
- });
-
- describe('#loadDirModules', function () {
-
- it('should load modules from directory', function (done) {
-
- var target = {};
- Hoek.loadDirModules(__dirname + '/modules', ['test2'], target);
- expect(target.Test1.x).to.equal(1);
- expect(target.Test2).to.not.exist;
- expect(target.Test3.z).to.equal(3);
- done();
- });
-
- it('should list modules from directory into function', function (done) {
-
- var target = {};
- Hoek.loadDirModules(__dirname + '/modules', ['test2'], function (path, name, capName) {
-
- target[name] = capName;
- });
-
- expect(target.test1).to.equal('Test1');
- expect(target.test2).to.not.exist;
- expect(target.test3).to.equal('Test3');
- done();
- });
- });
-
- describe('#rename', function () {
-
- it('should rename object key', function (done) {
-
- var a = { b: 'c' };
- Hoek.rename(a, 'b', 'x');
- expect(a.b).to.not.exist;
- expect(a.x).to.equal('c');
- done();
- });
- });
-
- describe('Timer', function () {
-
- it('should return time elapsed', function (done) {
-
- var timer = new Hoek.Timer();
- setTimeout(function () {
-
- expect(timer.elapsed()).to.be.above(9);
- done();
- }, 12);
- });
- });
-
- describe('#loadPackage', function () {
-
- it('should', function (done) {
-
- var pack = Hoek.loadPackage();
- expect(pack.name).to.equal('hoek');
- done();
- });
- });
-
- describe('#escapeRegex', function () {
-
- it('should escape all special regular expression characters', function (done) {
-
- var a = Hoek.escapeRegex('4^f$s.4*5+-_?%=#!:@|~\\/`"(>)[<]d{}s,');
- expect(a).to.equal('4\\^f\\$s\\.4\\*5\\+\\-_\\?%\\=#\\!\\:@\\|~\\\\\\/`"\\(>\\)\\[<\\]d\\{\\}s\\,');
- done();
- });
- });
-
- describe('#toss', function () {
-
- it('should call callback with new error', function (done) {
-
- var callback = function (err) {
-
- expect(err).to.exist;
- expect(err.message).to.equal('bug');
- done();
- };
-
- Hoek.toss(true, 'feature', callback);
- Hoek.toss(false, 'bug', callback);
- });
-
- it('should call callback with new error and no message', function (done) {
-
- Hoek.toss(false, function (err) {
-
- expect(err).to.exist;
- expect(err.message).to.equal('');
- done();
- });
- });
-
- it('should call callback with error condition', function (done) {
-
- Hoek.toss(new Error('boom'), function (err) {
-
- expect(err).to.exist;
- expect(err.message).to.equal('boom');
- done();
- });
- });
-
- it('should call callback with new error using message with error condition', function (done) {
-
- Hoek.toss(new Error('ka'), 'boom', function (err) {
-
- expect(err).to.exist;
- expect(err.message).to.equal('boom');
- done();
- });
- });
-
- it('should call callback with new error using passed error with error condition', function (done) {
-
- Hoek.toss(new Error('ka'), new Error('boom'), function (err) {
-
- expect(err).to.exist;
- expect(err.message).to.equal('boom');
- done();
- });
- });
- });
-
- describe('Base64Url', function () {
-
- var base64str = 'AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0-P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn-AgYKDhIWGh4iJiouMjY6PkJGSk5SVlpeYmZqbnJ2en6ChoqOkpaanqKmqq6ytrq-wsbKztLW2t7i5uru8vb6_wMHCw8TFxsfIycrLzM3Oz9DR0tPU1dbX2Nna29zd3t_g4eLj5OXm5-jp6uvs7e7v8PHy8_T19vf4-fr7_P3-_w';
- var str = unescape('%00%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%20%21%22%23%24%25%26%27%28%29*+%2C-./0123456789%3A%3B%3C%3D%3E%3F@ABCDEFGHIJKLMNOPQRSTUVWXYZ%5B%5C%5D%5E_%60abcdefghijklmnopqrstuvwxyz%7B%7C%7D%7E%7F%80%81%82%83%84%85%86%87%88%89%8A%8B%8C%8D%8E%8F%90%91%92%93%94%95%96%97%98%99%9A%9B%9C%9D%9E%9F%A0%A1%A2%A3%A4%A5%A6%A7%A8%A9%AA%AB%AC%AD%AE%AF%B0%B1%B2%B3%B4%B5%B6%B7%B8%B9%BA%BB%BC%BD%BE%BF%C0%C1%C2%C3%C4%C5%C6%C7%C8%C9%CA%CB%CC%CD%CE%CF%D0%D1%D2%D3%D4%D5%D6%D7%D8%D9%DA%DB%DC%DD%DE%DF%E0%E1%E2%E3%E4%E5%E6%E7%E8%E9%EA%EB%EC%ED%EE%EF%F0%F1%F2%F3%F4%F5%F6%F7%F8%F9%FA%FB%FC%FD%FE%FF');
-
- describe('#base64urlEncode', function () {
-
- it('should base64 URL-safe a string', function (done) {
-
- expect(Hoek.base64urlEncode(str)).to.equal(base64str);
- done();
- });
- });
-
- describe('#base64urlDecode', function () {
-
- it('should un-base64 URL-safe a string', function (done) {
-
- expect(Hoek.base64urlDecode(base64str)).to.equal(str);
- done();
- });
-
- it('should return error on undefined input', function (done) {
-
- expect(Hoek.base64urlDecode().message).to.exist;
- done();
- });
-
- it('should return error on invalid input', function (done) {
-
- expect(Hoek.base64urlDecode('*').message).to.exist;
- done();
- });
- });
- });
-
- describe('#escapeHeaderAttribute', function () {
-
- it('should not alter ascii values', function (done) {
-
- var a = Hoek.escapeHeaderAttribute('My Value');
- expect(a).to.equal('My Value');
- done();
- });
-
- it('should escape all special HTTP header attribute characters', function (done) {
-
- var a = Hoek.escapeHeaderAttribute('I said go!!!#"' + String.fromCharCode(92));
- expect(a).to.equal('I said go!!!#\\"\\\\');
- done();
- });
-
- it('should throw on large unicode characters', function (done) {
-
- var fn = function () {
-
- Hoek.escapeHeaderAttribute('this is a test' + String.fromCharCode(500) + String.fromCharCode(300));
- };
-
- expect(fn).to.throw(Error);
- done();
- });
-
- it('should throw on CRLF to prevent response splitting', function (done) {
-
- var fn = function () {
-
- Hoek.escapeHeaderAttribute('this is a test\r\n');
- };
-
- expect(fn).to.throw(Error);
- done();
- });
- });
-
- describe('#escapeHtml', function () {
-
- it('should escape all special HTML characters', function (done) {
-
- var a = Hoek.escapeHtml('&<>"\'`');
- expect(a).to.equal('&<>"'`');
- done();
- });
-
- it('should return empty string on falsy input', function (done) {
-
- var a = Hoek.escapeHtml('');
- expect(a).to.equal('');
- done();
- });
-
- it('should return unchanged string on no reserved input', function (done) {
-
- var a = Hoek.escapeHtml('abc');
- expect(a).to.equal('abc');
- done();
- });
- });
-
- describe('#printEvent', function () {
-
- it('outputs event as string', function (done) {
-
- var event = {
- timestamp: (new Date(2013, 1, 1, 6, 30, 45, 123)).getTime(),
- tags: ['a', 'b', 'c'],
- data: { some: 'data' }
- };
-
- Hoek.consoleFunc = function (string) {
-
- Hoek.consoleFunc = console.log;
- expect(string).to.equal('130201/063045.123, a, {"some":"data"}');
- done();
- };
-
- Hoek.printEvent(event);
- });
-
- it('outputs JSON error', function (done) {
-
- var event = {
- timestamp: (new Date(2013, 1, 1, 6, 30, 45, 123)).getTime(),
- tags: ['a', 'b', 'c'],
- data: { some: 'data' }
- };
-
- event.data.a = event.data;
-
- Hoek.consoleFunc = function (string) {
-
- Hoek.consoleFunc = console.log;
- expect(string).to.equal('130201/063045.123, a, JSON Error: Converting circular structure to JSON');
- done();
- };
-
- Hoek.printEvent(event);
- });
- });
-
- describe('#nextTick', function () {
-
- it('calls the provided callback on nextTick', function (done) {
-
- var a = 0;
-
- var inc = function (step, next) {
-
- a += step;
- next();
- };
-
- var ticked = Hoek.nextTick(inc);
-
- ticked(5, function () {
-
- expect(a).to.equal(6);
- done();
- });
-
- expect(a).to.equal(0);
- inc(1, function () {
-
- expect(a).to.equal(1);
- });
- });
- });
-});
-
diff --git a/deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/test/modules/test1.js b/deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/test/modules/test1.js deleted file mode 100755 index 3f41e601e54..00000000000 --- a/deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/test/modules/test1.js +++ /dev/null @@ -1 +0,0 @@ -exports.x = 1;
diff --git a/deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/test/modules/test2.js b/deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/test/modules/test2.js deleted file mode 100755 index 38556b274d3..00000000000 --- a/deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/test/modules/test2.js +++ /dev/null @@ -1 +0,0 @@ -exports.y = 2;
diff --git a/deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/test/modules/test3.js b/deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/test/modules/test3.js deleted file mode 100755 index 436b860b807..00000000000 --- a/deps/npm/node_modules/request/node_modules/hawk/node_modules/boom/node_modules/hoek/test/modules/test3.js +++ /dev/null @@ -1 +0,0 @@ -exports.z = 3;
diff --git a/deps/npm/node_modules/request/node_modules/hawk/node_modules/cryptiles/.npmignore b/deps/npm/node_modules/request/node_modules/hawk/node_modules/cryptiles/.npmignore index 77ba16cb055..b3bb5176305 100644 --- a/deps/npm/node_modules/request/node_modules/hawk/node_modules/cryptiles/.npmignore +++ b/deps/npm/node_modules/request/node_modules/hawk/node_modules/cryptiles/.npmignore @@ -1,18 +1,18 @@ -.idea -*.iml -npm-debug.log -dump.rdb -node_modules -results.tap -results.xml -npm-shrinkwrap.json -config.json -.DS_Store -*/.DS_Store -*/*/.DS_Store -._* -*/._* -*/*/._* -coverage.* -lib-cov - +.idea
+*.iml
+npm-debug.log
+dump.rdb
+node_modules
+results.tap
+results.xml
+npm-shrinkwrap.json
+config.json
+.DS_Store
+*/.DS_Store
+*/*/.DS_Store
+._*
+*/._*
+*/*/._*
+coverage.*
+lib-cov
+
diff --git a/deps/npm/node_modules/request/node_modules/hawk/node_modules/cryptiles/.travis.yml b/deps/npm/node_modules/request/node_modules/hawk/node_modules/cryptiles/.travis.yml index 047f7e3d5e1..40ca59eeebd 100755 --- a/deps/npm/node_modules/request/node_modules/hawk/node_modules/cryptiles/.travis.yml +++ b/deps/npm/node_modules/request/node_modules/hawk/node_modules/cryptiles/.travis.yml @@ -1,5 +1,5 @@ -language: node_js - -node_js: - - 0.10 - +language: node_js
+
+node_js:
+ - 0.10
+
diff --git a/deps/npm/node_modules/request/node_modules/hawk/node_modules/cryptiles/lib/index.js b/deps/npm/node_modules/request/node_modules/hawk/node_modules/cryptiles/lib/index.js index 4a377368154..dcf2bc38ffd 100755 --- a/deps/npm/node_modules/request/node_modules/hawk/node_modules/cryptiles/lib/index.js +++ b/deps/npm/node_modules/request/node_modules/hawk/node_modules/cryptiles/lib/index.js @@ -45,6 +45,12 @@ exports.randomBits = function (bits) { exports.fixedTimeComparison = function (a, b) { + if (typeof a !== 'string' || + typeof b !== 'string') { + + return false; + } + var mismatch = (a.length === b.length ? 0 : 1); if (mismatch) { b = a; diff --git a/deps/npm/node_modules/request/node_modules/hawk/node_modules/cryptiles/package.json b/deps/npm/node_modules/request/node_modules/hawk/node_modules/cryptiles/package.json index c3673dd7789..c4aee15f013 100755 --- a/deps/npm/node_modules/request/node_modules/hawk/node_modules/cryptiles/package.json +++ b/deps/npm/node_modules/request/node_modules/hawk/node_modules/cryptiles/package.json @@ -1,7 +1,7 @@ { "name": "cryptiles", "description": "General purpose crypto utilities", - "version": "0.2.1", + "version": "0.2.2", "author": { "name": "Eran Hammer", "email": "eran@hueniverse.com", @@ -42,6 +42,6 @@ "bugs": { "url": "https://github.com/hueniverse/cryptiles/issues" }, - "_id": "cryptiles@0.2.1", + "_id": "cryptiles@0.2.2", "_from": "cryptiles@0.2.x" } diff --git a/deps/npm/node_modules/request/node_modules/hawk/node_modules/cryptiles/test/index.js b/deps/npm/node_modules/request/node_modules/hawk/node_modules/cryptiles/test/index.js index 0d6b73c89a1..58aaa70b310 100755 --- a/deps/npm/node_modules/request/node_modules/hawk/node_modules/cryptiles/test/index.js +++ b/deps/npm/node_modules/request/node_modules/hawk/node_modules/cryptiles/test/index.js @@ -89,6 +89,12 @@ describe('Cryptiles', function () { expect(Cryptiles.fixedTimeComparison(a + 'x', a + 'y')).to.equal(false); done(); }); + + it('should return false when not a string', function (done) { + + expect(Cryptiles.fixedTimeComparison('x', null)).to.equal(false); + done(); + }); }); }); diff --git a/deps/npm/node_modules/request/node_modules/hawk/node_modules/hoek/.travis.yml b/deps/npm/node_modules/request/node_modules/hawk/node_modules/hoek/.travis.yml index 047f7e3d5e1..40ca59eeebd 100755 --- a/deps/npm/node_modules/request/node_modules/hawk/node_modules/hoek/.travis.yml +++ b/deps/npm/node_modules/request/node_modules/hawk/node_modules/hoek/.travis.yml @@ -1,5 +1,5 @@ -language: node_js - -node_js: - - 0.10 - +language: node_js
+
+node_js:
+ - 0.10
+
diff --git a/deps/npm/node_modules/request/node_modules/hawk/node_modules/hoek/LICENSE b/deps/npm/node_modules/request/node_modules/hawk/node_modules/hoek/LICENSE index 87c1f4e11fe..394adcff2ed 100755 --- a/deps/npm/node_modules/request/node_modules/hawk/node_modules/hoek/LICENSE +++ b/deps/npm/node_modules/request/node_modules/hawk/node_modules/hoek/LICENSE @@ -1,33 +1,33 @@ -Copyright (c) 2011-2013, Walmart. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of Walmart nor the - names of its contributors may be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL WALMART BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - - * * * - - -Portions of this project were initially based on Postmile, Copyright (c) 2011, Yahoo Inc. -Postmile is published at https://github.com/yahoo/postmile and its licensing terms are -published at https://github.com/yahoo/postmile/blob/master/LICENSE. - +Copyright (c) 2011-2013, Walmart.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of Walmart nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL WALMART BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+ * * *
+
+
+Portions of this project were initially based on Postmile, Copyright (c) 2011, Yahoo Inc.
+Postmile is published at https://github.com/yahoo/postmile and its licensing terms are
+published at https://github.com/yahoo/postmile/blob/master/LICENSE.
+
diff --git a/deps/npm/node_modules/request/node_modules/hawk/node_modules/hoek/Makefile b/deps/npm/node_modules/request/node_modules/hawk/node_modules/hoek/Makefile index 48ee48e73fa..e605d6c049d 100755 --- a/deps/npm/node_modules/request/node_modules/hawk/node_modules/hoek/Makefile +++ b/deps/npm/node_modules/request/node_modules/hawk/node_modules/hoek/Makefile @@ -1,10 +1,10 @@ -test: - @./node_modules/.bin/lab -test-cov: - @./node_modules/.bin/lab -r threshold -t 100 -test-cov-html: - @./node_modules/.bin/lab -r html -o coverage.html -complexity: - @./node_modules/.bin/cr -o complexity.md -f markdown lib - -.PHONY: test test-cov test-cov-html complexity
\ No newline at end of file +test:
+ @node node_modules/lab/bin/lab
+test-cov:
+ @node node_modules/lab/bin/lab -r threshold -t 100
+test-cov-html:
+ @node node_modules/lab/bin/lab -r html -o coverage.html
+complexity:
+ @node node_modules/complexity-report/src/cli.js -o complexity.md -f markdown lib
+
+.PHONY: test test-cov test-cov-html complexity
diff --git a/deps/npm/node_modules/request/node_modules/hawk/node_modules/hoek/lib/escape.js b/deps/npm/node_modules/request/node_modules/hawk/node_modules/hoek/lib/escape.js index e5a47708a9a..666b3dc8206 100755 --- a/deps/npm/node_modules/request/node_modules/hawk/node_modules/hoek/lib/escape.js +++ b/deps/npm/node_modules/request/node_modules/hawk/node_modules/hoek/lib/escape.js @@ -1,132 +1,132 @@ -// Declare internals - -var internals = {}; - - -exports.escapeJavaScript = function (input) { - - if (!input) { - return ''; - } - - var escaped = ''; - - for (var i = 0, il = input.length; i < il; ++i) { - - var charCode = input.charCodeAt(i); - - if (internals.isSafe(charCode)) { - escaped += input[i]; - } - else { - escaped += internals.escapeJavaScriptChar(charCode); - } - } - - return escaped; -}; - - -exports.escapeHtml = function (input) { - - if (!input) { - return ''; - } - - var escaped = ''; - - for (var i = 0, il = input.length; i < il; ++i) { - - var charCode = input.charCodeAt(i); - - if (internals.isSafe(charCode)) { - escaped += input[i]; - } - else { - escaped += internals.escapeHtmlChar(charCode); - } - } - - return escaped; -}; - - -internals.escapeJavaScriptChar = function (charCode) { - - if (charCode >= 256) { - return '\\u' + internals.padLeft('' + charCode, 4); - } - - var hexValue = new Buffer(String.fromCharCode(charCode), 'ascii').toString('hex'); - return '\\x' + internals.padLeft(hexValue, 2); -}; - - -internals.escapeHtmlChar = function (charCode) { - - var namedEscape = internals.namedHtml[charCode]; - if (typeof namedEscape !== 'undefined') { - return namedEscape; - } - - if (charCode >= 256) { - return '&#' + charCode + ';'; - } - - var hexValue = new Buffer(String.fromCharCode(charCode), 'ascii').toString('hex'); - return '&#x' + internals.padLeft(hexValue, 2) + ';'; -}; - - -internals.padLeft = function (str, len) { - - while (str.length < len) { - str = '0' + str; - } - - return str; -}; - - -internals.isSafe = function (charCode) { - - return (typeof internals.safeCharCodes[charCode] !== 'undefined'); -}; - - -internals.namedHtml = { - '38': '&', - '60': '<', - '62': '>', - '34': '"', - '160': ' ', - '162': '¢', - '163': '£', - '164': '¤', - '169': '©', - '174': '®' -}; - - -internals.safeCharCodes = (function () { - - var safe = {}; - - for (var i = 32; i < 123; ++i) { - - if ((i >= 97 && i <= 122) || // a-z - (i >= 65 && i <= 90) || // A-Z - (i >= 48 && i <= 57) || // 0-9 - i === 32 || // space - i === 46 || // . - i === 44 || // , - i === 45 || // - - i === 58 || // : - i === 95) { // _ - - safe[i] = null; - } - } - - return safe; +// Declare internals
+
+var internals = {};
+
+
+exports.escapeJavaScript = function (input) {
+
+ if (!input) {
+ return '';
+ }
+
+ var escaped = '';
+
+ for (var i = 0, il = input.length; i < il; ++i) {
+
+ var charCode = input.charCodeAt(i);
+
+ if (internals.isSafe(charCode)) {
+ escaped += input[i];
+ }
+ else {
+ escaped += internals.escapeJavaScriptChar(charCode);
+ }
+ }
+
+ return escaped;
+};
+
+
+exports.escapeHtml = function (input) {
+
+ if (!input) {
+ return '';
+ }
+
+ var escaped = '';
+
+ for (var i = 0, il = input.length; i < il; ++i) {
+
+ var charCode = input.charCodeAt(i);
+
+ if (internals.isSafe(charCode)) {
+ escaped += input[i];
+ }
+ else {
+ escaped += internals.escapeHtmlChar(charCode);
+ }
+ }
+
+ return escaped;
+};
+
+
+internals.escapeJavaScriptChar = function (charCode) {
+
+ if (charCode >= 256) {
+ return '\\u' + internals.padLeft('' + charCode, 4);
+ }
+
+ var hexValue = new Buffer(String.fromCharCode(charCode), 'ascii').toString('hex');
+ return '\\x' + internals.padLeft(hexValue, 2);
+};
+
+
+internals.escapeHtmlChar = function (charCode) {
+
+ var namedEscape = internals.namedHtml[charCode];
+ if (typeof namedEscape !== 'undefined') {
+ return namedEscape;
+ }
+
+ if (charCode >= 256) {
+ return '&#' + charCode + ';';
+ }
+
+ var hexValue = new Buffer(String.fromCharCode(charCode), 'ascii').toString('hex');
+ return '&#x' + internals.padLeft(hexValue, 2) + ';';
+};
+
+
+internals.padLeft = function (str, len) {
+
+ while (str.length < len) {
+ str = '0' + str;
+ }
+
+ return str;
+};
+
+
+internals.isSafe = function (charCode) {
+
+ return (typeof internals.safeCharCodes[charCode] !== 'undefined');
+};
+
+
+internals.namedHtml = {
+ '38': '&',
+ '60': '<',
+ '62': '>',
+ '34': '"',
+ '160': ' ',
+ '162': '¢',
+ '163': '£',
+ '164': '¤',
+ '169': '©',
+ '174': '®'
+};
+
+
+internals.safeCharCodes = (function () {
+
+ var safe = {};
+
+ for (var i = 32; i < 123; ++i) {
+
+ if ((i >= 97 && i <= 122) || // a-z
+ (i >= 65 && i <= 90) || // A-Z
+ (i >= 48 && i <= 57) || // 0-9
+ i === 32 || // space
+ i === 46 || // .
+ i === 44 || // ,
+ i === 45 || // -
+ i === 58 || // :
+ i === 95) { // _
+
+ safe[i] = null;
+ }
+ }
+
+ return safe;
}());
\ No newline at end of file diff --git a/deps/npm/node_modules/request/node_modules/hawk/node_modules/hoek/lib/index.js b/deps/npm/node_modules/request/node_modules/hawk/node_modules/hoek/lib/index.js index ebe5da9b9ea..806260d25eb 100755 --- a/deps/npm/node_modules/request/node_modules/hawk/node_modules/hoek/lib/index.js +++ b/deps/npm/node_modules/request/node_modules/hawk/node_modules/hoek/lib/index.js @@ -70,16 +70,16 @@ exports.merge = function (target, source, isNullOverride /* = true */, isMergeAr target.length = 0; // Must not change target assignment
}
- source.forEach(function (item) {
-
- target.push(item);
- });
+ for (var i = 0, il = source.length; i < il; ++i) {
+ target.push(source[i]);
+ }
return target;
}
- Object.keys(source).forEach(function (key) {
-
+ var keys = Object.keys(source);
+ for (var k = 0, kl = keys.length; k < kl; ++k) {
+ var key = keys[k];
var value = source[key];
if (value &&
typeof value === 'object') {
@@ -101,7 +101,7 @@ exports.merge = function (target, source, isNullOverride /* = true */, isMergeAr target[key] = value;
}
}
- });
+ }
return target;
};
@@ -174,7 +174,7 @@ exports.mapToObject = function (array, key) { // Find the common unique items in two arrays
-exports.intersect = function (array1, array2) {
+exports.intersect = function (array1, array2, justFirst) {
if (!array1 || !array2) {
return [];
@@ -185,12 +185,16 @@ exports.intersect = function (array1, array2) { var found = {};
for (var i = 0, il = array2.length; i < il; ++i) {
if (hash[array2[i]] && !found[array2[i]]) {
+ if (justFirst) {
+ return array2[i];
+ }
+
common.push(array2[i]);
found[array2[i]] = true;
}
}
- return common;
+ return (justFirst ? null : common);
};
@@ -243,12 +247,11 @@ exports.reach = function (obj, chain) { var path = chain.split('.');
var ref = obj;
- path.forEach(function (level) {
-
+ for (var i = 0, il = path.length; i < il; ++i) {
if (ref) {
- ref = ref[level];
+ ref = ref[path[i]];
}
- });
+ }
return ref;
};
@@ -291,10 +294,10 @@ exports.inheritAsync = function (self, obj, keys) { exports.formatStack = function (stack) {
var trace = [];
- stack.forEach(function (item) {
-
+ for (var i = 0, il = stack.length; i < il; ++i) {
+ var item = stack[i];
trace.push([item.getFileName(), item.getLineNumber(), item.getColumnNumber(), item.getFunctionName(), item.isConstructor()]);
- });
+ }
return trace;
};
@@ -303,10 +306,11 @@ exports.formatStack = function (stack) { exports.formatTrace = function (trace) {
var display = [];
- trace.forEach(function (row) {
+ for (var i = 0, il = trace.length; i < il; ++i) {
+ var row = trace[i];
display.push((row[4] ? 'new ' : '') + row[3] + ' (' + row[0] + ':' + row[1] + ':' + row[2] + ')');
- });
+ }
return display;
};
@@ -386,8 +390,9 @@ exports.loadDirModules = function (path, excludeFiles, target) { // target( exclude[excludeFiles[i] + '.js'] = true;
}
- Fs.readdirSync(path).forEach(function (filename) {
-
+ var files = Fs.readdirSync(path);
+ for (i = 0, il = files.length; i < il; ++i) {
+ var filename = files[i];
if (/\.js$/.test(filename) &&
!exclude[filename]) {
@@ -401,7 +406,7 @@ exports.loadDirModules = function (path, excludeFiles, target) { // target( target(path + '/' + name, name, capName);
}
}
- });
+ }
};
diff --git a/deps/npm/node_modules/request/node_modules/hawk/node_modules/hoek/package.json b/deps/npm/node_modules/request/node_modules/hawk/node_modules/hoek/package.json index 8ef9bace7fe..06e082b21ee 100755 --- a/deps/npm/node_modules/request/node_modules/hawk/node_modules/hoek/package.json +++ b/deps/npm/node_modules/request/node_modules/hawk/node_modules/hoek/package.json @@ -1,7 +1,7 @@ { "name": "hoek", "description": "General purpose node utilities", - "version": "0.8.5", + "version": "0.9.1", "author": { "name": "Eran Hammer", "email": "eran@hueniverse.com", @@ -43,6 +43,6 @@ "bugs": { "url": "https://github.com/spumko/hoek/issues" }, - "_id": "hoek@0.8.5", - "_from": "hoek@0.8.x" + "_id": "hoek@0.9.1", + "_from": "hoek@0.9.x" } diff --git a/deps/npm/node_modules/request/node_modules/hawk/node_modules/hoek/test/escaper.js b/deps/npm/node_modules/request/node_modules/hawk/node_modules/hoek/test/escaper.js index 4d1d67ac777..4dddd77dc9d 100644 --- a/deps/npm/node_modules/request/node_modules/hawk/node_modules/hoek/test/escaper.js +++ b/deps/npm/node_modules/request/node_modules/hawk/node_modules/hoek/test/escaper.js @@ -1,86 +1,86 @@ -// Load modules - -var Lab = require('lab'); -var Hoek = require('../lib'); - - -// Declare internals - -var internals = {}; - - -// Test shortcuts - -var expect = Lab.expect; -var before = Lab.before; -var after = Lab.after; -var describe = Lab.experiment; -var it = Lab.test; - - -describe('Hoek', function () { - - describe('#escapeJavaScript', function () { - - it('encodes / characters', function (done) { - - var encoded = Hoek.escapeJavaScript('<script>alert(1)</script>'); - expect(encoded).to.equal('\\x3cscript\\x3ealert\\x281\\x29\\x3c\\x2fscript\\x3e'); - done(); - }); - - it('encodes \' characters', function (done) { - - var encoded = Hoek.escapeJavaScript('something(\'param\')'); - expect(encoded).to.equal('something\\x28\\x27param\\x27\\x29'); - done(); - }); - - it('encodes large unicode characters with the correct padding', function (done) { - - var encoded = Hoek.escapeJavaScript(String.fromCharCode(500) + String.fromCharCode(1000)); - expect(encoded).to.equal('\\u0500\\u1000'); - done(); - }); - - it('doesn\'t throw an exception when passed null', function (done) { - - var encoded = Hoek.escapeJavaScript(null); - expect(encoded).to.equal(''); - done(); - }); - }); - - describe('#escapeHtml', function () { - - it('encodes / characters', function (done) { - - var encoded = Hoek.escapeHtml('<script>alert(1)</script>'); - expect(encoded).to.equal('<script>alert(1)</script>'); - done(); - }); - - it('encodes < and > as named characters', function (done) { - - var encoded = Hoek.escapeHtml('<script><>'); - expect(encoded).to.equal('<script><>'); - done(); - }); - - it('encodes large unicode characters', function (done) { - - var encoded = Hoek.escapeHtml(String.fromCharCode(500) + String.fromCharCode(1000)); - expect(encoded).to.equal('ǴϨ'); - done(); - }); - - it('doesn\'t throw an exception when passed null', function (done) { - - var encoded = Hoek.escapeHtml(null); - expect(encoded).to.equal(''); - done(); - }); - }); -}); - - +// Load modules
+
+var Lab = require('lab');
+var Hoek = require('../lib');
+
+
+// Declare internals
+
+var internals = {};
+
+
+// Test shortcuts
+
+var expect = Lab.expect;
+var before = Lab.before;
+var after = Lab.after;
+var describe = Lab.experiment;
+var it = Lab.test;
+
+
+describe('Hoek', function () {
+
+ describe('#escapeJavaScript', function () {
+
+ it('encodes / characters', function (done) {
+
+ var encoded = Hoek.escapeJavaScript('<script>alert(1)</script>');
+ expect(encoded).to.equal('\\x3cscript\\x3ealert\\x281\\x29\\x3c\\x2fscript\\x3e');
+ done();
+ });
+
+ it('encodes \' characters', function (done) {
+
+ var encoded = Hoek.escapeJavaScript('something(\'param\')');
+ expect(encoded).to.equal('something\\x28\\x27param\\x27\\x29');
+ done();
+ });
+
+ it('encodes large unicode characters with the correct padding', function (done) {
+
+ var encoded = Hoek.escapeJavaScript(String.fromCharCode(500) + String.fromCharCode(1000));
+ expect(encoded).to.equal('\\u0500\\u1000');
+ done();
+ });
+
+ it('doesn\'t throw an exception when passed null', function (done) {
+
+ var encoded = Hoek.escapeJavaScript(null);
+ expect(encoded).to.equal('');
+ done();
+ });
+ });
+
+ describe('#escapeHtml', function () {
+
+ it('encodes / characters', function (done) {
+
+ var encoded = Hoek.escapeHtml('<script>alert(1)</script>');
+ expect(encoded).to.equal('<script>alert(1)</script>');
+ done();
+ });
+
+ it('encodes < and > as named characters', function (done) {
+
+ var encoded = Hoek.escapeHtml('<script><>');
+ expect(encoded).to.equal('<script><>');
+ done();
+ });
+
+ it('encodes large unicode characters', function (done) {
+
+ var encoded = Hoek.escapeHtml(String.fromCharCode(500) + String.fromCharCode(1000));
+ expect(encoded).to.equal('ǴϨ');
+ done();
+ });
+
+ it('doesn\'t throw an exception when passed null', function (done) {
+
+ var encoded = Hoek.escapeHtml(null);
+ expect(encoded).to.equal('');
+ done();
+ });
+ });
+});
+
+
diff --git a/deps/npm/node_modules/request/node_modules/hawk/node_modules/hoek/test/index.js b/deps/npm/node_modules/request/node_modules/hawk/node_modules/hoek/test/index.js index cd93e7657f6..c40e3ad9a4a 100755 --- a/deps/npm/node_modules/request/node_modules/hawk/node_modules/hoek/test/index.js +++ b/deps/npm/node_modules/request/node_modules/hawk/node_modules/hoek/test/index.js @@ -426,6 +426,15 @@ describe('Hoek', function () { done();
});
+ it('should return just the first common object of two arrays', function (done) {
+
+ var array1 = [1, 2, 3, 4, 4, 5, 5];
+ var array2 = [5, 4, 5, 6, 7];
+ var common = Hoek.intersect(array1, array2, true);
+ expect(common).to.equal(5);
+ done();
+ });
+
it('should return an empty array if either input is null', function (done) {
expect(Hoek.intersect([1], null).length).to.equal(0);
diff --git a/deps/npm/node_modules/request/node_modules/hawk/node_modules/hoek/test/modules/test1.js b/deps/npm/node_modules/request/node_modules/hawk/node_modules/hoek/test/modules/test1.js index fa4e06abe0a..3f41e601e54 100755 --- a/deps/npm/node_modules/request/node_modules/hawk/node_modules/hoek/test/modules/test1.js +++ b/deps/npm/node_modules/request/node_modules/hawk/node_modules/hoek/test/modules/test1.js @@ -1 +1 @@ -exports.x = 1; +exports.x = 1;
diff --git a/deps/npm/node_modules/request/node_modules/hawk/node_modules/hoek/test/modules/test2.js b/deps/npm/node_modules/request/node_modules/hawk/node_modules/hoek/test/modules/test2.js index 88e9166e860..38556b274d3 100755 --- a/deps/npm/node_modules/request/node_modules/hawk/node_modules/hoek/test/modules/test2.js +++ b/deps/npm/node_modules/request/node_modules/hawk/node_modules/hoek/test/modules/test2.js @@ -1 +1 @@ -exports.y = 2; +exports.y = 2;
diff --git a/deps/npm/node_modules/request/node_modules/hawk/node_modules/hoek/test/modules/test3.js b/deps/npm/node_modules/request/node_modules/hawk/node_modules/hoek/test/modules/test3.js index 670e724a6e6..436b860b807 100755 --- a/deps/npm/node_modules/request/node_modules/hawk/node_modules/hoek/test/modules/test3.js +++ b/deps/npm/node_modules/request/node_modules/hawk/node_modules/hoek/test/modules/test3.js @@ -1 +1 @@ -exports.z = 3; +exports.z = 3;
diff --git a/deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/.npmignore b/deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/.npmignore deleted file mode 100644 index 9966e5e637c..00000000000 --- a/deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/.npmignore +++ /dev/null @@ -1,18 +0,0 @@ -.idea
-*.iml
-npm-debug.log
-dump.rdb
-node_modules
-results.tap
-results.xml
-npm-shrinkwrap.json
-config.json
-.DS_Store
-*/.DS_Store
-*/*/.DS_Store
-._*
-*/._*
-*/*/._*
-coverage.*
-lib-cov
-complexity.md
diff --git a/deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/.travis.yml b/deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/.travis.yml deleted file mode 100755 index 40ca59eeebd..00000000000 --- a/deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/.travis.yml +++ /dev/null @@ -1,5 +0,0 @@ -language: node_js
-
-node_js:
- - 0.10
-
diff --git a/deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/LICENSE b/deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/LICENSE deleted file mode 100755 index 394adcff2ed..00000000000 --- a/deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/LICENSE +++ /dev/null @@ -1,33 +0,0 @@ -Copyright (c) 2011-2013, Walmart.
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- * Neither the name of Walmart nor the
- names of its contributors may be used to endorse or promote products
- derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL WALMART BE LIABLE FOR ANY
-DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-
- * * *
-
-
-Portions of this project were initially based on Postmile, Copyright (c) 2011, Yahoo Inc.
-Postmile is published at https://github.com/yahoo/postmile and its licensing terms are
-published at https://github.com/yahoo/postmile/blob/master/LICENSE.
-
diff --git a/deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/Makefile b/deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/Makefile deleted file mode 100755 index e605d6c049d..00000000000 --- a/deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -test:
- @node node_modules/lab/bin/lab
-test-cov:
- @node node_modules/lab/bin/lab -r threshold -t 100
-test-cov-html:
- @node node_modules/lab/bin/lab -r html -o coverage.html
-complexity:
- @node node_modules/complexity-report/src/cli.js -o complexity.md -f markdown lib
-
-.PHONY: test test-cov test-cov-html complexity
diff --git a/deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/README.md b/deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/README.md deleted file mode 100755 index ac64e2fda1f..00000000000 --- a/deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/README.md +++ /dev/null @@ -1,436 +0,0 @@ -<a href="https://github.com/spumko"><img src="https://raw.github.com/spumko/spumko/master/images/from.png" align="right" /></a>
-![hoek Logo](https://raw.github.com/spumko/hoek/master/images/hoek.png)
-
-General purpose node utilities
-
-[![Build Status](https://secure.travis-ci.org/spumko/hoek.png)](http://travis-ci.org/spumko/hoek)
-
-# Table of Contents
-
-* [Introduction](#introduction "Introduction")
-* [Object](#object "Object")
- * [clone](#cloneobj "clone")
- * [merge](#mergetarget-source-isnulloverride-ismergearrays "merge")
- * [applyToDefaults](#applytodefaultsdefaults-options "applyToDefaults")
- * [unique](#uniquearray-key "unique")
- * [mapToObject](#maptoobjectarray-key "mapToObject")
- * [intersect](#intersectarray1-array2 "intersect")
- * [matchKeys](#matchkeysobj-keys "matchKeys")
- * [flatten](#flattenarray-target "flatten")
- * [removeKeys](#removekeysobject-keys "removeKeys")
- * [reach](#reachobj-chain "reach")
- * [inheritAsync](#inheritasyncself-obj-keys "inheritAsync")
- * [rename](#renameobj-from-to "rename")
-* [Timer](#timer "Timer")
-* [Binary Encoding/Decoding](#binary "Binary Encoding/Decoding")
- * [base64urlEncode](#binary64urlEncodevalue "binary64urlEncode")
- * [base64urlDecode](#binary64urlDecodevalue "binary64urlDecode")
-* [Escaping Characters](#escaped "Escaping Characters")
- * [escapeHtml](#escapeHtmlstring "escapeHtml")
- * [escapeHeaderAttribute](#escapeHeaderAttributeattribute "escapeHeaderAttribute")
- * [escapeRegex](#escapeRegexstring "escapeRegex")
-* [Errors](#errors "Errors")
- * [assert](#assertmessage "assert")
- * [abort](#abortmessage "abort")
- * [displayStack](#displayStackslice "displayStack")
- * [callStack](#callStackslice "callStack")
- * [toss](#tosscondition "toss")
-* [Load files](#load-files "Load Files")
- * [loadPackage](#loadPackagedir "loadpackage")
- * [loadDirModules](#loadDirModulespath-excludefiles-target "loaddirmodules")
-
-
-
-# Introduction
-
-The *Hoek* general purpose node utilities library is used to aid in a variety of manners. It comes with useful methods for Arrays (clone, merge, applyToDefaults), Objects (removeKeys, copy), Asserting and more.
-
-For example, to use Hoek to set configuration with default options:
-```javascript
-var Hoek = require('hoek');
-
-var default = {url : "www.github.com", port : "8000", debug : true}
-
-var config = Hoek.applyToDefaults(default, {port : "3000", admin : true});
-
-// In this case, config would be { url: 'www.github.com', port: '3000', debug: true, admin: true }
-```
-
-Under each of the sections (such as Array), there are subsections which correspond to Hoek methods. Each subsection will explain how to use the corresponding method. In each js excerpt below, the var Hoek = require('hoek') is omitted for brevity.
-
-## Object
-
-Hoek provides several helpful methods for objects and arrays.
-
-### clone(obj)
-
-This method is used to clone an object or an array. A *deep copy* is made (duplicates everything, including values that are objects).
-
-```javascript
-
-var nestedObj = {
- w: /^something$/ig,
- x: {
- a: [1, 2, 3],
- b: 123456,
- c: new Date()
- },
- y: 'y',
- z: new Date()
- };
-
-var copy = Hoek.clone(nestedObj);
-
-copy.x.b = 100;
-
-console.log(copy.y) // results in 'y'
-console.log(nestedObj.x.b) // results in 123456
-console.log(copy.x.b) // results in 100
-```
-
-### merge(target, source, isNullOverride, isMergeArrays)
-isNullOverride, isMergeArrays default to true
-
-Merge all the properties of source into target, source wins in conflic, and by default null and undefined from source are applied
-
-
-```javascript
-
-var target = {a: 1, b : 2}
-var source = {a: 0, c: 5}
-var source2 = {a: null, c: 5}
-
-var targetArray = [1, 2, 3];
-var sourceArray = [4, 5];
-
-var newTarget = Hoek.merge(target, source); // results in {a: 0, b: 2, c: 5}
-newTarget = Hoek.merge(target, source2); // results in {a: null, b: 2, c: 5}
-newTarget = Hoek.merge(target, source2, false); // results in {a: 1, b: 2, c: 5}
-
-newTarget = Hoek.merge(targetArray, sourceArray) // results in [1, 2, 3, 4, 5]
-newTarget = Hoek.merge(targetArray, sourceArray, true, false) // results in [4, 5]
-
-
-
-
-```
-
-### applyToDefaults(defaults, options)
-
-Apply options to a copy of the defaults
-
-```javascript
-
-var defaults = {host: "localhost", port: 8000};
-var options = {port: 8080};
-
-var config = Hoek.applyToDefaults(defaults, options); // results in {host: "localhost", port: 8080};
-
-
-```
-
-### unique(array, key)
-
-Remove duplicate items from Array
-
-```javascript
-
-var array = [1, 2, 2, 3, 3, 4, 5, 6];
-
-var newArray = Hoek.unique(array); // results in [1,2,3,4,5,6];
-
-array = [{id: 1}, {id: 1}, {id: 2}];
-
-newArray = Hoek.unique(array, "id") // results in [{id: 1}, {id: 2}]
-
-```
-
-### mapToObject(array, key)
-
-Convert an Array into an Object
-
-```javascript
-
-var array = [1,2,3];
-var newObject = Hoek.mapToObject(array); // results in [{"1": true}, {"2": true}, {"3": true}]
-
-array = [{id: 1}, {id: 2}];
-newObject = Hoek.mapToObject(array, "id") // results in [{"id": 1}, {"id": 2}]
-
-```
-### intersect(array1, array2)
-
-Find the common unique items in two arrays
-
-```javascript
-
-var array1 = [1, 2, 3];
-var array2 = [1, 4, 5];
-
-var newArray = Hoek.intersect(array1, array2) // results in [1]
-
-```
-
-### matchKeys(obj, keys)
-
-Find which keys are present
-
-```javascript
-
-var obj = {a: 1, b: 2, c: 3};
-var keys = ["a", "e"];
-
-Hoek.matchKeys(obj, keys) // returns ["a"]
-
-```
-
-### flatten(array, target)
-
-Flatten an array
-
-```javascript
-
-var array = [1, 2, 3];
-var target = [4, 5];
-
-var flattenedArray = Hoek.flatten(array, target) // results in [4, 5, 1, 2, 3];
-
-```
-
-### removeKeys(object, keys)
-
-Remove keys
-
-```javascript
-
-var object = {a: 1, b: 2, c: 3, d: 4};
-
-var keys = ["a", "b"];
-
-Hoek.removeKeys(object, keys) // object is now {c: 3, d: 4}
-
-```
-
-### reach(obj, chain)
-
-Converts an object key chain string to reference
-
-```javascript
-
-var chain = 'a.b.c';
-var obj = {a : {b : { c : 1}}};
-
-Hoek.reach(obj, chain) // returns 1
-
-```
-
-### inheritAsync(self, obj, keys)
-
-Inherits a selected set of methods from an object, wrapping functions in asynchronous syntax and catching errors
-
-```javascript
-
-var targetFunc = function () { };
-
-var proto = {
- a: function () {
- return 'a!';
- },
- b: function () {
- return 'b!';
- },
- c: function () {
- throw new Error('c!');
- }
- };
-
-var keys = ['a', 'c'];
-
-Hoek.inheritAsync(targetFunc, proto, ['a', 'c']);
-
-var target = new targetFunc();
-
-target.a(function(err, result){console.log(result)} // returns 'a!'
-
-target.c(function(err, result){console.log(result)} // returns undefined
-
-target.b(function(err, result){console.log(result)} // gives error: Object [object Object] has no method 'b'
-
-```
-
-### rename(obj, from, to)
-
-Rename a key of an object
-
-```javascript
-
-var obj = {a : 1, b : 2};
-
-Hoek.rename(obj, "a", "c"); // obj is now {c : 1, b : 2}
-
-```
-
-
-# Timer
-
-A Timer object. Initializing a new timer object sets the ts to the number of milliseconds elapsed since 1 January 1970 00:00:00 UTC.
-
-```javascript
-
-
-example :
-
-
-var timerObj = new Hoek.Timer();
-console.log("Time is now: " + timerObj.ts)
-console.log("Elapsed time from initialization: " + timerObj.elapsed() + 'milliseconds')
-
-```
-
-# Binary Encoding/Decoding
-
-### base64urlEncode(value)
-
-Encodes value in Base64 or URL encoding
-
-### base64urlDecode(value)
-
-Decodes data in Base64 or URL encoding.
-# Escaping Characters
-
-Hoek provides convenient methods for escaping html characters. The escaped characters are as followed:
-
-```javascript
-
-internals.htmlEscaped = {
- '&': '&',
- '<': '<',
- '>': '>',
- '"': '"',
- "'": ''',
- '`': '`'
-};
-
-```
-
-### escapeHtml(string)
-
-```javascript
-
-var string = '<html> hey </html>';
-var escapedString = Hoek.escapeHtml(string); // returns <html> hey </html>
-
-```
-
-### escapeHeaderAttribute(attribute)
-
-Escape attribute value for use in HTTP header
-
-```javascript
-
-var a = Hoek.escapeHeaderAttribute('I said "go w\\o me"'); //returns I said \"go w\\o me\"
-
-
-```
-
-
-### escapeRegex(string)
-
-Escape string for Regex construction
-
-```javascript
-
-var a = Hoek.escapeRegex('4^f$s.4*5+-_?%=#!:@|~\\/`"(>)[<]d{}s,'); // returns 4\^f\$s\.4\*5\+\-_\?%\=#\!\:@\|~\\\/`"\(>\)\[<\]d\{\}s\,
-
-
-
-```
-
-# Errors
-
-### assert(message)
-
-```javascript
-
-var a = 1, b =2;
-
-Hoek.assert(a === b, 'a should equal b'); // ABORT: a should equal b
-
-```
-
-### abort(message)
-
-First checks if process.env.NODE_ENV === 'test', and if so, throws error message. Otherwise,
-displays most recent stack and then exits process.
-
-
-
-### displayStack(slice)
-
-Displays the trace stack
-
-```javascript
-
-var stack = Hoek.displayStack();
-console.log(stack) // returns something like:
-
-[ 'null (/Users/user/Desktop/hoek/test.js:4:18)',
- 'Module._compile (module.js:449:26)',
- 'Module._extensions..js (module.js:467:10)',
- 'Module.load (module.js:356:32)',
- 'Module._load (module.js:312:12)',
- 'Module.runMain (module.js:492:10)',
- 'startup.processNextTick.process._tickCallback (node.js:244:9)' ]
-
-```
-
-### callStack(slice)
-
-Returns a trace stack array.
-
-```javascript
-
-var stack = Hoek.callStack();
-console.log(stack) // returns something like:
-
-[ [ '/Users/user/Desktop/hoek/test.js', 4, 18, null, false ],
- [ 'module.js', 449, 26, 'Module._compile', false ],
- [ 'module.js', 467, 10, 'Module._extensions..js', false ],
- [ 'module.js', 356, 32, 'Module.load', false ],
- [ 'module.js', 312, 12, 'Module._load', false ],
- [ 'module.js', 492, 10, 'Module.runMain', false ],
- [ 'node.js',
- 244,
- 9,
- 'startup.processNextTick.process._tickCallback',
- false ] ]
-
-
-```
-
-### toss(condition)
-
-toss(condition /*, [message], callback */)
-
-Return an error as first argument of a callback
-
-
-# Load Files
-
-### loadPackage(dir)
-
-Load and parse package.json process root or given directory
-
-```javascript
-
-var pack = Hoek.loadPackage(); // pack.name === 'hoek'
-
-```
-
-### loadDirModules(path, excludeFiles, target)
-
-Loads modules from a given path; option to exclude files (array).
-
-
-
-
diff --git a/deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/images/hoek.png b/deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/images/hoek.png Binary files differdeleted file mode 100755 index 6ccfcb12be7..00000000000 --- a/deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/images/hoek.png +++ /dev/null diff --git a/deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/index.js b/deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/index.js deleted file mode 100755 index 4cc88b35877..00000000000 --- a/deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/index.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('./lib');
\ No newline at end of file diff --git a/deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/lib/escape.js b/deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/lib/escape.js deleted file mode 100755 index 666b3dc8206..00000000000 --- a/deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/lib/escape.js +++ /dev/null @@ -1,132 +0,0 @@ -// Declare internals
-
-var internals = {};
-
-
-exports.escapeJavaScript = function (input) {
-
- if (!input) {
- return '';
- }
-
- var escaped = '';
-
- for (var i = 0, il = input.length; i < il; ++i) {
-
- var charCode = input.charCodeAt(i);
-
- if (internals.isSafe(charCode)) {
- escaped += input[i];
- }
- else {
- escaped += internals.escapeJavaScriptChar(charCode);
- }
- }
-
- return escaped;
-};
-
-
-exports.escapeHtml = function (input) {
-
- if (!input) {
- return '';
- }
-
- var escaped = '';
-
- for (var i = 0, il = input.length; i < il; ++i) {
-
- var charCode = input.charCodeAt(i);
-
- if (internals.isSafe(charCode)) {
- escaped += input[i];
- }
- else {
- escaped += internals.escapeHtmlChar(charCode);
- }
- }
-
- return escaped;
-};
-
-
-internals.escapeJavaScriptChar = function (charCode) {
-
- if (charCode >= 256) {
- return '\\u' + internals.padLeft('' + charCode, 4);
- }
-
- var hexValue = new Buffer(String.fromCharCode(charCode), 'ascii').toString('hex');
- return '\\x' + internals.padLeft(hexValue, 2);
-};
-
-
-internals.escapeHtmlChar = function (charCode) {
-
- var namedEscape = internals.namedHtml[charCode];
- if (typeof namedEscape !== 'undefined') {
- return namedEscape;
- }
-
- if (charCode >= 256) {
- return '&#' + charCode + ';';
- }
-
- var hexValue = new Buffer(String.fromCharCode(charCode), 'ascii').toString('hex');
- return '&#x' + internals.padLeft(hexValue, 2) + ';';
-};
-
-
-internals.padLeft = function (str, len) {
-
- while (str.length < len) {
- str = '0' + str;
- }
-
- return str;
-};
-
-
-internals.isSafe = function (charCode) {
-
- return (typeof internals.safeCharCodes[charCode] !== 'undefined');
-};
-
-
-internals.namedHtml = {
- '38': '&',
- '60': '<',
- '62': '>',
- '34': '"',
- '160': ' ',
- '162': '¢',
- '163': '£',
- '164': '¤',
- '169': '©',
- '174': '®'
-};
-
-
-internals.safeCharCodes = (function () {
-
- var safe = {};
-
- for (var i = 32; i < 123; ++i) {
-
- if ((i >= 97 && i <= 122) || // a-z
- (i >= 65 && i <= 90) || // A-Z
- (i >= 48 && i <= 57) || // 0-9
- i === 32 || // space
- i === 46 || // .
- i === 44 || // ,
- i === 45 || // -
- i === 58 || // :
- i === 95) { // _
-
- safe[i] = null;
- }
- }
-
- return safe;
-}());
\ No newline at end of file diff --git a/deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/lib/index.js b/deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/lib/index.js deleted file mode 100755 index 806260d25eb..00000000000 --- a/deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/lib/index.js +++ /dev/null @@ -1,585 +0,0 @@ -// Load modules
-
-var Fs = require('fs');
-var Escape = require('./escape');
-
-
-// Declare internals
-
-var internals = {};
-
-
-// Clone object or array
-
-exports.clone = function (obj, seen) {
-
- if (typeof obj !== 'object' ||
- obj === null) {
-
- return obj;
- }
-
- seen = seen || { orig: [], copy: [] };
-
- var lookup = seen.orig.indexOf(obj);
- if (lookup !== -1) {
- return seen.copy[lookup];
- }
-
- var newObj = (obj instanceof Array) ? [] : {};
-
- seen.orig.push(obj);
- seen.copy.push(newObj);
-
- for (var i in obj) {
- if (obj.hasOwnProperty(i)) {
- if (obj[i] instanceof Buffer) {
- newObj[i] = new Buffer(obj[i]);
- }
- else if (obj[i] instanceof Date) {
- newObj[i] = new Date(obj[i].getTime());
- }
- else if (obj[i] instanceof RegExp) {
- var flags = '' + (obj[i].global ? 'g' : '') + (obj[i].ignoreCase ? 'i' : '') + (obj[i].multiline ? 'm' : '');
- newObj[i] = new RegExp(obj[i].source, flags);
- }
- else {
- newObj[i] = exports.clone(obj[i], seen);
- }
- }
- }
-
- return newObj;
-};
-
-
-// Merge all the properties of source into target, source wins in conflic, and by default null and undefined from source are applied
-
-exports.merge = function (target, source, isNullOverride /* = true */, isMergeArrays /* = true */) {
-
- exports.assert(target && typeof target == 'object', 'Invalid target value: must be an object');
- exports.assert(source === null || source === undefined || typeof source === 'object', 'Invalid source value: must be null, undefined, or an object');
-
- if (!source) {
- return target;
- }
-
- if (source instanceof Array) {
- exports.assert(target instanceof Array, 'Cannot merge array onto an object');
- if (isMergeArrays === false) { // isMergeArrays defaults to true
- target.length = 0; // Must not change target assignment
- }
-
- for (var i = 0, il = source.length; i < il; ++i) {
- target.push(source[i]);
- }
-
- return target;
- }
-
- var keys = Object.keys(source);
- for (var k = 0, kl = keys.length; k < kl; ++k) {
- var key = keys[k];
- var value = source[key];
- if (value &&
- typeof value === 'object') {
-
- if (!target[key] ||
- typeof target[key] !== 'object') {
-
- target[key] = exports.clone(value);
- }
- else {
- exports.merge(target[key], source[key], isNullOverride, isMergeArrays);
- }
- }
- else {
- if (value !== null && value !== undefined) { // Explicit to preserve empty strings
- target[key] = value;
- }
- else if (isNullOverride !== false) { // Defaults to true
- target[key] = value;
- }
- }
- }
-
- return target;
-};
-
-
-// Apply options to a copy of the defaults
-
-exports.applyToDefaults = function (defaults, options) {
-
- exports.assert(defaults && typeof defaults == 'object', 'Invalid defaults value: must be an object');
- exports.assert(!options || options === true || typeof options === 'object', 'Invalid options value: must be true, falsy or an object');
-
- if (!options) { // If no options, return null
- return null;
- }
-
- var copy = exports.clone(defaults);
-
- if (options === true) { // If options is set to true, use defaults
- return copy;
- }
-
- return exports.merge(copy, options, false, false);
-};
-
-
-// Remove duplicate items from array
-
-exports.unique = function (array, key) {
-
- var index = {};
- var result = [];
-
- for (var i = 0, il = array.length; i < il; ++i) {
- var id = (key ? array[i][key] : array[i]);
- if (index[id] !== true) {
-
- result.push(array[i]);
- index[id] = true;
- }
- }
-
- return result;
-};
-
-
-// Convert array into object
-
-exports.mapToObject = function (array, key) {
-
- if (!array) {
- return null;
- }
-
- var obj = {};
- for (var i = 0, il = array.length; i < il; ++i) {
- if (key) {
- if (array[i][key]) {
- obj[array[i][key]] = true;
- }
- }
- else {
- obj[array[i]] = true;
- }
- }
-
- return obj;
-};
-
-
-// Find the common unique items in two arrays
-
-exports.intersect = function (array1, array2, justFirst) {
-
- if (!array1 || !array2) {
- return [];
- }
-
- var common = [];
- var hash = (array1 instanceof Array ? exports.mapToObject(array1) : array1);
- var found = {};
- for (var i = 0, il = array2.length; i < il; ++i) {
- if (hash[array2[i]] && !found[array2[i]]) {
- if (justFirst) {
- return array2[i];
- }
-
- common.push(array2[i]);
- found[array2[i]] = true;
- }
- }
-
- return (justFirst ? null : common);
-};
-
-
-// Find which keys are present
-
-exports.matchKeys = function (obj, keys) {
-
- var matched = [];
- for (var i = 0, il = keys.length; i < il; ++i) {
- if (obj.hasOwnProperty(keys[i])) {
- matched.push(keys[i]);
- }
- }
- return matched;
-};
-
-
-// Flatten array
-
-exports.flatten = function (array, target) {
-
- var result = target || [];
-
- for (var i = 0, il = array.length; i < il; ++i) {
- if (Array.isArray(array[i])) {
- exports.flatten(array[i], result);
- }
- else {
- result.push(array[i]);
- }
- }
-
- return result;
-};
-
-
-// Remove keys
-
-exports.removeKeys = function (object, keys) {
-
- for (var i = 0, il = keys.length; i < il; i++) {
- delete object[keys[i]];
- }
-};
-
-
-// Convert an object key chain string ('a.b.c') to reference (object[a][b][c])
-
-exports.reach = function (obj, chain) {
-
- var path = chain.split('.');
- var ref = obj;
- for (var i = 0, il = path.length; i < il; ++i) {
- if (ref) {
- ref = ref[path[i]];
- }
- }
-
- return ref;
-};
-
-
-// Inherits a selected set of methods from an object, wrapping functions in asynchronous syntax and catching errors
-
-exports.inheritAsync = function (self, obj, keys) {
-
- keys = keys || null;
-
- for (var i in obj) {
- if (obj.hasOwnProperty(i)) {
- if (keys instanceof Array &&
- keys.indexOf(i) < 0) {
-
- continue;
- }
-
- self.prototype[i] = (function (fn) {
-
- return function (next) {
-
- var result = null;
- try {
- result = fn();
- }
- catch (err) {
- return next(err);
- }
-
- return next(null, result);
- };
- })(obj[i]);
- }
- }
-};
-
-
-exports.formatStack = function (stack) {
-
- var trace = [];
- for (var i = 0, il = stack.length; i < il; ++i) {
- var item = stack[i];
- trace.push([item.getFileName(), item.getLineNumber(), item.getColumnNumber(), item.getFunctionName(), item.isConstructor()]);
- }
-
- return trace;
-};
-
-
-exports.formatTrace = function (trace) {
-
- var display = [];
-
- for (var i = 0, il = trace.length; i < il; ++i) {
- var row = trace[i];
- display.push((row[4] ? 'new ' : '') + row[3] + ' (' + row[0] + ':' + row[1] + ':' + row[2] + ')');
- }
-
- return display;
-};
-
-
-exports.callStack = function (slice) {
-
- // http://code.google.com/p/v8/wiki/JavaScriptStackTraceApi
-
- var v8 = Error.prepareStackTrace;
- Error.prepareStackTrace = function (err, stack) {
-
- return stack;
- };
-
- var capture = {};
- Error.captureStackTrace(capture, arguments.callee);
- var stack = capture.stack;
-
- Error.prepareStackTrace = v8;
-
- var trace = exports.formatStack(stack);
-
- if (slice) {
- return trace.slice(slice);
- }
-
- return trace;
-};
-
-
-exports.displayStack = function (slice) {
-
- var trace = exports.callStack(slice === undefined ? 1 : slice + 1);
-
- return exports.formatTrace(trace);
-};
-
-
-exports.abortThrow = false;
-
-
-exports.abort = function (message, hideStack) {
-
- if (process.env.NODE_ENV === 'test' || exports.abortThrow === true) {
- throw new Error(message || 'Unknown error');
- }
-
- var stack = '';
- if (!hideStack) {
- stack = exports.displayStack(1).join('\n\t');
- }
- console.log('ABORT: ' + message + '\n\t' + stack);
- process.exit(1);
-};
-
-
-exports.assert = function (condition /*, msg1, msg2, msg3 */) {
-
- if (condition) {
- return;
- }
-
- var msgs = Array.prototype.slice.call(arguments, 1);
- msgs = msgs.map(function (msg) {
-
- return typeof msg === 'string' ? msg : msg instanceof Error ? msg.message : JSON.stringify(msg);
- });
- throw new Error(msgs.join(' ') || 'Unknown error');
-};
-
-
-exports.loadDirModules = function (path, excludeFiles, target) { // target(filename, name, capName)
-
- var exclude = {};
- for (var i = 0, il = excludeFiles.length; i < il; ++i) {
- exclude[excludeFiles[i] + '.js'] = true;
- }
-
- var files = Fs.readdirSync(path);
- for (i = 0, il = files.length; i < il; ++i) {
- var filename = files[i];
- if (/\.js$/.test(filename) &&
- !exclude[filename]) {
-
- var name = filename.substr(0, filename.lastIndexOf('.'));
- var capName = name.charAt(0).toUpperCase() + name.substr(1).toLowerCase();
-
- if (typeof target !== 'function') {
- target[capName] = require(path + '/' + name);
- }
- else {
- target(path + '/' + name, name, capName);
- }
- }
- }
-};
-
-
-exports.rename = function (obj, from, to) {
-
- obj[to] = obj[from];
- delete obj[from];
-};
-
-
-exports.Timer = function () {
-
- this.reset();
-};
-
-
-exports.Timer.prototype.reset = function () {
-
- this.ts = Date.now();
-};
-
-
-exports.Timer.prototype.elapsed = function () {
-
- return Date.now() - this.ts;
-};
-
-
-// Load and parse package.json process root or given directory
-
-exports.loadPackage = function (dir) {
-
- var result = {};
- var filepath = (dir || process.env.PWD) + '/package.json';
- if (Fs.existsSync(filepath)) {
- try {
- result = JSON.parse(Fs.readFileSync(filepath));
- }
- catch (e) { }
- }
-
- return result;
-};
-
-
-// Escape string for Regex construction
-
-exports.escapeRegex = function (string) {
-
- // Escape ^$.*+-?=!:|\/()[]{},
- return string.replace(/[\^\$\.\*\+\-\?\=\!\:\|\\\/\(\)\[\]\{\}\,]/g, '\\$&');
-};
-
-
-// Return an error as first argument of a callback
-
-exports.toss = function (condition /*, [message], next */) {
-
- var message = (arguments.length === 3 ? arguments[1] : '');
- var next = (arguments.length === 3 ? arguments[2] : arguments[1]);
-
- var err = (message instanceof Error ? message : (message ? new Error(message) : (condition instanceof Error ? condition : new Error())));
-
- if (condition instanceof Error ||
- !condition) {
-
- return next(err);
- }
-};
-
-
-// Base64url (RFC 4648) encode
-
-exports.base64urlEncode = function (value) {
-
- return (new Buffer(value, 'binary')).toString('base64').replace(/\+/g, '-').replace(/\//g, '_').replace(/\=/g, '');
-};
-
-
-// Base64url (RFC 4648) decode
-
-exports.base64urlDecode = function (encoded) {
-
- if (encoded &&
- !encoded.match(/^[\w\-]*$/)) {
-
- return new Error('Invalid character');
- }
-
- try {
- return (new Buffer(encoded.replace(/-/g, '+').replace(/:/g, '/'), 'base64')).toString('binary');
- }
- catch (err) {
- return err;
- }
-};
-
-
-// Escape attribute value for use in HTTP header
-
-exports.escapeHeaderAttribute = function (attribute) {
-
- // Allowed value characters: !#$%&'()*+,-./:;<=>?@[]^_`{|}~ and space, a-z, A-Z, 0-9, \, "
-
- exports.assert(attribute.match(/^[ \w\!#\$%&'\(\)\*\+,\-\.\/\:;<\=>\?@\[\]\^`\{\|\}~\"\\]*$/), 'Bad attribute value (' + attribute + ')');
-
- return attribute.replace(/\\/g, '\\\\').replace(/\"/g, '\\"'); // Escape quotes and slash
-};
-
-
-exports.escapeHtml = function (string) {
-
- return Escape.escapeHtml(string);
-};
-
-
-exports.escapeJavaScript = function (string) {
-
- return Escape.escapeJavaScript(string);
-};
-
-
-/*
-var event = {
- timestamp: now.getTime(),
- tags: ['tag'],
- data: { some: 'data' }
-};
-*/
-
-exports.consoleFunc = console.log;
-
-exports.printEvent = function (event) {
-
- var pad = function (value) {
-
- return (value < 10 ? '0' : '') + value;
- };
-
- var now = new Date(event.timestamp);
- var timestring = (now.getYear() - 100).toString() +
- pad(now.getMonth() + 1) +
- pad(now.getDate()) +
- '/' +
- pad(now.getHours()) +
- pad(now.getMinutes()) +
- pad(now.getSeconds()) +
- '.' +
- now.getMilliseconds();
-
- var data = event.data;
- if (typeof event.data !== 'string') {
- try {
- data = JSON.stringify(event.data);
- }
- catch (e) {
- data = 'JSON Error: ' + e.message;
- }
- }
-
- var output = timestring + ', ' + event.tags[0] + ', ' + data;
- exports.consoleFunc(output);
-};
-
-
-exports.nextTick = function (callback) {
-
- return function () {
-
- var args = arguments;
- process.nextTick(function () {
-
- callback.apply(null, args);
- });
- };
-};
diff --git a/deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/package.json b/deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/package.json deleted file mode 100755 index 152a5de7d85..00000000000 --- a/deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/package.json +++ /dev/null @@ -1,52 +0,0 @@ -{ - "name": "hoek", - "description": "General purpose node utilities", - "version": "0.9.1", - "author": { - "name": "Eran Hammer", - "email": "eran@hueniverse.com", - "url": "http://hueniverse.com" - }, - "contributors": [ - { - "name": "Van Nguyen", - "email": "the.gol.effect@gmail.com" - } - ], - "repository": { - "type": "git", - "url": "git://github.com/spumko/hoek" - }, - "main": "index", - "keywords": [ - "utilities" - ], - "engines": { - "node": ">=0.8.0" - }, - "dependencies": {}, - "devDependencies": { - "lab": "0.1.x", - "complexity-report": "0.x.x" - }, - "scripts": { - "test": "make test-cov" - }, - "licenses": [ - { - "type": "BSD", - "url": "http://github.com/spumko/hoek/raw/master/LICENSE" - } - ], - "readme": "<a href=\"https://github.com/spumko\"><img src=\"https://raw.github.com/spumko/spumko/master/images/from.png\" align=\"right\" /></a>\r\n![hoek Logo](https://raw.github.com/spumko/hoek/master/images/hoek.png)\r\n\r\nGeneral purpose node utilities\r\n\r\n[![Build Status](https://secure.travis-ci.org/spumko/hoek.png)](http://travis-ci.org/spumko/hoek)\r\n\r\n# Table of Contents\r\n\r\n* [Introduction](#introduction \"Introduction\")\r\n* [Object](#object \"Object\")\r\n * [clone](#cloneobj \"clone\")\r\n * [merge](#mergetarget-source-isnulloverride-ismergearrays \"merge\")\r\n * [applyToDefaults](#applytodefaultsdefaults-options \"applyToDefaults\")\r\n * [unique](#uniquearray-key \"unique\")\r\n * [mapToObject](#maptoobjectarray-key \"mapToObject\")\r\n * [intersect](#intersectarray1-array2 \"intersect\")\r\n * [matchKeys](#matchkeysobj-keys \"matchKeys\")\r\n * [flatten](#flattenarray-target \"flatten\")\r\n * [removeKeys](#removekeysobject-keys \"removeKeys\")\r\n * [reach](#reachobj-chain \"reach\")\r\n * [inheritAsync](#inheritasyncself-obj-keys \"inheritAsync\")\r\n * [rename](#renameobj-from-to \"rename\")\r\n* [Timer](#timer \"Timer\")\r\n* [Binary Encoding/Decoding](#binary \"Binary Encoding/Decoding\")\r\n * [base64urlEncode](#binary64urlEncodevalue \"binary64urlEncode\")\r\n * [base64urlDecode](#binary64urlDecodevalue \"binary64urlDecode\")\r\n* [Escaping Characters](#escaped \"Escaping Characters\")\r\n * [escapeHtml](#escapeHtmlstring \"escapeHtml\")\r\n * [escapeHeaderAttribute](#escapeHeaderAttributeattribute \"escapeHeaderAttribute\")\r\n * [escapeRegex](#escapeRegexstring \"escapeRegex\")\r\n* [Errors](#errors \"Errors\")\r\n * [assert](#assertmessage \"assert\")\r\n * [abort](#abortmessage \"abort\")\r\n * [displayStack](#displayStackslice \"displayStack\")\r\n * [callStack](#callStackslice \"callStack\")\r\n * [toss](#tosscondition \"toss\")\r\n* [Load files](#load-files \"Load Files\")\r\n * [loadPackage](#loadPackagedir \"loadpackage\")\r\n * [loadDirModules](#loadDirModulespath-excludefiles-target \"loaddirmodules\")\r\n\r\n\r\n\r\n# Introduction\r\n\r\nThe *Hoek* general purpose node utilities library is used to aid in a variety of manners. It comes with useful methods for Arrays (clone, merge, applyToDefaults), Objects (removeKeys, copy), Asserting and more. \r\n\r\nFor example, to use Hoek to set configuration with default options:\r\n```javascript\r\nvar Hoek = require('hoek');\r\n\r\nvar default = {url : \"www.github.com\", port : \"8000\", debug : true}\r\n\r\nvar config = Hoek.applyToDefaults(default, {port : \"3000\", admin : true});\r\n\r\n// In this case, config would be { url: 'www.github.com', port: '3000', debug: true, admin: true }\r\n```\r\n\r\nUnder each of the sections (such as Array), there are subsections which correspond to Hoek methods. Each subsection will explain how to use the corresponding method. In each js excerpt below, the var Hoek = require('hoek') is omitted for brevity.\r\n\r\n## Object\r\n\r\nHoek provides several helpful methods for objects and arrays.\r\n\r\n### clone(obj)\r\n\r\nThis method is used to clone an object or an array. A *deep copy* is made (duplicates everything, including values that are objects). \r\n\r\n```javascript\r\n\r\nvar nestedObj = {\r\n w: /^something$/ig,\r\n x: {\r\n a: [1, 2, 3],\r\n b: 123456,\r\n c: new Date()\r\n },\r\n y: 'y',\r\n z: new Date()\r\n };\r\n\r\nvar copy = Hoek.clone(nestedObj);\r\n\r\ncopy.x.b = 100;\r\n\r\nconsole.log(copy.y) // results in 'y'\r\nconsole.log(nestedObj.x.b) // results in 123456\r\nconsole.log(copy.x.b) // results in 100\r\n```\r\n\r\n### merge(target, source, isNullOverride, isMergeArrays)\r\nisNullOverride, isMergeArrays default to true\r\n\r\nMerge all the properties of source into target, source wins in conflic, and by default null and undefined from source are applied\r\n\r\n\r\n```javascript\r\n\r\nvar target = {a: 1, b : 2}\r\nvar source = {a: 0, c: 5}\r\nvar source2 = {a: null, c: 5}\r\n\r\nvar targetArray = [1, 2, 3];\r\nvar sourceArray = [4, 5];\r\n\r\nvar newTarget = Hoek.merge(target, source); // results in {a: 0, b: 2, c: 5}\r\nnewTarget = Hoek.merge(target, source2); // results in {a: null, b: 2, c: 5}\r\nnewTarget = Hoek.merge(target, source2, false); // results in {a: 1, b: 2, c: 5}\r\n\r\nnewTarget = Hoek.merge(targetArray, sourceArray) // results in [1, 2, 3, 4, 5]\r\nnewTarget = Hoek.merge(targetArray, sourceArray, true, false) // results in [4, 5]\r\n\r\n\r\n\r\n\r\n```\r\n\r\n### applyToDefaults(defaults, options)\r\n\r\nApply options to a copy of the defaults\r\n\r\n```javascript\r\n\r\nvar defaults = {host: \"localhost\", port: 8000};\r\nvar options = {port: 8080};\r\n\r\nvar config = Hoek.applyToDefaults(defaults, options); // results in {host: \"localhost\", port: 8080};\r\n\r\n\r\n```\r\n\r\n### unique(array, key)\r\n\r\nRemove duplicate items from Array\r\n\r\n```javascript\r\n\r\nvar array = [1, 2, 2, 3, 3, 4, 5, 6];\r\n\r\nvar newArray = Hoek.unique(array); // results in [1,2,3,4,5,6];\r\n\r\narray = [{id: 1}, {id: 1}, {id: 2}];\r\n\r\nnewArray = Hoek.unique(array, \"id\") // results in [{id: 1}, {id: 2}]\r\n\r\n```\r\n\r\n### mapToObject(array, key)\r\n\r\nConvert an Array into an Object\r\n\r\n```javascript\r\n\r\nvar array = [1,2,3];\r\nvar newObject = Hoek.mapToObject(array); // results in [{\"1\": true}, {\"2\": true}, {\"3\": true}]\r\n\r\narray = [{id: 1}, {id: 2}];\r\nnewObject = Hoek.mapToObject(array, \"id\") // results in [{\"id\": 1}, {\"id\": 2}]\r\n\r\n```\r\n### intersect(array1, array2)\r\n\r\nFind the common unique items in two arrays\r\n\r\n```javascript\r\n\r\nvar array1 = [1, 2, 3];\r\nvar array2 = [1, 4, 5];\r\n\r\nvar newArray = Hoek.intersect(array1, array2) // results in [1]\r\n\r\n```\r\n\r\n### matchKeys(obj, keys) \r\n\r\nFind which keys are present\r\n\r\n```javascript\r\n\r\nvar obj = {a: 1, b: 2, c: 3};\r\nvar keys = [\"a\", \"e\"];\r\n\r\nHoek.matchKeys(obj, keys) // returns [\"a\"]\r\n\r\n```\r\n\r\n### flatten(array, target)\r\n\r\nFlatten an array\r\n\r\n```javascript\r\n\r\nvar array = [1, 2, 3];\r\nvar target = [4, 5]; \r\n\r\nvar flattenedArray = Hoek.flatten(array, target) // results in [4, 5, 1, 2, 3];\r\n\r\n```\r\n\r\n### removeKeys(object, keys)\r\n\r\nRemove keys\r\n\r\n```javascript\r\n\r\nvar object = {a: 1, b: 2, c: 3, d: 4};\r\n\r\nvar keys = [\"a\", \"b\"];\r\n\r\nHoek.removeKeys(object, keys) // object is now {c: 3, d: 4}\r\n\r\n```\r\n\r\n### reach(obj, chain)\r\n\r\nConverts an object key chain string to reference\r\n\r\n```javascript\r\n\r\nvar chain = 'a.b.c';\r\nvar obj = {a : {b : { c : 1}}};\r\n\r\nHoek.reach(obj, chain) // returns 1\r\n\r\n```\r\n\r\n### inheritAsync(self, obj, keys) \r\n\r\nInherits a selected set of methods from an object, wrapping functions in asynchronous syntax and catching errors\r\n\r\n```javascript\r\n\r\nvar targetFunc = function () { };\r\n\r\nvar proto = {\r\n a: function () {\r\n return 'a!';\r\n },\r\n b: function () {\r\n return 'b!';\r\n },\r\n c: function () {\r\n throw new Error('c!');\r\n }\r\n };\r\n\r\nvar keys = ['a', 'c'];\r\n\r\nHoek.inheritAsync(targetFunc, proto, ['a', 'c']);\r\n\r\nvar target = new targetFunc();\r\n\r\ntarget.a(function(err, result){console.log(result)} // returns 'a!' \r\n\r\ntarget.c(function(err, result){console.log(result)} // returns undefined\r\n\r\ntarget.b(function(err, result){console.log(result)} // gives error: Object [object Object] has no method 'b'\r\n\r\n```\r\n\r\n### rename(obj, from, to)\r\n\r\nRename a key of an object\r\n\r\n```javascript\r\n\r\nvar obj = {a : 1, b : 2};\r\n\r\nHoek.rename(obj, \"a\", \"c\"); // obj is now {c : 1, b : 2}\r\n\r\n```\r\n\r\n\r\n# Timer\r\n\r\nA Timer object. Initializing a new timer object sets the ts to the number of milliseconds elapsed since 1 January 1970 00:00:00 UTC.\r\n\r\n```javascript\r\n\r\n\r\nexample : \r\n\r\n\r\nvar timerObj = new Hoek.Timer();\r\nconsole.log(\"Time is now: \" + timerObj.ts)\r\nconsole.log(\"Elapsed time from initialization: \" + timerObj.elapsed() + 'milliseconds')\r\n\r\n```\r\n\r\n# Binary Encoding/Decoding\r\n\r\n### base64urlEncode(value)\r\n\r\nEncodes value in Base64 or URL encoding\r\n\r\n### base64urlDecode(value)\r\n\r\nDecodes data in Base64 or URL encoding.\r\n# Escaping Characters\r\n\r\nHoek provides convenient methods for escaping html characters. The escaped characters are as followed:\r\n\r\n```javascript\r\n\r\ninternals.htmlEscaped = {\r\n '&': '&',\r\n '<': '<',\r\n '>': '>',\r\n '\"': '"',\r\n \"'\": ''',\r\n '`': '`'\r\n};\r\n\r\n```\r\n\r\n### escapeHtml(string)\r\n\r\n```javascript\r\n\r\nvar string = '<html> hey </html>';\r\nvar escapedString = Hoek.escapeHtml(string); // returns <html> hey </html>\r\n\r\n```\r\n\r\n### escapeHeaderAttribute(attribute)\r\n\r\nEscape attribute value for use in HTTP header\r\n\r\n```javascript\r\n\r\nvar a = Hoek.escapeHeaderAttribute('I said \"go w\\\\o me\"'); //returns I said \\\"go w\\\\o me\\\"\r\n\r\n\r\n```\r\n\r\n\r\n### escapeRegex(string)\r\n\r\nEscape string for Regex construction\r\n\r\n```javascript\r\n\r\nvar a = Hoek.escapeRegex('4^f$s.4*5+-_?%=#!:@|~\\\\/`\"(>)[<]d{}s,'); // returns 4\\^f\\$s\\.4\\*5\\+\\-_\\?%\\=#\\!\\:@\\|~\\\\\\/`\"\\(>\\)\\[<\\]d\\{\\}s\\,\r\n\r\n\r\n\r\n```\r\n\r\n# Errors\r\n\r\n### assert(message)\r\n\r\n```javascript\r\n\r\nvar a = 1, b =2;\r\n\r\nHoek.assert(a === b, 'a should equal b'); // ABORT: a should equal b\r\n\r\n```\r\n\r\n### abort(message)\r\n\r\nFirst checks if process.env.NODE_ENV === 'test', and if so, throws error message. Otherwise,\r\ndisplays most recent stack and then exits process.\r\n\r\n\r\n\r\n### displayStack(slice)\r\n\r\nDisplays the trace stack\r\n\r\n```javascript\r\n\r\nvar stack = Hoek.displayStack();\r\nconsole.log(stack) // returns something like:\r\n\r\n[ 'null (/Users/user/Desktop/hoek/test.js:4:18)',\r\n 'Module._compile (module.js:449:26)',\r\n 'Module._extensions..js (module.js:467:10)',\r\n 'Module.load (module.js:356:32)',\r\n 'Module._load (module.js:312:12)',\r\n 'Module.runMain (module.js:492:10)',\r\n 'startup.processNextTick.process._tickCallback (node.js:244:9)' ]\r\n\r\n```\r\n\r\n### callStack(slice)\r\n\r\nReturns a trace stack array.\r\n\r\n```javascript\r\n\r\nvar stack = Hoek.callStack();\r\nconsole.log(stack) // returns something like:\r\n\r\n[ [ '/Users/user/Desktop/hoek/test.js', 4, 18, null, false ],\r\n [ 'module.js', 449, 26, 'Module._compile', false ],\r\n [ 'module.js', 467, 10, 'Module._extensions..js', false ],\r\n [ 'module.js', 356, 32, 'Module.load', false ],\r\n [ 'module.js', 312, 12, 'Module._load', false ],\r\n [ 'module.js', 492, 10, 'Module.runMain', false ],\r\n [ 'node.js',\r\n 244,\r\n 9,\r\n 'startup.processNextTick.process._tickCallback',\r\n false ] ]\r\n\r\n\r\n```\r\n\r\n### toss(condition)\r\n\r\ntoss(condition /*, [message], callback */)\r\n\r\nReturn an error as first argument of a callback\r\n\r\n\r\n# Load Files\r\n\r\n### loadPackage(dir)\r\n\r\nLoad and parse package.json process root or given directory\r\n\r\n```javascript\r\n\r\nvar pack = Hoek.loadPackage(); // pack.name === 'hoek'\r\n\r\n```\r\n\r\n### loadDirModules(path, excludeFiles, target) \r\n\r\nLoads modules from a given path; option to exclude files (array).\r\n\r\n\r\n\r\n\r\n", - "readmeFilename": "README.md", - "bugs": { - "url": "https://github.com/spumko/hoek/issues" - }, - "_id": "hoek@0.9.1", - "dist": { - "shasum": "396f2118033eabc93ae5c2cd6ca75f0a89c03592" - }, - "_from": "hoek@0.9.x", - "_resolved": "https://registry.npmjs.org/hoek/-/hoek-0.9.1.tgz" -} diff --git a/deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/test/escaper.js b/deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/test/escaper.js deleted file mode 100644 index 4dddd77dc9d..00000000000 --- a/deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/test/escaper.js +++ /dev/null @@ -1,86 +0,0 @@ -// Load modules
-
-var Lab = require('lab');
-var Hoek = require('../lib');
-
-
-// Declare internals
-
-var internals = {};
-
-
-// Test shortcuts
-
-var expect = Lab.expect;
-var before = Lab.before;
-var after = Lab.after;
-var describe = Lab.experiment;
-var it = Lab.test;
-
-
-describe('Hoek', function () {
-
- describe('#escapeJavaScript', function () {
-
- it('encodes / characters', function (done) {
-
- var encoded = Hoek.escapeJavaScript('<script>alert(1)</script>');
- expect(encoded).to.equal('\\x3cscript\\x3ealert\\x281\\x29\\x3c\\x2fscript\\x3e');
- done();
- });
-
- it('encodes \' characters', function (done) {
-
- var encoded = Hoek.escapeJavaScript('something(\'param\')');
- expect(encoded).to.equal('something\\x28\\x27param\\x27\\x29');
- done();
- });
-
- it('encodes large unicode characters with the correct padding', function (done) {
-
- var encoded = Hoek.escapeJavaScript(String.fromCharCode(500) + String.fromCharCode(1000));
- expect(encoded).to.equal('\\u0500\\u1000');
- done();
- });
-
- it('doesn\'t throw an exception when passed null', function (done) {
-
- var encoded = Hoek.escapeJavaScript(null);
- expect(encoded).to.equal('');
- done();
- });
- });
-
- describe('#escapeHtml', function () {
-
- it('encodes / characters', function (done) {
-
- var encoded = Hoek.escapeHtml('<script>alert(1)</script>');
- expect(encoded).to.equal('<script>alert(1)</script>');
- done();
- });
-
- it('encodes < and > as named characters', function (done) {
-
- var encoded = Hoek.escapeHtml('<script><>');
- expect(encoded).to.equal('<script><>');
- done();
- });
-
- it('encodes large unicode characters', function (done) {
-
- var encoded = Hoek.escapeHtml(String.fromCharCode(500) + String.fromCharCode(1000));
- expect(encoded).to.equal('ǴϨ');
- done();
- });
-
- it('doesn\'t throw an exception when passed null', function (done) {
-
- var encoded = Hoek.escapeHtml(null);
- expect(encoded).to.equal('');
- done();
- });
- });
-});
-
-
diff --git a/deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/test/index.js b/deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/test/index.js deleted file mode 100755 index c40e3ad9a4a..00000000000 --- a/deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/test/index.js +++ /dev/null @@ -1,1078 +0,0 @@ -// Load modules
-
-var Lab = require('lab');
-var Hoek = require('../lib');
-
-
-// Declare internals
-
-var internals = {};
-
-
-// Test shortcuts
-
-var expect = Lab.expect;
-var before = Lab.before;
-var after = Lab.after;
-var describe = Lab.experiment;
-var it = Lab.test;
-
-
-describe('Hoek', function () {
-
- var nestedObj = {
- v: [7,8,9],
- w: /^something$/igm,
- x: {
- a: [1, 2, 3],
- b: 123456,
- c: new Date(),
- d: /hi/igm,
- e: /hello/
- },
- y: 'y',
- z: new Date()
- };
-
- var dupsArray = [nestedObj, { z: 'z' }, nestedObj];
- var reducedDupsArray = [nestedObj, { z: 'z' }];
-
- describe('#clone', function () {
-
- it('should clone a nested object', function (done) {
-
- var a = nestedObj;
- var b = Hoek.clone(a);
-
- expect(a).to.deep.equal(b);
- expect(a.z.getTime()).to.equal(b.z.getTime());
- done();
- });
-
- it('should clone a null object', function (done) {
-
- var b = Hoek.clone(null);
-
- expect(b).to.equal(null);
- done();
- });
-
- it('should not convert undefined properties to null', function (done) {
-
- var obj = { something: undefined };
- var b = Hoek.clone(obj);
-
- expect(typeof b.something).to.equal('undefined');
- done();
- });
-
- it('should not throw on circular reference', function (done) {
-
- var a = {};
- a.x = a;
-
- var test = (function () {
-
- var b = Hoek.clone(a);
- });
-
- expect(test).to.not.throw();
- done();
- });
-
- it('should properly clone circular reference', function (done) {
-
- var x = {
- 'z': new Date()
- };
- x.y = x;
-
- var b = Hoek.clone(x);
- expect(Object.keys(b.y)).to.deep.equal(Object.keys(x))
- expect(b.z).to.not.equal(x.z);
- expect(b.y).to.not.equal(x.y);
- expect(b.y.z).to.not.equal(x.y.z);
- expect(b.y).to.equal(b);
- expect(b.y.y.y.y).to.equal(b);
- done();
- });
-
- it('should properly clone deeply nested object', function (done) {
-
- var a = {
- x: {
- y: {
- a: [1, 2, 3],
- b: 123456,
- c: new Date(),
- d: /hi/igm,
- e: /hello/
- },
- }
- };
-
- var b = Hoek.clone(a);
-
- expect(a).to.deep.equal(b);
- expect(a.x.y.c.getTime()).to.equal(b.x.y.c.getTime());
- done();
- });
-
- it('should properly clone arrays', function (done) {
-
- var a = [1,2,3];
-
- var b = Hoek.clone(a);
-
- expect(a).to.deep.equal(b);
- done();
- });
-
- it('should perform actual copy for shallow keys (no pass by reference)', function (done) {
-
- var x = Hoek.clone(nestedObj);
- var y = Hoek.clone(nestedObj);
-
- // Date
- expect(x.z).to.not.equal(nestedObj.z);
- expect(x.z).to.not.equal(y.z);
-
- // Regex
- expect(x.w).to.not.equal(nestedObj.w);
- expect(x.w).to.not.equal(y.w);
-
- // Array
- expect(x.v).to.not.equal(nestedObj.v);
- expect(x.v).to.not.equal(y.v);
-
- // Immutable(s)
- x.y = 5;
- expect(x.y).to.not.equal(nestedObj.y);
- expect(x.y).to.not.equal(y.y);
-
- done();
- });
-
- it('should perform actual copy for deep keys (no pass by reference)', function (done) {
-
- var x = Hoek.clone(nestedObj);
- var y = Hoek.clone(nestedObj);
-
- expect(x.x.c).to.not.equal(nestedObj.x.c);
- expect(x.x.c).to.not.equal(y.x.c);
-
- expect(x.x.c.getTime()).to.equal(nestedObj.x.c.getTime());
- expect(x.x.c.getTime()).to.equal(y.x.c.getTime());
- done();
- });
-
- it('copies functions with properties', function (done) {
-
- var a = {
- x: function () { return 1; },
- y: {}
- };
- a.x.z = 'string in function';
- a.x.v = function () { return 2; };
- a.y.u = a.x;
-
- var b = Hoek.clone(a);
- expect(b.x()).to.equal(1);
- expect(b.x.v()).to.equal(2);
- expect(b.y.u).to.equal(b.x);
- expect(b.x.z).to.equal('string in function');
- done();
- });
-
- it('should copy a buffer', function(done){
- var tls = {
- key: new Buffer([1,2,3,4,5]),
- cert: new Buffer([1,2,3,4,5,6,10])
- }
-
- copiedTls = Hoek.clone(tls);
- expect(Buffer.isBuffer(copiedTls.key)).to.equal(true);
- expect(JSON.stringify(copiedTls.key)).to.equal(JSON.stringify(tls.key))
- expect(Buffer.isBuffer(copiedTls.cert)).to.equal(true);
- expect(JSON.stringify(copiedTls.cert)).to.equal(JSON.stringify(tls.cert))
- done();
- });
- });
-
- describe('#merge', function () {
-
- it('does not throw if source is null', function (done) {
-
- var a = {};
- var b = null;
- var c = null;
-
- expect(function () {
-
- c = Hoek.merge(a, b);
- }).to.not.throw();
-
- expect(c).to.equal(a);
- done();
- });
-
- it('does not throw if source is undefined', function (done) {
-
- var a = {};
- var b = undefined;
- var c = null;
-
- expect(function () {
-
- c = Hoek.merge(a, b);
- }).to.not.throw();
-
- expect(c).to.equal(a);
- done();
- });
-
- it('throws if source is not an object', function (done) {
-
- expect(function () {
-
- var a = {};
- var b = 0;
-
- Hoek.merge(a, b);
- }).to.throw('Invalid source value: must be null, undefined, or an object');
- done();
- });
-
- it('throws if target is not an object', function (done) {
-
- expect(function () {
-
- var a = 0;
- var b = {};
-
- Hoek.merge(a, b);
- }).to.throw('Invalid target value: must be an object');
- done();
- });
-
- it('throws if target is not an array and source is', function (done) {
-
- expect(function () {
-
- var a = {};
- var b = [1, 2];
-
- Hoek.merge(a, b);
- }).to.throw('Cannot merge array onto an object');
- done();
- });
-
- it('returns the same object when merging arrays', function (done) {
-
- var a = [];
- var b = [1, 2];
-
- expect(Hoek.merge(a, b)).to.equal(a);
- done();
- });
-
- it('should combine an empty object with a non-empty object', function (done) {
-
- var a = {};
- var b = nestedObj;
-
- var c = Hoek.merge(a, b);
- expect(a).to.deep.equal(b);
- expect(c).to.deep.equal(b);
- done();
- });
-
- it('should override values in target', function (done) {
-
- var a = { x: 1, y: 2, z: 3, v: 5, t: 'test', m: 'abc' };
- var b = { x: null, z: 4, v: 0, t: { u: 6 }, m: '123' };
-
- var c = Hoek.merge(a, b);
- expect(c.x).to.equal(null);
- expect(c.y).to.equal(2);
- expect(c.z).to.equal(4);
- expect(c.v).to.equal(0);
- expect(c.m).to.equal('123');
- expect(c.t).to.deep.equal({ u: 6 });
- done();
- });
-
- it('should override values in target (flip)', function (done) {
-
- var a = { x: 1, y: 2, z: 3, v: 5, t: 'test', m: 'abc' };
- var b = { x: null, z: 4, v: 0, t: { u: 6 }, m: '123' };
-
- var d = Hoek.merge(b, a);
- expect(d.x).to.equal(1);
- expect(d.y).to.equal(2);
- expect(d.z).to.equal(3);
- expect(d.v).to.equal(5);
- expect(d.m).to.equal('abc');
- expect(d.t).to.deep.equal('test');
- done();
- });
- });
-
- describe('#applyToDefaults', function () {
-
- var defaults = {
- a: 1,
- b: 2,
- c: {
- d: 3,
- e: [5, 6]
- },
- f: 6,
- g: 'test'
- };
-
- it('should return null if options is false', function (done) {
-
- var result = Hoek.applyToDefaults(defaults, false);
- expect(result).to.equal(null);
- done();
- });
-
- it('should return a copy of defaults if options is true', function (done) {
-
- var result = Hoek.applyToDefaults(defaults, true);
- expect(result).to.deep.equal(result);
- done();
- });
-
- it('should apply object to defaults', function (done) {
-
- var obj = {
- a: null,
- c: {
- e: [4]
- },
- f: 0,
- g: {
- h: 5
- }
- };
-
- var result = Hoek.applyToDefaults(defaults, obj);
- expect(result.c.e).to.deep.equal([4]);
- expect(result.a).to.equal(1);
- expect(result.b).to.equal(2);
- expect(result.f).to.equal(0);
- expect(result.g).to.deep.equal({ h: 5 });
- done();
- });
- });
-
- describe('#unique', function () {
-
- it('should ensure uniqueness within array of objects based on subkey', function (done) {
-
- var a = Hoek.unique(dupsArray, 'x');
- expect(a).to.deep.equal(reducedDupsArray);
- done();
- });
-
- it('removes duplicated without key', function (done) {
-
- expect(Hoek.unique([1, 2, 3, 4, 2, 1, 5])).to.deep.equal([1, 2, 3, 4, 5]);
- done();
- });
- });
-
- describe('#mapToObject', function () {
-
- it('should return null on null array', function (done) {
-
- var a = Hoek.mapToObject(null);
- expect(a).to.equal(null);
- done();
- });
-
- it('should convert basic array to existential object', function (done) {
-
- var keys = [1, 2, 3, 4];
- var a = Hoek.mapToObject(keys);
- for (var i in keys) {
- expect(a[keys[i]]).to.equal(true);
- }
- done();
- });
-
- it('should convert array of objects to existential object', function (done) {
-
- var keys = [{ x: 1 }, { x: 2 }, { x: 3 }];
- var subkey = 'x';
- var a = Hoek.mapToObject(keys, subkey);
- for (var i in keys) {
- expect(a[keys[i][subkey]]).to.equal(true);
- }
- done();
- });
- });
-
- describe('#intersect', function () {
-
- it('should return the common objects of two arrays', function (done) {
-
- var array1 = [1, 2, 3, 4, 4, 5, 5];
- var array2 = [5, 4, 5, 6, 7];
- var common = Hoek.intersect(array1, array2);
- expect(common.length).to.equal(2);
- done();
- });
-
- it('should return just the first common object of two arrays', function (done) {
-
- var array1 = [1, 2, 3, 4, 4, 5, 5];
- var array2 = [5, 4, 5, 6, 7];
- var common = Hoek.intersect(array1, array2, true);
- expect(common).to.equal(5);
- done();
- });
-
- it('should return an empty array if either input is null', function (done) {
-
- expect(Hoek.intersect([1], null).length).to.equal(0);
- expect(Hoek.intersect(null, [1]).length).to.equal(0);
- done();
- });
-
- it('should return the common objects of object and array', function (done) {
-
- var array1 = [1, 2, 3, 4, 4, 5, 5];
- var array2 = [5, 4, 5, 6, 7];
- var common = Hoek.intersect(Hoek.mapToObject(array1), array2);
- expect(common.length).to.equal(2);
- done();
- });
- });
-
- describe('#matchKeys', function () {
-
- it('should match the existing object keys', function (done) {
-
- var obj = {
- a: 1,
- b: 2,
- c: 3,
- d: null
- };
-
- expect(Hoek.matchKeys(obj, ['b', 'c', 'd', 'e'])).to.deep.equal(['b', 'c', 'd']);
- done();
- });
- });
-
- describe('#flatten', function () {
-
- it('should return a flat array', function (done) {
-
- var result = Hoek.flatten([1, 2, [3, 4, [5, 6], [7], 8], [9], [10, [11, 12]], 13]);
- expect(result.length).to.equal(13);
- expect(result).to.deep.equal([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]);
- done();
- });
- });
-
- describe('#removeKeys', function () {
-
- var objWithHiddenKeys = {
- location: {
- name: 'San Bruno'
- },
- company: {
- name: '@WalmartLabs'
- }
- };
-
- it('should delete params with definition\'s hide set to true', function (done) {
-
- var a = Hoek.removeKeys(objWithHiddenKeys, ['location']);
- expect(objWithHiddenKeys.location).to.not.exist;
- expect(objWithHiddenKeys.company).to.exist;
- done();
- });
- });
-
- describe('#reach', function () {
-
- var obj = {
- a: {
- b: {
- c: {
- d: 1,
- e: 2
- },
- f: 'hello'
- },
- g: {
- h: 3
- }
- },
- i: function () { }
- };
-
- it('returns a valid member', function (done) {
-
- expect(Hoek.reach(obj, 'a.b.c.d')).to.equal(1);
- done();
- });
-
- it('returns null on null object', function (done) {
-
- expect(Hoek.reach(null, 'a.b.c.d')).to.not.exist;
- done();
- });
-
- it('returns null on missing member', function (done) {
-
- expect(Hoek.reach(obj, 'a.b.c.d.x')).to.not.exist;
- done();
- });
-
- it('returns null on invalid member', function (done) {
-
- expect(Hoek.reach(obj, 'a.b.c.d-.x')).to.not.exist;
- done();
- });
-
- it('returns function member', function (done) {
-
- expect(typeof Hoek.reach(obj, 'i')).to.equal('function');
- done();
- });
- });
-
- describe('#inheritAsync', function () {
-
- it('should inherit selected methods and wrap in async call', function (done) {
-
- var proto = {
- a: function () {
- return 'a!';
- },
- b: function () {
- return 'b!';
- },
- c: function () {
- throw new Error('c!');
- }
- };
-
- var targetFunc = function () { };
- targetFunc.prototype.c = function () {
-
- return 'oops';
- };
-
- Hoek.inheritAsync(targetFunc, proto, ['a', 'c']);
- var target = new targetFunc();
-
- expect(typeof target.a).to.equal('function');
- expect(typeof target.c).to.equal('function');
- expect(target.b).to.not.exist;
-
- target.a(function (err, result) {
-
- expect(err).to.not.exist;
- expect(result).to.equal('a!');
-
- target.c(function (err, result) {
-
- expect(result).to.not.exist;
- expect(err.message).to.equal('c!');
- done();
- });
- });
- });
- });
-
- describe('#callStack', function () {
-
- it('should return the full call stack', function (done) {
-
- var stack = Hoek.callStack();
- expect(stack[0][0]).to.contain('index.js');
- expect(stack[0][2]).to.equal(30);
- done();
- });
- });
-
- describe('#displayStack ', function () {
-
- it('should return the full call stack for display', function (done) {
-
- var stack = Hoek.displayStack();
- expect(stack[0]).to.contain('test/index.js:');
- done();
- });
-
- it('should include constructor functions correctly', function (done) {
-
- var Something = function (next) {
-
- next();
- };
-
- var something = new Something(function () {
-
- var stack = Hoek.displayStack();
- expect(stack[1]).to.contain('new Something');
- done();
- });
- });
- });
-
- describe('#abort', function () {
-
- it('should exit process when not in test mode', function (done) {
-
- var env = process.env.NODE_ENV;
- var write = process.stdout.write;
- var exit = process.exit;
-
- process.env.NODE_ENV = 'nottatest';
- process.stdout.write = function () { };
- process.exit = function (state) {
-
- process.exit = exit;
- process.env.NODE_ENV = env;
- process.stdout.write = write;
-
- expect(state).to.equal(1);
- done();
- };
-
- Hoek.abort('Boom');
- });
-
- it('should throw when not in test mode and abortThrow is true', function (done) {
-
- var env = process.env.NODE_ENV;
- process.env.NODE_ENV = 'nottatest';
- Hoek.abortThrow = true;
-
- var fn = function () {
-
- Hoek.abort('my error message');
- };
-
- expect(fn).to.throw('my error message');
- Hoek.abortThrow = false;
- process.env.NODE_ENV = env;
-
- done();
- });
-
-
- it('should respect hideStack argument', function (done) {
-
- var env = process.env.NODE_ENV;
- var write = process.stdout.write;
- var exit = process.exit;
- var output = '';
-
- process.exit = function () { };
- process.env.NODE_ENV = '';
- process.stdout.write = function (message) {
-
- output = message;
- };
-
- Hoek.abort('my error message', true);
-
- process.env.NODE_ENV = env;
- process.stdout.write = write;
- process.exit = exit;
-
- expect(output).to.equal('ABORT: my error message\n\t\n');
-
- done();
- });
-
- it('should default to showing stack', function (done) {
-
- var env = process.env.NODE_ENV;
- var write = process.stdout.write;
- var exit = process.exit;
- var output = '';
-
- process.exit = function () { };
- process.env.NODE_ENV = '';
- process.stdout.write = function (message) {
-
- output = message;
- };
-
- Hoek.abort('my error message');
-
- process.env.NODE_ENV = env;
- process.stdout.write = write;
- process.exit = exit;
-
- expect(output).to.contain('index.js');
-
- done();
- });
- });
-
- describe('#assert', function () {
-
- it('should throw an Error when using assert in a test', function (done) {
-
- var fn = function () {
-
- Hoek.assert(false, 'my error message');
- };
-
- expect(fn).to.throw('my error message');
- done();
- });
-
- it('should throw an Error when using assert in a test with no message', function (done) {
-
- var fn = function () {
-
- Hoek.assert(false);
- };
-
- expect(fn).to.throw('Unknown error');
- done();
- });
-
- it('should throw an Error when using assert in a test with multipart message', function (done) {
-
- var fn = function () {
-
- Hoek.assert(false, 'This', 'is', 'my message');
- };
-
- expect(fn).to.throw('This is my message');
- done();
- });
-
- it('should throw an Error when using assert in a test with object message', function (done) {
-
- var fn = function () {
-
- Hoek.assert(false, 'This', 'is', { spinal: 'tap' });
- };
-
- expect(fn).to.throw('This is {"spinal":"tap"}');
- done();
- });
-
- it('should throw an Error when using assert in a test with error object message', function (done) {
-
- var fn = function () {
-
- Hoek.assert(false, new Error('This is spinal tap'));
- };
-
- expect(fn).to.throw('This is spinal tap');
- done();
- });
- });
-
- describe('#loadDirModules', function () {
-
- it('should load modules from directory', function (done) {
-
- var target = {};
- Hoek.loadDirModules(__dirname + '/modules', ['test2'], target);
- expect(target.Test1.x).to.equal(1);
- expect(target.Test2).to.not.exist;
- expect(target.Test3.z).to.equal(3);
- done();
- });
-
- it('should list modules from directory into function', function (done) {
-
- var target = {};
- Hoek.loadDirModules(__dirname + '/modules', ['test2'], function (path, name, capName) {
-
- target[name] = capName;
- });
-
- expect(target.test1).to.equal('Test1');
- expect(target.test2).to.not.exist;
- expect(target.test3).to.equal('Test3');
- done();
- });
- });
-
- describe('#rename', function () {
-
- it('should rename object key', function (done) {
-
- var a = { b: 'c' };
- Hoek.rename(a, 'b', 'x');
- expect(a.b).to.not.exist;
- expect(a.x).to.equal('c');
- done();
- });
- });
-
- describe('Timer', function () {
-
- it('should return time elapsed', function (done) {
-
- var timer = new Hoek.Timer();
- setTimeout(function () {
-
- expect(timer.elapsed()).to.be.above(9);
- done();
- }, 12);
- });
- });
-
- describe('#loadPackage', function () {
-
- it('should', function (done) {
-
- var pack = Hoek.loadPackage();
- expect(pack.name).to.equal('hoek');
- done();
- });
- });
-
- describe('#escapeRegex', function () {
-
- it('should escape all special regular expression characters', function (done) {
-
- var a = Hoek.escapeRegex('4^f$s.4*5+-_?%=#!:@|~\\/`"(>)[<]d{}s,');
- expect(a).to.equal('4\\^f\\$s\\.4\\*5\\+\\-_\\?%\\=#\\!\\:@\\|~\\\\\\/`"\\(>\\)\\[<\\]d\\{\\}s\\,');
- done();
- });
- });
-
- describe('#toss', function () {
-
- it('should call callback with new error', function (done) {
-
- var callback = function (err) {
-
- expect(err).to.exist;
- expect(err.message).to.equal('bug');
- done();
- };
-
- Hoek.toss(true, 'feature', callback);
- Hoek.toss(false, 'bug', callback);
- });
-
- it('should call callback with new error and no message', function (done) {
-
- Hoek.toss(false, function (err) {
-
- expect(err).to.exist;
- expect(err.message).to.equal('');
- done();
- });
- });
-
- it('should call callback with error condition', function (done) {
-
- Hoek.toss(new Error('boom'), function (err) {
-
- expect(err).to.exist;
- expect(err.message).to.equal('boom');
- done();
- });
- });
-
- it('should call callback with new error using message with error condition', function (done) {
-
- Hoek.toss(new Error('ka'), 'boom', function (err) {
-
- expect(err).to.exist;
- expect(err.message).to.equal('boom');
- done();
- });
- });
-
- it('should call callback with new error using passed error with error condition', function (done) {
-
- Hoek.toss(new Error('ka'), new Error('boom'), function (err) {
-
- expect(err).to.exist;
- expect(err.message).to.equal('boom');
- done();
- });
- });
- });
-
- describe('Base64Url', function () {
-
- var base64str = 'AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0-P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn-AgYKDhIWGh4iJiouMjY6PkJGSk5SVlpeYmZqbnJ2en6ChoqOkpaanqKmqq6ytrq-wsbKztLW2t7i5uru8vb6_wMHCw8TFxsfIycrLzM3Oz9DR0tPU1dbX2Nna29zd3t_g4eLj5OXm5-jp6uvs7e7v8PHy8_T19vf4-fr7_P3-_w';
- var str = unescape('%00%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%20%21%22%23%24%25%26%27%28%29*+%2C-./0123456789%3A%3B%3C%3D%3E%3F@ABCDEFGHIJKLMNOPQRSTUVWXYZ%5B%5C%5D%5E_%60abcdefghijklmnopqrstuvwxyz%7B%7C%7D%7E%7F%80%81%82%83%84%85%86%87%88%89%8A%8B%8C%8D%8E%8F%90%91%92%93%94%95%96%97%98%99%9A%9B%9C%9D%9E%9F%A0%A1%A2%A3%A4%A5%A6%A7%A8%A9%AA%AB%AC%AD%AE%AF%B0%B1%B2%B3%B4%B5%B6%B7%B8%B9%BA%BB%BC%BD%BE%BF%C0%C1%C2%C3%C4%C5%C6%C7%C8%C9%CA%CB%CC%CD%CE%CF%D0%D1%D2%D3%D4%D5%D6%D7%D8%D9%DA%DB%DC%DD%DE%DF%E0%E1%E2%E3%E4%E5%E6%E7%E8%E9%EA%EB%EC%ED%EE%EF%F0%F1%F2%F3%F4%F5%F6%F7%F8%F9%FA%FB%FC%FD%FE%FF');
-
- describe('#base64urlEncode', function () {
-
- it('should base64 URL-safe a string', function (done) {
-
- expect(Hoek.base64urlEncode(str)).to.equal(base64str);
- done();
- });
- });
-
- describe('#base64urlDecode', function () {
-
- it('should un-base64 URL-safe a string', function (done) {
-
- expect(Hoek.base64urlDecode(base64str)).to.equal(str);
- done();
- });
-
- it('should return error on undefined input', function (done) {
-
- expect(Hoek.base64urlDecode().message).to.exist;
- done();
- });
-
- it('should return error on invalid input', function (done) {
-
- expect(Hoek.base64urlDecode('*').message).to.exist;
- done();
- });
- });
- });
-
- describe('#escapeHeaderAttribute', function () {
-
- it('should not alter ascii values', function (done) {
-
- var a = Hoek.escapeHeaderAttribute('My Value');
- expect(a).to.equal('My Value');
- done();
- });
-
- it('should escape all special HTTP header attribute characters', function (done) {
-
- var a = Hoek.escapeHeaderAttribute('I said go!!!#"' + String.fromCharCode(92));
- expect(a).to.equal('I said go!!!#\\"\\\\');
- done();
- });
-
- it('should throw on large unicode characters', function (done) {
-
- var fn = function () {
-
- Hoek.escapeHeaderAttribute('this is a test' + String.fromCharCode(500) + String.fromCharCode(300));
- };
-
- expect(fn).to.throw(Error);
- done();
- });
-
- it('should throw on CRLF to prevent response splitting', function (done) {
-
- var fn = function () {
-
- Hoek.escapeHeaderAttribute('this is a test\r\n');
- };
-
- expect(fn).to.throw(Error);
- done();
- });
- });
-
- describe('#escapeHtml', function () {
-
- it('should escape all special HTML characters', function (done) {
-
- var a = Hoek.escapeHtml('&<>"\'`');
- expect(a).to.equal('&<>"'`');
- done();
- });
-
- it('should return empty string on falsy input', function (done) {
-
- var a = Hoek.escapeHtml('');
- expect(a).to.equal('');
- done();
- });
-
- it('should return unchanged string on no reserved input', function (done) {
-
- var a = Hoek.escapeHtml('abc');
- expect(a).to.equal('abc');
- done();
- });
- });
-
- describe('#printEvent', function () {
-
- it('outputs event as string', function (done) {
-
- var event = {
- timestamp: (new Date(2013, 1, 1, 6, 30, 45, 123)).getTime(),
- tags: ['a', 'b', 'c'],
- data: { some: 'data' }
- };
-
- Hoek.consoleFunc = function (string) {
-
- Hoek.consoleFunc = console.log;
- expect(string).to.equal('130201/063045.123, a, {"some":"data"}');
- done();
- };
-
- Hoek.printEvent(event);
- });
-
- it('outputs JSON error', function (done) {
-
- var event = {
- timestamp: (new Date(2013, 1, 1, 6, 30, 45, 123)).getTime(),
- tags: ['a', 'b', 'c'],
- data: { some: 'data' }
- };
-
- event.data.a = event.data;
-
- Hoek.consoleFunc = function (string) {
-
- Hoek.consoleFunc = console.log;
- expect(string).to.equal('130201/063045.123, a, JSON Error: Converting circular structure to JSON');
- done();
- };
-
- Hoek.printEvent(event);
- });
- });
-
- describe('#nextTick', function () {
-
- it('calls the provided callback on nextTick', function (done) {
-
- var a = 0;
-
- var inc = function (step, next) {
-
- a += step;
- next();
- };
-
- var ticked = Hoek.nextTick(inc);
-
- ticked(5, function () {
-
- expect(a).to.equal(6);
- done();
- });
-
- expect(a).to.equal(0);
- inc(1, function () {
-
- expect(a).to.equal(1);
- });
- });
- });
-});
-
diff --git a/deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/test/modules/test1.js b/deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/test/modules/test1.js deleted file mode 100755 index 3f41e601e54..00000000000 --- a/deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/test/modules/test1.js +++ /dev/null @@ -1 +0,0 @@ -exports.x = 1;
diff --git a/deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/test/modules/test2.js b/deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/test/modules/test2.js deleted file mode 100755 index 38556b274d3..00000000000 --- a/deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/test/modules/test2.js +++ /dev/null @@ -1 +0,0 @@ -exports.y = 2;
diff --git a/deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/test/modules/test3.js b/deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/test/modules/test3.js deleted file mode 100755 index 436b860b807..00000000000 --- a/deps/npm/node_modules/request/node_modules/hawk/node_modules/sntp/node_modules/hoek/test/modules/test3.js +++ /dev/null @@ -1 +0,0 @@ -exports.z = 3;
diff --git a/deps/npm/node_modules/request/node_modules/hawk/package.json b/deps/npm/node_modules/request/node_modules/hawk/package.json index 6c6ba75a736..1b71f956e3a 100755 --- a/deps/npm/node_modules/request/node_modules/hawk/package.json +++ b/deps/npm/node_modules/request/node_modules/hawk/package.json @@ -1,7 +1,7 @@ { "name": "hawk", "description": "HTTP Hawk Authentication Scheme", - "version": "0.13.1", + "version": "1.0.0", "author": { "name": "Eran Hammer", "email": "eran@hueniverse.com", @@ -23,7 +23,7 @@ "node": ">=0.8.0" }, "dependencies": { - "hoek": "0.8.x", + "hoek": "0.9.x", "boom": "0.4.x", "cryptiles": "0.2.x", "sntp": "0.2.x" @@ -42,11 +42,11 @@ "url": "http://github.com/hueniverse/hawk/raw/master/LICENSE" } ], - "readme": "![hawk Logo](https://raw.github.com/hueniverse/hawk/master/images/hawk.png)\r\n\r\n<img align=\"right\" src=\"https://raw.github.com/hueniverse/hawk/master/images/logo.png\" /> **Hawk** is an HTTP authentication scheme using a message authentication code (MAC) algorithm to provide partial\r\nHTTP request cryptographic verification. For more complex use cases such as access delegation, see [Oz](https://github.com/hueniverse/oz).\r\n\r\nCurrent version: **0.13**\r\n\r\n[![Build Status](https://secure.travis-ci.org/hueniverse/hawk.png)](http://travis-ci.org/hueniverse/hawk)\r\n\r\n# Table of Content\r\n\r\n- [**Introduction**](#introduction)\r\n - [Replay Protection](#replay-protection)\r\n - [Usage Example](#usage-example)\r\n - [Protocol Example](#protocol-example)\r\n - [Payload Validation](#payload-validation)\r\n - [Response Payload Validation](#response-payload-validation)\r\n - [Browser Support and Considerations](#browser-support-and-considerations)\r\n<p></p>\r\n- [**Single URI Authorization**](#single-uri-authorization)\r\n - [Usage Example](#bewit-usage-example)\r\n<p></p>\r\n- [**Security Considerations**](#security-considerations)\r\n - [MAC Keys Transmission](#mac-keys-transmission)\r\n - [Confidentiality of Requests](#confidentiality-of-requests)\r\n - [Spoofing by Counterfeit Servers](#spoofing-by-counterfeit-servers)\r\n - [Plaintext Storage of Credentials](#plaintext-storage-of-credentials)\r\n - [Entropy of Keys](#entropy-of-keys)\r\n - [Coverage Limitations](#coverage-limitations)\r\n - [Future Time Manipulation](#future-time-manipulation)\r\n - [Client Clock Poisoning](#client-clock-poisoning)\r\n - [Bewit Limitations](#bewit-limitations)\r\n<p></p>\r\n- [**Frequently Asked Questions**](#frequently-asked-questions)\r\n<p></p>\r\n- [**Acknowledgements**](#acknowledgements)\r\n\r\n# Introduction\r\n\r\n**Hawk** is an HTTP authentication scheme providing mechanisms for making authenticated HTTP requests with\r\npartial cryptographic verification of the request and response, covering the HTTP method, request URI, host,\r\nand optionally the request payload.\r\n\r\nSimilar to the HTTP [Digest access authentication schemes](http://www.ietf.org/rfc/rfc2617.txt), **Hawk** uses a set of\r\nclient credentials which include an identifier (e.g. username) and key (e.g. password). Likewise, just as with the Digest scheme,\r\nthe key is never included in authenticated requests. Instead, it is used to calculate a request MAC value which is\r\nincluded in its place.\r\n\r\nHowever, **Hawk** has several differences from Digest. In particular, while both use a nonce to limit the possibility of\r\nreplay attacks, in **Hawk** the client generates the nonce and uses it in combination with a timestamp, leading to less\r\n\"chattiness\" (interaction with the server).\r\n\r\nAlso unlike Digest, this scheme is not intended to protect the key itself (the password in Digest) because\r\nthe client and server must both have access to the key material in the clear.\r\n\r\nThe primary design goals of this scheme are to:\r\n* simplify and improve HTTP authentication for services that are unwilling or unable to deploy TLS for all resources,\r\n* secure credentials against leakage (e.g., when the client uses some form of dynamic configuration to determine where\r\n to send an authenticated request), and\r\n* avoid the exposure of credentials sent to a malicious server over an unauthenticated secure channel due to client\r\n failure to validate the server's identity as part of its TLS handshake.\r\n\r\nIn addition, **Hawk** supports a method for granting third-parties temporary access to individual resources using\r\na query parameter called _bewit_ (in falconry, a leather strap used to attach a tracking device to the leg of a hawk).\r\n\r\nThe **Hawk** scheme requires the establishment of a shared symmetric key between the client and the server,\r\nwhich is beyond the scope of this module. Typically, the shared credentials are established via an initial\r\nTLS-protected phase or derived from some other shared confidential information available to both the client\r\nand the server.\r\n\r\n\r\n## Replay Protection\r\n\r\nWithout replay protection, an attacker can use a compromised (but otherwise valid and authenticated) request more \r\nthan once, gaining access to a protected resource. To mitigate this, clients include both a nonce and a timestamp when \r\nmaking requests. This gives the server enough information to prevent replay attacks.\r\n\r\nThe nonce is generated by the client, and is a string unique across all requests with the same timestamp and\r\nkey identifier combination. \r\n\r\nThe timestamp enables the server to restrict the validity period of the credentials where requests occuring afterwards\r\nare rejected. It also removes the need for the server to retain an unbounded number of nonce values for future checks.\r\nBy default, **Hawk** uses a time window of 1 minute to allow for time skew between the client and server (which in\r\npractice translates to a maximum of 2 minutes as the skew can be positive or negative).\r\n\r\nUsing a timestamp requires the client's clock to be in sync with the server's clock. **Hawk** requires both the client\r\nclock and the server clock to use NTP to ensure synchronization. However, given the limitations of some client types\r\n(e.g. browsers) to deploy NTP, the server provides the client with its current time (in seconds precision) in response\r\nto a bad timestamp.\r\n\r\nThere is no expectation that the client will adjust its system clock to match the server (in fact, this would be a\r\npotential attack vector). Instead, the client only uses the server's time to calculate an offset used only\r\nfor communications with that particular server. The protocol rewards clients with synchronized clocks by reducing\r\nthe number of round trips required to authenticate the first request.\r\n\r\n\r\n## Usage Example\r\n\r\nServer code:\r\n\r\n```javascript\r\nvar Http = require('http');\r\nvar Hawk = require('hawk');\r\n\r\n\r\n// Credentials lookup function\r\n\r\nvar credentialsFunc = function (id, callback) {\r\n\r\n var credentials = {\r\n key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn',\r\n algorithm: 'sha256',\r\n user: 'Steve'\r\n };\r\n\r\n return callback(null, credentials);\r\n};\r\n\r\n// Create HTTP server\r\n\r\nvar handler = function (req, res) {\r\n\r\n // Authenticate incoming request\r\n\r\n Hawk.server.authenticate(req, credentialsFunc, {}, function (err, credentials, artifacts) {\r\n\r\n // Prepare response\r\n\r\n var payload = (!err ? 'Hello ' + credentials.user + ' ' + artifacts.ext : 'Shoosh!');\r\n var headers = { 'Content-Type': 'text/plain' };\r\n\r\n // Generate Server-Authorization response header\r\n\r\n var header = Hawk.server.header(credentials, artifacts, { payload: payload, contentType: headers['Content-Type'] });\r\n headers['Server-Authorization'] = header;\r\n\r\n // Send the response back\r\n\r\n res.writeHead(!err ? 200 : 401, headers);\r\n res.end(payload);\r\n });\r\n};\r\n\r\n// Start server\r\n\r\nHttp.createServer(handler).listen(8000, 'example.com');\r\n```\r\n\r\nClient code:\r\n\r\n```javascript\r\nvar Request = require('request');\r\nvar Hawk = require('hawk');\r\n\r\n\r\n// Client credentials\r\n\r\nvar credentials = {\r\n id: 'dh37fgj492je',\r\n key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn',\r\n algorithm: 'sha256'\r\n}\r\n\r\n// Request options\r\n\r\nvar requestOptions = {\r\n uri: 'http://example.com:8000/resource/1?b=1&a=2',\r\n method: 'GET',\r\n headers: {}\r\n};\r\n\r\n// Generate Authorization request header\r\n\r\nvar header = Hawk.client.header('http://example.com:8000/resource/1?b=1&a=2', 'GET', { credentials: credentials, ext: 'some-app-data' });\r\nrequestOptions.headers.Authorization = header.field;\r\n\r\n// Send authenticated request\r\n\r\nRequest(requestOptions, function (error, response, body) {\r\n\r\n // Authenticate the server's response\r\n\r\n var isValid = Hawk.client.authenticate(response, credentials, header.artifacts, { payload: body });\r\n\r\n // Output results\r\n\r\n console.log(response.statusCode + ': ' + body + (isValid ? ' (valid)' : ' (invalid)'));\r\n});\r\n```\r\n\r\n**Hawk** utilized the [**SNTP**](https://github.com/hueniverse/sntp) module for time sync management. By default, the local\r\nmachine time is used. To automatically retrieve and synchronice the clock within the application, use the SNTP 'start()' method.\r\n\r\n```javascript\r\nHawk.sntp.start();\r\n```\r\n\r\n\r\n## Protocol Example\r\n\r\nThe client attempts to access a protected resource without authentication, sending the following HTTP request to\r\nthe resource server:\r\n\r\n```\r\nGET /resource/1?b=1&a=2 HTTP/1.1\r\nHost: example.com:8000\r\n```\r\n\r\nThe resource server returns an authentication challenge.\r\n\r\n```\r\nHTTP/1.1 401 Unauthorized\r\nWWW-Authenticate: Hawk\r\n```\r\n\r\nThe client has previously obtained a set of **Hawk** credentials for accessing resources on the \"http://example.com/\"\r\nserver. The **Hawk** credentials issued to the client include the following attributes:\r\n\r\n* Key identifier: dh37fgj492je\r\n* Key: werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn\r\n* Algorithm: sha256\r\n\r\nThe client generates the authentication header by calculating a timestamp (e.g. the number of seconds since January 1,\r\n1970 00:00:00 GMT), generating a nonce, and constructing the normalized request string (each value followed by a newline\r\ncharacter):\r\n\r\n```\r\nhawk.1.header\r\n1353832234\r\nj4h3g2\r\nGET\r\n/resource?a=1&b=2\r\nexample.com\r\n8000\r\n\r\nsome-app-ext-data\r\n\r\n```\r\n\r\nThe request MAC is calculated using HMAC with the specified hash algorithm \"sha256\" and the key over the normalized request string.\r\nThe result is base64-encoded to produce the request MAC:\r\n\r\n```\r\n6R4rV5iE+NPoym+WwjeHzjAGXUtLNIxmo1vpMofpLAE=\r\n```\r\n\r\nThe client includes the **Hawk** key identifier, timestamp, nonce, application specific data, and request MAC with the request using\r\nthe HTTP `Authorization` request header field:\r\n\r\n```\r\nGET /resource/1?b=1&a=2 HTTP/1.1\r\nHost: example.com:8000\r\nAuthorization: Hawk id=\"dh37fgj492je\", ts=\"1353832234\", nonce=\"j4h3g2\", ext=\"some-app-ext-data\", mac=\"6R4rV5iE+NPoym+WwjeHzjAGXUtLNIxmo1vpMofpLAE=\"\r\n```\r\n\r\nThe server validates the request by calculating the request MAC again based on the request received and verifies the validity\r\nand scope of the **Hawk** credentials. If valid, the server responds with the requested resource.\r\n\r\n\r\n### Payload Validation\r\n\r\n**Hawk** provides optional payload validation. When generating the authentication header, the client calculates a payload hash\r\nusing the specified hash algorithm. The hash is calculated over the concatenated value of (each followed by a newline character):\r\n* `hawk.1.payload`\r\n* the content-type in lowercase, without any parameters (e.g. `application/json`)\r\n* the request payload prior to any content encoding (the exact representation requirements should be specified by the server for payloads other than simple single-part ascii to ensure interoperability)\r\n\r\nFor example:\r\n\r\n* Payload: `Thank you for flying Hawk`\r\n* Content Type: `text/plain`\r\n* Hash (sha256): `Yi9LfIIFRtBEPt74PVmbTF/xVAwPn7ub15ePICfgnuY=`\r\n\r\nResults in the following input to the payload hash function (newline terminated values):\r\n\r\n```\r\nhawk.1.payload\r\ntext/plain\r\nThank you for flying Hawk\r\n\r\n```\r\n\r\nWhich produces the following hash value:\r\n\r\n```\r\nYi9LfIIFRtBEPt74PVmbTF/xVAwPn7ub15ePICfgnuY=\r\n```\r\n\r\nThe client constructs the normalized request string (newline terminated values):\r\n\r\n```\r\nhawk.1.header\r\n1353832234\r\nj4h3g2\r\nPOST\r\n/resource?a=1&b=2\r\nexample.com\r\n8000\r\nYi9LfIIFRtBEPt74PVmbTF/xVAwPn7ub15ePICfgnuY=\r\nsome-app-ext-data\r\n\r\n```\r\n\r\nThen calculates the request MAC and includes the **Hawk** key identifier, timestamp, nonce, payload hash, application specific data,\r\nand request MAC, with the request using the HTTP `Authorization` request header field:\r\n\r\n```\r\nPOST /resource/1 HTTP/1.1\r\nHost: example.com:8000\r\nAuthorization: Hawk id=\"dh37fgj492je\", ts=\"1353832234\", nonce=\"j4h3g2\", hash=\"Yi9LfIIFRtBEPt74PVmbTF/xVAwPn7ub15ePICfgnuY=\", ext=\"some-app-ext-data\", mac=\"aSe1DERmZuRl3pI36/9BdZmnErTw3sNzOOAUlfeKjVw=\"\r\n```\r\n\r\nIt is up to the server if and when it validates the payload for any given request, based solely on it's security policy\r\nand the nature of the data included.\r\n\r\nIf the payload is available at the time of authentication, the server uses the hash value provided by the client to construct\r\nthe normalized string and validates the MAC. If the MAC is valid, the server calculates the payload hash and compares the value\r\nwith the provided payload hash in the header. In many cases, checking the MAC first is faster than calculating the payload hash.\r\n\r\nHowever, if the payload is not available at authentication time (e.g. too large to fit in memory, streamed elsewhere, or processed\r\nat a different stage in the application), the server may choose to defer payload validation for later by retaining the hash value\r\nprovided by the client after validating the MAC.\r\n\r\nIt is important to note that MAC validation does not mean the hash value provided by the client is valid, only that the value\r\nincluded in the header was not modified. Without calculating the payload hash on the server and comparing it to the value provided\r\nby the client, the payload may be modified by an attacker.\r\n\r\n\r\n## Response Payload Validation\r\n\r\n**Hawk** provides partial response payload validation. The server includes the `Server-Authorization` response header which enables the\r\nclient to authenticate the response and ensure it is talking to the right server. **Hawk** defines the HTTP `Server-Authorization` header\r\nas a response header using the exact same syntax as the `Authorization` request header field.\r\n\r\nThe header is contructed using the same process as the client's request header. The server uses the same credentials and other\r\nartifacts provided by the client to constructs the normalized request string. The `ext` and `hash` values are replaced with\r\nnew values based on the server response. The rest as identical to those used by the client.\r\n\r\nThe result MAC digest is included with the optional `hash` and `ext` values:\r\n\r\n```\r\nServer-Authorization: Hawk mac=\"XIJRsMl/4oL+nn+vKoeVZPdCHXB4yJkNnBbTbHFZUYE=\", hash=\"f9cDF/TDm7TkYRLnGwRMfeDzT6LixQVLvrIKhh0vgmM=\", ext=\"response-specific\"\r\n```\r\n\r\n\r\n## Browser Support and Considerations\r\n\r\nA browser script is provided for including using a `<script>` tag in [lib/browser.js](/lib/browser.js).\r\n\r\n**Hawk** relies on the _Server-Authorization_ and _WWW-Authenticate_ headers in its response to communicate with the client.\r\nTherefore, in case of CORS requests, it is important to consider sending _Access-Control-Expose-Headers_ with the value\r\n_\"WWW-Authenticate, Server-Authorization\"_ on each response from your server. As explained in the\r\n[specifications](http://www.w3.org/TR/cors/#access-control-expose-headers-response-header), it will indicate that these headers\r\ncan safely be accessed by the client (using getResponseHeader() on the XmlHttpRequest object). Otherwise you will be met with a\r\n[\"simple response header\"](http://www.w3.org/TR/cors/#simple-response-header) which excludes these fields and would prevent the\r\nHawk client from authenticating the requests.You can read more about the why and how in this\r\n[article](http://www.html5rocks.com/en/tutorials/cors/#toc-adding-cors-support-to-the-server)\r\n\r\n\r\n# Single URI Authorization\r\n\r\nThere are cases in which limited and short-term access to a protected resource is granted to a third party which does not\r\nhave access to the shared credentials. For example, displaying a protected image on a web page accessed by anyone. **Hawk**\r\nprovides limited support for such URIs in the form of a _bewit_ - a URI query parameter appended to the request URI which contains\r\nthe necessary credentials to authenticate the request.\r\n\r\nBecause of the significant security risks involved in issuing such access, bewit usage is purposely limited only to GET requests\r\nand for a finite period of time. Both the client and server can issue bewit credentials, however, the server should not use the same\r\ncredentials as the client to maintain clear traceability as to who issued which credentials.\r\n\r\nIn order to simplify implementation, bewit credentials do not support single-use policy and can be replayed multiple times within\r\nthe granted access timeframe. \r\n\r\n\r\n## Bewit Usage Example\r\n\r\nServer code:\r\n\r\n```javascript\r\nvar Http = require('http');\r\nvar Hawk = require('hawk');\r\n\r\n\r\n// Credentials lookup function\r\n\r\nvar credentialsFunc = function (id, callback) {\r\n\r\n var credentials = {\r\n key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn',\r\n algorithm: 'sha256'\r\n };\r\n\r\n return callback(null, credentials);\r\n};\r\n\r\n// Create HTTP server\r\n\r\nvar handler = function (req, res) {\r\n\r\n Hawk.uri.authenticate(req, credentialsFunc, {}, function (err, credentials, attributes) {\r\n\r\n res.writeHead(!err ? 200 : 401, { 'Content-Type': 'text/plain' });\r\n res.end(!err ? 'Access granted' : 'Shoosh!');\r\n });\r\n};\r\n\r\nHttp.createServer(handler).listen(8000, 'example.com');\r\n```\r\n\r\nBewit code generation:\r\n\r\n```javascript\r\nvar Request = require('request');\r\nvar Hawk = require('hawk');\r\n\r\n\r\n// Client credentials\r\n\r\nvar credentials = {\r\n id: 'dh37fgj492je',\r\n key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn',\r\n algorithm: 'sha256'\r\n}\r\n\r\n// Generate bewit\r\n\r\nvar duration = 60 * 5; // 5 Minutes\r\nvar bewit = Hawk.uri.getBewit('http://example.com:8080/resource/1?b=1&a=2', { credentials: credentials, ttlSec: duration, ext: 'some-app-data' });\r\nvar uri = 'http://example.com:8000/resource/1?b=1&a=2' + '&bewit=' + bewit;\r\n```\r\n\r\n\r\n# Security Considerations\r\n\r\nThe greatest sources of security risks are usually found not in **Hawk** but in the policies and procedures surrounding its use.\r\nImplementers are strongly encouraged to assess how this module addresses their security requirements. This section includes\r\nan incomplete list of security considerations that must be reviewed and understood before deploying **Hawk** on the server.\r\nMany of the protections provided in **Hawk** depends on whether and how they are used.\r\n\r\n### MAC Keys Transmission\r\n\r\n**Hawk** does not provide any mechanism for obtaining or transmitting the set of shared credentials required. Any mechanism used\r\nto obtain **Hawk** credentials must ensure that these transmissions are protected using transport-layer mechanisms such as TLS.\r\n\r\n### Confidentiality of Requests\r\n\r\nWhile **Hawk** provides a mechanism for verifying the integrity of HTTP requests, it provides no guarantee of request\r\nconfidentiality. Unless other precautions are taken, eavesdroppers will have full access to the request content. Servers should\r\ncarefully consider the types of data likely to be sent as part of such requests, and employ transport-layer security mechanisms\r\nto protect sensitive resources.\r\n\r\n### Spoofing by Counterfeit Servers\r\n\r\n**Hawk** provides limited verification of the server authenticity. When receiving a response back from the server, the server\r\nmay choose to include a response `Server-Authorization` header which the client can use to verify the response. However, it is up to\r\nthe server to determine when such measure is included, to up to the client to enforce that policy.\r\n\r\nA hostile party could take advantage of this by intercepting the client's requests and returning misleading or otherwise\r\nincorrect responses. Service providers should consider such attacks when developing services using this protocol, and should\r\nrequire transport-layer security for any requests where the authenticity of the resource server or of server responses is an issue.\r\n\r\n### Plaintext Storage of Credentials\r\n\r\nThe **Hawk** key functions the same way passwords do in traditional authentication systems. In order to compute the request MAC,\r\nthe server must have access to the key in plaintext form. This is in contrast, for example, to modern operating systems, which\r\nstore only a one-way hash of user credentials.\r\n\r\nIf an attacker were to gain access to these keys - or worse, to the server's database of all such keys - he or she would be able\r\nto perform any action on behalf of any resource owner. Accordingly, it is critical that servers protect these keys from unauthorized\r\naccess.\r\n\r\n### Entropy of Keys\r\n\r\nUnless a transport-layer security protocol is used, eavesdroppers will have full access to authenticated requests and request\r\nMAC values, and will thus be able to mount offline brute-force attacks to recover the key used. Servers should be careful to\r\nassign keys which are long enough, and random enough, to resist such attacks for at least the length of time that the **Hawk**\r\ncredentials are valid.\r\n\r\nFor example, if the credentials are valid for two weeks, servers should ensure that it is not possible to mount a brute force\r\nattack that recovers the key in less than two weeks. Of course, servers are urged to err on the side of caution, and use the\r\nlongest key reasonable.\r\n\r\nIt is equally important that the pseudo-random number generator (PRNG) used to generate these keys be of sufficiently high\r\nquality. Many PRNG implementations generate number sequences that may appear to be random, but which nevertheless exhibit\r\npatterns or other weaknesses which make cryptanalysis or brute force attacks easier. Implementers should be careful to use\r\ncryptographically secure PRNGs to avoid these problems.\r\n\r\n### Coverage Limitations\r\n\r\nThe request MAC only covers the HTTP `Host` header and optionally the `Content-Type` header. It does not cover any other headers\r\nwhich can often affect how the request body is interpreted by the server. If the server behavior is influenced by the presence\r\nor value of such headers, an attacker can manipulate the request headers without being detected. Implementers should use the\r\n`ext` feature to pass application-specific information via the `Authorization` header which is protected by the request MAC.\r\n\r\nThe response authentication, when performed, only covers the response payload, content-type, and the request information \r\nprovided by the client in it's request (method, resource, timestamp, nonce, etc.). It does not cover the HTTP status code or\r\nany other response header field (e.g. Location) which can affect the client's behaviour.\r\n\r\n### Future Time Manipulation\r\n\r\nThe protocol relies on a clock sync between the client and server. To accomplish this, the server informs the client of its\r\ncurrent time when an invalid timestamp is received.\r\n\r\nIf an attacker is able to manipulate this information and cause the client to use an incorrect time, it would be able to cause\r\nthe client to generate authenticated requests using time in the future. Such requests will fail when sent by the client, and will\r\nnot likely leave a trace on the server (given the common implementation of nonce, if at all enforced). The attacker will then\r\nbe able to replay the request at the correct time without detection.\r\n\r\nThe client must only use the time information provided by the server if:\r\n* it was delivered over a TLS connection and the server identity has been verified, or\r\n* the `tsm` MAC digest calculated using the same client credentials over the timestamp has been verified.\r\n\r\n### Client Clock Poisoning\r\n\r\nWhen receiving a request with a bad timestamp, the server provides the client with its current time. The client must never use\r\nthe time received from the server to adjust its own clock, and must only use it to calculate an offset for communicating with\r\nthat particular server.\r\n\r\n### Bewit Limitations\r\n\r\nSpecial care must be taken when issuing bewit credentials to third parties. Bewit credentials are valid until expiration and cannot\r\nbe revoked or limited without using other means. Whatever resource they grant access to will be completely exposed to anyone with\r\naccess to the bewit credentials which act as bearer credentials for that particular resource. While bewit usage is limited to GET\r\nrequests only and therefore cannot be used to perform transactions or change server state, it can still be used to expose private\r\nand sensitive information.\r\n\r\n\r\n# Frequently Asked Questions\r\n\r\n### Where is the protocol specification?\r\n\r\nIf you are looking for some prose explaining how all this works, **this is it**. **Hawk** is being developed as an open source\r\nproject instead of a standard. In other words, the [code](/hueniverse/hawk/tree/master/lib) is the specification. Not sure about\r\nsomething? Open an issue!\r\n\r\n### Is it done?\r\n\r\nAt if version 0.10.0, **Hawk** is feature-complete. However, until this module reaches version 1.0.0 it is considered experimental\r\nand is likely to change. This also means your feedback and contribution are very welcome. Feel free to open issues with questions\r\nand suggestions.\r\n\r\n### Where can I find **Hawk** implementations in other languages?\r\n\r\n**Hawk**'s only reference implementation is provided in JavaScript as a node.js module. However, others are actively porting it to other\r\nplatforms. There is already a [PHP](https://github.com/alexbilbie/PHP-Hawk),\r\n[.NET](https://github.com/pcibraro/hawknet), and [JAVA](https://github.com/wealdtech/hawk) libraries available. The full list\r\nis maintained [here](https://github.com/hueniverse/hawk/issues?labels=port). Please add an issue if you are working on another\r\nport. A cross-platform test-suite is in the works.\r\n\r\n### Why isn't the algorithm part of the challenge or dynamically negotiated?\r\n\r\nThe algorithm used is closely related to the key issued as different algorithms require different key sizes (and other\r\nrequirements). While some keys can be used for multiple algorithm, the protocol is designed to closely bind the key and algorithm\r\ntogether as part of the issued credentials.\r\n\r\n### Why is Host and Content-Type the only headers covered by the request MAC?\r\n\r\nIt is really hard to include other headers. Headers can be changed by proxies and other intermediaries and there is no\r\nwell-established way to normalize them. Many platforms change the case of header field names and values. The only\r\nstraight-forward solution is to include the headers in some blob (say, base64 encoded JSON) and include that with the request,\r\nan approach taken by JWT and other such formats. However, that design violates the HTTP header boundaries, repeats information,\r\nand introduces other security issues because firewalls will not be aware of these \"hidden\" headers. In addition, any information\r\nrepeated must be compared to the duplicated information in the header and therefore only moves the problem elsewhere.\r\n\r\n### Why not just use HTTP Digest?\r\n\r\nDigest requires pre-negotiation to establish a nonce. This means you can't just make a request - you must first send\r\na protocol handshake to the server. This pattern has become unacceptable for most web services, especially mobile\r\nwhere extra round-trip are costly.\r\n\r\n### Why bother with all this nonce and timestamp business?\r\n\r\n**Hawk** is an attempt to find a reasonable, practical compromise between security and usability. OAuth 1.0 got timestamp\r\nand nonces halfway right but failed when it came to scalability and consistent developer experience. **Hawk** addresses\r\nit by requiring the client to sync its clock, but provides it with tools to accomplish it.\r\n\r\nIn general, replay protection is a matter of application-specific threat model. It is less of an issue on a TLS-protected\r\nsystem where the clients are implemented using best practices and are under the control of the server. Instead of dropping\r\nreplay protection, **Hawk** offers a required time window and an optional nonce verification. Together, it provides developers\r\nwith the ability to decide how to enforce their security policy without impacting the client's implementation.\r\n\r\n### What are `app` and `dlg` in the authorization header and normalized mac string?\r\n\r\nThe original motivation for **Hawk** was to replace the OAuth 1.0 use cases. This included both a simple client-server mode which\r\nthis module is specifically designed for, and a delegated access mode which is being developed separately in\r\n[Oz](https://github.com/hueniverse/oz). In addition to the **Hawk** use cases, Oz requires another attribute: the application id `app`.\r\nThis provides binding between the credentials and the application in a way that prevents an attacker from tricking an application\r\nto use credentials issued to someone else. It also has an optional 'delegated-by' attribute `dlg` which is the application id of the\r\napplication the credentials were directly issued to. The goal of these two additions is to allow Oz to utilize **Hawk** directly,\r\nbut with the additional security of delegated credentials.\r\n\r\n### What is the purpose of the static strings used in each normalized MAC input?\r\n\r\nWhen calculating a hash or MAC, a static prefix (tag) is added. The prefix is used to prevent MAC values from being\r\nused or reused for a purpose other than what they were created for (i.e. prevents switching MAC values between a request,\r\nresponse, and a bewit use cases). It also protects against expliots created after a potential change in how the protocol\r\ncreates the normalized string. For example, if a future version would switch the order of nonce and timestamp, it\r\ncan create an exploit opportunity for cases where the nonce is similar in format to a timestamp.\r\n\r\n### Does **Hawk** have anything to do with OAuth?\r\n\r\nShort answer: no.\r\n\r\n**Hawk** was originally proposed as the OAuth MAC Token specification. However, the OAuth working group in its consistent\r\nincompetence failed to produce a final, usable solution to address one of the most popular use cases of OAuth 1.0 - using it\r\nto authenticate simple client-server transactions (i.e. two-legged). As you can guess, the OAuth working group is still hard\r\nat work to produce more garbage.\r\n\r\n**Hawk** provides a simple HTTP authentication scheme for making client-server requests. It does not address the OAuth use case\r\nof delegating access to a third party. If you are looking for an OAuth alternative, check out [Oz](https://github.com/hueniverse/oz).\r\n\r\n\r\n# Acknowledgements\r\n\r\n**Hawk** is a derivative work of the [HTTP MAC Authentication Scheme](http://tools.ietf.org/html/draft-hammer-oauth-v2-mac-token-05) proposal\r\nco-authored by Ben Adida, Adam Barth, and Eran Hammer, which in turn was based on the OAuth 1.0 community specification.\r\n\r\nSpecial thanks to Ben Laurie for his always insightful feedback and advice.\r\n\r\nThe **Hawk** logo was created by [Chris Carrasco](http://chriscarrasco.com).\r\n", + "readme": "![hawk Logo](https://raw.github.com/hueniverse/hawk/master/images/hawk.png)\n\n<img align=\"right\" src=\"https://raw.github.com/hueniverse/hawk/master/images/logo.png\" /> **Hawk** is an HTTP authentication scheme using a message authentication code (MAC) algorithm to provide partial\nHTTP request cryptographic verification. For more complex use cases such as access delegation, see [Oz](https://github.com/hueniverse/oz).\n\nCurrent version: **1.0**\n\n[![Build Status](https://secure.travis-ci.org/hueniverse/hawk.png)](http://travis-ci.org/hueniverse/hawk)\n\n# Table of Content\n\n- [**Introduction**](#introduction)\n - [Replay Protection](#replay-protection)\n - [Usage Example](#usage-example)\n - [Protocol Example](#protocol-example)\n - [Payload Validation](#payload-validation)\n - [Response Payload Validation](#response-payload-validation)\n - [Browser Support and Considerations](#browser-support-and-considerations)\n<p></p>\n- [**Single URI Authorization**](#single-uri-authorization)\n - [Usage Example](#bewit-usage-example)\n<p></p>\n- [**Security Considerations**](#security-considerations)\n - [MAC Keys Transmission](#mac-keys-transmission)\n - [Confidentiality of Requests](#confidentiality-of-requests)\n - [Spoofing by Counterfeit Servers](#spoofing-by-counterfeit-servers)\n - [Plaintext Storage of Credentials](#plaintext-storage-of-credentials)\n - [Entropy of Keys](#entropy-of-keys)\n - [Coverage Limitations](#coverage-limitations)\n - [Future Time Manipulation](#future-time-manipulation)\n - [Client Clock Poisoning](#client-clock-poisoning)\n - [Bewit Limitations](#bewit-limitations)\n - [Host Header Forgery](#host-header-forgery)\n<p></p>\n- [**Frequently Asked Questions**](#frequently-asked-questions)\n<p></p>\n- [**Acknowledgements**](#acknowledgements)\n\n# Introduction\n\n**Hawk** is an HTTP authentication scheme providing mechanisms for making authenticated HTTP requests with\npartial cryptographic verification of the request and response, covering the HTTP method, request URI, host,\nand optionally the request payload.\n\nSimilar to the HTTP [Digest access authentication schemes](http://www.ietf.org/rfc/rfc2617.txt), **Hawk** uses a set of\nclient credentials which include an identifier (e.g. username) and key (e.g. password). Likewise, just as with the Digest scheme,\nthe key is never included in authenticated requests. Instead, it is used to calculate a request MAC value which is\nincluded in its place.\n\nHowever, **Hawk** has several differences from Digest. In particular, while both use a nonce to limit the possibility of\nreplay attacks, in **Hawk** the client generates the nonce and uses it in combination with a timestamp, leading to less\n\"chattiness\" (interaction with the server).\n\nAlso unlike Digest, this scheme is not intended to protect the key itself (the password in Digest) because\nthe client and server must both have access to the key material in the clear.\n\nThe primary design goals of this scheme are to:\n* simplify and improve HTTP authentication for services that are unwilling or unable to deploy TLS for all resources,\n* secure credentials against leakage (e.g., when the client uses some form of dynamic configuration to determine where\n to send an authenticated request), and\n* avoid the exposure of credentials sent to a malicious server over an unauthenticated secure channel due to client\n failure to validate the server's identity as part of its TLS handshake.\n\nIn addition, **Hawk** supports a method for granting third-parties temporary access to individual resources using\na query parameter called _bewit_ (in falconry, a leather strap used to attach a tracking device to the leg of a hawk).\n\nThe **Hawk** scheme requires the establishment of a shared symmetric key between the client and the server,\nwhich is beyond the scope of this module. Typically, the shared credentials are established via an initial\nTLS-protected phase or derived from some other shared confidential information available to both the client\nand the server.\n\n\n## Replay Protection\n\nWithout replay protection, an attacker can use a compromised (but otherwise valid and authenticated) request more \nthan once, gaining access to a protected resource. To mitigate this, clients include both a nonce and a timestamp when \nmaking requests. This gives the server enough information to prevent replay attacks.\n\nThe nonce is generated by the client, and is a string unique across all requests with the same timestamp and\nkey identifier combination. \n\nThe timestamp enables the server to restrict the validity period of the credentials where requests occuring afterwards\nare rejected. It also removes the need for the server to retain an unbounded number of nonce values for future checks.\nBy default, **Hawk** uses a time window of 1 minute to allow for time skew between the client and server (which in\npractice translates to a maximum of 2 minutes as the skew can be positive or negative).\n\nUsing a timestamp requires the client's clock to be in sync with the server's clock. **Hawk** requires both the client\nclock and the server clock to use NTP to ensure synchronization. However, given the limitations of some client types\n(e.g. browsers) to deploy NTP, the server provides the client with its current time (in seconds precision) in response\nto a bad timestamp.\n\nThere is no expectation that the client will adjust its system clock to match the server (in fact, this would be a\npotential attack vector). Instead, the client only uses the server's time to calculate an offset used only\nfor communications with that particular server. The protocol rewards clients with synchronized clocks by reducing\nthe number of round trips required to authenticate the first request.\n\n\n## Usage Example\n\nServer code:\n\n```javascript\nvar Http = require('http');\nvar Hawk = require('hawk');\n\n\n// Credentials lookup function\n\nvar credentialsFunc = function (id, callback) {\n\n var credentials = {\n key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn',\n algorithm: 'sha256',\n user: 'Steve'\n };\n\n return callback(null, credentials);\n};\n\n// Create HTTP server\n\nvar handler = function (req, res) {\n\n // Authenticate incoming request\n\n Hawk.server.authenticate(req, credentialsFunc, {}, function (err, credentials, artifacts) {\n\n // Prepare response\n\n var payload = (!err ? 'Hello ' + credentials.user + ' ' + artifacts.ext : 'Shoosh!');\n var headers = { 'Content-Type': 'text/plain' };\n\n // Generate Server-Authorization response header\n\n var header = Hawk.server.header(credentials, artifacts, { payload: payload, contentType: headers['Content-Type'] });\n headers['Server-Authorization'] = header;\n\n // Send the response back\n\n res.writeHead(!err ? 200 : 401, headers);\n res.end(payload);\n });\n};\n\n// Start server\n\nHttp.createServer(handler).listen(8000, 'example.com');\n```\n\nClient code:\n\n```javascript\nvar Request = require('request');\nvar Hawk = require('hawk');\n\n\n// Client credentials\n\nvar credentials = {\n id: 'dh37fgj492je',\n key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn',\n algorithm: 'sha256'\n}\n\n// Request options\n\nvar requestOptions = {\n uri: 'http://example.com:8000/resource/1?b=1&a=2',\n method: 'GET',\n headers: {}\n};\n\n// Generate Authorization request header\n\nvar header = Hawk.client.header('http://example.com:8000/resource/1?b=1&a=2', 'GET', { credentials: credentials, ext: 'some-app-data' });\nrequestOptions.headers.Authorization = header.field;\n\n// Send authenticated request\n\nRequest(requestOptions, function (error, response, body) {\n\n // Authenticate the server's response\n\n var isValid = Hawk.client.authenticate(response, credentials, header.artifacts, { payload: body });\n\n // Output results\n\n console.log(response.statusCode + ': ' + body + (isValid ? ' (valid)' : ' (invalid)'));\n});\n```\n\n**Hawk** utilized the [**SNTP**](https://github.com/hueniverse/sntp) module for time sync management. By default, the local\nmachine time is used. To automatically retrieve and synchronice the clock within the application, use the SNTP 'start()' method.\n\n```javascript\nHawk.sntp.start();\n```\n\n\n## Protocol Example\n\nThe client attempts to access a protected resource without authentication, sending the following HTTP request to\nthe resource server:\n\n```\nGET /resource/1?b=1&a=2 HTTP/1.1\nHost: example.com:8000\n```\n\nThe resource server returns an authentication challenge.\n\n```\nHTTP/1.1 401 Unauthorized\nWWW-Authenticate: Hawk\n```\n\nThe client has previously obtained a set of **Hawk** credentials for accessing resources on the \"http://example.com/\"\nserver. The **Hawk** credentials issued to the client include the following attributes:\n\n* Key identifier: dh37fgj492je\n* Key: werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn\n* Algorithm: sha256\n\nThe client generates the authentication header by calculating a timestamp (e.g. the number of seconds since January 1,\n1970 00:00:00 GMT), generating a nonce, and constructing the normalized request string (each value followed by a newline\ncharacter):\n\n```\nhawk.1.header\n1353832234\nj4h3g2\nGET\n/resource/1?b=1&a=2\nexample.com\n8000\n\nsome-app-ext-data\n\n```\n\nThe request MAC is calculated using HMAC with the specified hash algorithm \"sha256\" and the key over the normalized request string.\nThe result is base64-encoded to produce the request MAC:\n\n```\n6R4rV5iE+NPoym+WwjeHzjAGXUtLNIxmo1vpMofpLAE=\n```\n\nThe client includes the **Hawk** key identifier, timestamp, nonce, application specific data, and request MAC with the request using\nthe HTTP `Authorization` request header field:\n\n```\nGET /resource/1?b=1&a=2 HTTP/1.1\nHost: example.com:8000\nAuthorization: Hawk id=\"dh37fgj492je\", ts=\"1353832234\", nonce=\"j4h3g2\", ext=\"some-app-ext-data\", mac=\"6R4rV5iE+NPoym+WwjeHzjAGXUtLNIxmo1vpMofpLAE=\"\n```\n\nThe server validates the request by calculating the request MAC again based on the request received and verifies the validity\nand scope of the **Hawk** credentials. If valid, the server responds with the requested resource.\n\n\n### Payload Validation\n\n**Hawk** provides optional payload validation. When generating the authentication header, the client calculates a payload hash\nusing the specified hash algorithm. The hash is calculated over the concatenated value of (each followed by a newline character):\n* `hawk.1.payload`\n* the content-type in lowercase, without any parameters (e.g. `application/json`)\n* the request payload prior to any content encoding (the exact representation requirements should be specified by the server for payloads other than simple single-part ascii to ensure interoperability)\n\nFor example:\n\n* Payload: `Thank you for flying Hawk`\n* Content Type: `text/plain`\n* Hash (sha256): `Yi9LfIIFRtBEPt74PVmbTF/xVAwPn7ub15ePICfgnuY=`\n\nResults in the following input to the payload hash function (newline terminated values):\n\n```\nhawk.1.payload\ntext/plain\nThank you for flying Hawk\n\n```\n\nWhich produces the following hash value:\n\n```\nYi9LfIIFRtBEPt74PVmbTF/xVAwPn7ub15ePICfgnuY=\n```\n\nThe client constructs the normalized request string (newline terminated values):\n\n```\nhawk.1.header\n1353832234\nj4h3g2\nPOST\n/resource/1?a=1&b=2\nexample.com\n8000\nYi9LfIIFRtBEPt74PVmbTF/xVAwPn7ub15ePICfgnuY=\nsome-app-ext-data\n\n```\n\nThen calculates the request MAC and includes the **Hawk** key identifier, timestamp, nonce, payload hash, application specific data,\nand request MAC, with the request using the HTTP `Authorization` request header field:\n\n```\nPOST /resource/1?a=1&b=2 HTTP/1.1\nHost: example.com:8000\nAuthorization: Hawk id=\"dh37fgj492je\", ts=\"1353832234\", nonce=\"j4h3g2\", hash=\"Yi9LfIIFRtBEPt74PVmbTF/xVAwPn7ub15ePICfgnuY=\", ext=\"some-app-ext-data\", mac=\"aSe1DERmZuRl3pI36/9BdZmnErTw3sNzOOAUlfeKjVw=\"\n```\n\nIt is up to the server if and when it validates the payload for any given request, based solely on it's security policy\nand the nature of the data included.\n\nIf the payload is available at the time of authentication, the server uses the hash value provided by the client to construct\nthe normalized string and validates the MAC. If the MAC is valid, the server calculates the payload hash and compares the value\nwith the provided payload hash in the header. In many cases, checking the MAC first is faster than calculating the payload hash.\n\nHowever, if the payload is not available at authentication time (e.g. too large to fit in memory, streamed elsewhere, or processed\nat a different stage in the application), the server may choose to defer payload validation for later by retaining the hash value\nprovided by the client after validating the MAC.\n\nIt is important to note that MAC validation does not mean the hash value provided by the client is valid, only that the value\nincluded in the header was not modified. Without calculating the payload hash on the server and comparing it to the value provided\nby the client, the payload may be modified by an attacker.\n\n\n## Response Payload Validation\n\n**Hawk** provides partial response payload validation. The server includes the `Server-Authorization` response header which enables the\nclient to authenticate the response and ensure it is talking to the right server. **Hawk** defines the HTTP `Server-Authorization` header\nas a response header using the exact same syntax as the `Authorization` request header field.\n\nThe header is contructed using the same process as the client's request header. The server uses the same credentials and other\nartifacts provided by the client to constructs the normalized request string. The `ext` and `hash` values are replaced with\nnew values based on the server response. The rest as identical to those used by the client.\n\nThe result MAC digest is included with the optional `hash` and `ext` values:\n\n```\nServer-Authorization: Hawk mac=\"XIJRsMl/4oL+nn+vKoeVZPdCHXB4yJkNnBbTbHFZUYE=\", hash=\"f9cDF/TDm7TkYRLnGwRMfeDzT6LixQVLvrIKhh0vgmM=\", ext=\"response-specific\"\n```\n\n\n## Browser Support and Considerations\n\nA browser script is provided for including using a `<script>` tag in [lib/browser.js](/lib/browser.js).\n\n**Hawk** relies on the _Server-Authorization_ and _WWW-Authenticate_ headers in its response to communicate with the client.\nTherefore, in case of CORS requests, it is important to consider sending _Access-Control-Expose-Headers_ with the value\n_\"WWW-Authenticate, Server-Authorization\"_ on each response from your server. As explained in the\n[specifications](http://www.w3.org/TR/cors/#access-control-expose-headers-response-header), it will indicate that these headers\ncan safely be accessed by the client (using getResponseHeader() on the XmlHttpRequest object). Otherwise you will be met with a\n[\"simple response header\"](http://www.w3.org/TR/cors/#simple-response-header) which excludes these fields and would prevent the\nHawk client from authenticating the requests.You can read more about the why and how in this\n[article](http://www.html5rocks.com/en/tutorials/cors/#toc-adding-cors-support-to-the-server)\n\n\n# Single URI Authorization\n\nThere are cases in which limited and short-term access to a protected resource is granted to a third party which does not\nhave access to the shared credentials. For example, displaying a protected image on a web page accessed by anyone. **Hawk**\nprovides limited support for such URIs in the form of a _bewit_ - a URI query parameter appended to the request URI which contains\nthe necessary credentials to authenticate the request.\n\nBecause of the significant security risks involved in issuing such access, bewit usage is purposely limited only to GET requests\nand for a finite period of time. Both the client and server can issue bewit credentials, however, the server should not use the same\ncredentials as the client to maintain clear traceability as to who issued which credentials.\n\nIn order to simplify implementation, bewit credentials do not support single-use policy and can be replayed multiple times within\nthe granted access timeframe. \n\n\n## Bewit Usage Example\n\nServer code:\n\n```javascript\nvar Http = require('http');\nvar Hawk = require('hawk');\n\n\n// Credentials lookup function\n\nvar credentialsFunc = function (id, callback) {\n\n var credentials = {\n key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn',\n algorithm: 'sha256'\n };\n\n return callback(null, credentials);\n};\n\n// Create HTTP server\n\nvar handler = function (req, res) {\n\n Hawk.uri.authenticate(req, credentialsFunc, {}, function (err, credentials, attributes) {\n\n res.writeHead(!err ? 200 : 401, { 'Content-Type': 'text/plain' });\n res.end(!err ? 'Access granted' : 'Shoosh!');\n });\n};\n\nHttp.createServer(handler).listen(8000, 'example.com');\n```\n\nBewit code generation:\n\n```javascript\nvar Request = require('request');\nvar Hawk = require('hawk');\n\n\n// Client credentials\n\nvar credentials = {\n id: 'dh37fgj492je',\n key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn',\n algorithm: 'sha256'\n}\n\n// Generate bewit\n\nvar duration = 60 * 5; // 5 Minutes\nvar bewit = Hawk.uri.getBewit('http://example.com:8080/resource/1?b=1&a=2', { credentials: credentials, ttlSec: duration, ext: 'some-app-data' });\nvar uri = 'http://example.com:8000/resource/1?b=1&a=2' + '&bewit=' + bewit;\n```\n\n\n# Security Considerations\n\nThe greatest sources of security risks are usually found not in **Hawk** but in the policies and procedures surrounding its use.\nImplementers are strongly encouraged to assess how this module addresses their security requirements. This section includes\nan incomplete list of security considerations that must be reviewed and understood before deploying **Hawk** on the server.\nMany of the protections provided in **Hawk** depends on whether and how they are used.\n\n### MAC Keys Transmission\n\n**Hawk** does not provide any mechanism for obtaining or transmitting the set of shared credentials required. Any mechanism used\nto obtain **Hawk** credentials must ensure that these transmissions are protected using transport-layer mechanisms such as TLS.\n\n### Confidentiality of Requests\n\nWhile **Hawk** provides a mechanism for verifying the integrity of HTTP requests, it provides no guarantee of request\nconfidentiality. Unless other precautions are taken, eavesdroppers will have full access to the request content. Servers should\ncarefully consider the types of data likely to be sent as part of such requests, and employ transport-layer security mechanisms\nto protect sensitive resources.\n\n### Spoofing by Counterfeit Servers\n\n**Hawk** provides limited verification of the server authenticity. When receiving a response back from the server, the server\nmay choose to include a response `Server-Authorization` header which the client can use to verify the response. However, it is up to\nthe server to determine when such measure is included, to up to the client to enforce that policy.\n\nA hostile party could take advantage of this by intercepting the client's requests and returning misleading or otherwise\nincorrect responses. Service providers should consider such attacks when developing services using this protocol, and should\nrequire transport-layer security for any requests where the authenticity of the resource server or of server responses is an issue.\n\n### Plaintext Storage of Credentials\n\nThe **Hawk** key functions the same way passwords do in traditional authentication systems. In order to compute the request MAC,\nthe server must have access to the key in plaintext form. This is in contrast, for example, to modern operating systems, which\nstore only a one-way hash of user credentials.\n\nIf an attacker were to gain access to these keys - or worse, to the server's database of all such keys - he or she would be able\nto perform any action on behalf of any resource owner. Accordingly, it is critical that servers protect these keys from unauthorized\naccess.\n\n### Entropy of Keys\n\nUnless a transport-layer security protocol is used, eavesdroppers will have full access to authenticated requests and request\nMAC values, and will thus be able to mount offline brute-force attacks to recover the key used. Servers should be careful to\nassign keys which are long enough, and random enough, to resist such attacks for at least the length of time that the **Hawk**\ncredentials are valid.\n\nFor example, if the credentials are valid for two weeks, servers should ensure that it is not possible to mount a brute force\nattack that recovers the key in less than two weeks. Of course, servers are urged to err on the side of caution, and use the\nlongest key reasonable.\n\nIt is equally important that the pseudo-random number generator (PRNG) used to generate these keys be of sufficiently high\nquality. Many PRNG implementations generate number sequences that may appear to be random, but which nevertheless exhibit\npatterns or other weaknesses which make cryptanalysis or brute force attacks easier. Implementers should be careful to use\ncryptographically secure PRNGs to avoid these problems.\n\n### Coverage Limitations\n\nThe request MAC only covers the HTTP `Host` header and optionally the `Content-Type` header. It does not cover any other headers\nwhich can often affect how the request body is interpreted by the server. If the server behavior is influenced by the presence\nor value of such headers, an attacker can manipulate the request headers without being detected. Implementers should use the\n`ext` feature to pass application-specific information via the `Authorization` header which is protected by the request MAC.\n\nThe response authentication, when performed, only covers the response payload, content-type, and the request information \nprovided by the client in it's request (method, resource, timestamp, nonce, etc.). It does not cover the HTTP status code or\nany other response header field (e.g. Location) which can affect the client's behaviour.\n\n### Future Time Manipulation\n\nThe protocol relies on a clock sync between the client and server. To accomplish this, the server informs the client of its\ncurrent time when an invalid timestamp is received.\n\nIf an attacker is able to manipulate this information and cause the client to use an incorrect time, it would be able to cause\nthe client to generate authenticated requests using time in the future. Such requests will fail when sent by the client, and will\nnot likely leave a trace on the server (given the common implementation of nonce, if at all enforced). The attacker will then\nbe able to replay the request at the correct time without detection.\n\nThe client must only use the time information provided by the server if:\n* it was delivered over a TLS connection and the server identity has been verified, or\n* the `tsm` MAC digest calculated using the same client credentials over the timestamp has been verified.\n\n### Client Clock Poisoning\n\nWhen receiving a request with a bad timestamp, the server provides the client with its current time. The client must never use\nthe time received from the server to adjust its own clock, and must only use it to calculate an offset for communicating with\nthat particular server.\n\n### Bewit Limitations\n\nSpecial care must be taken when issuing bewit credentials to third parties. Bewit credentials are valid until expiration and cannot\nbe revoked or limited without using other means. Whatever resource they grant access to will be completely exposed to anyone with\naccess to the bewit credentials which act as bearer credentials for that particular resource. While bewit usage is limited to GET\nrequests only and therefore cannot be used to perform transactions or change server state, it can still be used to expose private\nand sensitive information.\n\n### Host Header Forgery\n\nHawk validates the incoming request MAC against the incoming HTTP Host header. However, unless the optional `host` and `port`\noptions are used with `server.authenticate()`, a malicous client can mint new host names pointing to the server's IP address and\nuse that to craft an attack by sending a valid request that's meant for another hostname than the one used by the server. Server\nimplementors must manually verify that the host header received matches their expectation (or use the options mentioned above).\n\n# Frequently Asked Questions\n\n### Where is the protocol specification?\n\nIf you are looking for some prose explaining how all this works, **this is it**. **Hawk** is being developed as an open source\nproject instead of a standard. In other words, the [code](/hueniverse/hawk/tree/master/lib) is the specification. Not sure about\nsomething? Open an issue!\n\n### Is it done?\n\nAt if version 0.10.0, **Hawk** is feature-complete. However, until this module reaches version 1.0.0 it is considered experimental\nand is likely to change. This also means your feedback and contribution are very welcome. Feel free to open issues with questions\nand suggestions.\n\n### Where can I find **Hawk** implementations in other languages?\n\n**Hawk**'s only reference implementation is provided in JavaScript as a node.js module. However, others are actively porting it to other\nplatforms. There is already a [PHP](https://github.com/alexbilbie/PHP-Hawk),\n[.NET](https://github.com/pcibraro/hawknet), and [JAVA](https://github.com/wealdtech/hawk) libraries available. The full list\nis maintained [here](https://github.com/hueniverse/hawk/issues?labels=port). Please add an issue if you are working on another\nport. A cross-platform test-suite is in the works.\n\n### Why isn't the algorithm part of the challenge or dynamically negotiated?\n\nThe algorithm used is closely related to the key issued as different algorithms require different key sizes (and other\nrequirements). While some keys can be used for multiple algorithm, the protocol is designed to closely bind the key and algorithm\ntogether as part of the issued credentials.\n\n### Why is Host and Content-Type the only headers covered by the request MAC?\n\nIt is really hard to include other headers. Headers can be changed by proxies and other intermediaries and there is no\nwell-established way to normalize them. Many platforms change the case of header field names and values. The only\nstraight-forward solution is to include the headers in some blob (say, base64 encoded JSON) and include that with the request,\nan approach taken by JWT and other such formats. However, that design violates the HTTP header boundaries, repeats information,\nand introduces other security issues because firewalls will not be aware of these \"hidden\" headers. In addition, any information\nrepeated must be compared to the duplicated information in the header and therefore only moves the problem elsewhere.\n\n### Why not just use HTTP Digest?\n\nDigest requires pre-negotiation to establish a nonce. This means you can't just make a request - you must first send\na protocol handshake to the server. This pattern has become unacceptable for most web services, especially mobile\nwhere extra round-trip are costly.\n\n### Why bother with all this nonce and timestamp business?\n\n**Hawk** is an attempt to find a reasonable, practical compromise between security and usability. OAuth 1.0 got timestamp\nand nonces halfway right but failed when it came to scalability and consistent developer experience. **Hawk** addresses\nit by requiring the client to sync its clock, but provides it with tools to accomplish it.\n\nIn general, replay protection is a matter of application-specific threat model. It is less of an issue on a TLS-protected\nsystem where the clients are implemented using best practices and are under the control of the server. Instead of dropping\nreplay protection, **Hawk** offers a required time window and an optional nonce verification. Together, it provides developers\nwith the ability to decide how to enforce their security policy without impacting the client's implementation.\n\n### What are `app` and `dlg` in the authorization header and normalized mac string?\n\nThe original motivation for **Hawk** was to replace the OAuth 1.0 use cases. This included both a simple client-server mode which\nthis module is specifically designed for, and a delegated access mode which is being developed separately in\n[Oz](https://github.com/hueniverse/oz). In addition to the **Hawk** use cases, Oz requires another attribute: the application id `app`.\nThis provides binding between the credentials and the application in a way that prevents an attacker from tricking an application\nto use credentials issued to someone else. It also has an optional 'delegated-by' attribute `dlg` which is the application id of the\napplication the credentials were directly issued to. The goal of these two additions is to allow Oz to utilize **Hawk** directly,\nbut with the additional security of delegated credentials.\n\n### What is the purpose of the static strings used in each normalized MAC input?\n\nWhen calculating a hash or MAC, a static prefix (tag) is added. The prefix is used to prevent MAC values from being\nused or reused for a purpose other than what they were created for (i.e. prevents switching MAC values between a request,\nresponse, and a bewit use cases). It also protects against expliots created after a potential change in how the protocol\ncreates the normalized string. For example, if a future version would switch the order of nonce and timestamp, it\ncan create an exploit opportunity for cases where the nonce is similar in format to a timestamp.\n\n### Does **Hawk** have anything to do with OAuth?\n\nShort answer: no.\n\n**Hawk** was originally proposed as the OAuth MAC Token specification. However, the OAuth working group in its consistent\nincompetence failed to produce a final, usable solution to address one of the most popular use cases of OAuth 1.0 - using it\nto authenticate simple client-server transactions (i.e. two-legged). As you can guess, the OAuth working group is still hard\nat work to produce more garbage.\n\n**Hawk** provides a simple HTTP authentication scheme for making client-server requests. It does not address the OAuth use case\nof delegating access to a third party. If you are looking for an OAuth alternative, check out [Oz](https://github.com/hueniverse/oz).\n\n\n# Acknowledgements\n\n**Hawk** is a derivative work of the [HTTP MAC Authentication Scheme](http://tools.ietf.org/html/draft-hammer-oauth-v2-mac-token-05) proposal\nco-authored by Ben Adida, Adam Barth, and Eran Hammer, which in turn was based on the OAuth 1.0 community specification.\n\nSpecial thanks to Ben Laurie for his always insightful feedback and advice.\n\nThe **Hawk** logo was created by [Chris Carrasco](http://chriscarrasco.com).\n", "readmeFilename": "README.md", "bugs": { "url": "https://github.com/hueniverse/hawk/issues" }, - "_id": "hawk@0.13.1", - "_from": "hawk@~0.13.0" + "_id": "hawk@1.0.0", + "_from": "hawk@~1.0.0" } diff --git a/deps/npm/node_modules/request/node_modules/hawk/test/browser.js b/deps/npm/node_modules/request/node_modules/hawk/test/browser.js index 33e02038620..b25a10fd989 100755 --- a/deps/npm/node_modules/request/node_modules/hawk/test/browser.js +++ b/deps/npm/node_modules/request/node_modules/hawk/test/browser.js @@ -1,723 +1,771 @@ -// Load modules
-
-var Lab = require('lab');
-var Hawk = require('../lib');
-var Browser = require('../lib/browser');
-var LocalStorage = require('localStorage');
-
-
-// Declare internals
-
-var internals = {};
-
-
-// Test shortcuts
-
-var expect = Lab.expect;
-var before = Lab.before;
-var after = Lab.after;
-var describe = Lab.experiment;
-var it = Lab.test;
-
-
-describe('Browser', function () {
-
- var credentialsFunc = function (id, callback) {
-
- var credentials = {
- id: id,
- key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn',
- algorithm: (id === '1' ? 'sha1' : 'sha256'),
- user: 'steve'
- };
-
- return callback(null, credentials);
- };
-
- it('should generate a header then successfully parse it (configuration)', function (done) {
-
- var req = {
- method: 'GET',
- url: '/resource/4?filter=a',
- host: 'example.com',
- port: 8080
- };
-
- credentialsFunc('123456', function (err, credentials) {
-
- req.authorization = Browser.client.header('http://example.com:8080/resource/4?filter=a', req.method, { credentials: credentials, ext: 'some-app-data' }).field;
- expect(req.authorization).to.exist;
-
- Hawk.server.authenticate(req, credentialsFunc, {}, function (err, credentials, artifacts) {
-
- expect(err).to.not.exist;
- expect(credentials.user).to.equal('steve');
- expect(artifacts.ext).to.equal('some-app-data');
- done();
- });
- });
- });
-
- it('should generate a header then successfully parse it (node request)', function (done) {
-
- var req = {
- method: 'POST',
- url: '/resource/4?filter=a',
- headers: {
- host: 'example.com:8080',
- 'content-type': 'text/plain;x=y'
- }
- };
-
- var payload = 'some not so random text';
-
- credentialsFunc('123456', function (err, credentials) {
-
- var reqHeader = Browser.client.header('http://example.com:8080/resource/4?filter=a', req.method, { credentials: credentials, ext: 'some-app-data', payload: payload, contentType: req.headers['content-type'] });
- req.headers.authorization = reqHeader.field;
-
- Hawk.server.authenticate(req, credentialsFunc, {}, function (err, credentials, artifacts) {
-
- expect(err).to.not.exist;
- expect(credentials.user).to.equal('steve');
- expect(artifacts.ext).to.equal('some-app-data');
- expect(Hawk.server.authenticatePayload(payload, credentials, artifacts, req.headers['content-type'])).to.equal(true);
-
- var res = {
- headers: {
- 'content-type': 'text/plain'
- },
- getResponseHeader: function (header) {
-
- return res.headers[header.toLowerCase()];
- }
- };
-
- res.headers['server-authorization'] = Hawk.server.header(credentials, artifacts, { payload: 'some reply', contentType: 'text/plain', ext: 'response-specific' });
- expect(res.headers['server-authorization']).to.exist;
-
- expect(Browser.client.authenticate(res, credentials, artifacts, { payload: 'some reply' })).to.equal(true);
- done();
- });
- });
- });
-
- it('should generate a header then successfully parse it (no server header options)', function (done) {
-
- var req = {
- method: 'POST',
- url: '/resource/4?filter=a',
- headers: {
- host: 'example.com:8080',
- 'content-type': 'text/plain;x=y'
- }
- };
-
- var payload = 'some not so random text';
-
- credentialsFunc('123456', function (err, credentials) {
-
- var reqHeader = Browser.client.header('http://example.com:8080/resource/4?filter=a', req.method, { credentials: credentials, ext: 'some-app-data', payload: payload, contentType: req.headers['content-type'] });
- req.headers.authorization = reqHeader.field;
-
- Hawk.server.authenticate(req, credentialsFunc, {}, function (err, credentials, artifacts) {
-
- expect(err).to.not.exist;
- expect(credentials.user).to.equal('steve');
- expect(artifacts.ext).to.equal('some-app-data');
- expect(Hawk.server.authenticatePayload(payload, credentials, artifacts, req.headers['content-type'])).to.equal(true);
-
- var res = {
- headers: {
- 'content-type': 'text/plain'
- },
- getResponseHeader: function (header) {
-
- return res.headers[header.toLowerCase()];
- }
- };
-
- res.headers['server-authorization'] = Hawk.server.header(credentials, artifacts);
- expect(res.headers['server-authorization']).to.exist;
-
- expect(Browser.client.authenticate(res, credentials, artifacts)).to.equal(true);
- done();
- });
- });
- });
-
- it('should generate a header then successfully parse it (no server header)', function (done) {
-
- var req = {
- method: 'POST',
- url: '/resource/4?filter=a',
- headers: {
- host: 'example.com:8080',
- 'content-type': 'text/plain;x=y'
- }
- };
-
- var payload = 'some not so random text';
-
- credentialsFunc('123456', function (err, credentials) {
-
- var reqHeader = Browser.client.header('http://example.com:8080/resource/4?filter=a', req.method, { credentials: credentials, ext: 'some-app-data', payload: payload, contentType: req.headers['content-type'] });
- req.headers.authorization = reqHeader.field;
-
- Hawk.server.authenticate(req, credentialsFunc, {}, function (err, credentials, artifacts) {
-
- expect(err).to.not.exist;
- expect(credentials.user).to.equal('steve');
- expect(artifacts.ext).to.equal('some-app-data');
- expect(Hawk.server.authenticatePayload(payload, credentials, artifacts, req.headers['content-type'])).to.equal(true);
-
- var res = {
- headers: {
- 'content-type': 'text/plain'
- },
- getResponseHeader: function (header) {
-
- return res.headers[header.toLowerCase()];
- }
- };
-
- expect(Browser.client.authenticate(res, credentials, artifacts)).to.equal(true);
- done();
- });
- });
- });
-
- it('should generate a header with stale ts and successfully authenticate on second call', function (done) {
-
- var req = {
- method: 'GET',
- url: '/resource/4?filter=a',
- host: 'example.com',
- port: 8080
- };
-
- credentialsFunc('123456', function (err, credentials) {
-
- Browser.utils.setNtpOffset(60 * 60 * 1000);
- var header = Browser.client.header('http://example.com:8080/resource/4?filter=a', req.method, { credentials: credentials, ext: 'some-app-data' });
- req.authorization = header.field;
- expect(req.authorization).to.exist;
-
- Hawk.server.authenticate(req, credentialsFunc, {}, function (err, credentials, artifacts) {
-
- expect(err).to.exist;
- expect(err.message).to.equal('Stale timestamp');
-
- var res = {
- headers: {
- 'www-authenticate': err.response.headers['WWW-Authenticate']
- },
- getResponseHeader: function (header) {
-
- return res.headers[header.toLowerCase()];
- }
- };
-
- expect(Browser.utils.getNtpOffset()).to.equal(60 * 60 * 1000);
- expect(Browser.client.authenticate(res, credentials, header.artifacts)).to.equal(true);
- expect(Browser.utils.getNtpOffset()).to.equal(0);
-
- req.authorization = Browser.client.header('http://example.com:8080/resource/4?filter=a', req.method, { credentials: credentials, ext: 'some-app-data' }).field;
- expect(req.authorization).to.exist;
-
- Hawk.server.authenticate(req, credentialsFunc, {}, function (err, credentials, artifacts) {
-
- expect(err).to.not.exist;
- expect(credentials.user).to.equal('steve');
- expect(artifacts.ext).to.equal('some-app-data');
- done();
- });
- });
- });
- });
-
- it('should generate a header with stale ts and successfully authenticate on second call (manual localStorage)', function (done) {
-
- var req = {
- method: 'GET',
- url: '/resource/4?filter=a',
- host: 'example.com',
- port: 8080
- };
-
- credentialsFunc('123456', function (err, credentials) {
- Browser.utils.setStorage(LocalStorage)
-
- Browser.utils.setNtpOffset(60 * 60 * 1000);
- var header = Browser.client.header('http://example.com:8080/resource/4?filter=a', req.method, { credentials: credentials, ext: 'some-app-data' });
- req.authorization = header.field;
- expect(req.authorization).to.exist;
-
- Hawk.server.authenticate(req, credentialsFunc, {}, function (err, credentials, artifacts) {
-
- expect(err).to.exist;
- expect(err.message).to.equal('Stale timestamp');
-
- var res = {
- headers: {
- 'www-authenticate': err.response.headers['WWW-Authenticate']
- },
- getResponseHeader: function (header) {
-
- return res.headers[header.toLowerCase()];
- }
- };
-
- expect(parseInt(LocalStorage.getItem('hawk_ntp_offset'))).to.equal(60 * 60 * 1000);
- expect(Browser.utils.getNtpOffset()).to.equal(60 * 60 * 1000);
- expect(Browser.client.authenticate(res, credentials, header.artifacts)).to.equal(true);
- expect(Browser.utils.getNtpOffset()).to.equal(0);
- expect(parseInt(LocalStorage.getItem('hawk_ntp_offset'))).to.equal(0);
-
- req.authorization = Browser.client.header('http://example.com:8080/resource/4?filter=a', req.method, { credentials: credentials, ext: 'some-app-data' }).field;
- expect(req.authorization).to.exist;
-
- Hawk.server.authenticate(req, credentialsFunc, {}, function (err, credentials, artifacts) {
-
- expect(err).to.not.exist;
- expect(credentials.user).to.equal('steve');
- expect(artifacts.ext).to.equal('some-app-data');
- done();
- });
- });
- });
- });
-
- it('should generate a header then fails to parse it (missing server header hash)', function (done) {
-
- var req = {
- method: 'POST',
- url: '/resource/4?filter=a',
- headers: {
- host: 'example.com:8080',
- 'content-type': 'text/plain;x=y'
- }
- };
-
- var payload = 'some not so random text';
-
- credentialsFunc('123456', function (err, credentials) {
-
- var reqHeader = Browser.client.header('http://example.com:8080/resource/4?filter=a', req.method, { credentials: credentials, ext: 'some-app-data', payload: payload, contentType: req.headers['content-type'] });
- req.headers.authorization = reqHeader.field;
-
- Hawk.server.authenticate(req, credentialsFunc, {}, function (err, credentials, artifacts) {
-
- expect(err).to.not.exist;
- expect(credentials.user).to.equal('steve');
- expect(artifacts.ext).to.equal('some-app-data');
- expect(Hawk.server.authenticatePayload(payload, credentials, artifacts, req.headers['content-type'])).to.equal(true);
-
- var res = {
- headers: {
- 'content-type': 'text/plain'
- },
- getResponseHeader: function (header) {
-
- return res.headers[header.toLowerCase()];
- }
- };
-
- res.headers['server-authorization'] = Hawk.server.header(credentials, artifacts);
- expect(res.headers['server-authorization']).to.exist;
-
- expect(Browser.client.authenticate(res, credentials, artifacts, { payload: 'some reply' })).to.equal(false);
- done();
- });
- });
- });
-
- it('should generate a header then successfully parse it (with hash)', function (done) {
-
- var req = {
- method: 'GET',
- url: '/resource/4?filter=a',
- host: 'example.com',
- port: 8080
- };
-
- credentialsFunc('123456', function (err, credentials) {
-
- req.authorization = Browser.client.header('http://example.com:8080/resource/4?filter=a', req.method, { credentials: credentials, payload: 'hola!', ext: 'some-app-data' }).field;
- Hawk.server.authenticate(req, credentialsFunc, {}, function (err, credentials, artifacts) {
-
- expect(err).to.not.exist;
- expect(credentials.user).to.equal('steve');
- expect(artifacts.ext).to.equal('some-app-data');
- done();
- });
- });
- });
-
- it('should generate a header then successfully parse it then validate payload', function (done) {
-
- var req = {
- method: 'GET',
- url: '/resource/4?filter=a',
- host: 'example.com',
- port: 8080
- };
-
- credentialsFunc('123456', function (err, credentials) {
-
- req.authorization = Browser.client.header('http://example.com:8080/resource/4?filter=a', req.method, { credentials: credentials, payload: 'hola!', ext: 'some-app-data' }).field;
- Hawk.server.authenticate(req, credentialsFunc, {}, function (err, credentials, artifacts) {
-
- expect(err).to.not.exist;
- expect(credentials.user).to.equal('steve');
- expect(artifacts.ext).to.equal('some-app-data');
- expect(Hawk.server.authenticatePayload('hola!', credentials, artifacts)).to.be.true;
- expect(Hawk.server.authenticatePayload('hello!', credentials, artifacts)).to.be.false;
- done();
- });
- });
- });
-
- it('should generate a header then successfully parse it (app)', function (done) {
-
- var req = {
- method: 'GET',
- url: '/resource/4?filter=a',
- host: 'example.com',
- port: 8080
- };
-
- credentialsFunc('123456', function (err, credentials) {
-
- req.authorization = Browser.client.header('http://example.com:8080/resource/4?filter=a', req.method, { credentials: credentials, ext: 'some-app-data', app: 'asd23ased' }).field;
- Hawk.server.authenticate(req, credentialsFunc, {}, function (err, credentials, artifacts) {
-
- expect(err).to.not.exist;
- expect(credentials.user).to.equal('steve');
- expect(artifacts.ext).to.equal('some-app-data');
- expect(artifacts.app).to.equal('asd23ased');
- done();
- });
- });
- });
-
- it('should generate a header then successfully parse it (app, dlg)', function (done) {
-
- var req = {
- method: 'GET',
- url: '/resource/4?filter=a',
- host: 'example.com',
- port: 8080
- };
-
- credentialsFunc('123456', function (err, credentials) {
-
- req.authorization = Browser.client.header('http://example.com:8080/resource/4?filter=a', req.method, { credentials: credentials, ext: 'some-app-data', app: 'asd23ased', dlg: '23434szr3q4d' }).field;
- Hawk.server.authenticate(req, credentialsFunc, {}, function (err, credentials, artifacts) {
-
- expect(err).to.not.exist;
- expect(credentials.user).to.equal('steve');
- expect(artifacts.ext).to.equal('some-app-data');
- expect(artifacts.app).to.equal('asd23ased');
- expect(artifacts.dlg).to.equal('23434szr3q4d');
- done();
- });
- });
- });
-
- it('should generate a header then fail authentication due to bad hash', function (done) {
-
- var req = {
- method: 'GET',
- url: '/resource/4?filter=a',
- host: 'example.com',
- port: 8080
- };
-
- credentialsFunc('123456', function (err, credentials) {
-
- req.authorization = Browser.client.header('http://example.com:8080/resource/4?filter=a', req.method, { credentials: credentials, payload: 'hola!', ext: 'some-app-data' }).field;
- Hawk.server.authenticate(req, credentialsFunc, { payload: 'byebye!' }, function (err, credentials, artifacts) {
-
- expect(err).to.exist;
- expect(err.response.payload.message).to.equal('Bad payload hash');
- done();
- });
- });
- });
-
- it('should generate a header for one resource then fail to authenticate another', function (done) {
-
- var req = {
- method: 'GET',
- url: '/resource/4?filter=a',
- host: 'example.com',
- port: 8080
- };
-
- credentialsFunc('123456', function (err, credentials) {
-
- req.authorization = Browser.client.header('http://example.com:8080/resource/4?filter=a', req.method, { credentials: credentials, ext: 'some-app-data' }).field;
- req.url = '/something/else';
-
- Hawk.server.authenticate(req, credentialsFunc, {}, function (err, credentials, artifacts) {
-
- expect(err).to.exist;
- expect(credentials).to.exist;
- done();
- });
- });
- });
-
- describe('client', function () {
-
- describe('#header', function () {
-
- it('should return a valid authorization header (sha1)', function (done) {
-
- var credentials = {
- id: '123456',
- key: '2983d45yun89q',
- algorithm: 'sha1'
- };
-
- var header = Browser.client.header('http://example.net/somewhere/over/the/rainbow', 'POST', { credentials: credentials, ext: 'Bazinga!', timestamp: 1353809207, nonce: 'Ygvqdz', payload: 'something to write about' }).field;
- expect(header).to.equal('Hawk id="123456", ts="1353809207", nonce="Ygvqdz", hash="bsvY3IfUllw6V5rvk4tStEvpBhE=", ext="Bazinga!", mac="qbf1ZPG/r/e06F4ht+T77LXi5vw="');
- done();
- });
-
- it('should return a valid authorization header (sha256)', function (done) {
-
- var credentials = {
- id: '123456',
- key: '2983d45yun89q',
- algorithm: 'sha256'
- };
-
- var header = Browser.client.header('https://example.net/somewhere/over/the/rainbow', 'POST', { credentials: credentials, ext: 'Bazinga!', timestamp: 1353809207, nonce: 'Ygvqdz', payload: 'something to write about', contentType: 'text/plain' }).field;
- expect(header).to.equal('Hawk id="123456", ts="1353809207", nonce="Ygvqdz", hash="2QfCt3GuY9HQnHWyWD3wX68ZOKbynqlfYmuO2ZBRqtY=", ext="Bazinga!", mac="q1CwFoSHzPZSkbIvl0oYlD+91rBUEvFk763nMjMndj8="');
- done();
- });
-
- it('should return a valid authorization header (no ext)', function (done) {
-
- var credentials = {
- id: '123456',
- key: '2983d45yun89q',
- algorithm: 'sha256'
- };
-
- var header = Browser.client.header('https://example.net/somewhere/over/the/rainbow', 'POST', { credentials: credentials, timestamp: 1353809207, nonce: 'Ygvqdz', payload: 'something to write about', contentType: 'text/plain' }).field;
- expect(header).to.equal('Hawk id="123456", ts="1353809207", nonce="Ygvqdz", hash="2QfCt3GuY9HQnHWyWD3wX68ZOKbynqlfYmuO2ZBRqtY=", mac="HTgtd0jPI6E4izx8e4OHdO36q00xFCU0FolNq3RiCYs="');
- done();
- });
-
- it('should return an empty authorization header on missing options', function (done) {
-
- var header = Browser.client.header('https://example.net/somewhere/over/the/rainbow', 'POST').field;
- expect(header).to.equal('');
- done();
- });
-
- it('should return an empty authorization header on invalid credentials', function (done) {
-
- var credentials = {
- key: '2983d45yun89q',
- algorithm: 'sha256'
- };
-
- var header = Browser.client.header('https://example.net/somewhere/over/the/rainbow', 'POST', { credentials: credentials, ext: 'Bazinga!', timestamp: 1353809207 }).field;
- expect(header).to.equal('');
- done();
- });
-
- it('should return an empty authorization header on invalid algorithm', function (done) {
-
- var credentials = {
- id: '123456',
- key: '2983d45yun89q',
- algorithm: 'hmac-sha-0'
- };
-
- var header = Browser.client.header('https://example.net/somewhere/over/the/rainbow', 'POST', { credentials: credentials, payload: 'something, anything!', ext: 'Bazinga!', timestamp: 1353809207 }).field;
- expect(header).to.equal('');
- done();
- });
- });
-
- describe('#authenticate', function () {
-
- it('should return false on invalid header', function (done) {
-
- var res = {
- headers: {
- 'server-authorization': 'Hawk mac="abc", bad="xyz"'
- },
- getResponseHeader: function (header) {
-
- return res.headers[header.toLowerCase()];
- }
- };
-
- expect(Browser.client.authenticate(res, {})).to.equal(false);
- done();
- });
-
- it('should return false on invalid mac', function (done) {
-
- var res = {
- headers: {
- 'content-type': 'text/plain',
- 'server-authorization': 'Hawk mac="_IJRsMl/4oL+nn+vKoeVZPdCHXB4yJkNnBbTbHFZUYE=", hash="f9cDF/TDm7TkYRLnGwRMfeDzT6LixQVLvrIKhh0vgmM=", ext="response-specific"'
- },
- getResponseHeader: function (header) {
-
- return res.headers[header.toLowerCase()];
- }
- };
-
- var artifacts = {
- method: 'POST',
- host: 'example.com',
- port: '8080',
- resource: '/resource/4?filter=a',
- ts: '1362336900',
- nonce: 'eb5S_L',
- hash: 'nJjkVtBE5Y/Bk38Aiokwn0jiJxt/0S2WRSUwWLCf5xk=',
- ext: 'some-app-data',
- app: undefined,
- dlg: undefined,
- mac: 'BlmSe8K+pbKIb6YsZCnt4E1GrYvY1AaYayNR82dGpIk=',
- id: '123456'
- };
-
- var credentials = {
- id: '123456',
- key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn',
- algorithm: 'sha256',
- user: 'steve'
- };
-
- expect(Browser.client.authenticate(res, credentials, artifacts)).to.equal(false);
- done();
- });
-
- it('should return true on ignoring hash', function (done) {
-
- var res = {
- headers: {
- 'content-type': 'text/plain',
- 'server-authorization': 'Hawk mac="XIJRsMl/4oL+nn+vKoeVZPdCHXB4yJkNnBbTbHFZUYE=", hash="f9cDF/TDm7TkYRLnGwRMfeDzT6LixQVLvrIKhh0vgmM=", ext="response-specific"'
- },
- getResponseHeader: function (header) {
-
- return res.headers[header.toLowerCase()];
- }
- };
-
- var artifacts = {
- method: 'POST',
- host: 'example.com',
- port: '8080',
- resource: '/resource/4?filter=a',
- ts: '1362336900',
- nonce: 'eb5S_L',
- hash: 'nJjkVtBE5Y/Bk38Aiokwn0jiJxt/0S2WRSUwWLCf5xk=',
- ext: 'some-app-data',
- app: undefined,
- dlg: undefined,
- mac: 'BlmSe8K+pbKIb6YsZCnt4E1GrYvY1AaYayNR82dGpIk=',
- id: '123456'
- };
-
- var credentials = {
- id: '123456',
- key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn',
- algorithm: 'sha256',
- user: 'steve'
- };
-
- expect(Browser.client.authenticate(res, credentials, artifacts)).to.equal(true);
- done();
- });
-
- it('should fail on invalid WWW-Authenticate header format', function (done) {
-
- var res = {
- headers: {
- 'www-authenticate': 'Hawk ts="1362346425875", tsm="PhwayS28vtnn3qbv0mqRBYSXebN/zggEtucfeZ620Zo=", x="Stale timestamp"'
- },
- getResponseHeader: function (header) {
-
- return res.headers[header.toLowerCase()];
- }
- };
-
- expect(Browser.client.authenticate(res, {})).to.equal(false);
- done();
- });
-
- it('should fail on invalid WWW-Authenticate header format', function (done) {
-
- var credentials = {
- id: '123456',
- key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn',
- algorithm: 'sha256',
- user: 'steve'
- };
-
- var res = {
- headers: {
- 'www-authenticate': 'Hawk ts="1362346425875", tsm="hwayS28vtnn3qbv0mqRBYSXebN/zggEtucfeZ620Zo=", error="Stale timestamp"'
- },
- getResponseHeader: function (header) {
-
- return res.headers[header.toLowerCase()];
- }
- };
-
- expect(Browser.client.authenticate(res, credentials)).to.equal(false);
- done();
- });
- });
- });
-
- describe('#parseAuthorizationHeader', function (done) {
-
- it('returns null on missing header', function (done) {
-
- expect(Browser.utils.parseAuthorizationHeader()).to.equal(null);
- done();
- });
-
- it('returns null on bad header syntax (structure)', function (done) {
-
- expect(Browser.utils.parseAuthorizationHeader('Hawk')).to.equal(null);
- done();
- });
-
- it('returns null on bad header syntax (parts)', function (done) {
-
- expect(Browser.utils.parseAuthorizationHeader(' ')).to.equal(null);
- done();
- });
-
- it('returns null on bad scheme name', function (done) {
-
- expect(Browser.utils.parseAuthorizationHeader('Basic asdasd')).to.equal(null);
- done();
- });
-
- it('returns null on bad attribute value', function (done) {
-
- expect(Browser.utils.parseAuthorizationHeader('Hawk test="\t"', ['test'])).to.equal(null);
- done();
- });
-
- it('returns null on duplicated attribute', function (done) {
-
- expect(Browser.utils.parseAuthorizationHeader('Hawk test="a", test="b"', ['test'])).to.equal(null);
- done();
- });
- });
-});
+// Load modules + +var Lab = require('lab'); +var Hoek = require('hoek'); +var Hawk = require('../lib'); +var Browser = require('../lib/browser'); +var LocalStorage = require('localStorage'); + + +// Declare internals + +var internals = {}; + + +// Test shortcuts + +var expect = Lab.expect; +var before = Lab.before; +var after = Lab.after; +var describe = Lab.experiment; +var it = Lab.test; + + +describe('Browser', function () { + + var credentialsFunc = function (id, callback) { + + var credentials = { + id: id, + key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn', + algorithm: (id === '1' ? 'sha1' : 'sha256'), + user: 'steve' + }; + + return callback(null, credentials); + }; + + it('should generate a header then successfully parse it (configuration)', function (done) { + + var req = { + method: 'GET', + url: '/resource/4?filter=a', + host: 'example.com', + port: 8080 + }; + + credentialsFunc('123456', function (err, credentials) { + + req.authorization = Browser.client.header('http://example.com:8080/resource/4?filter=a', req.method, { credentials: credentials, ext: 'some-app-data' }).field; + expect(req.authorization).to.exist; + + Hawk.server.authenticate(req, credentialsFunc, {}, function (err, credentials, artifacts) { + + expect(err).to.not.exist; + expect(credentials.user).to.equal('steve'); + expect(artifacts.ext).to.equal('some-app-data'); + done(); + }); + }); + }); + + it('should generate a header then successfully parse it (node request)', function (done) { + + var req = { + method: 'POST', + url: '/resource/4?filter=a', + headers: { + host: 'example.com:8080', + 'content-type': 'text/plain;x=y' + } + }; + + var payload = 'some not so random text'; + + credentialsFunc('123456', function (err, credentials) { + + var reqHeader = Browser.client.header('http://example.com:8080/resource/4?filter=a', req.method, { credentials: credentials, ext: 'some-app-data', payload: payload, contentType: req.headers['content-type'] }); + req.headers.authorization = reqHeader.field; + + Hawk.server.authenticate(req, credentialsFunc, {}, function (err, credentials, artifacts) { + + expect(err).to.not.exist; + expect(credentials.user).to.equal('steve'); + expect(artifacts.ext).to.equal('some-app-data'); + expect(Hawk.server.authenticatePayload(payload, credentials, artifacts, req.headers['content-type'])).to.equal(true); + + var res = { + headers: { + 'content-type': 'text/plain' + }, + getResponseHeader: function (header) { + + return res.headers[header.toLowerCase()]; + } + }; + + res.headers['server-authorization'] = Hawk.server.header(credentials, artifacts, { payload: 'some reply', contentType: 'text/plain', ext: 'response-specific' }); + expect(res.headers['server-authorization']).to.exist; + + expect(Browser.client.authenticate(res, credentials, artifacts, { payload: 'some reply' })).to.equal(true); + done(); + }); + }); + }); + + it('should generate a header then successfully parse it (no server header options)', function (done) { + + var req = { + method: 'POST', + url: '/resource/4?filter=a', + headers: { + host: 'example.com:8080', + 'content-type': 'text/plain;x=y' + } + }; + + var payload = 'some not so random text'; + + credentialsFunc('123456', function (err, credentials) { + + var reqHeader = Browser.client.header('http://example.com:8080/resource/4?filter=a', req.method, { credentials: credentials, ext: 'some-app-data', payload: payload, contentType: req.headers['content-type'] }); + req.headers.authorization = reqHeader.field; + + Hawk.server.authenticate(req, credentialsFunc, {}, function (err, credentials, artifacts) { + + expect(err).to.not.exist; + expect(credentials.user).to.equal('steve'); + expect(artifacts.ext).to.equal('some-app-data'); + expect(Hawk.server.authenticatePayload(payload, credentials, artifacts, req.headers['content-type'])).to.equal(true); + + var res = { + headers: { + 'content-type': 'text/plain' + }, + getResponseHeader: function (header) { + + return res.headers[header.toLowerCase()]; + } + }; + + res.headers['server-authorization'] = Hawk.server.header(credentials, artifacts); + expect(res.headers['server-authorization']).to.exist; + + expect(Browser.client.authenticate(res, credentials, artifacts)).to.equal(true); + done(); + }); + }); + }); + + it('should generate a header then successfully parse it (no server header)', function (done) { + + var req = { + method: 'POST', + url: '/resource/4?filter=a', + headers: { + host: 'example.com:8080', + 'content-type': 'text/plain;x=y' + } + }; + + var payload = 'some not so random text'; + + credentialsFunc('123456', function (err, credentials) { + + var reqHeader = Browser.client.header('http://example.com:8080/resource/4?filter=a', req.method, { credentials: credentials, ext: 'some-app-data', payload: payload, contentType: req.headers['content-type'] }); + req.headers.authorization = reqHeader.field; + + Hawk.server.authenticate(req, credentialsFunc, {}, function (err, credentials, artifacts) { + + expect(err).to.not.exist; + expect(credentials.user).to.equal('steve'); + expect(artifacts.ext).to.equal('some-app-data'); + expect(Hawk.server.authenticatePayload(payload, credentials, artifacts, req.headers['content-type'])).to.equal(true); + + var res = { + headers: { + 'content-type': 'text/plain' + }, + getResponseHeader: function (header) { + + return res.headers[header.toLowerCase()]; + } + }; + + expect(Browser.client.authenticate(res, credentials, artifacts)).to.equal(true); + done(); + }); + }); + }); + + it('should generate a header with stale ts and successfully authenticate on second call', function (done) { + + var req = { + method: 'GET', + url: '/resource/4?filter=a', + host: 'example.com', + port: 8080 + }; + + credentialsFunc('123456', function (err, credentials) { + + Browser.utils.setNtpOffset(60 * 60 * 1000); + var header = Browser.client.header('http://example.com:8080/resource/4?filter=a', req.method, { credentials: credentials, ext: 'some-app-data' }); + req.authorization = header.field; + expect(req.authorization).to.exist; + + Hawk.server.authenticate(req, credentialsFunc, {}, function (err, credentials, artifacts) { + + expect(err).to.exist; + expect(err.message).to.equal('Stale timestamp'); + + var res = { + headers: { + 'www-authenticate': err.response.headers['WWW-Authenticate'] + }, + getResponseHeader: function (header) { + + return res.headers[header.toLowerCase()]; + } + }; + + expect(Browser.utils.getNtpOffset()).to.equal(60 * 60 * 1000); + expect(Browser.client.authenticate(res, credentials, header.artifacts)).to.equal(true); + expect(Browser.utils.getNtpOffset()).to.equal(0); + + req.authorization = Browser.client.header('http://example.com:8080/resource/4?filter=a', req.method, { credentials: credentials, ext: 'some-app-data' }).field; + expect(req.authorization).to.exist; + + Hawk.server.authenticate(req, credentialsFunc, {}, function (err, credentials, artifacts) { + + expect(err).to.not.exist; + expect(credentials.user).to.equal('steve'); + expect(artifacts.ext).to.equal('some-app-data'); + done(); + }); + }); + }); + }); + + it('should generate a header with stale ts and successfully authenticate on second call (manual localStorage)', function (done) { + + var req = { + method: 'GET', + url: '/resource/4?filter=a', + host: 'example.com', + port: 8080 + }; + + credentialsFunc('123456', function (err, credentials) { + Browser.utils.setStorage(LocalStorage) + + Browser.utils.setNtpOffset(60 * 60 * 1000); + var header = Browser.client.header('http://example.com:8080/resource/4?filter=a', req.method, { credentials: credentials, ext: 'some-app-data' }); + req.authorization = header.field; + expect(req.authorization).to.exist; + + Hawk.server.authenticate(req, credentialsFunc, {}, function (err, credentials, artifacts) { + + expect(err).to.exist; + expect(err.message).to.equal('Stale timestamp'); + + var res = { + headers: { + 'www-authenticate': err.response.headers['WWW-Authenticate'] + }, + getResponseHeader: function (header) { + + return res.headers[header.toLowerCase()]; + } + }; + + expect(parseInt(LocalStorage.getItem('hawk_ntp_offset'))).to.equal(60 * 60 * 1000); + expect(Browser.utils.getNtpOffset()).to.equal(60 * 60 * 1000); + expect(Browser.client.authenticate(res, credentials, header.artifacts)).to.equal(true); + expect(Browser.utils.getNtpOffset()).to.equal(0); + expect(parseInt(LocalStorage.getItem('hawk_ntp_offset'))).to.equal(0); + + req.authorization = Browser.client.header('http://example.com:8080/resource/4?filter=a', req.method, { credentials: credentials, ext: 'some-app-data' }).field; + expect(req.authorization).to.exist; + + Hawk.server.authenticate(req, credentialsFunc, {}, function (err, credentials, artifacts) { + + expect(err).to.not.exist; + expect(credentials.user).to.equal('steve'); + expect(artifacts.ext).to.equal('some-app-data'); + done(); + }); + }); + }); + }); + + it('should generate a header then fails to parse it (missing server header hash)', function (done) { + + var req = { + method: 'POST', + url: '/resource/4?filter=a', + headers: { + host: 'example.com:8080', + 'content-type': 'text/plain;x=y' + } + }; + + var payload = 'some not so random text'; + + credentialsFunc('123456', function (err, credentials) { + + var reqHeader = Browser.client.header('http://example.com:8080/resource/4?filter=a', req.method, { credentials: credentials, ext: 'some-app-data', payload: payload, contentType: req.headers['content-type'] }); + req.headers.authorization = reqHeader.field; + + Hawk.server.authenticate(req, credentialsFunc, {}, function (err, credentials, artifacts) { + + expect(err).to.not.exist; + expect(credentials.user).to.equal('steve'); + expect(artifacts.ext).to.equal('some-app-data'); + expect(Hawk.server.authenticatePayload(payload, credentials, artifacts, req.headers['content-type'])).to.equal(true); + + var res = { + headers: { + 'content-type': 'text/plain' + }, + getResponseHeader: function (header) { + + return res.headers[header.toLowerCase()]; + } + }; + + res.headers['server-authorization'] = Hawk.server.header(credentials, artifacts); + expect(res.headers['server-authorization']).to.exist; + + expect(Browser.client.authenticate(res, credentials, artifacts, { payload: 'some reply' })).to.equal(false); + done(); + }); + }); + }); + + it('should generate a header then successfully parse it (with hash)', function (done) { + + var req = { + method: 'GET', + url: '/resource/4?filter=a', + host: 'example.com', + port: 8080 + }; + + credentialsFunc('123456', function (err, credentials) { + + req.authorization = Browser.client.header('http://example.com:8080/resource/4?filter=a', req.method, { credentials: credentials, payload: 'hola!', ext: 'some-app-data' }).field; + Hawk.server.authenticate(req, credentialsFunc, {}, function (err, credentials, artifacts) { + + expect(err).to.not.exist; + expect(credentials.user).to.equal('steve'); + expect(artifacts.ext).to.equal('some-app-data'); + done(); + }); + }); + }); + + it('should generate a header then successfully parse it then validate payload', function (done) { + + var req = { + method: 'GET', + url: '/resource/4?filter=a', + host: 'example.com', + port: 8080 + }; + + credentialsFunc('123456', function (err, credentials) { + + req.authorization = Browser.client.header('http://example.com:8080/resource/4?filter=a', req.method, { credentials: credentials, payload: 'hola!', ext: 'some-app-data' }).field; + Hawk.server.authenticate(req, credentialsFunc, {}, function (err, credentials, artifacts) { + + expect(err).to.not.exist; + expect(credentials.user).to.equal('steve'); + expect(artifacts.ext).to.equal('some-app-data'); + expect(Hawk.server.authenticatePayload('hola!', credentials, artifacts)).to.be.true; + expect(Hawk.server.authenticatePayload('hello!', credentials, artifacts)).to.be.false; + done(); + }); + }); + }); + + it('should generate a header then successfully parse it (app)', function (done) { + + var req = { + method: 'GET', + url: '/resource/4?filter=a', + host: 'example.com', + port: 8080 + }; + + credentialsFunc('123456', function (err, credentials) { + + req.authorization = Browser.client.header('http://example.com:8080/resource/4?filter=a', req.method, { credentials: credentials, ext: 'some-app-data', app: 'asd23ased' }).field; + Hawk.server.authenticate(req, credentialsFunc, {}, function (err, credentials, artifacts) { + + expect(err).to.not.exist; + expect(credentials.user).to.equal('steve'); + expect(artifacts.ext).to.equal('some-app-data'); + expect(artifacts.app).to.equal('asd23ased'); + done(); + }); + }); + }); + + it('should generate a header then successfully parse it (app, dlg)', function (done) { + + var req = { + method: 'GET', + url: '/resource/4?filter=a', + host: 'example.com', + port: 8080 + }; + + credentialsFunc('123456', function (err, credentials) { + + req.authorization = Browser.client.header('http://example.com:8080/resource/4?filter=a', req.method, { credentials: credentials, ext: 'some-app-data', app: 'asd23ased', dlg: '23434szr3q4d' }).field; + Hawk.server.authenticate(req, credentialsFunc, {}, function (err, credentials, artifacts) { + + expect(err).to.not.exist; + expect(credentials.user).to.equal('steve'); + expect(artifacts.ext).to.equal('some-app-data'); + expect(artifacts.app).to.equal('asd23ased'); + expect(artifacts.dlg).to.equal('23434szr3q4d'); + done(); + }); + }); + }); + + it('should generate a header then fail authentication due to bad hash', function (done) { + + var req = { + method: 'GET', + url: '/resource/4?filter=a', + host: 'example.com', + port: 8080 + }; + + credentialsFunc('123456', function (err, credentials) { + + req.authorization = Browser.client.header('http://example.com:8080/resource/4?filter=a', req.method, { credentials: credentials, payload: 'hola!', ext: 'some-app-data' }).field; + Hawk.server.authenticate(req, credentialsFunc, { payload: 'byebye!' }, function (err, credentials, artifacts) { + + expect(err).to.exist; + expect(err.response.payload.message).to.equal('Bad payload hash'); + done(); + }); + }); + }); + + it('should generate a header for one resource then fail to authenticate another', function (done) { + + var req = { + method: 'GET', + url: '/resource/4?filter=a', + host: 'example.com', + port: 8080 + }; + + credentialsFunc('123456', function (err, credentials) { + + req.authorization = Browser.client.header('http://example.com:8080/resource/4?filter=a', req.method, { credentials: credentials, ext: 'some-app-data' }).field; + req.url = '/something/else'; + + Hawk.server.authenticate(req, credentialsFunc, {}, function (err, credentials, artifacts) { + + expect(err).to.exist; + expect(credentials).to.exist; + done(); + }); + }); + }); + + describe('client', function () { + + describe('#header', function () { + + it('should return a valid authorization header (sha1)', function (done) { + + var credentials = { + id: '123456', + key: '2983d45yun89q', + algorithm: 'sha1' + }; + + var header = Browser.client.header('http://example.net/somewhere/over/the/rainbow', 'POST', { credentials: credentials, ext: 'Bazinga!', timestamp: 1353809207, nonce: 'Ygvqdz', payload: 'something to write about' }).field; + expect(header).to.equal('Hawk id="123456", ts="1353809207", nonce="Ygvqdz", hash="bsvY3IfUllw6V5rvk4tStEvpBhE=", ext="Bazinga!", mac="qbf1ZPG/r/e06F4ht+T77LXi5vw="'); + done(); + }); + + it('should return a valid authorization header (sha256)', function (done) { + + var credentials = { + id: '123456', + key: '2983d45yun89q', + algorithm: 'sha256' + }; + + var header = Browser.client.header('https://example.net/somewhere/over/the/rainbow', 'POST', { credentials: credentials, ext: 'Bazinga!', timestamp: 1353809207, nonce: 'Ygvqdz', payload: 'something to write about', contentType: 'text/plain' }).field; + expect(header).to.equal('Hawk id="123456", ts="1353809207", nonce="Ygvqdz", hash="2QfCt3GuY9HQnHWyWD3wX68ZOKbynqlfYmuO2ZBRqtY=", ext="Bazinga!", mac="q1CwFoSHzPZSkbIvl0oYlD+91rBUEvFk763nMjMndj8="'); + done(); + }); + + it('should return a valid authorization header (no ext)', function (done) { + + var credentials = { + id: '123456', + key: '2983d45yun89q', + algorithm: 'sha256' + }; + + var header = Browser.client.header('https://example.net/somewhere/over/the/rainbow', 'POST', { credentials: credentials, timestamp: 1353809207, nonce: 'Ygvqdz', payload: 'something to write about', contentType: 'text/plain' }).field; + expect(header).to.equal('Hawk id="123456", ts="1353809207", nonce="Ygvqdz", hash="2QfCt3GuY9HQnHWyWD3wX68ZOKbynqlfYmuO2ZBRqtY=", mac="HTgtd0jPI6E4izx8e4OHdO36q00xFCU0FolNq3RiCYs="'); + done(); + }); + + it('should return an empty authorization header on missing options', function (done) { + + var header = Browser.client.header('https://example.net/somewhere/over/the/rainbow', 'POST').field; + expect(header).to.equal(''); + done(); + }); + + it('should return an empty authorization header on invalid credentials', function (done) { + + var credentials = { + key: '2983d45yun89q', + algorithm: 'sha256' + }; + + var header = Browser.client.header('https://example.net/somewhere/over/the/rainbow', 'POST', { credentials: credentials, ext: 'Bazinga!', timestamp: 1353809207 }).field; + expect(header).to.equal(''); + done(); + }); + + it('should return an empty authorization header on invalid algorithm', function (done) { + + var credentials = { + id: '123456', + key: '2983d45yun89q', + algorithm: 'hmac-sha-0' + }; + + var header = Browser.client.header('https://example.net/somewhere/over/the/rainbow', 'POST', { credentials: credentials, payload: 'something, anything!', ext: 'Bazinga!', timestamp: 1353809207 }).field; + expect(header).to.equal(''); + done(); + }); + }); + + describe('#authenticate', function () { + + it('should return false on invalid header', function (done) { + + var res = { + headers: { + 'server-authorization': 'Hawk mac="abc", bad="xyz"' + }, + getResponseHeader: function (header) { + + return res.headers[header.toLowerCase()]; + } + }; + + expect(Browser.client.authenticate(res, {})).to.equal(false); + done(); + }); + + it('should return false on invalid mac', function (done) { + + var res = { + headers: { + 'content-type': 'text/plain', + 'server-authorization': 'Hawk mac="_IJRsMl/4oL+nn+vKoeVZPdCHXB4yJkNnBbTbHFZUYE=", hash="f9cDF/TDm7TkYRLnGwRMfeDzT6LixQVLvrIKhh0vgmM=", ext="response-specific"' + }, + getResponseHeader: function (header) { + + return res.headers[header.toLowerCase()]; + } + }; + + var artifacts = { + method: 'POST', + host: 'example.com', + port: '8080', + resource: '/resource/4?filter=a', + ts: '1362336900', + nonce: 'eb5S_L', + hash: 'nJjkVtBE5Y/Bk38Aiokwn0jiJxt/0S2WRSUwWLCf5xk=', + ext: 'some-app-data', + app: undefined, + dlg: undefined, + mac: 'BlmSe8K+pbKIb6YsZCnt4E1GrYvY1AaYayNR82dGpIk=', + id: '123456' + }; + + var credentials = { + id: '123456', + key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn', + algorithm: 'sha256', + user: 'steve' + }; + + expect(Browser.client.authenticate(res, credentials, artifacts)).to.equal(false); + done(); + }); + + it('should return true on ignoring hash', function (done) { + + var res = { + headers: { + 'content-type': 'text/plain', + 'server-authorization': 'Hawk mac="XIJRsMl/4oL+nn+vKoeVZPdCHXB4yJkNnBbTbHFZUYE=", hash="f9cDF/TDm7TkYRLnGwRMfeDzT6LixQVLvrIKhh0vgmM=", ext="response-specific"' + }, + getResponseHeader: function (header) { + + return res.headers[header.toLowerCase()]; + } + }; + + var artifacts = { + method: 'POST', + host: 'example.com', + port: '8080', + resource: '/resource/4?filter=a', + ts: '1362336900', + nonce: 'eb5S_L', + hash: 'nJjkVtBE5Y/Bk38Aiokwn0jiJxt/0S2WRSUwWLCf5xk=', + ext: 'some-app-data', + app: undefined, + dlg: undefined, + mac: 'BlmSe8K+pbKIb6YsZCnt4E1GrYvY1AaYayNR82dGpIk=', + id: '123456' + }; + + var credentials = { + id: '123456', + key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn', + algorithm: 'sha256', + user: 'steve' + }; + + expect(Browser.client.authenticate(res, credentials, artifacts)).to.equal(true); + done(); + }); + + it('should fail on invalid WWW-Authenticate header format', function (done) { + + var res = { + headers: { + 'www-authenticate': 'Hawk ts="1362346425875", tsm="PhwayS28vtnn3qbv0mqRBYSXebN/zggEtucfeZ620Zo=", x="Stale timestamp"' + }, + getResponseHeader: function (header) { + + return res.headers[header.toLowerCase()]; + } + }; + + expect(Browser.client.authenticate(res, {})).to.equal(false); + done(); + }); + + it('should fail on invalid WWW-Authenticate header format', function (done) { + + var credentials = { + id: '123456', + key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn', + algorithm: 'sha256', + user: 'steve' + }; + + var res = { + headers: { + 'www-authenticate': 'Hawk ts="1362346425875", tsm="hwayS28vtnn3qbv0mqRBYSXebN/zggEtucfeZ620Zo=", error="Stale timestamp"' + }, + getResponseHeader: function (header) { + + return res.headers[header.toLowerCase()]; + } + }; + + expect(Browser.client.authenticate(res, credentials)).to.equal(false); + done(); + }); + }); + + describe('#message', function () { + it('should generate an authorization then successfully parse it', function (done) { + + credentialsFunc('123456', function (err, credentials) { + + var auth = Browser.client.message('example.com', 8080, 'some message', { credentials: credentials }); + expect(auth).to.exist; + + Hawk.server.authenticateMessage('example.com', 8080, 'some message', auth, credentialsFunc, {}, function (err, credentials) { + + expect(err).to.not.exist; + expect(credentials.user).to.equal('steve'); + done(); + }); + }); + }); + + it('should fail on missing host', function (done) { + + credentialsFunc('123456', function (err, credentials) { + + var auth = Browser.client.message(null, 8080, 'some message', { credentials: credentials }); + expect(auth).to.not.exist; + done(); + }); + }); + + it('should fail on missing credentials', function (done) { + + var auth = Browser.client.message('example.com', 8080, 'some message', {}); + expect(auth).to.not.exist; + done(); + }); + + it('should fail on invalid algorithm', function (done) { + + credentialsFunc('123456', function (err, credentials) { + + var creds = Hoek.clone(credentials); + creds.algorithm = 'blah'; + var auth = Browser.client.message('example.com', 8080, 'some message', { credentials: creds }); + expect(auth).to.not.exist; + done(); + }); + }); + }); + }); + + describe('#parseAuthorizationHeader', function (done) { + + it('returns null on missing header', function (done) { + + expect(Browser.utils.parseAuthorizationHeader()).to.equal(null); + done(); + }); + + it('returns null on bad header syntax (structure)', function (done) { + + expect(Browser.utils.parseAuthorizationHeader('Hawk')).to.equal(null); + done(); + }); + + it('returns null on bad header syntax (parts)', function (done) { + + expect(Browser.utils.parseAuthorizationHeader(' ')).to.equal(null); + done(); + }); + + it('returns null on bad scheme name', function (done) { + + expect(Browser.utils.parseAuthorizationHeader('Basic asdasd')).to.equal(null); + done(); + }); + + it('returns null on bad attribute value', function (done) { + + expect(Browser.utils.parseAuthorizationHeader('Hawk test="\t"', ['test'])).to.equal(null); + done(); + }); + + it('returns null on duplicated attribute', function (done) { + + expect(Browser.utils.parseAuthorizationHeader('Hawk test="a", test="b"', ['test'])).to.equal(null); + done(); + }); + }); +}); diff --git a/deps/npm/node_modules/request/node_modules/hawk/test/message.js b/deps/npm/node_modules/request/node_modules/hawk/test/message.js new file mode 100755 index 00000000000..04b91d4124c --- /dev/null +++ b/deps/npm/node_modules/request/node_modules/hawk/test/message.js @@ -0,0 +1,246 @@ +// Load modules + +var Url = require('url'); +var Lab = require('lab'); +var Hoek = require('hoek'); +var Hawk = require('../lib'); + + +// Declare internals + +var internals = {}; + + +// Test shortcuts + +var expect = Lab.expect; +var before = Lab.before; +var after = Lab.after; +var describe = Lab.experiment; +var it = Lab.test; + + +describe('Hawk', function () { + + var credentialsFunc = function (id, callback) { + + var credentials = { + id: id, + key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn', + algorithm: (id === '1' ? 'sha1' : 'sha256'), + user: 'steve' + }; + + return callback(null, credentials); + }; + + it('should generate an authorization then successfully parse it', function (done) { + + credentialsFunc('123456', function (err, credentials) { + + var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: credentials }); + expect(auth).to.exist; + + Hawk.server.authenticateMessage('example.com', 8080, 'some message', auth, credentialsFunc, {}, function (err, credentials) { + + expect(err).to.not.exist; + expect(credentials.user).to.equal('steve'); + done(); + }); + }); + }); + + it('should fail authorization on mismatching host', function (done) { + + credentialsFunc('123456', function (err, credentials) { + + var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: credentials }); + expect(auth).to.exist; + + Hawk.server.authenticateMessage('example1.com', 8080, 'some message', auth, credentialsFunc, {}, function (err, credentials) { + + expect(err).to.exist; + expect(err.message).to.equal('Bad mac'); + done(); + }); + }); + }); + + it('should fail authorization on stale timestamp', function (done) { + + credentialsFunc('123456', function (err, credentials) { + + var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: credentials }); + expect(auth).to.exist; + + Hawk.server.authenticateMessage('example.com', 8080, 'some message', auth, credentialsFunc, { localtimeOffsetMsec: 100000 }, function (err, credentials) { + + expect(err).to.exist; + expect(err.message).to.equal('Stale timestamp'); + done(); + }); + }); + }); + + it('should fail authorization on invalid authorization', function (done) { + + credentialsFunc('123456', function (err, credentials) { + + var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: credentials }); + expect(auth).to.exist; + delete auth.id; + + Hawk.server.authenticateMessage('example.com', 8080, 'some message', auth, credentialsFunc, {}, function (err, credentials) { + + expect(err).to.exist; + expect(err.message).to.equal('Invalid authorization'); + done(); + }); + }); + }); + + it('should fail authorization on bad hash', function (done) { + + credentialsFunc('123456', function (err, credentials) { + + var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: credentials }); + expect(auth).to.exist; + + Hawk.server.authenticateMessage('example.com', 8080, 'some message1', auth, credentialsFunc, {}, function (err, credentials) { + + expect(err).to.exist; + expect(err.message).to.equal('Bad message hash'); + done(); + }); + }); + }); + + it('should fail authorization on nonce error', function (done) { + + credentialsFunc('123456', function (err, credentials) { + + var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: credentials }); + expect(auth).to.exist; + + Hawk.server.authenticateMessage('example.com', 8080, 'some message', auth, credentialsFunc, { nonceFunc: function (nonce, ts, callback) { callback (new Error('kaboom')); } }, function (err, credentials) { + + expect(err).to.exist; + expect(err.message).to.equal('Invalid nonce'); + done(); + }); + }); + }); + + it('should fail authorization on credentials error', function (done) { + + credentialsFunc('123456', function (err, credentials) { + + var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: credentials }); + expect(auth).to.exist; + + var errFunc = function (id, callback) { + + callback(new Error('kablooey')); + }; + + Hawk.server.authenticateMessage('example.com', 8080, 'some message', auth, errFunc, {}, function (err, credentials) { + + expect(err).to.exist; + expect(err.message).to.equal('kablooey'); + done(); + }); + }); + }); + + it('should fail authorization on missing credentials', function (done) { + + credentialsFunc('123456', function (err, credentials) { + + var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: credentials }); + expect(auth).to.exist; + + var errFunc = function (id, callback) { + + callback(); + }; + + Hawk.server.authenticateMessage('example.com', 8080, 'some message', auth, errFunc, {}, function (err, credentials) { + + expect(err).to.exist; + expect(err.message).to.equal('Unknown credentials'); + done(); + }); + }); + }); + + it('should fail authorization on invalid credentials', function (done) { + + credentialsFunc('123456', function (err, credentials) { + + var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: credentials }); + expect(auth).to.exist; + + var errFunc = function (id, callback) { + + callback(null, {}); + }; + + Hawk.server.authenticateMessage('example.com', 8080, 'some message', auth, errFunc, {}, function (err, credentials) { + + expect(err).to.exist; + expect(err.message).to.equal('Invalid credentials'); + done(); + }); + }); + }); + + it('should fail authorization on invalid credentials algorithm', function (done) { + + credentialsFunc('123456', function (err, credentials) { + + var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: credentials }); + expect(auth).to.exist; + + var errFunc = function (id, callback) { + + callback(null, { key: '123', algorithm: '456' }); + }; + + Hawk.server.authenticateMessage('example.com', 8080, 'some message', auth, errFunc, {}, function (err, credentials) { + + expect(err).to.exist; + expect(err.message).to.equal('Unknown algorithm'); + done(); + }); + }); + }); + + it('should fail on missing host', function (done) { + + credentialsFunc('123456', function (err, credentials) { + + var auth = Hawk.client.message(null, 8080, 'some message', { credentials: credentials }); + expect(auth).to.not.exist; + done(); + }); + }); + + it('should fail on missing credentials', function (done) { + + var auth = Hawk.client.message('example.com', 8080, 'some message', {}); + expect(auth).to.not.exist; + done(); + }); + + it('should fail on invalid algorithm', function (done) { + + credentialsFunc('123456', function (err, credentials) { + + var creds = Hoek.clone(credentials); + creds.algorithm = 'blah'; + var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: creds }); + expect(auth).to.not.exist; + done(); + }); + }); +}); diff --git a/deps/npm/node_modules/request/node_modules/hawk/test/server.js b/deps/npm/node_modules/request/node_modules/hawk/test/server.js index 404674fb3f2..3e92427a8dd 100755 --- a/deps/npm/node_modules/request/node_modules/hawk/test/server.js +++ b/deps/npm/node_modules/request/node_modules/hawk/test/server.js @@ -44,7 +44,7 @@ describe('Hawk', function () { url: '/resource/4?filter=a', host: 'example.com', port: 8080, - authorization: 'Hawk id="1", ts="1353788437", nonce="k3j4h2", mac="zy79QQ5/EYFmQqutVnYb73gAc/U=", ext="hello"', + authorization: 'Hawk id="1", ts="1353788437", nonce="k3j4h2", mac="zy79QQ5/EYFmQqutVnYb73gAc/U=", ext="hello"' }; Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) { @@ -62,7 +62,7 @@ describe('Hawk', function () { url: '/resource/1?b=1&a=2', host: 'example.com', port: 8000, - authorization: 'Hawk id="dh37fgj492je", ts="1353832234", nonce="j4h3g2", mac="m8r1rHbXN6NgO+KIIhjO7sFRyd78RNGVUwehe8Cp2dU=", ext="some-app-data"', + authorization: 'Hawk id="dh37fgj492je", ts="1353832234", nonce="j4h3g2", mac="m8r1rHbXN6NgO+KIIhjO7sFRyd78RNGVUwehe8Cp2dU=", ext="some-app-data"' }; Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353832234000 - Hawk.utils.now() }, function (err, credentials, artifacts) { @@ -73,6 +73,44 @@ describe('Hawk', function () { }); }); + it('should parse a valid authentication header (host override)', function (done) { + + var req = { + method: 'GET', + url: '/resource/4?filter=a', + headers: { + host: 'example1.com:8080', + authorization: 'Hawk id="1", ts="1353788437", nonce="k3j4h2", mac="zy79QQ5/EYFmQqutVnYb73gAc/U=", ext="hello"' + } + }; + + Hawk.server.authenticate(req, credentialsFunc, { host: 'example.com', localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) { + + expect(err).to.not.exist; + expect(credentials.user).to.equal('steve'); + done(); + }); + }); + + it('should parse a valid authentication header (host port override)', function (done) { + + var req = { + method: 'GET', + url: '/resource/4?filter=a', + headers: { + host: 'example1.com:80', + authorization: 'Hawk id="1", ts="1353788437", nonce="k3j4h2", mac="zy79QQ5/EYFmQqutVnYb73gAc/U=", ext="hello"' + } + }; + + Hawk.server.authenticate(req, credentialsFunc, { host: 'example.com', port: 8080, localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) { + + expect(err).to.not.exist; + expect(credentials.user).to.equal('steve'); + done(); + }); + }); + it('should parse a valid authentication header (POST with payload)', function (done) { var req = { @@ -80,7 +118,7 @@ describe('Hawk', function () { url: '/resource/4?filter=a', host: 'example.com', port: 8080, - authorization: 'Hawk id="123456", ts="1357926341", nonce="1AwuJD", hash="qAiXIVv+yjDATneWxZP2YCTa9aHRgQdnH9b3Wc+o3dg=", ext="some-app-data", mac="UeYcj5UoTVaAWXNvJfLVia7kU3VabxCqrccXP8sUGC4="', + authorization: 'Hawk id="123456", ts="1357926341", nonce="1AwuJD", hash="qAiXIVv+yjDATneWxZP2YCTa9aHRgQdnH9b3Wc+o3dg=", ext="some-app-data", mac="UeYcj5UoTVaAWXNvJfLVia7kU3VabxCqrccXP8sUGC4="' }; Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1357926341000 - Hawk.utils.now() }, function (err, credentials, artifacts) { @@ -98,7 +136,7 @@ describe('Hawk', function () { url: '/resource/1?b=1&a=2', host: 'example.com', port: 8000, - authorization: 'Hawk id="dh37fgj492je", ts="1353832234", nonce="j4h3g2", mac="m8r1rHbXN6NgO+KIIhjO7sFRyd78RNGVUwehe8Cp2dU=", ext="some-app-data"', + authorization: 'Hawk id="dh37fgj492je", ts="1353832234", nonce="j4h3g2", mac="m8r1rHbXN6NgO+KIIhjO7sFRyd78RNGVUwehe8Cp2dU=", ext="some-app-data"' }; Hawk.server.authenticate(req, credentialsFunc, { payload: 'body', localtimeOffsetMsec: 1353832234000 - Hawk.utils.now() }, function (err, credentials, artifacts) { @@ -116,7 +154,7 @@ describe('Hawk', function () { url: '/resource/4?filter=a', host: 'example.com', port: 8080, - authorization: 'Hawk id="123456", ts="1362337299", nonce="UzmxSs", ext="some-app-data", mac="wnNUxchvvryMH2RxckTdZ/gY3ijzvccx4keVvELC61w="', + authorization: 'Hawk id="123456", ts="1362337299", nonce="UzmxSs", ext="some-app-data", mac="wnNUxchvvryMH2RxckTdZ/gY3ijzvccx4keVvELC61w="' }; Hawk.server.authenticate(req, credentialsFunc, {}, function (err, credentials, artifacts) { @@ -146,7 +184,7 @@ describe('Hawk', function () { url: '/resource/4?filter=a', host: 'example.com', port: 8080, - authorization: 'Hawk id="123", ts="1353788437", nonce="k3j4h2", mac="bXx7a7p1h9QYQNZ8x7QhvDQym8ACgab4m3lVSFn4DBw=", ext="hello"', + authorization: 'Hawk id="123", ts="1353788437", nonce="k3j4h2", mac="bXx7a7p1h9QYQNZ8x7QhvDQym8ACgab4m3lVSFn4DBw=", ext="hello"' }; var memoryCache = {}; diff --git a/deps/npm/node_modules/request/node_modules/hawk/test/utils.js b/deps/npm/node_modules/request/node_modules/hawk/test/utils.js index e6e6dfa409c..0f5fef77547 100755 --- a/deps/npm/node_modules/request/node_modules/hawk/test/utils.js +++ b/deps/npm/node_modules/request/node_modules/hawk/test/utils.js @@ -57,6 +57,44 @@ describe('Hawk', function () { expect(Hawk.utils.parseHost(req, 'Host').port).to.equal(443); done(); }); + + it('returns port 443 for non tls node request (IPv6)', function (done) { + + var req = { + method: 'POST', + url: '/resource/4?filter=a', + headers: { + host: '[123:123:123]', + 'content-type': 'text/plain;x=y' + }, + connection: { + encrypted: true + } + }; + + expect(Hawk.utils.parseHost(req, 'Host').port).to.equal(443); + done(); + }); + + it('parses IPv6 headers', function (done) { + + var req = { + method: 'POST', + url: '/resource/4?filter=a', + headers: { + host: '[123:123:123]:8000', + 'content-type': 'text/plain;x=y' + }, + connection: { + encrypted: true + } + }; + + var host = Hawk.utils.parseHost(req, 'Host'); + expect(host.port).to.equal('8000'); + expect(host.name).to.equal('[123:123:123]'); + done(); + }); }); describe('#version', function () { @@ -68,14 +106,14 @@ describe('Hawk', function () { }); }); - describe('#unauthorized', function () {
+ describe('#unauthorized', function () { - it('returns a hawk 401', function (done) {
+ it('returns a hawk 401', function (done) { expect(Hawk.utils.unauthorized('kaboom').response.headers['WWW-Authenticate']).to.equal('Hawk error="kaboom"'); - done();
- });
- });
+ done(); + }); + }); }); }); diff --git a/deps/npm/node_modules/request/node_modules/http-signature/.npmignore b/deps/npm/node_modules/request/node_modules/http-signature/.npmignore index 486127c70af..c143fb3a46c 100644 --- a/deps/npm/node_modules/request/node_modules/http-signature/.npmignore +++ b/deps/npm/node_modules/request/node_modules/http-signature/.npmignore @@ -1,6 +1,7 @@ .gitmodules -Makefile deps docs +Makefile +node_modules test tools
\ No newline at end of file diff --git a/deps/npm/node_modules/request/node_modules/http-signature/README.md b/deps/npm/node_modules/request/node_modules/http-signature/README.md index 3ed2e464036..0c7071492c6 100644 --- a/deps/npm/node_modules/request/node_modules/http-signature/README.md +++ b/deps/npm/node_modules/request/node_modules/http-signature/README.md @@ -1,5 +1,7 @@ +# node-http-signature + node-http-signature is a node.js library that has client and server components -for Joyent's `HTTP Signature Scheme`. +for Joyent's [HTTP Signature Scheme](http_signing.md). ## Usage diff --git a/deps/npm/node_modules/request/node_modules/http-signature/http_signing.md b/deps/npm/node_modules/request/node_modules/http-signature/http_signing.md index 585926cad2e..ba7321da15e 100644 --- a/deps/npm/node_modules/request/node_modules/http-signature/http_signing.md +++ b/deps/npm/node_modules/request/node_modules/http-signature/http_signing.md @@ -46,14 +46,15 @@ HTTP `Date` header. The client is expected to send an Authorization header (as defined in RFC 2617) with the following parameterization: - credentials := "Signature" params digitalSignature - params := 1#(keyId | [algorithm] | [headers] | [ext]) + credentials := "Signature" params + params := 1#(keyId | algorithm | [headers] | [ext] | signature) digitalSignature := plain-string keyId := "keyId" "=" <"> plain-string <"> algorithm := "algorithm" "=" <"> plain-string <"> headers := "headers" "=" <"> 1#headers-value <"> ext := "ext" "=" <"> plain-string <"> + signature := "signature" "=" <"> plain-string <"> headers-value := plain-string plain-string = 1*( %x20-21 / %x23-5B / %x5D-7E ) @@ -92,20 +93,26 @@ OPTIONAL. The `extensions` parameter is used to include additional information which is covered by the request. The content and format of the string is out of scope for this document, and expected to be specified by implementors. -### Digital Signature +#### signature -The `digitalSignature` portion of the credentials is a REQUIRED field, and is +REQUIRED. The `signature` parameter is a `Base64` encoded digital signature generated by the client. The client uses the `algorithm` and `headers` request parameters to form a canonicalized `signing string`. This `signing string` is -then signed with the key associated with `keyId` and the algorithm corresponding -to `algorithm`. The result is then `Base64` encoded. +then signed with the key associated with `keyId` and the algorithm +corresponding to `algorithm`. The `signature` parameter is then set to the +`Base64` encoding of the signature. ### Signing String Composition -In order to generate the string that is signed with a key, the client MUST -take the values of each HTTP header specified by `headers`, in the order they -appear, and separate with an ASCII newline `\n`. The last header in the list -MUST NOT include a trailing ASCII newline. +In order to generate the string that is signed with a key, the client MUST take +the values of each HTTP header specified by `headers` in the order they appear. + +1. If the header name is not `request-line` then append the lowercased header + name followed with an ASCII colon `:` and an ASCII space ` `. +2. If the header name is `request-line` then appened the HTTP request line, + otherwise append the header value. +3. If value is not the last value then append an ASCII newline `\n`. The string + MUST NOT include a trailing ASCII newline. # Example Requests @@ -118,24 +125,43 @@ All requests refer to the following request (body ommitted): Content-MD5: h0auK8hnYJKmHTLhKtMTkQ== Content-Length: 123 +The "rsa-key-1" keyId refers to a private key known to the client and a public +key known to the server. The "hmac-key-1" keyId refers to key known to the +client and server. + ## Default parameterization - Authorization: Signature keyId="123" Base64(RSA-SHA256(Tue, 07 Jun 2011 20:51:35 GMT)) +The authorization header and signature would be generated as: + + Authorization: Signature keyId="rsa-key-1",algorithm="rsa-sha256",signature="Base64(RSA-SHA256(signing string))" + +The client would compose the signing string as: + + date: Tue, 07 Jun 2011 20:51:35 GMT ## Header List - Authorization: Signature keyId="123",headers="content-type Date content-md5" Base64(RSA-SHA256(Tue, 07 Jun 2011 20:51:35 GMT)) +The authorization header and signature would be generated as: + + Authorization: Signature keyId="rsa-key-1",algorithm="rsa-sha256",headers="request-line date content-type content-md5",signature="Base64(RSA-SHA256(signing string))" The client would compose the signing string as (`+ "\n"` inserted for readability): - application/json + "\n" - Tue, 07 Jun 2011 20:51:35 GMT + "\n" - h0auK8hnYJKmHTLhKtMTkQ== + POST /foo HTTP/1.1 + "\n" + date: Tue, 07 Jun 2011 20:51:35 GMT + "\n" + content-type: application/json + "\n" + content-md5: h0auK8hnYJKmHTLhKtMTkQ== ## Algorithm - Authorization: Signature keyId="123",algorithm="hmac-sha1" Base64(HMAC-SHA1(Tue, 07 Jun 2011 20:51:35 GMT)) +The authorization header and signature would be generated as: + + Authorization: Signature keyId="hmac-key-1",algorithm="hmac-sha1",signature="Base64(HMAC-SHA1(signing string))" + +The client would compose the signing string as: + + date: Tue, 07 Jun 2011 20:51:35 GMT # Signing Algorithms @@ -144,6 +170,7 @@ Currently supported algorithm names are: * rsa-sha1 * rsa-sha256 * rsa-sha512 +* dsa-sha1 * hmac-sha1 * hmac-sha256 * hmac-sha512 @@ -245,29 +272,25 @@ And all examples use this request: The string to sign would be: -``` -Thu, 05 Jan 2012 21:31:40 GMT -``` + date: Thu, 05 Jan 2012 21:31:40 GMT The Authorization header would be: - Authorization: Signature keyId="Test",algorithm="rsa-sha256" MDyO5tSvin5FBVdq3gMBTwtVgE8U/JpzSwFvY7gu7Q2tiZ5TvfHzf/RzmRoYwO8PoV1UGaw6IMwWzxDQkcoYOwvG/w4ljQBBoNusO/mYSvKrbqxUmZi8rNtrMcb82MS33bai5IeLnOGl31W1UbL4qE/wL8U9wCPGRJlCFLsTgD8= + Authorization: Signature keyId="Test",algorithm="rsa-sha256",signature="JldXnt8W9t643M2Sce10gqCh/+E7QIYLiI+bSjnFBGCti7s+mPPvOjVb72sbd1FjeOUwPTDpKbrQQORrm+xBYfAwCxF3LBSSzORvyJ5nRFCFxfJ3nlQD6Kdxhw8wrVZX5nSem4A/W3C8qH5uhFTRwF4ruRjh+ENHWuovPgO/HGQ=" ### All Headers -Parameterized to include all headers, the string to sign would be: +Parameterized to include all headers, the string to sign would be (`+ "\n"` +inserted for readability): -``` -/foo?param=value&pet=dog HTTP/1.1 -example.com -Thu, 05 Jan 2012 21:31:40 GMT -application/json -Sd/dVLAcvNLSq16eXua5uQ== -18 -``` + POST /foo?param=value&pet=dog HTTP/1.1 + "\n" + host: example.com + "\n" + date: Thu, 05 Jan 2012 21:31:40 GMT + "\n" + content-type: application/json + "\n" + content-md5: Sd/dVLAcvNLSq16eXua5uQ== + "\n" + content-length: 18 The Authorization header would be: - Authorization: Signature - keyId="Test",algorithm="rsa-sha256",headers="request-line host date content-type content-md5 content-length" gVrKP7wVh1+FmWbNlhj0pNXIe9XmeOA6EcnoOKAvUILnwaMFzaKaam9UmeDPwjC9TdT+jSRqjtyZE49kZcSpYAHxGlPQ4ziXFRfPprlN/3Xwg3sUOGqbBiS3WFuY3QOOWv4tzc5p70g74U/QvHNNiYMcjoz89vRJhefbFSNwCDs= + Authorization: Signature keyId="Test",algorithm="rsa-sha256",headers="request-line host date content-type content-md5 content-length",signature="Gm7W/r+e90REDpWytALMrft4MqZxCmslOTOvwJX17ViEBA5E65QqvWI0vIH3l/vSsGiaMVmuUgzYsJLYMLcm5dGrv1+a+0fCoUdVKPZWHyImQEqpLkopVwqEH67LVECFBqFTAKlQgBn676zrfXQbb+b/VebAsNUtvQMe6cTjnDY=" diff --git a/deps/npm/node_modules/request/node_modules/http-signature/lib/parser.js b/deps/npm/node_modules/request/node_modules/http-signature/lib/parser.js index 98a5ee5dc6d..fd9ac1022ad 100644 --- a/deps/npm/node_modules/request/node_modules/http-signature/lib/parser.js +++ b/deps/npm/node_modules/request/node_modules/http-signature/lib/parser.js @@ -19,13 +19,14 @@ var Algorithms = { var State = { New: 0, - Params: 1, - Signature: 2 + Params: 1 }; var ParamsState = { Name: 0, - Value: 1 + Quote: 1, + Value: 2, + Comma: 3 }; @@ -88,9 +89,9 @@ module.exports = { * "headers": [ * "date" or "x-date", * "content-md5" - * ] + * ], + * "signature": "base64" * }, - * "signature": "base64", * "signingString": "ready to be passed to crypto.verify()" * } * @@ -138,7 +139,6 @@ module.exports = { var parsed = { scheme: '', params: {}, - signature: '', signingString: '', get algorithm() { @@ -166,24 +166,44 @@ module.exports = { switch (Number(substate)) { case ParamsState.Name: + var code = c.charCodeAt(0); + // restricted name of A-Z / a-z + if ((code >= 0x41 && code <= 0x5a) || // A-Z + (code >= 0x61 && code <= 0x7a)) { // a-z + tmpName += c; + } else if (c === '=') { + if (tmpName.length === 0) + throw new InvalidHeaderError('bad param format'); + substate = ParamsState.Quote; + } else { + throw new InvalidHeaderError('bad param format'); + } + break; + + case ParamsState.Quote: if (c === '"') { - parsed.params[tmpName] = ''; tmpValue = ''; substate = ParamsState.Value; - } else if (c === ' ') { - state = State.Signature; - } else if (c !== '=' && c !== ',') { - tmpName += c; + } else { + throw new InvalidHeaderError('bad param format'); } break; case ParamsState.Value: if (c === '"') { parsed.params[tmpName] = tmpValue; + substate = ParamsState.Comma; + } else { + tmpValue += c; + } + break; + + case ParamsState.Comma: + if (c === ',') { tmpName = ''; substate = ParamsState.Name; } else { - tmpValue += c; + throw new InvalidHeaderError('bad param format'); } break; @@ -192,11 +212,6 @@ module.exports = { } break; - - case State.Signature: - parsed.signature += c; - break; - default: throw new Error('Invalid substate'); } @@ -223,8 +238,8 @@ module.exports = { if (!parsed.params.algorithm) throw new InvalidHeaderError('algorithm was not specified'); - if (!parsed.signature) - throw new InvalidHeaderError('signature was empty'); + if (!parsed.params.signature) + throw new InvalidHeaderError('signature was not specified'); // Check the algorithm against the official list parsed.params.algorithm = parsed.params.algorithm.toLowerCase(); @@ -237,17 +252,16 @@ module.exports = { var h = parsed.params.headers[i].toLowerCase(); parsed.params.headers[i] = h; - var value; if (h !== 'request-line') { - value = request.headers[h]; + var value = request.headers[h]; if (!value) throw new MissingHeaderError(h + ' was not in the request'); + parsed.signingString += h + ': ' + value; } else { - value = + parsed.signingString += request.method + ' ' + request.url + ' HTTP/' + request.httpVersion; } - parsed.signingString += value; if ((i + 1) < parsed.params.headers.length) parsed.signingString += '\n'; } diff --git a/deps/npm/node_modules/request/node_modules/http-signature/lib/signer.js b/deps/npm/node_modules/request/node_modules/http-signature/lib/signer.js index cc750ce737f..8095f0d1790 100644 --- a/deps/npm/node_modules/request/node_modules/http-signature/lib/signer.js +++ b/deps/npm/node_modules/request/node_modules/http-signature/lib/signer.js @@ -20,7 +20,8 @@ var Algorithms = { 'hmac-sha512': true }; -var Authorization = 'Signature keyId="%s",algorithm="%s",headers="%s" %s'; +var Authorization = + 'Signature keyId="%s",algorithm="%s",headers="%s",signature="%s"'; @@ -101,6 +102,7 @@ module.exports = { * - {String} key required (either a PEM or HMAC key). * - {Array} headers optional; defaults to ['date']. * - {String} algorithm optional; defaults to 'rsa-sha256'. + * - {String} httpVersion optional; defaults to '1.1'. * @return {Boolean} true if Authorization (and optionally Date) were added. * @throws {TypeError} on bad parameter types (input). * @throws {InvalidAlgorithmError} if algorithm was bad. @@ -113,6 +115,7 @@ module.exports = { assert.optionalString(options.algorithm, 'options.algorithm'); assert.string(options.keyId, 'options.keyId'); assert.optionalArrayOfString(options.headers, 'options.headers'); + assert.optionalString(options.httpVersion, 'options.httpVersion'); if (!request.getHeader('Date')) request.setHeader('Date', _rfc1123()); @@ -120,6 +123,8 @@ module.exports = { options.headers = ['date']; if (!options.algorithm) options.algorithm = 'rsa-sha256'; + if (!options.httpVersion) + options.httpVersion = '1.1'; options.algorithm = options.algorithm.toLowerCase(); @@ -133,18 +138,19 @@ module.exports = { throw new TypeError('options.headers must be an array of Strings'); var h = options.headers[i].toLowerCase(); - request.getHeader(h); - var value = request.getHeader(h); - if (!value) { - if (h === 'request-line') { - value = request.method + ' ' + request.path + ' HTTP/1.1'; - } else { + if (h !== 'request-line') { + var value = request.getHeader(h); + if (!value) { throw new MissingHeaderError(h + ' was not in the request'); } + stringToSign += h + ': ' + value; + } else { + value = + stringToSign += + request.method + ' ' + request.path + ' HTTP/' + options.httpVersion; } - stringToSign += value; if ((i + 1) < options.headers.length) stringToSign += '\n'; } diff --git a/deps/npm/node_modules/request/node_modules/http-signature/lib/verify.js b/deps/npm/node_modules/request/node_modules/http-signature/lib/verify.js index 0846c798000..5bf958964c8 100644 --- a/deps/npm/node_modules/request/node_modules/http-signature/lib/verify.js +++ b/deps/npm/node_modules/request/node_modules/http-signature/lib/verify.js @@ -29,13 +29,13 @@ module.exports = { parsedSignature.algorithm); if (alg[1] === 'HMAC') { - var hmac = crypto.createHmac(alg[2].toLowerCase(), key); + var hmac = crypto.createHmac(alg[2].toUpperCase(), key); hmac.update(parsedSignature.signingString); - return (hmac.digest('base64') === parsedSignature.signature); + return (hmac.digest('base64') === parsedSignature.params.signature); } else { var verify = crypto.createVerify(alg[0]); verify.update(parsedSignature.signingString); - return verify.verify(key, parsedSignature.signature, 'base64'); + return verify.verify(key, parsedSignature.params.signature, 'base64'); } } diff --git a/deps/npm/node_modules/request/node_modules/http-signature/package.json b/deps/npm/node_modules/request/node_modules/http-signature/package.json index 4fe460403d2..1a50c484d1d 100644 --- a/deps/npm/node_modules/request/node_modules/http-signature/package.json +++ b/deps/npm/node_modules/request/node_modules/http-signature/package.json @@ -4,7 +4,7 @@ }, "name": "http-signature", "description": "Reference implementation of Joyent's HTTP Signature Scheme", - "version": "0.9.11", + "version": "0.10.0", "repository": { "type": "git", "url": "git://github.com/joyent/node-http-signature.git" @@ -23,13 +23,13 @@ }, "devDependencies": { "node-uuid": "1.4.0", - "tap": "0.3.1" + "tap": "0.4.2" }, - "readme": "node-http-signature is a node.js library that has client and server components\nfor Joyent's `HTTP Signature Scheme`.\n\n## Usage\n\nNote the example below signs a request with the same key/cert used to start an\nHTTP server. This is almost certainly not what you actaully want, but is just\nused to illustrate the API calls; you will need to provide your own key\nmanagement in addition to this library.\n\n### Client\n\n var fs = require('fs');\n var https = require('https');\n var httpSignature = require('http-signature');\n\n var key = fs.readFileSync('./key.pem', 'ascii');\n\n var options = {\n host: 'localhost',\n port: 8443,\n path: '/',\n method: 'GET',\n headers: {}\n };\n\n // Adds a 'Date' header in, signs it, and adds the\n // 'Authorization' header in.\n var req = https.request(options, function(res) {\n console.log(res.statusCode);\n });\n\n\n httpSignature.sign(req, {\n key: key,\n keyId: './cert.pem'\n });\n\n req.end();\n\n### Server\n\n var fs = require('fs');\n var https = require('https');\n var httpSignature = require('http-signature');\n\n var options = {\n key: fs.readFileSync('./key.pem'),\n cert: fs.readFileSync('./cert.pem')\n };\n\n https.createServer(options, function (req, res) {\n var rc = 200;\n var parsed = httpSignature.parseRequest(req);\n var pub = fs.readFileSync(parsed.keyId, 'ascii');\n if (!httpSignature.verifySignature(parsed, pub))\n rc = 401;\n\n res.writeHead(rc);\n res.end();\n }).listen(8443);\n\n## Installation\n\n npm install http-signature\n\n## License\n\nMIT.\n\n## Bugs\n\nSee <https://github.com/joyent/node-http-signature/issues>.\n", + "readme": "# node-http-signature\n\nnode-http-signature is a node.js library that has client and server components\nfor Joyent's [HTTP Signature Scheme](http_signing.md).\n\n## Usage\n\nNote the example below signs a request with the same key/cert used to start an\nHTTP server. This is almost certainly not what you actaully want, but is just\nused to illustrate the API calls; you will need to provide your own key\nmanagement in addition to this library.\n\n### Client\n\n var fs = require('fs');\n var https = require('https');\n var httpSignature = require('http-signature');\n\n var key = fs.readFileSync('./key.pem', 'ascii');\n\n var options = {\n host: 'localhost',\n port: 8443,\n path: '/',\n method: 'GET',\n headers: {}\n };\n\n // Adds a 'Date' header in, signs it, and adds the\n // 'Authorization' header in.\n var req = https.request(options, function(res) {\n console.log(res.statusCode);\n });\n\n\n httpSignature.sign(req, {\n key: key,\n keyId: './cert.pem'\n });\n\n req.end();\n\n### Server\n\n var fs = require('fs');\n var https = require('https');\n var httpSignature = require('http-signature');\n\n var options = {\n key: fs.readFileSync('./key.pem'),\n cert: fs.readFileSync('./cert.pem')\n };\n\n https.createServer(options, function (req, res) {\n var rc = 200;\n var parsed = httpSignature.parseRequest(req);\n var pub = fs.readFileSync(parsed.keyId, 'ascii');\n if (!httpSignature.verifySignature(parsed, pub))\n rc = 401;\n\n res.writeHead(rc);\n res.end();\n }).listen(8443);\n\n## Installation\n\n npm install http-signature\n\n## License\n\nMIT.\n\n## Bugs\n\nSee <https://github.com/joyent/node-http-signature/issues>.\n", "readmeFilename": "README.md", "bugs": { "url": "https://github.com/joyent/node-http-signature/issues" }, - "_id": "http-signature@0.9.11", - "_from": "http-signature@~0.9.11" + "_id": "http-signature@0.10.0", + "_from": "http-signature@~0.10.0" } diff --git a/deps/npm/node_modules/request/node_modules/json-stringify-safe/README.md b/deps/npm/node_modules/request/node_modules/json-stringify-safe/README.md index c0537a9c3f2..5d764f3a47b 100644 --- a/deps/npm/node_modules/request/node_modules/json-stringify-safe/README.md +++ b/deps/npm/node_modules/request/node_modules/json-stringify-safe/README.md @@ -25,3 +25,25 @@ Output: ] } ``` + +## Details + +``` +stringify(obj, serializer, indent, decycler) +``` + +The first three arguments are the same as to JSON.stringify. The last +is an argument that's only used when the object has been seen already. + +The default `decycler` function returns the string `'[Circular]'`. +If, for example, you pass in `function(k,v){}` (return nothing) then it +will prune cycles. If you pass in `function(k,v){ return {foo: 'bar'}}`, +then cyclical objects will always be represented as `{"foo":"bar"}` in +the result. + +``` +stringify.getSerialize(serializer, decycler) +``` + +Returns a serializer that can be used elsewhere. This is the actual +function that's passed to JSON.stringify. diff --git a/deps/npm/node_modules/request/node_modules/json-stringify-safe/package.json b/deps/npm/node_modules/request/node_modules/json-stringify-safe/package.json index faaaadc47df..d730f7f881c 100644 --- a/deps/npm/node_modules/request/node_modules/json-stringify-safe/package.json +++ b/deps/npm/node_modules/request/node_modules/json-stringify-safe/package.json @@ -1,6 +1,6 @@ { "name": "json-stringify-safe", - "version": "4.0.0", + "version": "5.0.0", "description": "Like JSON.stringify, but doesn't blow up on circular refs", "main": "stringify.js", "scripts": { @@ -23,10 +23,10 @@ }, "license": "BSD", "readmeFilename": "README.md", - "readme": "# json-stringify-safe\n\nLike JSON.stringify, but doesn't throw on circular references.\n\n## Usage\n\nTakes the same arguments as `JSON.stringify`.\n\n```javascript\nvar stringify = require('json-stringify-safe');\nvar circularObj = {};\ncircularObj.circularRef = circularObj;\ncircularObj.list = [ circularObj, circularObj ];\nconsole.log(stringify(circularObj, null, 2));\n```\n\nOutput:\n\n```json\n{\n \"circularRef\": \"[Circular]\",\n \"list\": [\n \"[Circular]\",\n \"[Circular]\"\n ]\n}\n```\n", + "readme": "# json-stringify-safe\n\nLike JSON.stringify, but doesn't throw on circular references.\n\n## Usage\n\nTakes the same arguments as `JSON.stringify`.\n\n```javascript\nvar stringify = require('json-stringify-safe');\nvar circularObj = {};\ncircularObj.circularRef = circularObj;\ncircularObj.list = [ circularObj, circularObj ];\nconsole.log(stringify(circularObj, null, 2));\n```\n\nOutput:\n\n```json\n{\n \"circularRef\": \"[Circular]\",\n \"list\": [\n \"[Circular]\",\n \"[Circular]\"\n ]\n}\n```\n\n## Details\n\n```\nstringify(obj, serializer, indent, decycler)\n```\n\nThe first three arguments are the same as to JSON.stringify. The last\nis an argument that's only used when the object has been seen already.\n\nThe default `decycler` function returns the string `'[Circular]'`.\nIf, for example, you pass in `function(k,v){}` (return nothing) then it\nwill prune cycles. If you pass in `function(k,v){ return {foo: 'bar'}}`,\nthen cyclical objects will always be represented as `{\"foo\":\"bar\"}` in\nthe result.\n\n```\nstringify.getSerialize(serializer, decycler)\n```\n\nReturns a serializer that can be used elsewhere. This is the actual\nfunction that's passed to JSON.stringify.\n", "bugs": { "url": "https://github.com/isaacs/json-stringify-safe/issues" }, - "_id": "json-stringify-safe@4.0.0", - "_from": "json-stringify-safe@~4.0.0" + "_id": "json-stringify-safe@5.0.0", + "_from": "json-stringify-safe@~5.0.0" } diff --git a/deps/npm/node_modules/request/node_modules/json-stringify-safe/stringify.js b/deps/npm/node_modules/request/node_modules/json-stringify-safe/stringify.js index de14349adbf..853ef9b237a 100644 --- a/deps/npm/node_modules/request/node_modules/json-stringify-safe/stringify.js +++ b/deps/npm/node_modules/request/node_modules/json-stringify-safe/stringify.js @@ -1,23 +1,37 @@ module.exports = stringify; function getSerialize (fn, decycle) { - var seen = []; + var seen = [], keys = []; decycle = decycle || function(key, value) { - return '[Circular]'; + return '[Circular ' + getPath(value, seen, keys) + ']' }; return function(key, value) { var ret = value; if (typeof value === 'object' && value) { if (seen.indexOf(value) !== -1) ret = decycle(key, value); - else + else { seen.push(value); + keys.push(key); + } } if (fn) ret = fn(key, ret); return ret; } } +function getPath (value, seen, keys) { + var index = seen.indexOf(value); + var path = [ keys[index] ]; + for (index--; index >= 0; index--) { + if (seen[index][ path[0] ] === value) { + value = seen[index]; + path.unshift(keys[index]); + } + } + return '~' + path.join('.'); +} + function stringify(obj, fn, spaces, decycle) { return JSON.stringify(obj, getSerialize(fn, decycle), spaces); } diff --git a/deps/npm/node_modules/request/node_modules/json-stringify-safe/test.js b/deps/npm/node_modules/request/node_modules/json-stringify-safe/test.js index 7f6a01cb7f2..991e9197c40 100644 --- a/deps/npm/node_modules/request/node_modules/json-stringify-safe/test.js +++ b/deps/npm/node_modules/request/node_modules/json-stringify-safe/test.js @@ -8,10 +8,10 @@ circularObj.list = [ circularObj, circularObj ]; // default var testObj = { "a": "b", - "circularRef": "[Circular]", + "circularRef": "[Circular ~]", "list": [ - "[Circular]", - "[Circular]" + "[Circular ~]", + "[Circular ~]" ] }; @@ -91,6 +91,38 @@ assert.equal(JSON.stringify(testObj, null, 2), stringify(circularObj, null, 2, signer)); +/////// +//multi +var a = { x: 1 }; +a.a = a; +var b = { x: 2 }; +b.a = a; + +var c = { a: a, b: b }; +var d = { list: [ a, b, c ] }; +d.d = d; + +var multi = { + "list": [ + { + "x": 1, + "a": "[Circular ~.list.0]" + }, + { + "x": 2, + "a": "[Circular ~.list.0]" + }, + { + "a": "[Circular ~.list.0]", + "b": "[Circular ~.list.1]" + } + ], + "d": "[Circular ~]" +}; + +assert.equal(JSON.stringify(multi, null, 2), + stringify(d, null, 2)); + //////// // pass! console.log('ok'); diff --git a/deps/npm/node_modules/request/node_modules/mime/README.md b/deps/npm/node_modules/request/node_modules/mime/README.md index b90552a3b96..6ca19bd1e85 100644 --- a/deps/npm/node_modules/request/node_modules/mime/README.md +++ b/deps/npm/node_modules/request/node_modules/mime/README.md @@ -11,7 +11,7 @@ Install with [npm](http://github.com/isaacs/npm): ## API - Queries ### mime.lookup(path) -Get the mime type associated with a file. Performs a case-insensitive lookup using the extension in `path` (the substring after the last '/' or '.'). E.g. +Get the mime type associated with a file, if no mime type is found `application/octet-stream` is returned. Performs a case-insensitive lookup using the extension in `path` (the substring after the last '/' or '.'). E.g. var mime = require('mime'); @@ -20,6 +20,9 @@ Get the mime type associated with a file. Performs a case-insensitive lookup usi mime.lookup('.TXT'); // => 'text/plain' mime.lookup('htm'); // => 'text/html' +### mime.default_type +Sets the mime type returned when `mime.lookup` fails to find the extension searched for. (Default is `application/octet-stream`.) + ### mime.extension(type) Get the default extension for `type` diff --git a/deps/npm/node_modules/request/node_modules/mime/mime.js b/deps/npm/node_modules/request/node_modules/mime/mime.js index 70a63842486..8a7eb093f3e 100644 --- a/deps/npm/node_modules/request/node_modules/mime/mime.js +++ b/deps/npm/node_modules/request/node_modules/mime/mime.js @@ -78,7 +78,8 @@ Mime.prototype.lookup = function(path, fallback) { * Return file extension associated with a mime type */ Mime.prototype.extension = function(mimeType) { - return this.extensions[mimeType]; + var type = mimeType.match(/^\s*([^;\s]*)(?:;|\s|$)/)[1].toLowerCase(); + return this.extensions[type]; }; // Default instance diff --git a/deps/npm/node_modules/request/node_modules/mime/package.json b/deps/npm/node_modules/request/node_modules/mime/package.json index dfa9ef5a970..cb57777d392 100644 --- a/deps/npm/node_modules/request/node_modules/mime/package.json +++ b/deps/npm/node_modules/request/node_modules/mime/package.json @@ -24,12 +24,12 @@ "url": "https://github.com/broofa/node-mime", "type": "git" }, - "version": "1.2.9", - "readme": "# mime\n\nComprehensive MIME type mapping API. Includes all 600+ types and 800+ extensions defined by the Apache project, plus additional types submitted by the node.js community.\n\n## Install\n\nInstall with [npm](http://github.com/isaacs/npm):\n\n npm install mime\n\n## API - Queries\n\n### mime.lookup(path)\nGet the mime type associated with a file. Performs a case-insensitive lookup using the extension in `path` (the substring after the last '/' or '.'). E.g.\n\n var mime = require('mime');\n\n mime.lookup('/path/to/file.txt'); // => 'text/plain'\n mime.lookup('file.txt'); // => 'text/plain'\n mime.lookup('.TXT'); // => 'text/plain'\n mime.lookup('htm'); // => 'text/html'\n\n### mime.extension(type)\nGet the default extension for `type`\n\n mime.extension('text/html'); // => 'html'\n mime.extension('application/octet-stream'); // => 'bin'\n\n### mime.charsets.lookup()\n\nMap mime-type to charset\n\n mime.charsets.lookup('text/plain'); // => 'UTF-8'\n\n(The logic for charset lookups is pretty rudimentary. Feel free to suggest improvements.)\n\n## API - Defining Custom Types\n\nThe following APIs allow you to add your own type mappings within your project. If you feel a type should be included as part of node-mime, see [requesting new types](https://github.com/broofa/node-mime/wiki/Requesting-New-Types).\n\n### mime.define()\n\nAdd custom mime/extension mappings\n\n mime.define({\n 'text/x-some-format': ['x-sf', 'x-sft', 'x-sfml'],\n 'application/x-my-type': ['x-mt', 'x-mtt'],\n // etc ...\n });\n\n mime.lookup('x-sft'); // => 'text/x-some-format'\n\nThe first entry in the extensions array is returned by `mime.extension()`. E.g.\n\n mime.extension('text/x-some-format'); // => 'x-sf'\n\n### mime.load(filepath)\n\nLoad mappings from an Apache \".types\" format file\n\n mime.load('./my_project.types');\n\nThe .types file format is simple - See the `types` dir for examples.\n", + "version": "1.2.10", + "readme": "# mime\n\nComprehensive MIME type mapping API. Includes all 600+ types and 800+ extensions defined by the Apache project, plus additional types submitted by the node.js community.\n\n## Install\n\nInstall with [npm](http://github.com/isaacs/npm):\n\n npm install mime\n\n## API - Queries\n\n### mime.lookup(path)\nGet the mime type associated with a file, if no mime type is found `application/octet-stream` is returned. Performs a case-insensitive lookup using the extension in `path` (the substring after the last '/' or '.'). E.g.\n\n var mime = require('mime');\n\n mime.lookup('/path/to/file.txt'); // => 'text/plain'\n mime.lookup('file.txt'); // => 'text/plain'\n mime.lookup('.TXT'); // => 'text/plain'\n mime.lookup('htm'); // => 'text/html'\n\n### mime.default_type\nSets the mime type returned when `mime.lookup` fails to find the extension searched for. (Default is `application/octet-stream`.)\n\n### mime.extension(type)\nGet the default extension for `type`\n\n mime.extension('text/html'); // => 'html'\n mime.extension('application/octet-stream'); // => 'bin'\n\n### mime.charsets.lookup()\n\nMap mime-type to charset\n\n mime.charsets.lookup('text/plain'); // => 'UTF-8'\n\n(The logic for charset lookups is pretty rudimentary. Feel free to suggest improvements.)\n\n## API - Defining Custom Types\n\nThe following APIs allow you to add your own type mappings within your project. If you feel a type should be included as part of node-mime, see [requesting new types](https://github.com/broofa/node-mime/wiki/Requesting-New-Types).\n\n### mime.define()\n\nAdd custom mime/extension mappings\n\n mime.define({\n 'text/x-some-format': ['x-sf', 'x-sft', 'x-sfml'],\n 'application/x-my-type': ['x-mt', 'x-mtt'],\n // etc ...\n });\n\n mime.lookup('x-sft'); // => 'text/x-some-format'\n\nThe first entry in the extensions array is returned by `mime.extension()`. E.g.\n\n mime.extension('text/x-some-format'); // => 'x-sf'\n\n### mime.load(filepath)\n\nLoad mappings from an Apache \".types\" format file\n\n mime.load('./my_project.types');\n\nThe .types file format is simple - See the `types` dir for examples.\n", "readmeFilename": "README.md", "bugs": { "url": "https://github.com/broofa/node-mime/issues" }, - "_id": "mime@1.2.9", + "_id": "mime@1.2.10", "_from": "mime@~1.2.9" } diff --git a/deps/npm/node_modules/request/node_modules/mime/test.js b/deps/npm/node_modules/request/node_modules/mime/test.js index cbad034a18f..27df4403027 100644 --- a/deps/npm/node_modules/request/node_modules/mime/test.js +++ b/deps/npm/node_modules/request/node_modules/mime/test.js @@ -4,6 +4,7 @@ var mime = require('./mime'); var assert = require('assert'); +var path = require('path'); function eq(a, b) { console.log('Test: ' + a + ' === ' + b); @@ -35,14 +36,23 @@ eq('application/x-web-app-manifest+json', mime.lookup('text.webapp')); eq('txt', mime.extension(mime.types.text)); eq('html', mime.extension(mime.types.htm)); eq('bin', mime.extension('application/octet-stream')); +eq('bin', mime.extension('application/octet-stream ')); +eq('html', mime.extension(' text/html; charset=UTF-8')); +eq('html', mime.extension('text/html; charset=UTF-8 ')); +eq('html', mime.extension('text/html; charset=UTF-8')); +eq('html', mime.extension('text/html ; charset=UTF-8')); +eq('html', mime.extension('text/html;charset=UTF-8')); +eq('html', mime.extension('text/Html;charset=UTF-8')); eq(undefined, mime.extension('constructor')); // // Test node types // +eq('application/font-woff', mime.lookup('file.woff')); eq('application/octet-stream', mime.lookup('file.buffer')); eq('audio/mp4', mime.lookup('file.m4a')); +eq('font/opentype', mime.lookup('file.otf')); // // Test charsets @@ -52,4 +62,23 @@ eq('UTF-8', mime.charsets.lookup('text/plain')); eq(undefined, mime.charsets.lookup(mime.types.js)); eq('fallback', mime.charsets.lookup('application/octet-stream', 'fallback')); +// +// Test for overlaps between mime.types and node.types +// + +var apacheTypes = new mime.Mime(), nodeTypes = new mime.Mime(); +apacheTypes.load(path.join(__dirname, 'types/mime.types')); +nodeTypes.load(path.join(__dirname, 'types/node.types')); + +var keys = [].concat(Object.keys(apacheTypes.types)) + .concat(Object.keys(nodeTypes.types)); +keys.sort(); +for (var i = 1; i < keys.length; i++) { + if (keys[i] == keys[i-1]) { + console.warn('Warning: ' + + 'node.types defines ' + keys[i] + '->' + nodeTypes.types[keys[i]] + + ', mime.types defines ' + keys[i] + '->' + apacheTypes.types[keys[i]]); + } +} + console.log('\nOK'); diff --git a/deps/npm/node_modules/request/node_modules/mime/types/mime.types b/deps/npm/node_modules/request/node_modules/mime/types/mime.types index b90b1658761..da8cd691879 100644 --- a/deps/npm/node_modules/request/node_modules/mime/types/mime.types +++ b/deps/npm/node_modules/request/node_modules/mime/types/mime.types @@ -1054,7 +1054,7 @@ application/x-font-snf snf # application/x-font-sunos-news application/x-font-ttf ttf ttc application/x-font-type1 pfa pfb pfm afm -application/x-font-woff woff +application/font-woff woff # application/x-font-vfont application/x-freearc arc application/x-futuresplash spl diff --git a/deps/npm/node_modules/request/node_modules/mime/types/node.types b/deps/npm/node_modules/request/node_modules/mime/types/node.types index 970a1bd85d6..55b2cf794ee 100644 --- a/deps/npm/node_modules/request/node_modules/mime/types/node.types +++ b/deps/npm/node_modules/request/node_modules/mime/types/node.types @@ -15,11 +15,11 @@ application/x-chrome-extension crx # Added by: niftylettuce text/x-component htc -# What: HTML5 application cache manifest +# What: HTML5 application cache manifes ('.manifest' extension) # Why: De-facto standard. Required by Mozilla browser when serving HTML5 apps # per https://developer.mozilla.org/en/offline_resources_in_firefox # Added by: louisremi -text/cache-manifest appcache manifest +text/cache-manifest manifest # What: node binary buffer format # Why: semi-standard extension w/in the node community @@ -58,3 +58,20 @@ application/x-lua-bytecode luac # Why: http://stackoverflow.com/questions/10701983/what-is-the-mime-type-for-markdown # Added by: avoidwork text/x-markdown markdown md mkd + +# What: ini files +# Why: because they're just text files +# Added by: Matthew Kastor +text/plain ini + +# What: DASH Adaptive Streaming manifest +# Why: https://developer.mozilla.org/en-US/docs/DASH_Adaptive_Streaming_for_HTML_5_Video +# Added by: eelcocramer +application/dash+xml mdp + +# What: OpenType font files - http://www.microsoft.com/typography/otspec/ +# Why: Browsers usually ignore the font MIME types and sniff the content, +# but Chrome, shows a warning if OpenType fonts aren't served with +# the `font/opentype` MIME type: http://i.imgur.com/8c5RN8M.png. +# Added by: alrra +font/opentype otf diff --git a/deps/npm/node_modules/request/package.json b/deps/npm/node_modules/request/package.json index 07b632e7b8e..471472789cb 100755 --- a/deps/npm/node_modules/request/package.json +++ b/deps/npm/node_modules/request/package.json @@ -7,7 +7,7 @@ "util", "utility" ], - "version": "2.21.0", + "version": "2.25.0", "author": { "name": "Mikeal Rogers", "email": "mikeal.rogers@gmail.com" @@ -25,23 +25,23 @@ "main": "index.js", "dependencies": { "qs": "~0.6.0", - "json-stringify-safe": "~4.0.0", + "json-stringify-safe": "~5.0.0", "forever-agent": "~0.5.0", "tunnel-agent": "~0.3.0", - "http-signature": "~0.9.11", - "hawk": "~0.13.0", + "http-signature": "~0.10.0", + "hawk": "~1.0.0", "aws-sign": "~0.3.0", "oauth-sign": "~0.3.0", "cookie-jar": "~0.3.0", "node-uuid": "~1.4.0", "mime": "~1.2.9", - "form-data": "0.0.8" + "form-data": "~0.1.0" }, "scripts": { "test": "node tests/run.js" }, - "readme": "# Request -- Simplified HTTP request method\n\n## Install\n\n<pre>\n npm install request\n</pre>\n\nOr from source:\n\n<pre>\n git clone git://github.com/mikeal/request.git \n cd request\n npm link\n</pre>\n\n## Super simple to use\n\nRequest is designed to be the simplest way possible to make http calls. It supports HTTPS and follows redirects by default.\n\n```javascript\nvar request = require('request');\nrequest('http://www.google.com', function (error, response, body) {\n if (!error && response.statusCode == 200) {\n console.log(body) // Print the google web page.\n }\n})\n```\n\n## Streaming\n\nYou can stream any response to a file stream.\n\n```javascript\nrequest('http://google.com/doodle.png').pipe(fs.createWriteStream('doodle.png'))\n```\n\nYou can also stream a file to a PUT or POST request. This method will also check the file extension against a mapping of file extensions to content-types, in this case `application/json`, and use the proper content-type in the PUT request if one is not already provided in the headers.\n\n```javascript\nfs.createReadStream('file.json').pipe(request.put('http://mysite.com/obj.json'))\n```\n\nRequest can also pipe to itself. When doing so the content-type and content-length will be preserved in the PUT headers.\n\n```javascript\nrequest.get('http://google.com/img.png').pipe(request.put('http://mysite.com/img.png'))\n```\n\nNow let's get fancy.\n\n```javascript\nhttp.createServer(function (req, resp) {\n if (req.url === '/doodle.png') {\n if (req.method === 'PUT') {\n req.pipe(request.put('http://mysite.com/doodle.png'))\n } else if (req.method === 'GET' || req.method === 'HEAD') {\n request.get('http://mysite.com/doodle.png').pipe(resp)\n } \n }\n})\n```\n\nYou can also pipe() from a http.ServerRequest instance and to a http.ServerResponse instance. The HTTP method and headers will be sent as well as the entity-body data. Which means that, if you don't really care about security, you can do:\n\n```javascript\nhttp.createServer(function (req, resp) {\n if (req.url === '/doodle.png') {\n var x = request('http://mysite.com/doodle.png')\n req.pipe(x)\n x.pipe(resp)\n }\n})\n```\n\nAnd since pipe() returns the destination stream in node 0.5.x you can do one line proxying :)\n\n```javascript\nreq.pipe(request('http://mysite.com/doodle.png')).pipe(resp)\n```\n\nAlso, none of this new functionality conflicts with requests previous features, it just expands them.\n\n```javascript\nvar r = request.defaults({'proxy':'http://localproxy.com'})\n\nhttp.createServer(function (req, resp) {\n if (req.url === '/doodle.png') {\n r.get('http://google.com/doodle.png').pipe(resp)\n }\n})\n```\nYou can still use intermediate proxies, the requests will still follow HTTP forwards, etc.\n\n## Forms\n\n`request` supports `application/x-www-form-urlencoded` and `multipart/form-data` form uploads. For `multipart/related` refer to the `multipart` API.\n\nUrl encoded forms are simple\n\n```javascript\nrequest.post('http://service.com/upload', {form:{key:'value'}})\n// or\nrequest.post('http://service.com/upload').form({key:'value'})\n```\n\nFor `multipart/form-data` we use the [form-data](https://github.com/felixge/node-form-data) library by [@felixge](https://github.com/felixge). You don't need to worry about piping the form object or setting the headers, `request` will handle that for you.\n\n```javascript\nvar r = request.post('http://service.com/upload')\nvar form = r.form()\nform.append('my_field', 'my_value')\nform.append('my_buffer', new Buffer([1, 2, 3]))\nform.append('my_file', fs.createReadStream(path.join(__dirname, 'doodle.png'))\nform.append('remote_file', request('http://google.com/doodle.png'))\n```\n\n## HTTP Authentication\n\n```javascript\nrequest.auth('username', 'password', false).get('http://some.server.com/');\n// or\nrequest.get('http://some.server.com/', {\n 'auth': {\n 'user': 'username',\n 'pass': 'password',\n 'sendImmediately': false\n }\n});\n```\n\nIf passed as an option, `auth` should be a hash containing values `user` || `username`, `password` || `pass`, and `sendImmediately` (optional). The method form takes parameters `auth(username, password, sendImmediately)`.\n\n`sendImmediately` defaults to true, which will cause a basic authentication header to be sent. If `sendImmediately` is `false`, then `request` will retry with a proper authentication header after receiving a 401 response from the server (which must contain a `WWW-Authenticate` header indicating the required authentication method).\n\nDigest authentication is supported, but it only works with `sendImmediately` set to `false` (otherwise `request` will send basic authentication on the initial request, which will probably cause the request to fail).\n\n## OAuth Signing\n\n```javascript\n// Twitter OAuth\nvar qs = require('querystring')\n , oauth =\n { callback: 'http://mysite.com/callback/'\n , consumer_key: CONSUMER_KEY\n , consumer_secret: CONSUMER_SECRET\n }\n , url = 'https://api.twitter.com/oauth/request_token'\n ;\nrequest.post({url:url, oauth:oauth}, function (e, r, body) {\n // Ideally, you would take the body in the response\n // and construct a URL that a user clicks on (like a sign in button).\n // The verifier is only available in the response after a user has \n // verified with twitter that they are authorizing your app.\n var access_token = qs.parse(body)\n , oauth = \n { consumer_key: CONSUMER_KEY\n , consumer_secret: CONSUMER_SECRET\n , token: access_token.oauth_token\n , verifier: access_token.oauth_verifier\n }\n , url = 'https://api.twitter.com/oauth/access_token'\n ;\n request.post({url:url, oauth:oauth}, function (e, r, body) {\n var perm_token = qs.parse(body)\n , oauth = \n { consumer_key: CONSUMER_KEY\n , consumer_secret: CONSUMER_SECRET\n , token: perm_token.oauth_token\n , token_secret: perm_token.oauth_token_secret\n }\n , url = 'https://api.twitter.com/1/users/show.json?'\n , params = \n { screen_name: perm_token.screen_name\n , user_id: perm_token.user_id\n }\n ;\n url += qs.stringify(params)\n request.get({url:url, oauth:oauth, json:true}, function (e, r, user) {\n console.log(user)\n })\n })\n})\n```\n\n\n\n### request(options, callback)\n\nThe first argument can be either a url or an options object. The only required option is uri, all others are optional.\n\n* `uri` || `url` - fully qualified uri or a parsed url object from url.parse()\n* `qs` - object containing querystring values to be appended to the uri\n* `method` - http method, defaults to GET\n* `headers` - http headers, defaults to {}\n* `body` - entity body for PATCH, POST and PUT requests. Must be buffer or string.\n* `form` - when passed an object this will set `body` but to a querystring representation of value and adds `Content-type: application/x-www-form-urlencoded; charset=utf-8` header. When passed no option a FormData instance is returned that will be piped to request.\n* `auth` - A hash containing values `user` || `username`, `password` || `pass`, and `sendImmediately` (optional). See documentation above.\n* `json` - sets `body` but to JSON representation of value and adds `Content-type: application/json` header. Additionally, parses the response body as json.\n* `multipart` - (experimental) array of objects which contains their own headers and `body` attribute. Sends `multipart/related` request. See example below.\n* `followRedirect` - follow HTTP 3xx responses as redirects. defaults to true.\n* `followAllRedirects` - follow non-GET HTTP 3xx responses as redirects. defaults to false.\n* `maxRedirects` - the maximum number of redirects to follow, defaults to 10.\n* `encoding` - Encoding to be used on `setEncoding` of response data. If set to `null`, the body is returned as a Buffer.\n* `pool` - A hash object containing the agents for these requests. If omitted this request will use the global pool which is set to node's default maxSockets.\n* `pool.maxSockets` - Integer containing the maximum amount of sockets in the pool.\n* `timeout` - Integer containing the number of milliseconds to wait for a request to respond before aborting the request\t\n* `proxy` - An HTTP proxy to be used. Support proxy Auth with Basic Auth the same way it's supported with the `url` parameter by embedding the auth info in the uri.\n* `oauth` - Options for OAuth HMAC-SHA1 signing, see documentation above.\n* `hawk` - Options for [Hawk signing](https://github.com/hueniverse/hawk). The `credentials` key must contain the necessary signing info, [see hawk docs for details](https://github.com/hueniverse/hawk#usage-example).\n* `strictSSL` - Set to `true` to require that SSL certificates be valid. Note: to use your own certificate authority, you need to specify an agent that was created with that ca as an option.\n* `jar` - Set to `false` if you don't want cookies to be remembered for future use or define your custom cookie jar (see examples section)\n* `aws` - object containing aws signing information, should have the properties `key` and `secret` as well as `bucket` unless you're specifying your bucket as part of the path, or you are making a request that doesn't use a bucket (i.e. GET Services)\n* `httpSignature` - Options for the [HTTP Signature Scheme](https://github.com/joyent/node-http-signature/blob/master/http_signing.md) using [Joyent's library](https://github.com/joyent/node-http-signature). The `keyId` and `key` properties must be specified. See the docs for other options.\n* `localAddress` - Local interface to bind for network connections.\n\n\nThe callback argument gets 3 arguments. The first is an error when applicable (usually from the http.Client option not the http.ClientRequest object). The second in an http.ClientResponse object. The third is the response body String or Buffer.\n\n## Convenience methods\n\nThere are also shorthand methods for different HTTP METHODs and some other conveniences.\n\n### request.defaults(options) \n \nThis method returns a wrapper around the normal request API that defaults to whatever options you pass in to it.\n\n### request.put\n\nSame as request() but defaults to `method: \"PUT\"`.\n\n```javascript\nrequest.put(url)\n```\n\n### request.patch\n\nSame as request() but defaults to `method: \"PATCH\"`.\n\n```javascript\nrequest.patch(url)\n```\n\n### request.post\n\nSame as request() but defaults to `method: \"POST\"`.\n\n```javascript\nrequest.post(url)\n```\n\n### request.head\n\nSame as request() but defaults to `method: \"HEAD\"`.\n\n```javascript\nrequest.head(url)\n```\n\n### request.del\n\nSame as request() but defaults to `method: \"DELETE\"`.\n\n```javascript\nrequest.del(url)\n```\n\n### request.get\n\nAlias to normal request method for uniformity.\n\n```javascript\nrequest.get(url)\n```\n### request.cookie\n\nFunction that creates a new cookie.\n\n```javascript\nrequest.cookie('cookie_string_here')\n```\n### request.jar\n\nFunction that creates a new cookie jar.\n\n```javascript\nrequest.jar()\n```\n\n\n## Examples:\n\n```javascript\n var request = require('request')\n , rand = Math.floor(Math.random()*100000000).toString()\n ;\n request(\n { method: 'PUT'\n , uri: 'http://mikeal.iriscouch.com/testjs/' + rand\n , multipart: \n [ { 'content-type': 'application/json'\n , body: JSON.stringify({foo: 'bar', _attachments: {'message.txt': {follows: true, length: 18, 'content_type': 'text/plain' }}})\n }\n , { body: 'I am an attachment' }\n ] \n }\n , function (error, response, body) {\n if(response.statusCode == 201){\n console.log('document saved as: http://mikeal.iriscouch.com/testjs/'+ rand)\n } else {\n console.log('error: '+ response.statusCode)\n console.log(body)\n }\n }\n )\n```\nCookies are enabled by default (so they can be used in subsequent requests). To disable cookies set jar to false (either in defaults or in the options sent).\n\n```javascript\nvar request = request.defaults({jar: false})\nrequest('http://www.google.com', function () {\n request('http://images.google.com')\n})\n```\n\nIf you to use a custom cookie jar (instead of letting request use its own global cookie jar) you do so by setting the jar default or by specifying it as an option:\n\n```javascript\nvar j = request.jar()\nvar request = request.defaults({jar:j})\nrequest('http://www.google.com', function () {\n request('http://images.google.com')\n})\n```\nOR\n\n```javascript\nvar j = request.jar()\nvar cookie = request.cookie('your_cookie_here')\nj.add(cookie)\nrequest({url: 'http://www.google.com', jar: j}, function () {\n request('http://images.google.com')\n})\n```\n", + "readme": "# Request -- Simplified HTTP request method\n\n## Install\n\n<pre>\n npm install request\n</pre>\n\nOr from source:\n\n<pre>\n git clone git://github.com/mikeal/request.git \n cd request\n npm link\n</pre>\n\n## Super simple to use\n\nRequest is designed to be the simplest way possible to make http calls. It supports HTTPS and follows redirects by default.\n\n```javascript\nvar request = require('request');\nrequest('http://www.google.com', function (error, response, body) {\n if (!error && response.statusCode == 200) {\n console.log(body) // Print the google web page.\n }\n})\n```\n\n## Streaming\n\nYou can stream any response to a file stream.\n\n```javascript\nrequest('http://google.com/doodle.png').pipe(fs.createWriteStream('doodle.png'))\n```\n\nYou can also stream a file to a PUT or POST request. This method will also check the file extension against a mapping of file extensions to content-types, in this case `application/json`, and use the proper content-type in the PUT request if one is not already provided in the headers.\n\n```javascript\nfs.createReadStream('file.json').pipe(request.put('http://mysite.com/obj.json'))\n```\n\nRequest can also pipe to itself. When doing so the content-type and content-length will be preserved in the PUT headers.\n\n```javascript\nrequest.get('http://google.com/img.png').pipe(request.put('http://mysite.com/img.png'))\n```\n\nNow let's get fancy.\n\n```javascript\nhttp.createServer(function (req, resp) {\n if (req.url === '/doodle.png') {\n if (req.method === 'PUT') {\n req.pipe(request.put('http://mysite.com/doodle.png'))\n } else if (req.method === 'GET' || req.method === 'HEAD') {\n request.get('http://mysite.com/doodle.png').pipe(resp)\n } \n }\n})\n```\n\nYou can also pipe() from a http.ServerRequest instance and to a http.ServerResponse instance. The HTTP method and headers will be sent as well as the entity-body data. Which means that, if you don't really care about security, you can do:\n\n```javascript\nhttp.createServer(function (req, resp) {\n if (req.url === '/doodle.png') {\n var x = request('http://mysite.com/doodle.png')\n req.pipe(x)\n x.pipe(resp)\n }\n})\n```\n\nAnd since pipe() returns the destination stream in node 0.5.x you can do one line proxying :)\n\n```javascript\nreq.pipe(request('http://mysite.com/doodle.png')).pipe(resp)\n```\n\nAlso, none of this new functionality conflicts with requests previous features, it just expands them.\n\n```javascript\nvar r = request.defaults({'proxy':'http://localproxy.com'})\n\nhttp.createServer(function (req, resp) {\n if (req.url === '/doodle.png') {\n r.get('http://google.com/doodle.png').pipe(resp)\n }\n})\n```\nYou can still use intermediate proxies, the requests will still follow HTTP forwards, etc.\n\n## Forms\n\n`request` supports `application/x-www-form-urlencoded` and `multipart/form-data` form uploads. For `multipart/related` refer to the `multipart` API.\n\nUrl encoded forms are simple\n\n```javascript\nrequest.post('http://service.com/upload', {form:{key:'value'}})\n// or\nrequest.post('http://service.com/upload').form({key:'value'})\n```\n\nFor `multipart/form-data` we use the [form-data](https://github.com/felixge/node-form-data) library by [@felixge](https://github.com/felixge). You don't need to worry about piping the form object or setting the headers, `request` will handle that for you.\n\n```javascript\nvar r = request.post('http://service.com/upload')\nvar form = r.form()\nform.append('my_field', 'my_value')\nform.append('my_buffer', new Buffer([1, 2, 3]))\nform.append('my_file', fs.createReadStream(path.join(__dirname, 'doodle.png'))\nform.append('remote_file', request('http://google.com/doodle.png'))\n```\n\n## HTTP Authentication\n\n```javascript\nrequest.get('http://some.server.com/').auth('username', 'password', false);\n// or\nrequest.get('http://some.server.com/', {\n 'auth': {\n 'user': 'username',\n 'pass': 'password',\n 'sendImmediately': false\n }\n});\n```\n\nIf passed as an option, `auth` should be a hash containing values `user` || `username`, `password` || `pass`, and `sendImmediately` (optional). The method form takes parameters `auth(username, password, sendImmediately)`.\n\n`sendImmediately` defaults to true, which will cause a basic authentication header to be sent. If `sendImmediately` is `false`, then `request` will retry with a proper authentication header after receiving a 401 response from the server (which must contain a `WWW-Authenticate` header indicating the required authentication method).\n\nDigest authentication is supported, but it only works with `sendImmediately` set to `false` (otherwise `request` will send basic authentication on the initial request, which will probably cause the request to fail).\n\n## OAuth Signing\n\n```javascript\n// Twitter OAuth\nvar qs = require('querystring')\n , oauth =\n { callback: 'http://mysite.com/callback/'\n , consumer_key: CONSUMER_KEY\n , consumer_secret: CONSUMER_SECRET\n }\n , url = 'https://api.twitter.com/oauth/request_token'\n ;\nrequest.post({url:url, oauth:oauth}, function (e, r, body) {\n // Ideally, you would take the body in the response\n // and construct a URL that a user clicks on (like a sign in button).\n // The verifier is only available in the response after a user has \n // verified with twitter that they are authorizing your app.\n var access_token = qs.parse(body)\n , oauth = \n { consumer_key: CONSUMER_KEY\n , consumer_secret: CONSUMER_SECRET\n , token: access_token.oauth_token\n , verifier: access_token.oauth_verifier\n }\n , url = 'https://api.twitter.com/oauth/access_token'\n ;\n request.post({url:url, oauth:oauth}, function (e, r, body) {\n var perm_token = qs.parse(body)\n , oauth = \n { consumer_key: CONSUMER_KEY\n , consumer_secret: CONSUMER_SECRET\n , token: perm_token.oauth_token\n , token_secret: perm_token.oauth_token_secret\n }\n , url = 'https://api.twitter.com/1/users/show.json?'\n , params = \n { screen_name: perm_token.screen_name\n , user_id: perm_token.user_id\n }\n ;\n url += qs.stringify(params)\n request.get({url:url, oauth:oauth, json:true}, function (e, r, user) {\n console.log(user)\n })\n })\n})\n```\n\n\n\n### request(options, callback)\n\nThe first argument can be either a url or an options object. The only required option is uri, all others are optional.\n\n* `uri` || `url` - fully qualified uri or a parsed url object from url.parse()\n* `qs` - object containing querystring values to be appended to the uri\n* `method` - http method, defaults to GET\n* `headers` - http headers, defaults to {}\n* `body` - entity body for PATCH, POST and PUT requests. Must be buffer or string.\n* `form` - when passed an object this will set `body` but to a querystring representation of value and adds `Content-type: application/x-www-form-urlencoded; charset=utf-8` header. When passed no option a FormData instance is returned that will be piped to request.\n* `auth` - A hash containing values `user` || `username`, `password` || `pass`, and `sendImmediately` (optional). See documentation above.\n* `json` - sets `body` but to JSON representation of value and adds `Content-type: application/json` header. Additionally, parses the response body as json.\n* `multipart` - (experimental) array of objects which contains their own headers and `body` attribute. Sends `multipart/related` request. See example below.\n* `followRedirect` - follow HTTP 3xx responses as redirects. defaults to true.\n* `followAllRedirects` - follow non-GET HTTP 3xx responses as redirects. defaults to false.\n* `maxRedirects` - the maximum number of redirects to follow, defaults to 10.\n* `encoding` - Encoding to be used on `setEncoding` of response data. If set to `null`, the body is returned as a Buffer.\n* `pool` - A hash object containing the agents for these requests. If omitted this request will use the global pool which is set to node's default maxSockets.\n* `pool.maxSockets` - Integer containing the maximum amount of sockets in the pool.\n* `timeout` - Integer containing the number of milliseconds to wait for a request to respond before aborting the request\t\n* `proxy` - An HTTP proxy to be used. Support proxy Auth with Basic Auth the same way it's supported with the `url` parameter by embedding the auth info in the uri.\n* `oauth` - Options for OAuth HMAC-SHA1 signing, see documentation above.\n* `hawk` - Options for [Hawk signing](https://github.com/hueniverse/hawk). The `credentials` key must contain the necessary signing info, [see hawk docs for details](https://github.com/hueniverse/hawk#usage-example).\n* `strictSSL` - Set to `true` to require that SSL certificates be valid. Note: to use your own certificate authority, you need to specify an agent that was created with that ca as an option.\n* `jar` - Set to `true` if you want cookies to be remembered for future use, or define your custom cookie jar (see examples section)\n* `aws` - object containing aws signing information, should have the properties `key` and `secret` as well as `bucket` unless you're specifying your bucket as part of the path, or you are making a request that doesn't use a bucket (i.e. GET Services)\n* `httpSignature` - Options for the [HTTP Signature Scheme](https://github.com/joyent/node-http-signature/blob/master/http_signing.md) using [Joyent's library](https://github.com/joyent/node-http-signature). The `keyId` and `key` properties must be specified. See the docs for other options.\n* `localAddress` - Local interface to bind for network connections.\n\n\nThe callback argument gets 3 arguments. The first is an error when applicable (usually from the http.Client option not the http.ClientRequest object). The second is an http.ClientResponse object. The third is the response body String or Buffer.\n\n## Convenience methods\n\nThere are also shorthand methods for different HTTP METHODs and some other conveniences.\n\n### request.defaults(options) \n \nThis method returns a wrapper around the normal request API that defaults to whatever options you pass in to it.\n\n### request.put\n\nSame as request() but defaults to `method: \"PUT\"`.\n\n```javascript\nrequest.put(url)\n```\n\n### request.patch\n\nSame as request() but defaults to `method: \"PATCH\"`.\n\n```javascript\nrequest.patch(url)\n```\n\n### request.post\n\nSame as request() but defaults to `method: \"POST\"`.\n\n```javascript\nrequest.post(url)\n```\n\n### request.head\n\nSame as request() but defaults to `method: \"HEAD\"`.\n\n```javascript\nrequest.head(url)\n```\n\n### request.del\n\nSame as request() but defaults to `method: \"DELETE\"`.\n\n```javascript\nrequest.del(url)\n```\n\n### request.get\n\nAlias to normal request method for uniformity.\n\n```javascript\nrequest.get(url)\n```\n### request.cookie\n\nFunction that creates a new cookie.\n\n```javascript\nrequest.cookie('cookie_string_here')\n```\n### request.jar\n\nFunction that creates a new cookie jar.\n\n```javascript\nrequest.jar()\n```\n\n\n## Examples:\n\n```javascript\n var request = require('request')\n , rand = Math.floor(Math.random()*100000000).toString()\n ;\n request(\n { method: 'PUT'\n , uri: 'http://mikeal.iriscouch.com/testjs/' + rand\n , multipart: \n [ { 'content-type': 'application/json'\n , body: JSON.stringify({foo: 'bar', _attachments: {'message.txt': {follows: true, length: 18, 'content_type': 'text/plain' }}})\n }\n , { body: 'I am an attachment' }\n ] \n }\n , function (error, response, body) {\n if(response.statusCode == 201){\n console.log('document saved as: http://mikeal.iriscouch.com/testjs/'+ rand)\n } else {\n console.log('error: '+ response.statusCode)\n console.log(body)\n }\n }\n )\n```\nCookies are disabled by default (else, they would be used in subsequent requests). To enable cookies set jar to true (either in defaults or in the options sent).\n\n```javascript\nvar request = request.defaults({jar: true})\nrequest('http://www.google.com', function () {\n request('http://images.google.com')\n})\n```\n\nIf you to use a custom cookie jar (instead of letting request use its own global cookie jar) you do so by setting the jar default or by specifying it as an option:\n\n```javascript\nvar j = request.jar()\nvar request = request.defaults({jar:j})\nrequest('http://www.google.com', function () {\n request('http://images.google.com')\n})\n```\nOR\n\n```javascript\nvar j = request.jar()\nvar cookie = request.cookie('your_cookie_here')\nj.add(cookie)\nrequest({url: 'http://www.google.com', jar: j}, function () {\n request('http://images.google.com')\n})\n```\n", "readmeFilename": "README.md", - "_id": "request@2.21.0", + "_id": "request@2.25.0", "_from": "request@latest" } diff --git a/deps/npm/node_modules/request/tests/test-agentOptions.js b/deps/npm/node_modules/request/tests/test-agentOptions.js new file mode 100644 index 00000000000..47fe3aaed60 --- /dev/null +++ b/deps/npm/node_modules/request/tests/test-agentOptions.js @@ -0,0 +1,23 @@ +var request = require('../index') + , http = require('http') + , server = require('./server') + , assert = require('assert') + ; + +var s = http.createServer(function (req, resp) { + resp.statusCode = 200 + resp.end('') +}).listen(6767, function () { + // requests without agentOptions should use global agent + var r = request('http://localhost:6767', function (e, resp, body) { + assert.deepEqual(r.agent, http.globalAgent); + assert.equal(Object.keys(r.pool).length, 0); + + // requests with agentOptions should apply agentOptions to new agent in pool + var r2 = request('http://localhost:6767', { agentOptions: { foo: 'bar' } }, function (e, resp, body) { + assert.deepEqual(r2.agent.options, { foo: 'bar' }); + assert.equal(Object.keys(r2.pool).length, 1); + s.close() + }); + }) +}) diff --git a/deps/npm/node_modules/request/tests/test-follow-all.js b/deps/npm/node_modules/request/tests/test-follow-all.js index 035d6326fa4..f2e51ffa795 100644 --- a/deps/npm/node_modules/request/tests/test-follow-all.js +++ b/deps/npm/node_modules/request/tests/test-follow-all.js @@ -26,6 +26,7 @@ server.listen(6767); request.post({ url: 'http://localhost:6767/foo', followAllRedirects: true, + jar: true, form: { foo: 'bar' } }, function (er, req, body) { if (er) throw er; assert.equal(body, 'ok: 5'); diff --git a/deps/npm/node_modules/semver/README.md b/deps/npm/node_modules/semver/README.md index 2c499a98414..018eb573910 100644 --- a/deps/npm/node_modules/semver/README.md +++ b/deps/npm/node_modules/semver/README.md @@ -60,9 +60,21 @@ The following range styles are supported: using tilde operators, prerelease versions are supported as well, but a prerelease of the next significant digit will NOT be satisfactory, so `1.3.0-beta` will not satisfy `~1.2.3`. +* `^1.2.3` := `>=1.2.3-0 <2.0.0-0` "Compatible with 1.2.3". When + using caret operators, anything from the specified version (including + prerelease) will be supported up to, but not including, the next + major version (or its prereleases). `1.5.1` will satisfy `^1.2.3`, + while `1.2.2` and `2.0.0-beta` will not. +* `^0.1.3` := `>=0.1.3-0 <0.2.0-0` "Compatible with 0.1.3". 0.x.x versions are + special: the first non-zero component indicates potentially breaking changes, + meaning the caret operator matches any version with the same first non-zero + component starting at the specified version. +* `^0.0.2` := `=0.0.2` "Only the version 0.0.2 is considered compatible" * `~1.2` := `>=1.2.0-0 <1.3.0-0` "Any version starting with 1.2" +* `^1.2` := `>=1.2.0-0 <2.0.0-0` "Any version compatible with 1.2" * `1.2.x` := `>=1.2.0-0 <1.3.0-0` "Any version starting with 1.2" * `~1` := `>=1.0.0-0 <2.0.0-0` "Any version starting with 1" +* `^1` := `>=1.0.0-0 <2.0.0-0` "Any version compatible with 1" * `1.x` := `>=1.0.0-0 <2.0.0-0` "Any version starting with 1" diff --git a/deps/npm/node_modules/semver/package.json b/deps/npm/node_modules/semver/package.json index aa6df5ab7a8..258d839ec2c 100644 --- a/deps/npm/node_modules/semver/package.json +++ b/deps/npm/node_modules/semver/package.json @@ -1,6 +1,6 @@ { "name": "semver", - "version": "2.0.11", + "version": "2.1.0", "description": "The semantic version parser used by npm.", "main": "semver.js", "browser": "semver.browser.js", @@ -21,11 +21,11 @@ "bin": { "semver": "./bin/semver" }, - "readme": "semver(1) -- The semantic versioner for npm\n===========================================\n\n## Usage\n\n $ npm install semver\n\n semver.valid('1.2.3') // '1.2.3'\n semver.valid('a.b.c') // null\n semver.clean(' =v1.2.3 ') // '1.2.3'\n semver.satisfies('1.2.3', '1.x || >=2.5.0 || 5.0.0 - 7.2.3') // true\n semver.gt('1.2.3', '9.8.7') // false\n semver.lt('1.2.3', '9.8.7') // true\n\nAs a command-line utility:\n\n $ semver -h\n\n Usage: semver <version> [<version> [...]] [-r <range> | -i <inc> | -d <dec>]\n Test if version(s) satisfy the supplied range(s), and sort them.\n\n Multiple versions or ranges may be supplied, unless increment\n or decrement options are specified. In that case, only a single\n version may be used, and it is incremented by the specified level\n\n Program exits successfully if any valid version satisfies\n all supplied ranges, and prints all satisfying versions.\n\n If no versions are valid, or ranges are not satisfied,\n then exits failure.\n\n Versions are printed in ascending order, so supplying\n multiple versions to the utility will just sort them.\n\n## Versions\n\nA \"version\" is described by the v2.0.0 specification found at\n<http://semver.org/>.\n\nA leading `\"=\"` or `\"v\"` character is stripped off and ignored.\n\n## Ranges\n\nThe following range styles are supported:\n\n* `1.2.3` A specific version. When nothing else will do. Note that\n build metadata is still ignored, so `1.2.3+build2012` will satisfy\n this range.\n* `>1.2.3` Greater than a specific version.\n* `<1.2.3` Less than a specific version. If there is no prerelease\n tag on the version range, then no prerelease version will be allowed\n either, even though these are technically \"less than\".\n* `>=1.2.3` Greater than or equal to. Note that prerelease versions\n are NOT equal to their \"normal\" equivalents, so `1.2.3-beta` will\n not satisfy this range, but `2.3.0-beta` will.\n* `<=1.2.3` Less than or equal to. In this case, prerelease versions\n ARE allowed, so `1.2.3-beta` would satisfy.\n* `1.2.3 - 2.3.4` := `>=1.2.3 <=2.3.4`\n* `~1.2.3` := `>=1.2.3-0 <1.3.0-0` \"Reasonably close to 1.2.3\". When\n using tilde operators, prerelease versions are supported as well,\n but a prerelease of the next significant digit will NOT be\n satisfactory, so `1.3.0-beta` will not satisfy `~1.2.3`.\n* `~1.2` := `>=1.2.0-0 <1.3.0-0` \"Any version starting with 1.2\"\n* `1.2.x` := `>=1.2.0-0 <1.3.0-0` \"Any version starting with 1.2\"\n* `~1` := `>=1.0.0-0 <2.0.0-0` \"Any version starting with 1\"\n* `1.x` := `>=1.0.0-0 <2.0.0-0` \"Any version starting with 1\"\n\n\nRanges can be joined with either a space (which implies \"and\") or a\n`||` (which implies \"or\").\n\n## Functions\n\nAll methods and classes take a final `loose` boolean argument that, if\ntrue, will be more forgiving about not-quite-valid semver strings.\nThe resulting output will always be 100% strict, of course.\n\nStrict-mode Comparators and Ranges will be strict about the SemVer\nstrings that they parse.\n\n* valid(v): Return the parsed version, or null if it's not valid.\n* inc(v, release): Return the version incremented by the release type\n (major, minor, patch, or prerelease), or null if it's not valid.\n\n### Comparison\n\n* gt(v1, v2): `v1 > v2`\n* gte(v1, v2): `v1 >= v2`\n* lt(v1, v2): `v1 < v2`\n* lte(v1, v2): `v1 <= v2`\n* eq(v1, v2): `v1 == v2` This is true if they're logically equivalent,\n even if they're not the exact same string. You already know how to\n compare strings.\n* neq(v1, v2): `v1 != v2` The opposite of eq.\n* cmp(v1, comparator, v2): Pass in a comparison string, and it'll call\n the corresponding function above. `\"===\"` and `\"!==\"` do simple\n string comparison, but are included for completeness. Throws if an\n invalid comparison string is provided.\n* compare(v1, v2): Return 0 if v1 == v2, or 1 if v1 is greater, or -1 if\n v2 is greater. Sorts in ascending order if passed to Array.sort().\n* rcompare(v1, v2): The reverse of compare. Sorts an array of versions\n in descending order when passed to Array.sort().\n\n\n### Ranges\n\n* validRange(range): Return the valid range or null if it's not valid\n* satisfies(version, range): Return true if the version satisfies the\n range.\n* maxSatisfying(versions, range): Return the highest version in the list\n that satisfies the range, or null if none of them do.\n", + "readme": "semver(1) -- The semantic versioner for npm\n===========================================\n\n## Usage\n\n $ npm install semver\n\n semver.valid('1.2.3') // '1.2.3'\n semver.valid('a.b.c') // null\n semver.clean(' =v1.2.3 ') // '1.2.3'\n semver.satisfies('1.2.3', '1.x || >=2.5.0 || 5.0.0 - 7.2.3') // true\n semver.gt('1.2.3', '9.8.7') // false\n semver.lt('1.2.3', '9.8.7') // true\n\nAs a command-line utility:\n\n $ semver -h\n\n Usage: semver <version> [<version> [...]] [-r <range> | -i <inc> | -d <dec>]\n Test if version(s) satisfy the supplied range(s), and sort them.\n\n Multiple versions or ranges may be supplied, unless increment\n or decrement options are specified. In that case, only a single\n version may be used, and it is incremented by the specified level\n\n Program exits successfully if any valid version satisfies\n all supplied ranges, and prints all satisfying versions.\n\n If no versions are valid, or ranges are not satisfied,\n then exits failure.\n\n Versions are printed in ascending order, so supplying\n multiple versions to the utility will just sort them.\n\n## Versions\n\nA \"version\" is described by the v2.0.0 specification found at\n<http://semver.org/>.\n\nA leading `\"=\"` or `\"v\"` character is stripped off and ignored.\n\n## Ranges\n\nThe following range styles are supported:\n\n* `1.2.3` A specific version. When nothing else will do. Note that\n build metadata is still ignored, so `1.2.3+build2012` will satisfy\n this range.\n* `>1.2.3` Greater than a specific version.\n* `<1.2.3` Less than a specific version. If there is no prerelease\n tag on the version range, then no prerelease version will be allowed\n either, even though these are technically \"less than\".\n* `>=1.2.3` Greater than or equal to. Note that prerelease versions\n are NOT equal to their \"normal\" equivalents, so `1.2.3-beta` will\n not satisfy this range, but `2.3.0-beta` will.\n* `<=1.2.3` Less than or equal to. In this case, prerelease versions\n ARE allowed, so `1.2.3-beta` would satisfy.\n* `1.2.3 - 2.3.4` := `>=1.2.3 <=2.3.4`\n* `~1.2.3` := `>=1.2.3-0 <1.3.0-0` \"Reasonably close to 1.2.3\". When\n using tilde operators, prerelease versions are supported as well,\n but a prerelease of the next significant digit will NOT be\n satisfactory, so `1.3.0-beta` will not satisfy `~1.2.3`.\n* `^1.2.3` := `>=1.2.3-0 <2.0.0-0` \"Compatible with 1.2.3\". When\n using caret operators, anything from the specified version (including\n prerelease) will be supported up to, but not including, the next\n major version (or its prereleases). `1.5.1` will satisfy `^1.2.3`,\n while `1.2.2` and `2.0.0-beta` will not.\n* `^0.1.3` := `>=0.1.3-0 <0.2.0-0` \"Compatible with 0.1.3\". 0.x.x versions are\n special: the first non-zero component indicates potentially breaking changes,\n meaning the caret operator matches any version with the same first non-zero\n component starting at the specified version.\n* `^0.0.2` := `=0.0.2` \"Only the version 0.0.2 is considered compatible\"\n* `~1.2` := `>=1.2.0-0 <1.3.0-0` \"Any version starting with 1.2\"\n* `^1.2` := `>=1.2.0-0 <2.0.0-0` \"Any version compatible with 1.2\"\n* `1.2.x` := `>=1.2.0-0 <1.3.0-0` \"Any version starting with 1.2\"\n* `~1` := `>=1.0.0-0 <2.0.0-0` \"Any version starting with 1\"\n* `^1` := `>=1.0.0-0 <2.0.0-0` \"Any version compatible with 1\"\n* `1.x` := `>=1.0.0-0 <2.0.0-0` \"Any version starting with 1\"\n\n\nRanges can be joined with either a space (which implies \"and\") or a\n`||` (which implies \"or\").\n\n## Functions\n\nAll methods and classes take a final `loose` boolean argument that, if\ntrue, will be more forgiving about not-quite-valid semver strings.\nThe resulting output will always be 100% strict, of course.\n\nStrict-mode Comparators and Ranges will be strict about the SemVer\nstrings that they parse.\n\n* valid(v): Return the parsed version, or null if it's not valid.\n* inc(v, release): Return the version incremented by the release type\n (major, minor, patch, or prerelease), or null if it's not valid.\n\n### Comparison\n\n* gt(v1, v2): `v1 > v2`\n* gte(v1, v2): `v1 >= v2`\n* lt(v1, v2): `v1 < v2`\n* lte(v1, v2): `v1 <= v2`\n* eq(v1, v2): `v1 == v2` This is true if they're logically equivalent,\n even if they're not the exact same string. You already know how to\n compare strings.\n* neq(v1, v2): `v1 != v2` The opposite of eq.\n* cmp(v1, comparator, v2): Pass in a comparison string, and it'll call\n the corresponding function above. `\"===\"` and `\"!==\"` do simple\n string comparison, but are included for completeness. Throws if an\n invalid comparison string is provided.\n* compare(v1, v2): Return 0 if v1 == v2, or 1 if v1 is greater, or -1 if\n v2 is greater. Sorts in ascending order if passed to Array.sort().\n* rcompare(v1, v2): The reverse of compare. Sorts an array of versions\n in descending order when passed to Array.sort().\n\n\n### Ranges\n\n* validRange(range): Return the valid range or null if it's not valid\n* satisfies(version, range): Return true if the version satisfies the\n range.\n* maxSatisfying(versions, range): Return the highest version in the list\n that satisfies the range, or null if none of them do.\n", "readmeFilename": "README.md", "bugs": { "url": "https://github.com/isaacs/node-semver/issues" }, - "_id": "semver@2.0.11", - "_from": "semver@latest" + "_id": "semver@2.1.0", + "_from": "semver@2.1" } diff --git a/deps/npm/node_modules/semver/r.js b/deps/npm/node_modules/semver/r.js deleted file mode 100644 index 3273d7dae12..00000000000 --- a/deps/npm/node_modules/semver/r.js +++ /dev/null @@ -1,4 +0,0 @@ -var semver = require('./') -var r = new semver.Range('git+https://user:password0123@github.com/foo/bar.git', true) -r.inspect = null -console.log(r) diff --git a/deps/npm/node_modules/semver/semver.browser.js b/deps/npm/node_modules/semver/semver.browser.js index d19f104fea3..087133e6921 100644 --- a/deps/npm/node_modules/semver/semver.browser.js +++ b/deps/npm/node_modules/semver/semver.browser.js @@ -151,14 +151,29 @@ var LONETILDE = R++; src[LONETILDE] = '(?:~>?)'; var TILDETRIM = R++; -src[TILDETRIM] = src[LONETILDE] + '\\s+'; -var tildeTrimReplace = '~'; +src[TILDETRIM] = '(\\s*)' + src[LONETILDE] + '\\s+'; +re[TILDETRIM] = new RegExp(src[TILDETRIM], 'g'); +var tildeTrimReplace = '$1~'; var TILDE = R++; src[TILDE] = '^' + src[LONETILDE] + src[XRANGEPLAIN] + '$'; var TILDELOOSE = R++; src[TILDELOOSE] = '^' + src[LONETILDE] + src[XRANGEPLAINLOOSE] + '$'; +// Caret ranges. +// Meaning is "at least and backwards compatible with" +var LONECARET = R++; +src[LONECARET] = '(?:\\^)'; + +var CARETTRIM = R++; +src[CARETTRIM] = '(\\s*)' + src[LONECARET] + '\\s+'; +re[CARETTRIM] = new RegExp(src[CARETTRIM], 'g'); +var caretTrimReplace = '$1^'; + +var CARET = R++; +src[CARET] = '^' + src[LONECARET] + src[XRANGEPLAIN] + '$'; +var CARETLOOSE = R++; +src[CARETLOOSE] = '^' + src[LONECARET] + src[XRANGEPLAINLOOSE] + '$'; // A simple gt/lt/eq thing, or just "" to indicate "any version" var COMPARATORLOOSE = R++; @@ -592,6 +607,9 @@ Range.prototype.parseRange = function(range) { // `~ 1.2.3` => `~1.2.3` range = range.replace(re[TILDETRIM], tildeTrimReplace); + // `^ 1.2.3` => `^1.2.3` + range = range.replace(re[CARETTRIM], caretTrimReplace); + // normalize spaces range = range.split(/\s+/).join(' '); @@ -630,6 +648,8 @@ function toComparators(range, loose) { // turn into a set of JUST comparators. function parseComparator(comp, loose) { ; + comp = replaceCarets(comp, loose); + ; comp = replaceTildes(comp, loose); ; comp = replaceXRanges(comp, loose); @@ -684,6 +704,54 @@ function replaceTilde(comp, loose) { }); } +// ^ --> * (any, kinda silly) +// ^2, ^2.x, ^2.x.x --> >=2.0.0 <3.0.0 +// ^2.0, ^2.0.x --> >=2.0.0 <3.0.0 +// ^1.2, ^1.2.x --> >=1.2.0 <2.0.0 +// ^1.2.3 --> >=1.2.3 <2.0.0 +// ^1.2.0 --> >=1.2.0 <2.0.0 +function replaceCarets(comp, loose) { + return comp.trim().split(/\s+/).map(function(comp) { + return replaceCaret(comp, loose); + }).join(' '); +} + +function replaceCaret(comp, loose) { + var r = loose ? re[CARETLOOSE] : re[CARET]; + return comp.replace(r, function(_, M, m, p, pr) { + ; + var ret; + + if (isX(M)) + ret = ''; + else if (isX(m)) + ret = '>=' + M + '.0.0-0 <' + (+M + 1) + '.0.0-0'; + else if (isX(p)) + if (M === '0') ret = '>=' + M + '.' + m + '.0-0 <' + M + '.' + (+m + 1) + '.0-0'; + else ret = '>=' + M + '.' + m + '.0-0 <' + (+M + 1) + '.0.0-0'; + else if (pr) { + ; + if (pr.charAt(0) !== '-') + pr = '-' + pr; + if (M === '0') + if (m === '0') ret = '=' + M + '.' + m + '.' + p + pr; + else ret = '>=' + M + '.' + m + '.' + p + pr + + ' <' + M + '.' + (+m + 1) + '.0-0'; + else ret = '>=' + M + '.' + m + '.' + p + pr + + ' <' + (+M + 1) + '.0.0-0'; + } else + if (M === '0') + if (m === '0') ret = '=' + M + '.' + m + '.' + p; + else ret = '>=' + M + '.' + m + '.' + p + '-0' + + ' <' + M + '.' + (+m + 1) + '.0-0'; + else ret = '>=' + M + '.' + m + '.' + p + '-0' + + ' <' + (+M + 1) + '.0.0-0'; + + ; + return ret; + }); +} + function replaceXRanges(comp, loose) { ; return comp.split(/\s+/).map(function(comp) { diff --git a/deps/npm/node_modules/semver/semver.browser.js.gz b/deps/npm/node_modules/semver/semver.browser.js.gz Binary files differindex eca788e5b32..fe7ba007c88 100644 --- a/deps/npm/node_modules/semver/semver.browser.js.gz +++ b/deps/npm/node_modules/semver/semver.browser.js.gz diff --git a/deps/npm/node_modules/semver/semver.js b/deps/npm/node_modules/semver/semver.js index 28fa1c03b05..5445fc170b1 100644 --- a/deps/npm/node_modules/semver/semver.js +++ b/deps/npm/node_modules/semver/semver.js @@ -161,14 +161,29 @@ var LONETILDE = R++; src[LONETILDE] = '(?:~>?)'; var TILDETRIM = R++; -src[TILDETRIM] = src[LONETILDE] + '\\s+'; -var tildeTrimReplace = '~'; +src[TILDETRIM] = '(\\s*)' + src[LONETILDE] + '\\s+'; +re[TILDETRIM] = new RegExp(src[TILDETRIM], 'g'); +var tildeTrimReplace = '$1~'; var TILDE = R++; src[TILDE] = '^' + src[LONETILDE] + src[XRANGEPLAIN] + '$'; var TILDELOOSE = R++; src[TILDELOOSE] = '^' + src[LONETILDE] + src[XRANGEPLAINLOOSE] + '$'; +// Caret ranges. +// Meaning is "at least and backwards compatible with" +var LONECARET = R++; +src[LONECARET] = '(?:\\^)'; + +var CARETTRIM = R++; +src[CARETTRIM] = '(\\s*)' + src[LONECARET] + '\\s+'; +re[CARETTRIM] = new RegExp(src[CARETTRIM], 'g'); +var caretTrimReplace = '$1^'; + +var CARET = R++; +src[CARET] = '^' + src[LONECARET] + src[XRANGEPLAIN] + '$'; +var CARETLOOSE = R++; +src[CARETLOOSE] = '^' + src[LONECARET] + src[XRANGEPLAINLOOSE] + '$'; // A simple gt/lt/eq thing, or just "" to indicate "any version" var COMPARATORLOOSE = R++; @@ -602,6 +617,9 @@ Range.prototype.parseRange = function(range) { // `~ 1.2.3` => `~1.2.3` range = range.replace(re[TILDETRIM], tildeTrimReplace); + // `^ 1.2.3` => `^1.2.3` + range = range.replace(re[CARETTRIM], caretTrimReplace); + // normalize spaces range = range.split(/\s+/).join(' '); @@ -640,6 +658,8 @@ function toComparators(range, loose) { // turn into a set of JUST comparators. function parseComparator(comp, loose) { debug('comp', comp); + comp = replaceCarets(comp, loose); + debug('caret', comp); comp = replaceTildes(comp, loose); debug('tildes', comp); comp = replaceXRanges(comp, loose); @@ -694,6 +714,54 @@ function replaceTilde(comp, loose) { }); } +// ^ --> * (any, kinda silly) +// ^2, ^2.x, ^2.x.x --> >=2.0.0 <3.0.0 +// ^2.0, ^2.0.x --> >=2.0.0 <3.0.0 +// ^1.2, ^1.2.x --> >=1.2.0 <2.0.0 +// ^1.2.3 --> >=1.2.3 <2.0.0 +// ^1.2.0 --> >=1.2.0 <2.0.0 +function replaceCarets(comp, loose) { + return comp.trim().split(/\s+/).map(function(comp) { + return replaceCaret(comp, loose); + }).join(' '); +} + +function replaceCaret(comp, loose) { + var r = loose ? re[CARETLOOSE] : re[CARET]; + return comp.replace(r, function(_, M, m, p, pr) { + debug('caret', comp, _, M, m, p, pr); + var ret; + + if (isX(M)) + ret = ''; + else if (isX(m)) + ret = '>=' + M + '.0.0-0 <' + (+M + 1) + '.0.0-0'; + else if (isX(p)) + if (M === '0') ret = '>=' + M + '.' + m + '.0-0 <' + M + '.' + (+m + 1) + '.0-0'; + else ret = '>=' + M + '.' + m + '.0-0 <' + (+M + 1) + '.0.0-0'; + else if (pr) { + debug('replaceCaret pr', pr); + if (pr.charAt(0) !== '-') + pr = '-' + pr; + if (M === '0') + if (m === '0') ret = '=' + M + '.' + m + '.' + p + pr; + else ret = '>=' + M + '.' + m + '.' + p + pr + + ' <' + M + '.' + (+m + 1) + '.0-0'; + else ret = '>=' + M + '.' + m + '.' + p + pr + + ' <' + (+M + 1) + '.0.0-0'; + } else + if (M === '0') + if (m === '0') ret = '=' + M + '.' + m + '.' + p; + else ret = '>=' + M + '.' + m + '.' + p + '-0' + + ' <' + M + '.' + (+m + 1) + '.0-0'; + else ret = '>=' + M + '.' + m + '.' + p + '-0' + + ' <' + (+M + 1) + '.0.0-0'; + + debug('caret return', ret); + return ret; + }); +} + function replaceXRanges(comp, loose) { debug('replaceXRanges', comp, loose); return comp.split(/\s+/).map(function(comp) { diff --git a/deps/npm/node_modules/semver/semver.min.js b/deps/npm/node_modules/semver/semver.min.js index 90ccff3e233..45e22e0bcab 100644 --- a/deps/npm/node_modules/semver/semver.min.js +++ b/deps/npm/node_modules/semver/semver.min.js @@ -1 +1 @@ -!function(e){if(typeof module==="object"&&module.exports===e)e=module.exports=O;e.SEMVER_SPEC_VERSION="2.0.0";var r=e.re=[];var t=e.src=[];var n=0;var i=n++;t[i]="0|[1-9]\\d*";var s=n++;t[s]="[0-9]+";var o=n++;t[o]="\\d*[a-zA-Z-][a-zA-Z0-9-]*";var a=n++;t[a]="("+t[i]+")\\."+"("+t[i]+")\\."+"("+t[i]+")";var u=n++;t[u]="("+t[s]+")\\."+"("+t[s]+")\\."+"("+t[s]+")";var f=n++;t[f]="(?:"+t[i]+"|"+t[o]+")";var c=n++;t[c]="(?:"+t[s]+"|"+t[o]+")";var l=n++;t[l]="(?:-("+t[f]+"(?:\\."+t[f]+")*))";var p=n++;t[p]="(?:-?("+t[c]+"(?:\\."+t[c]+")*))";var h=n++;t[h]="[0-9A-Za-z-]+";var v=n++;t[v]="(?:\\+("+t[h]+"(?:\\."+t[h]+")*))";var m=n++;var g="v?"+t[a]+t[l]+"?"+t[v]+"?";t[m]="^"+g+"$";var d="[v=\\s]*"+t[u]+t[p]+"?"+t[v]+"?";var w=n++;t[w]="^"+d+"$";var y=n++;t[y]="((?:<|>)?=?)";var $=n++;t[$]=t[s]+"|x|X|\\*";var j=n++;t[j]=t[i]+"|x|X|\\*";var b=n++;t[b]="[v=\\s]*("+t[j]+")"+"(?:\\.("+t[j]+")"+"(?:\\.("+t[j]+")"+"(?:("+t[l]+")"+")?)?)?";var S=n++;t[S]="[v=\\s]*("+t[$]+")"+"(?:\\.("+t[$]+")"+"(?:\\.("+t[$]+")"+"(?:("+t[p]+")"+")?)?)?";var E=n++;t[E]="^"+t[y]+"\\s*"+t[b]+"$";var k=n++;t[k]="^"+t[y]+"\\s*"+t[S]+"$";var x=n++;t[x]="(?:~>?)";var R=n++;t[R]=t[x]+"\\s+";var V="~";var I=n++;t[I]="^"+t[x]+t[b]+"$";var C=n++;t[C]="^"+t[x]+t[S]+"$";var A=n++;t[A]="^"+t[y]+"\\s*("+d+")$|^$";var T=n++;t[T]="^"+t[y]+"\\s*("+g+")$|^$";var z=n++;t[z]="(\\s*)"+t[y]+"\\s*("+d+"|"+t[b]+")";r[z]=new RegExp(t[z],"g");var M="$1$2$3";var P=n++;t[P]="^\\s*("+t[b]+")"+"\\s+-\\s+"+"("+t[b]+")"+"\\s*$";var Z=n++;t[Z]="^\\s*("+t[S]+")"+"\\s+-\\s+"+"("+t[S]+")"+"\\s*$";var q=n++;t[q]="(<|>)?=?\\s*\\*";for(var L=0;L<n;L++){if(!r[L])r[L]=new RegExp(t[L])}e.parse=X;function X(e,t){var n=t?r[w]:r[m];return n.test(e)?new O(e,t):null}e.valid=_;function _(e,r){var t=X(e,r);return t?t.version:null}e.clean=N;function N(e,r){var t=X(e,r);return t?t.version:null}e.SemVer=O;function O(e,t){if(e instanceof O){if(e.loose===t)return e;else e=e.version}if(!(this instanceof O))return new O(e,t);this.loose=t;var n=e.trim().match(t?r[w]:r[m]);if(!n)throw new TypeError("Invalid Version: "+e);this.raw=e;this.major=+n[1];this.minor=+n[2];this.patch=+n[3];if(!n[4])this.prerelease=[];else this.prerelease=n[4].split(".").map(function(e){return/^[0-9]+$/.test(e)?+e:e});this.build=n[5]?n[5].split("."):[];this.format()}O.prototype.format=function(){this.version=this.major+"."+this.minor+"."+this.patch;if(this.prerelease.length)this.version+="-"+this.prerelease.join(".");return this.version};O.prototype.inspect=function(){return'<SemVer "'+this+'">'};O.prototype.toString=function(){return this.version};O.prototype.compare=function(e){if(!(e instanceof O))e=new O(e,this.loose);return this.compareMain(e)||this.comparePre(e)};O.prototype.compareMain=function(e){if(!(e instanceof O))e=new O(e,this.loose);return F(this.major,e.major)||F(this.minor,e.minor)||F(this.patch,e.patch)};O.prototype.comparePre=function(e){if(!(e instanceof O))e=new O(e,this.loose);if(this.prerelease.length&&!e.prerelease.length)return-1;else if(!this.prerelease.length&&e.prerelease.length)return 1;else if(!this.prerelease.lenth&&!e.prerelease.length)return 0;var r=0;do{var t=this.prerelease[r];var n=e.prerelease[r];if(t===undefined&&n===undefined)return 0;else if(n===undefined)return 1;else if(t===undefined)return-1;else if(t===n)continue;else return F(t,n)}while(++r)};O.prototype.inc=function(e){switch(e){case"major":this.major++;this.minor=-1;case"minor":this.minor++;this.patch=-1;case"patch":this.patch++;this.prerelease=[];break;case"prerelease":if(this.prerelease.length===0)this.prerelease=[0];else{var r=this.prerelease.length;while(--r>=0){if(typeof this.prerelease[r]==="number"){this.prerelease[r]++;r=-2}}if(r===-1)this.prerelease.push(0)}break;default:throw new Error("invalid increment argument: "+e)}this.format();return this};e.inc=B;function B(e,r,t){try{return new O(e,t).inc(r).version}catch(n){return null}}e.compareIdentifiers=F;var D=/^[0-9]+$/;function F(e,r){var t=D.test(e);var n=D.test(r);if(t&&n){e=+e;r=+r}return t&&!n?-1:n&&!t?1:e<r?-1:e>r?1:0}e.rcompareIdentifiers=G;function G(e,r){return F(r,e)}e.compare=H;function H(e,r,t){return new O(e,t).compare(r)}e.compareLoose=J;function J(e,r){return H(e,r,true)}e.rcompare=K;function K(e,r,t){return H(r,e,t)}e.sort=Q;function Q(r,t){return r.sort(function(r,n){return e.compare(r,n,t)})}e.rsort=U;function U(r,t){return r.sort(function(r,n){return e.rcompare(r,n,t)})}e.gt=W;function W(e,r,t){return H(e,r,t)>0}e.lt=Y;function Y(e,r,t){return H(e,r,t)<0}e.eq=er;function er(e,r,t){return H(e,r,t)===0}e.neq=rr;function rr(e,r,t){return H(e,r,t)!==0}e.gte=tr;function tr(e,r,t){return H(e,r,t)>=0}e.lte=nr;function nr(e,r,t){return H(e,r,t)<=0}e.cmp=ir;function ir(e,r,t,n){var i;switch(r){case"===":i=e===t;break;case"!==":i=e!==t;break;case"":case"=":case"==":i=er(e,t,n);break;case"!=":i=rr(e,t,n);break;case">":i=W(e,t,n);break;case">=":i=tr(e,t,n);break;case"<":i=Y(e,t,n);break;case"<=":i=nr(e,t,n);break;default:throw new TypeError("Invalid operator: "+r)}return i}e.Comparator=sr;function sr(e,r){if(e instanceof sr){if(e.loose===r)return e;else e=e.value}if(!(this instanceof sr))return new sr(e,r);this.loose=r;this.parse(e);if(this.semver===or)this.value="";else this.value=this.operator+this.semver.version}var or={};sr.prototype.parse=function(e){var t=this.loose?r[A]:r[T];var n=e.match(t);if(!n)throw new TypeError("Invalid comparator: "+e);this.operator=n[1];if(!n[2])this.semver=or;else{this.semver=new O(n[2],this.loose);if(this.operator==="<"&&!this.semver.prerelease.length){this.semver.prerelease=["0"];this.semver.format()}}};sr.prototype.inspect=function(){return'<SemVer Comparator "'+this+'">'};sr.prototype.toString=function(){return this.value};sr.prototype.test=function(e){return this.semver===or?true:ir(e,this.operator,this.semver,this.loose)};e.Range=ar;function ar(e,r){if(e instanceof ar&&e.loose===r)return e;if(!(this instanceof ar))return new ar(e,r);this.loose=r;this.raw=e;this.set=e.split(/\s*\|\|\s*/).map(function(e){return this.parseRange(e.trim())},this).filter(function(e){return e.length});if(!this.set.length){throw new TypeError("Invalid SemVer Range: "+e)}this.format()}ar.prototype.inspect=function(){return'<SemVer Range "'+this.range+'">'};ar.prototype.format=function(){this.range=this.set.map(function(e){return e.join(" ").trim()}).join("||").trim();return this.range};ar.prototype.toString=function(){return this.range};ar.prototype.parseRange=function(e){var t=this.loose;e=e.trim();var n=t?r[Z]:r[P];e=e.replace(n,gr);e=e.replace(r[z],M);e=e.replace(r[R],V);e=e.split(/\s+/).join(" ");var i=t?r[A]:r[T];var s=e.split(" ").map(function(e){return fr(e,t)}).join(" ").split(/\s+/);if(this.loose){s=s.filter(function(e){return!!e.match(i)})}s=s.map(function(e){return new sr(e,t)});return s};e.toComparators=ur;function ur(e,r){return new ar(e,r).set.map(function(e){return e.map(function(e){return e.value}).join(" ").trim().split(" ")})}function fr(e,r){e=lr(e,r);e=hr(e,r);e=mr(e,r);return e}function cr(e){return!e||e.toLowerCase()==="x"||e==="*"}function lr(e,r){return e.trim().split(/\s+/).map(function(e){return pr(e,r)}).join(" ")}function pr(e,t){var n=t?r[C]:r[I];return e.replace(n,function(e,r,t,n,i){var s;if(cr(r))s="";else if(cr(t))s=">="+r+".0.0-0 <"+(+r+1)+".0.0-0";else if(cr(n))s=">="+r+"."+t+".0-0 <"+r+"."+(+t+1)+".0-0";else if(i){if(i.charAt(0)!=="-")i="-"+i;s=">="+r+"."+t+"."+n+i+" <"+r+"."+(+t+1)+".0-0"}else s=">="+r+"."+t+"."+n+"-0"+" <"+r+"."+(+t+1)+".0-0";return s})}function hr(e,r){return e.split(/\s+/).map(function(e){return vr(e,r)}).join(" ")}function vr(e,t){e=e.trim();var n=t?r[k]:r[E];return e.replace(n,function(e,r,t,n,i,s){var o=cr(t);var a=o||cr(n);var u=a||cr(i);var f=u;if(r==="="&&f)r="";if(r&&f){if(o)t=0;if(a)n=0;if(u)i=0;if(r===">"){r=">=";if(o){}else if(a){t=+t+1;n=0;i=0}else if(u){n=+n+1;i=0}}e=r+t+"."+n+"."+i+"-0"}else if(o){e="*"}else if(a){e=">="+t+".0.0-0 <"+(+t+1)+".0.0-0"}else if(u){e=">="+t+"."+n+".0-0 <"+t+"."+(+n+1)+".0-0"}return e})}function mr(e,t){return e.trim().replace(r[q],"")}function gr(e,r,t,n,i,s,o,a,u,f,c,l,p){if(cr(t))r="";else if(cr(n))r=">="+t+".0.0-0";else if(cr(i))r=">="+t+"."+n+".0-0";else r=">="+r;if(cr(u))a="";else if(cr(f))a="<"+(+u+1)+".0.0-0";else if(cr(c))a="<"+u+"."+(+f+1)+".0-0";else if(l)a="<="+u+"."+f+"."+c+"-"+l;else a="<="+a;return(r+" "+a).trim()}ar.prototype.test=function(e){if(!e)return false;for(var r=0;r<this.set.length;r++){if(dr(this.set[r],e))return true}return false};function dr(e,r){for(var t=0;t<e.length;t++){if(!e[t].test(r))return false}return true}e.satisfies=wr;function wr(e,r,t){try{r=new ar(r,t)}catch(n){return false}return r.test(e)}e.maxSatisfying=yr;function yr(e,r,t){return e.filter(function(e){return wr(e,r,t)}).sort(function(e,r){return K(e,r,t)})[0]||null}e.validRange=$r;function $r(e,r){try{return new ar(e,r).range||"*"}catch(t){return null}}if(typeof define==="function"&&define.amd)define(e)}(typeof exports==="object"?exports:typeof define==="function"&&define.amd?{}:semver={});
\ No newline at end of file +!function(e){if(typeof module==="object"&&module.exports===e)e=module.exports=H;e.SEMVER_SPEC_VERSION="2.0.0";var r=e.re=[];var t=e.src=[];var n=0;var i=n++;t[i]="0|[1-9]\\d*";var s=n++;t[s]="[0-9]+";var o=n++;t[o]="\\d*[a-zA-Z-][a-zA-Z0-9-]*";var a=n++;t[a]="("+t[i]+")\\."+"("+t[i]+")\\."+"("+t[i]+")";var f=n++;t[f]="("+t[s]+")\\."+"("+t[s]+")\\."+"("+t[s]+")";var u=n++;t[u]="(?:"+t[i]+"|"+t[o]+")";var c=n++;t[c]="(?:"+t[s]+"|"+t[o]+")";var l=n++;t[l]="(?:-("+t[u]+"(?:\\."+t[u]+")*))";var p=n++;t[p]="(?:-?("+t[c]+"(?:\\."+t[c]+")*))";var h=n++;t[h]="[0-9A-Za-z-]+";var v=n++;t[v]="(?:\\+("+t[h]+"(?:\\."+t[h]+")*))";var m=n++;var g="v?"+t[a]+t[l]+"?"+t[v]+"?";t[m]="^"+g+"$";var w="[v=\\s]*"+t[f]+t[p]+"?"+t[v]+"?";var d=n++;t[d]="^"+w+"$";var y=n++;t[y]="((?:<|>)?=?)";var $=n++;t[$]=t[s]+"|x|X|\\*";var j=n++;t[j]=t[i]+"|x|X|\\*";var b=n++;t[b]="[v=\\s]*("+t[j]+")"+"(?:\\.("+t[j]+")"+"(?:\\.("+t[j]+")"+"(?:("+t[l]+")"+")?)?)?";var E=n++;t[E]="[v=\\s]*("+t[$]+")"+"(?:\\.("+t[$]+")"+"(?:\\.("+t[$]+")"+"(?:("+t[p]+")"+")?)?)?";var x=n++;t[x]="^"+t[y]+"\\s*"+t[b]+"$";var R=n++;t[R]="^"+t[y]+"\\s*"+t[E]+"$";var S=n++;t[S]="(?:~>?)";var k=n++;t[k]="(\\s*)"+t[S]+"\\s+";r[k]=new RegExp(t[k],"g");var V="$1~";var I=n++;t[I]="^"+t[S]+t[b]+"$";var A=n++;t[A]="^"+t[S]+t[E]+"$";var C=n++;t[C]="(?:\\^)";var T=n++;t[T]="(\\s*)"+t[C]+"\\s+";r[T]=new RegExp(t[T],"g");var z="$1^";var M=n++;t[M]="^"+t[C]+t[b]+"$";var P=n++;t[P]="^"+t[C]+t[E]+"$";var Z=n++;t[Z]="^"+t[y]+"\\s*("+w+")$|^$";var q=n++;t[q]="^"+t[y]+"\\s*("+g+")$|^$";var L=n++;t[L]="(\\s*)"+t[y]+"\\s*("+w+"|"+t[b]+")";r[L]=new RegExp(t[L],"g");var X="$1$2$3";var _=n++;t[_]="^\\s*("+t[b]+")"+"\\s+-\\s+"+"("+t[b]+")"+"\\s*$";var N=n++;t[N]="^\\s*("+t[E]+")"+"\\s+-\\s+"+"("+t[E]+")"+"\\s*$";var O=n++;t[O]="(<|>)?=?\\s*\\*";for(var B=0;B<n;B++){if(!r[B])r[B]=new RegExp(t[B])}e.parse=D;function D(e,t){var n=t?r[d]:r[m];return n.test(e)?new H(e,t):null}e.valid=F;function F(e,r){var t=D(e,r);return t?t.version:null}e.clean=G;function G(e,r){var t=D(e,r);return t?t.version:null}e.SemVer=H;function H(e,t){if(e instanceof H){if(e.loose===t)return e;else e=e.version}if(!(this instanceof H))return new H(e,t);this.loose=t;var n=e.trim().match(t?r[d]:r[m]);if(!n)throw new TypeError("Invalid Version: "+e);this.raw=e;this.major=+n[1];this.minor=+n[2];this.patch=+n[3];if(!n[4])this.prerelease=[];else this.prerelease=n[4].split(".").map(function(e){return/^[0-9]+$/.test(e)?+e:e});this.build=n[5]?n[5].split("."):[];this.format()}H.prototype.format=function(){this.version=this.major+"."+this.minor+"."+this.patch;if(this.prerelease.length)this.version+="-"+this.prerelease.join(".");return this.version};H.prototype.inspect=function(){return'<SemVer "'+this+'">'};H.prototype.toString=function(){return this.version};H.prototype.compare=function(e){if(!(e instanceof H))e=new H(e,this.loose);return this.compareMain(e)||this.comparePre(e)};H.prototype.compareMain=function(e){if(!(e instanceof H))e=new H(e,this.loose);return Q(this.major,e.major)||Q(this.minor,e.minor)||Q(this.patch,e.patch)};H.prototype.comparePre=function(e){if(!(e instanceof H))e=new H(e,this.loose);if(this.prerelease.length&&!e.prerelease.length)return-1;else if(!this.prerelease.length&&e.prerelease.length)return 1;else if(!this.prerelease.lenth&&!e.prerelease.length)return 0;var r=0;do{var t=this.prerelease[r];var n=e.prerelease[r];if(t===undefined&&n===undefined)return 0;else if(n===undefined)return 1;else if(t===undefined)return-1;else if(t===n)continue;else return Q(t,n)}while(++r)};H.prototype.inc=function(e){switch(e){case"major":this.major++;this.minor=-1;case"minor":this.minor++;this.patch=-1;case"patch":this.patch++;this.prerelease=[];break;case"prerelease":if(this.prerelease.length===0)this.prerelease=[0];else{var r=this.prerelease.length;while(--r>=0){if(typeof this.prerelease[r]==="number"){this.prerelease[r]++;r=-2}}if(r===-1)this.prerelease.push(0)}break;default:throw new Error("invalid increment argument: "+e)}this.format();return this};e.inc=J;function J(e,r,t){try{return new H(e,t).inc(r).version}catch(n){return null}}e.compareIdentifiers=Q;var K=/^[0-9]+$/;function Q(e,r){var t=K.test(e);var n=K.test(r);if(t&&n){e=+e;r=+r}return t&&!n?-1:n&&!t?1:e<r?-1:e>r?1:0}e.rcompareIdentifiers=U;function U(e,r){return Q(r,e)}e.compare=W;function W(e,r,t){return new H(e,t).compare(r)}e.compareLoose=Y;function Y(e,r){return W(e,r,true)}e.rcompare=er;function er(e,r,t){return W(r,e,t)}e.sort=rr;function rr(r,t){return r.sort(function(r,n){return e.compare(r,n,t)})}e.rsort=tr;function tr(r,t){return r.sort(function(r,n){return e.rcompare(r,n,t)})}e.gt=nr;function nr(e,r,t){return W(e,r,t)>0}e.lt=ir;function ir(e,r,t){return W(e,r,t)<0}e.eq=sr;function sr(e,r,t){return W(e,r,t)===0}e.neq=or;function or(e,r,t){return W(e,r,t)!==0}e.gte=ar;function ar(e,r,t){return W(e,r,t)>=0}e.lte=fr;function fr(e,r,t){return W(e,r,t)<=0}e.cmp=ur;function ur(e,r,t,n){var i;switch(r){case"===":i=e===t;break;case"!==":i=e!==t;break;case"":case"=":case"==":i=sr(e,t,n);break;case"!=":i=or(e,t,n);break;case">":i=nr(e,t,n);break;case">=":i=ar(e,t,n);break;case"<":i=ir(e,t,n);break;case"<=":i=fr(e,t,n);break;default:throw new TypeError("Invalid operator: "+r)}return i}e.Comparator=cr;function cr(e,r){if(e instanceof cr){if(e.loose===r)return e;else e=e.value}if(!(this instanceof cr))return new cr(e,r);this.loose=r;this.parse(e);if(this.semver===lr)this.value="";else this.value=this.operator+this.semver.version}var lr={};cr.prototype.parse=function(e){var t=this.loose?r[Z]:r[q];var n=e.match(t);if(!n)throw new TypeError("Invalid comparator: "+e);this.operator=n[1];if(!n[2])this.semver=lr;else{this.semver=new H(n[2],this.loose);if(this.operator==="<"&&!this.semver.prerelease.length){this.semver.prerelease=["0"];this.semver.format()}}};cr.prototype.inspect=function(){return'<SemVer Comparator "'+this+'">'};cr.prototype.toString=function(){return this.value};cr.prototype.test=function(e){return this.semver===lr?true:ur(e,this.operator,this.semver,this.loose)};e.Range=pr;function pr(e,r){if(e instanceof pr&&e.loose===r)return e;if(!(this instanceof pr))return new pr(e,r);this.loose=r;this.raw=e;this.set=e.split(/\s*\|\|\s*/).map(function(e){return this.parseRange(e.trim())},this).filter(function(e){return e.length});if(!this.set.length){throw new TypeError("Invalid SemVer Range: "+e)}this.format()}pr.prototype.inspect=function(){return'<SemVer Range "'+this.range+'">'};pr.prototype.format=function(){this.range=this.set.map(function(e){return e.join(" ").trim()}).join("||").trim();return this.range};pr.prototype.toString=function(){return this.range};pr.prototype.parseRange=function(e){var t=this.loose;e=e.trim();var n=t?r[N]:r[_];e=e.replace(n,Er);e=e.replace(r[L],X);e=e.replace(r[k],V);e=e.replace(r[T],z);e=e.split(/\s+/).join(" ");var i=t?r[Z]:r[q];var s=e.split(" ").map(function(e){return vr(e,t)}).join(" ").split(/\s+/);if(this.loose){s=s.filter(function(e){return!!e.match(i)})}s=s.map(function(e){return new cr(e,t)});return s};e.toComparators=hr;function hr(e,r){return new pr(e,r).set.map(function(e){return e.map(function(e){return e.value}).join(" ").trim().split(" ")})}function vr(e,r){e=dr(e,r);e=gr(e,r);e=$r(e,r);e=br(e,r);return e}function mr(e){return!e||e.toLowerCase()==="x"||e==="*"}function gr(e,r){return e.trim().split(/\s+/).map(function(e){return wr(e,r)}).join(" ")}function wr(e,t){var n=t?r[A]:r[I];return e.replace(n,function(e,r,t,n,i){var s;if(mr(r))s="";else if(mr(t))s=">="+r+".0.0-0 <"+(+r+1)+".0.0-0";else if(mr(n))s=">="+r+"."+t+".0-0 <"+r+"."+(+t+1)+".0-0";else if(i){if(i.charAt(0)!=="-")i="-"+i;s=">="+r+"."+t+"."+n+i+" <"+r+"."+(+t+1)+".0-0"}else s=">="+r+"."+t+"."+n+"-0"+" <"+r+"."+(+t+1)+".0-0";return s})}function dr(e,r){return e.trim().split(/\s+/).map(function(e){return yr(e,r)}).join(" ")}function yr(e,t){var n=t?r[P]:r[M];return e.replace(n,function(e,r,t,n,i){var s;if(mr(r))s="";else if(mr(t))s=">="+r+".0.0-0 <"+(+r+1)+".0.0-0";else if(mr(n))if(r==="0")s=">="+r+"."+t+".0-0 <"+r+"."+(+t+1)+".0-0";else s=">="+r+"."+t+".0-0 <"+(+r+1)+".0.0-0";else if(i){if(i.charAt(0)!=="-")i="-"+i;if(r==="0")if(t==="0")s="="+r+"."+t+"."+n+i;else s=">="+r+"."+t+"."+n+i+" <"+r+"."+(+t+1)+".0-0";else s=">="+r+"."+t+"."+n+i+" <"+(+r+1)+".0.0-0"}else if(r==="0")if(t==="0")s="="+r+"."+t+"."+n;else s=">="+r+"."+t+"."+n+"-0"+" <"+r+"."+(+t+1)+".0-0";else s=">="+r+"."+t+"."+n+"-0"+" <"+(+r+1)+".0.0-0";return s})}function $r(e,r){return e.split(/\s+/).map(function(e){return jr(e,r)}).join(" ")}function jr(e,t){e=e.trim();var n=t?r[R]:r[x];return e.replace(n,function(e,r,t,n,i,s){var o=mr(t);var a=o||mr(n);var f=a||mr(i);var u=f;if(r==="="&&u)r="";if(r&&u){if(o)t=0;if(a)n=0;if(f)i=0;if(r===">"){r=">=";if(o){}else if(a){t=+t+1;n=0;i=0}else if(f){n=+n+1;i=0}}e=r+t+"."+n+"."+i+"-0"}else if(o){e="*"}else if(a){e=">="+t+".0.0-0 <"+(+t+1)+".0.0-0"}else if(f){e=">="+t+"."+n+".0-0 <"+t+"."+(+n+1)+".0-0"}return e})}function br(e,t){return e.trim().replace(r[O],"")}function Er(e,r,t,n,i,s,o,a,f,u,c,l,p){if(mr(t))r="";else if(mr(n))r=">="+t+".0.0-0";else if(mr(i))r=">="+t+"."+n+".0-0";else r=">="+r;if(mr(f))a="";else if(mr(u))a="<"+(+f+1)+".0.0-0";else if(mr(c))a="<"+f+"."+(+u+1)+".0-0";else if(l)a="<="+f+"."+u+"."+c+"-"+l;else a="<="+a;return(r+" "+a).trim()}pr.prototype.test=function(e){if(!e)return false;for(var r=0;r<this.set.length;r++){if(xr(this.set[r],e))return true}return false};function xr(e,r){for(var t=0;t<e.length;t++){if(!e[t].test(r))return false}return true}e.satisfies=Rr;function Rr(e,r,t){try{r=new pr(r,t)}catch(n){return false}return r.test(e)}e.maxSatisfying=Sr;function Sr(e,r,t){return e.filter(function(e){return Rr(e,r,t)}).sort(function(e,r){return er(e,r,t)})[0]||null}e.validRange=kr;function kr(e,r){try{return new pr(e,r).range||"*"}catch(t){return null}}if(typeof define==="function"&&define.amd)define(e)}(typeof exports==="object"?exports:typeof define==="function"&&define.amd?{}:semver={});
\ No newline at end of file diff --git a/deps/npm/node_modules/semver/semver.min.js.gz b/deps/npm/node_modules/semver/semver.min.js.gz Binary files differindex ef9cc018479..d3742f6f350 100644 --- a/deps/npm/node_modules/semver/semver.min.js.gz +++ b/deps/npm/node_modules/semver/semver.min.js.gz diff --git a/deps/npm/node_modules/semver/test/index.js b/deps/npm/node_modules/semver/test/index.js index 51ad909ae32..5b488b2f847 100644 --- a/deps/npm/node_modules/semver/test/index.js +++ b/deps/npm/node_modules/semver/test/index.js @@ -207,7 +207,15 @@ test('\nrange tests', function(t) { ['>=1.2.1 >=1.2.3', '1.2.3'], ['<=1.2.3', '1.2.3-beta'], ['>1.2', '1.3.0-beta'], - ['>=1.2', '1.2.8'] + ['>=1.2', '1.2.8'], + ['^1.2.3', '1.8.1'], + ['^1.2.3', '1.2.3-beta'], + ['^0.1.2', '0.1.2'], + ['^0.1', '0.1.2'], + ['^1.2', '1.4.2'], + ['^1.2 ^1', '1.4.2'], + ['^1.2', '1.2.0-pre'], + ['^1.2.3', '1.2.3-pre'] ].forEach(function(v) { var range = v[0]; var ver = v[1]; @@ -268,9 +276,13 @@ test('\nnegative range tests', function(t) { ['<1.2.3', '1.2.3-beta'], ['=1.2.3', '1.2.3-beta'], ['>1.2', '1.2.8'], + ['^1.2.3', '2.0.0-alpha'], + ['^1.2.3', '1.2.2'], + ['^1.2', '1.1.9'], // invalid ranges never satisfied! ['blerg', '1.2.3'], - ['git+https://user:password0123@github.com/foo', '123.0.0', true] + ['git+https://user:password0123@github.com/foo', '123.0.0', true], + ['^1.2.3', '2.0.0-pre'] ].forEach(function(v) { var range = v[0]; var ver = v[1]; @@ -374,6 +386,16 @@ test('\nvalid range test', function(t) { ['~> 1', '>=1.0.0-0 <2.0.0-0'], ['~1.0', '>=1.0.0-0 <1.1.0-0'], ['~ 1.0', '>=1.0.0-0 <1.1.0-0'], + ['^0', '>=0.0.0-0 <1.0.0-0'], + ['^ 1', '>=1.0.0-0 <2.0.0-0'], + ['^0.1', '>=0.1.0-0 <0.2.0-0'], + ['^1.0', '>=1.0.0-0 <2.0.0-0'], + ['^1.2', '>=1.2.0-0 <2.0.0-0'], + ['^0.0.1', '=0.0.1'], + ['^0.0.1-beta', '=0.0.1-beta'], + ['^0.1.2', '>=0.1.2-0 <0.2.0-0'], + ['^1.2.3', '>=1.2.3-0 <2.0.0-0'], + ['^1.2.3-beta.4', '>=1.2.3-beta.4 <2.0.0-0'], ['<1', '<1.0.0-0'], ['< 1', '<1.0.0-0'], ['>=1', '>=1.0.0-0'], @@ -384,7 +406,8 @@ test('\nvalid range test', function(t) { ['>01.02.03', '>1.2.3', true], ['>01.02.03', null], ['~1.2.3beta', '>=1.2.3-beta <1.3.0-0', true], - ['~1.2.3beta', null] + ['~1.2.3beta', null], + ['^ 1.2 ^ 1', '>=1.2.0-0 <2.0.0-0 >=1.0.0-0 <2.0.0-0'] ].forEach(function(v) { var pre = v[0]; var wanted = v[1]; diff --git a/deps/npm/package.json b/deps/npm/package.json index 0c2802e1a83..ebda932aac5 100644 --- a/deps/npm/package.json +++ b/deps/npm/package.json @@ -1,5 +1,5 @@ { - "version": "1.3.6", + "version": "1.3.8", "name": "npm", "publishConfig": { "proprietary-attribs": false @@ -34,7 +34,7 @@ "main": "./lib/npm.js", "bin": "./bin/npm-cli.js", "dependencies": { - "semver": "~2.0.8", + "semver": "~2.1.0", "ini": "~1.1.0", "slide": "~1.1.4", "abbrev": "~1.0.4", @@ -42,7 +42,7 @@ "minimatch": "~0.2.12", "nopt": "~2.1.2", "rimraf": "~2.2.0", - "request": "~2.21.0", + "request": "~2.25.0", "which": "1", "tar": "~0.1.18", "fstream": "~0.1.23", @@ -50,18 +50,18 @@ "mkdirp": "~0.3.3", "read": "~1.0.4", "lru-cache": "~2.3.0", - "node-gyp": "~0.10.6", + "node-gyp": "~0.10.9", "fstream-npm": "~0.1.3", "uid-number": "0", "archy": "0", "chownr": "0", "npmlog": "0.0.4", "ansi": "~0.1.2", - "npm-registry-client": "~0.2.27", + "npm-registry-client": "~0.2.28", "read-package-json": "~1.1.0", "read-installed": "~0.2.2", - "glob": "~3.2.3", - "init-package-json": "0.0.10", + "glob": "~3.2.6", + "init-package-json": "0.0.11", "osenv": "0", "lockfile": "~0.4.0", "retry": "~0.6.0", @@ -73,7 +73,8 @@ "sha": "~1.2.1", "editor": "0.0.4", "child-process-close": "~0.1.1", - "npm-user-validate": "0.0.3" + "npm-user-validate": "0.0.3", + "github-url-from-git": "1.1.1" }, "bundleDependencies": [ "semver", @@ -117,11 +118,12 @@ "child-process-close", "editor", "npm-user-validate", - "normalize-package-data" + "github-url-from-git" ], "devDependencies": { "ronn": "~0.3.6", - "tap": "~0.4.0" + "tap": "~0.4.0", + "npm-registry-mock": "~0.2.0" }, "engines": { "node": ">=0.6", diff --git a/deps/npm/test/tap/ignore-shrinkwrap.js b/deps/npm/test/tap/ignore-shrinkwrap.js index b5b89a56cae..c76954694b5 100644 --- a/deps/npm/test/tap/ignore-shrinkwrap.js +++ b/deps/npm/test/tap/ignore-shrinkwrap.js @@ -1,61 +1,59 @@ var test = require("tap").test var npm = require("../../") var pkg = './ignore-shrinkwrap' -var http = require("http") +var mr = require("npm-registry-mock") -var server, child +var child var spawn = require("child_process").spawn var npm = require.resolve("../../bin/npm-cli.js") var node = process.execPath -test("ignore-shrinkwrap: using the option", function(t) { - t.plan(1) - server = http.createServer(function (req, res) { - res.setHeader("content-type", "application/javascript") - switch (req.url) { - case "/shrinkwrap.js": - t.fail() - break - case "/package.js": - t.pass("package.json used") +var customMocks = { + "get": { + "/package.js": [200, {"ente" : true}], + "/shrinkwrap.js": [200, {"ente" : true}] + } +} - } - t.end() - this.close() - child.kill() - res.statusCode = 500 - res.end('{"error":"Rocko Artischocko - oh oh oh oh!"}') - }) - server.listen(1337, function() { - child = createChild(true) +test("ignore-shrinkwrap: using the option", function(t) { + mr({port: 1337, mocks: customMocks}, function (s) { + s._server.on("request", function (req, res) { + switch (req.url) { + case "/shrinkwrap.js": + t.fail() + break + case "/package.js": + t.pass("package.json used") + } + }) + var child = createChild(true) + child.on("close", function (m) { + s.close() + t.end() + }) }) }) test("ignore-shrinkwrap: NOT using the option", function(t) { - t.plan(1) - server = http.createServer(function (req, res) { - res.setHeader("content-type", "application/javascript") - switch (req.url) { - case "/shrinkwrap.js": - t.pass("shrinkwrap used") - break - case "/package.js": - t.fail() - - } - t.end() - this.close() - child.kill() - res.statusCode = 500 - res.end('{"error":"Rocko Artischocko - oh oh oh oh!"}') - }) - server.listen(1337, function() { - child = createChild(false) + mr({port: 1337, mocks: customMocks}, function (s) { + s._server.on("request", function (req, res) { + switch (req.url) { + case "/shrinkwrap.js": + t.pass("shrinkwrap used") + break + case "/package.js": + t.fail() + } + }) + var child = createChild(false) + child.on("close", function (m) { + s.close() + t.end() + }) }) }) - function createChild (ignoreShrinkwrap) { var args if (ignoreShrinkwrap) { @@ -64,11 +62,10 @@ function createChild (ignoreShrinkwrap) { args = [npm, "install"] } - console.log(args) - return spawn(node, args, { cwd: pkg, env: { + npm_config_registry: "http://localhost:1337", npm_config_cache_lock_stale: 1000, npm_config_cache_lock_wait: 1000, HOME: process.env.HOME, diff --git a/deps/npm/test/tap/noargs-install-config-save.js b/deps/npm/test/tap/noargs-install-config-save.js index 840caf9f5c2..b7bf3a35f93 100644 --- a/deps/npm/test/tap/noargs-install-config-save.js +++ b/deps/npm/test/tap/noargs-install-config-save.js @@ -2,28 +2,29 @@ var test = require("tap").test var npm = require.resolve("../../bin/npm-cli.js") var osenv = require("osenv") var path = require("path") -var http = require("http") var fs = require("fs") var rimraf = require("rimraf") -var mkdirp = require('mkdirp') +var mkdirp = require("mkdirp") -var server, child +var mr = require("npm-registry-mock") + +var child var spawn = require("child_process").spawn var node = process.execPath -var pkg = process.env.npm_config_tmp || '/tmp' -pkg += path.sep + 'noargs-install-config-save' +var pkg = process.env.npm_config_tmp || "/tmp" +pkg += path.sep + "noargs-install-config-save" function writePackageJson() { rimraf.sync(pkg) mkdirp.sync(pkg) - fs.writeFileSync(pkg + '/package.json', JSON.stringify({ + fs.writeFileSync(pkg + "/package.json", JSON.stringify({ "author": "Rocko Artischocko", "name": "noargs", "version": "0.0.0", "devDependencies": { - "underscore": "1.3.0" + "underscore": "1.3.1" } }), 'utf8') } @@ -50,37 +51,29 @@ function createChild (args) { test("does not update the package.json with empty arguments", function (t) { writePackageJson() t.plan(1) - server = http.createServer(function (req, res) { - res.setHeader("content-type", "application/javascript") - res.statusCode = 200 - res.end(JSON.stringify(require("./fixtures/underscore-1-3-3.json"))) + + mr(1337, function (s) { + var child = createChild([npm, "install"]) child.on("close", function (m) { var text = JSON.stringify(fs.readFileSync(pkg + "/package.json", "utf8")) t.ok(text.indexOf('"dependencies') === -1) + s.close() t.end() }) - this.close() - }) - server.listen(1337, function() { - child = createChild([npm, "install"]) }) }) test("updates the package.json (adds dependencies) with an argument", function (t) { writePackageJson() t.plan(1) - server = http.createServer(function (req, res) { - res.setHeader("content-type", "application/javascript") - res.statusCode = 200 - res.end(JSON.stringify(require("./fixtures/underscore.json"))) + + mr(1337, function (s) { + var child = createChild([npm, "install", "underscore"]) child.on("close", function (m) { var text = JSON.stringify(fs.readFileSync(pkg + "/package.json", "utf8")) t.ok(text.indexOf('"dependencies') !== -1) + s.close() t.end() }) - this.close() - }) - server.listen(1337, function () { - child = createChild([npm, "install", "underscore"]) }) -}) +})
\ No newline at end of file |