diff --git a/.eslintrc b/.eslintrc
new file mode 100644
index 00000000..3e2f0333
--- /dev/null
+++ b/.eslintrc
@@ -0,0 +1,7 @@
+{
+ "parser": "babel-eslint",
+ "rules": {
+ "new-cap": [ 2, { "capIsNewExceptions": [ "XRegExp" ] } ]
+ },
+ "extends": "atom-build"
+}
diff --git a/.jscsrc b/.jscsrc
deleted file mode 100644
index fa65bfcd..00000000
--- a/.jscsrc
+++ /dev/null
@@ -1,33 +0,0 @@
-{
- "requireCurlyBraces": [ "if", "else", "for", "while", "do", "try", "catch" ],
- "requireSpaceAfterKeywords": [ "if", "else", "for", "while", "do", "switch", "return", "try", "catch" ],
- "requireParenthesesAroundIIFE": true,
- "requireSpacesInFunctionExpression": { "beforeOpeningCurlyBrace": true },
- "disallowEmptyBlocks": true,
- "requireSpacesInsideObjectBrackets": "all",
- "disallowSpaceAfterObjectKeys": true,
- "requireCommaBeforeLineBreak": true,
- "requireOperatorBeforeLineBreak": [ "?", "/", "*", "=", "==", "===", "!=", "!==", ">", ">=", "<", "<=" ],
- "requireSpacesInConditionalExpression": {
- "afterTest": true,
- "beforeConsequent": true,
- "afterConsequent": true,
- "beforeAlternate": true
- },
- "disallowSpaceAfterPrefixUnaryOperators": [ "++", "--", "+", "-", "~", "!" ],
- "disallowSpaceBeforePostfixUnaryOperators": [ "++", "--" ],
- "requireSpaceBeforeBinaryOperators": [ "+", "-", "/", "*", "=", "==", "===", "!=", "!==" ],
- "requireSpaceAfterBinaryOperators": [ "+", "-", "/", "*", "=", "==", "===", "!=", "!==" ],
- "disallowKeywords": [ "with", "eval" ],
- "disallowMultipleLineStrings": true,
- "disallowMultipleLineBreaks": true,
- "validateLineBreaks": "LF",
- "disallowMixedSpacesAndTabs": true,
- "disallowKeywordsOnNewLine": [ "else" ],
- "requireLineFeedAtFileEnd": true,
- "maximumLineLength": 180,
- "excludeFiles": [
- "node_modules/**",
- "spec/fixture/node_modules/**"
- ]
-}
diff --git a/.jshintrc b/.jshintrc
deleted file mode 100644
index 018d6b13..00000000
--- a/.jshintrc
+++ /dev/null
@@ -1,44 +0,0 @@
-{
- // Restricting options
- "strict": true, // https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Functions_and_function_scope/Strict_mode
- "trailing": true, // Makes it an error to leave a trailing whitespace in your code.
- "curly": true, // Force braces around blocks in loops and conditionals.
- "undef": true, // Prohibits the use of explicitly undeclared variables. Use /*global ... */ for exceptions
- "latedef": true, // Prohibits the use of a variable before it has been defined.
- "unused": "vars", // Warns when you define and never use your variables.
- "newcap": false, // Forces you to capitalize names of constructor functions.
- "noarg": true, // Prohibits the use of arguments.caller and arguments.callee, which are deprecated in EcmaScript 5.
- "quotmark": "single", // Force single quotes for strings
-
- // Relaxing options
- "expr": true, // Allow expressions where normally you would expect to see assignments or function calls.
- "onecase": true, // Allow switches with only one case (not counting default)
- "sub": true, // Allow using [] notation when it can also be expressed in dot notation: person['name'] vs. person.name.
-
- // Environment
- "node": true, // Define common browser globals: require, nodule, etc.
- "devel": true, // Define globals that are usually used for debugging: console, alert, etc.
- "globals": { // Define globals that are not defined per default
- "window": false,
- "document": false,
- "atom": false,
- "module": false,
- // Jasmine
- "jasmine": false,
- "before": false,
- "beforeEach": false,
- "after": false,
- "afterEach": false,
- "describe": false,
- "it": false,
- "waits": false,
- "waitsFor": false,
- "waitsForPromise": false,
- "runs": false,
- "expect": false
- },
-
- // Misc.
- "white": true, // Enforce Crockford style guides
- "indent": 2 // Set indentation to two spaces
-}
diff --git a/.travis.yml b/.travis.yml
index 16cc42c5..1a6fc1b7 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,5 +1,3 @@
-language: objective-c
-
notifications:
email:
on_success: never
@@ -12,10 +10,28 @@ notifications:
on_failure: always
on_start: false
+script: 'curl -s https://raw.githubusercontent.com/atom/ci/master/build-package.sh | sh'
+
+git:
+ depth: 10
+
+sudo: false
+
+os:
+ - osx
+
+env:
+ global:
+ - APM_TEST_PACKAGES=""
-before_script:
- - npm install
- - npm test
+ matrix:
+ - ATOM_CHANNEL=stable
+ - ATOM_CHANNEL=beta
-script:
- - 'curl -s https://raw.githubusercontent.com/atom/ci/master/build-package.sh | sh'
+addons:
+ apt:
+ packages:
+ - build-essential
+ - git
+ - libgnome-keyring-dev
+ - fakeroot
diff --git a/README.md b/README.md
index 68df12c1..70414716 100644
--- a/README.md
+++ b/README.md
@@ -1,72 +1,231 @@
# Atom Build package
-[](https://travis-ci.org/noseglid/atom-build)
-[](https://gitter.im/noseglid/atom-build)
+
+[Release notes](https://github.com/noseglid/atom-build/releases)
+
+[](https://atom.io/packages/build)
+[](https://atom.io/packages/build)
+
+[](https://travis-ci.org/noseglid/atom-build)
+[](https://ci.appveyor.com/project/noseglid/atom-build)
+
+[](https://gitter.im/noseglid/atom-build)
+[](http://atom-slack.herokuapp.com/)
+
Automatically build your project inside your new favorite editor, Atom.
- * `cmd-alt-b` / `ctrl-alt-b` builds your project.
- * `cmd-alt-g` / `ctrl-alt-g` cycles through causes of build error. See [Error Matching](#error-match).
- * `cmd-alt-h` / `ctrl-alt-h` goes to the first build error. See [Error Matching](#error-match).
- * `cmd-alt-v` / `ctrl-alt-v` Toggles the build panel.
- * `escape` terminates build / closes the build window.
-
-
-
-Supported build tools:
-
- 1. Custom by [specifying your own build command](#custom-build-command)
- 1. [NodeJS](http://nodejs.org) (runs `npm install`) - if `package.json` exists where `engines['node']` is set
- 1. [Atom](http://atom.io) (runs `apm install`) - if `package.json` exists where `engines['atom']` is set
- 1. [Grunt](http://gruntjs.com/) - if `Gruntfile.js` exists
- 1. [Gulp](http://gulpjs.com/) - if `gulpfile.js` exists
- 1. [GNU Make](https://www.gnu.org/software/make/) - if `Makefile` exists
- 1. [Elixir](http://elixir-lang.org/) - if `mix.exs` exists
- 1. [Cargo](http://doc.crates.io) - if `Cargo.toml` exists
- * Supports error matching.
-
-If multiple viable build options are found, `atom-build` will
-prioritise according to the list above. For instance, if `package.json` and
-`Gruntfile.js` are both available in the root folder, `npm install` will be
-executed by `atom-build`.
-
-If you need to run `grunt`, `gulp` or other tool to build your project, then you can utilize the [postinstall-script](https://www.npmjs.org/doc/misc/npm-scripts.html) of package.json. This will also help you if grunt is run as a node module since it
-will be downloaded (via `npm install`) prior.
-
-
-## Specifying a custom build command
-
-If the built-in defaults are not enough to suit your needs, you can specify
-exactly what to execute. Create a file named `.atom-build.json` in your project root:
-
- {
- "cmd": "",
- "args": [ "", "", ... ],
- "sh": true,
- "cwd": "",
- "env": {
- "VARIABLE1": "VALUE1",
- "VARIABLE2": "VALUE2",
- ...
- },
- "errorMatch": "^regexp$"
- }
-
-Note that if `sh` is false `cmd` must only be the executable - no arguments here. If the
+ * Cmd Alt B / Ctrl Alt B / F9 builds your project.
+ * Cmd Alt G / Ctrl Alt G / F4 cycles through causes of build error. See [Error Matching](#error-match).
+ * Cmd Alt G / Ctrl Alt H / Shift F4 goes to the first build error. See [Error Matching](#error-match).
+ * Cmd Alt V / Ctrl Alt V / F8 Toggles the build panel.
+ * Cmd Alt T / Ctrl Alt T / F7 Displays the available build targets.
+ * Esc terminates build / closes the build window.
+
+#### Builds your project - configure it your way
+
+
+#### Automatically extract targets - here with [build-make](https://github.com/AtomBuild/atom-build-make).
+
+
+#### Match errors and go directly to offending code - with [Atom Linter](https://atom.io/packages/linter).
+
+
+(You can also use keyboard shortcuts to go to errors if you don't like Atom Linter, or want to keep package dependencies to a minimum).
+
+### Quick start
+
+Install the build package using apm (apm can be installed using the install shell commands tool in Atom)(Linux/Mac):
+```bash
+$ apm install build
+```
+
+Create a file called `.atom-build.yml` (note the inital dot):
+```yml
+cmd: echo Hello world
+```
+
+Save it, and press Cmd Alt B (OS X) / Ctrl Alt B (Linux/Windows)
+and you should see the output of `echo Hello world`, which should be `Hello world` if all is correct.
+
+## Build providers
+
+Instead of specifying commands manually, you can use a build provider. They often include functionality such as parsing
+targets (for instance all tasks from `gulpfile.js` or `Makefile`).
+
+**[Full list of build providers](https://atombuild.github.io)**
+
+
+### Specify a custom build command
+
+If no build provider is enough to suit your needs, you can configure the custom build command extensively.
+
+Supported formats and the name of the configuration file is
+
+ * JSON: `.atom-build.json`
+ * CSON: `.atom-build.cson`
+ * YAML: `.atom-build.yaml` or `.atom-build.yml`
+ * JS: `.atom-build.js`
+
+Pick your favorite format, save that file in your project root, and specify exactly
+how your project is built (example in `yml`)
+
+```yml
+cmd: ""
+name: ""
+args:
+ -
+ -
+sh: true,
+cwd:
+env:
+ VARIABLE1: "VALUE1"
+ VARIABLE2: "VALUE2"
+errorMatch:
+ - ^regexp1$
+ - ^regexp2$
+warningMatch:
+ - ^regexp1$
+ - ^regexp2$
+keymap:
+atomCommandName: namespace:command
+targets:
+ extraTargetName:
+ cmd: ""
+ args:
+ # (any previous options are viable here except `targets` itself)
+```
+
+Note that if `sh` is false `cmd` must only be the executable - no arguments here. If the
executable is not in your path, either fully qualify it or specify the path
in you environment (e.g. by setting the `PATH` var appropriately on UNIX-like
systems).
+If `sh` is true, it will use a shell (e.g. `/bin/sh -c`) on unix/linux, and command (`cmd /S /C`)
+on windows.
+
+#### Programmatic Build commands (Javascript)
+
+Using a JavaScript (JS) file gives you the additional benefit of being able to specify `preBuild` and `postBuild` and being able to run arbitrary match functions instead of regex-matching. The
+javascript function needs to return an array of matches. The fields of the matches must be the same
+as those that the regex can set.
+
+Keep in mind that the JavaScript file must `export` the configuration
+
+```javascript
+module.exports = {
+ cmd: "myCommand",
+ preBuild: function () {
+ console.log('This is run **before** the build command');
+ },
+ postBuild: function () {
+ console.log('This is run **after** the build command');
+ },
+ functionMatch: function (terminal_output) {
+ // this is the array of matches that we create
+ var matches = [];
+ terminal_output.split(/\n/).forEach(function (line, line_number, terminal_output) {
+ // all lines starting with a slash
+ if line[0] == '/' {
+ this.push({
+ file: 'x.txt',
+ line: line_number.toString(),
+ message: line
+ });
+ }
+ }.bind(matches));
+ return matches;
+ }
+};
+```
+
+A major advantage of the `functionMatch` method is that you can keep state while
+parsing the output. For example, if you have a `Makefile` output like this:
+
+```terminal
+make[1]: Entering directory 'foo'
+make[2]: Entering directory 'foo/src'
+testmake.c: In function 'main':
+testmake.c:3:5: error: unknown type name 'error'
+```
+
+then you can't use a regex to match the filename, because the regex doesn't have
+the information about the directory changes. The following `functionMatch` can
+handle this case. Explanations are in the comments:
+
+```js
+module.exports = {
+ cmd: 'make',
+ name: 'Makefile',
+ sh: true,
+ functionMatch: function (output) {
+ const enterDir = /^make\[\d+\]: Entering directory '([^']+)'$/;
+ const error = /^([^:]+):(\d+):(\d+): error: (.+)$/;
+ // this is the list of error matches that atom-build will process
+ const array = [];
+ // stores the current directory
+ var dir = null;
+ // iterate over the output by lines
+ output.split(/\r?\n/).forEach(line => {
+ // update the current directory on lines with `Entering directory`
+ const dir_match = enterDir.exec(line);
+ if (dir_match) {
+ dir = dir_match[1];
+ } else {
+ // process possible error messages
+ const error_match = error.exec(line);
+ if (error_match) {
+ // map the regex match to the error object that atom-build expects
+ array.push({
+ file: dir ? dir + '/' + error_match[1] : error_match[1],
+ line: error_match[2],
+ col: error_match[3],
+ message: error_match[4]
+ });
+ }
+ }
+ });
+ return array;
+ }
+};
+```
+
+Another feature of `functionMatch` is that you can attach informational messages
+to the error messages:
+
+
+
+You can add these additional messages by setting the trace field of the error
+object. It needs to be an array of objects with the same fields as the error.
+Instead of adding squiggly lines at the location given by the `file`, `line` and
+`col` fields, a link is added to the popup message, so you can conveniently jump
+to the location given in the trace.
+
+One more feature provided by `functionMatch` is the ability to use HTML in
+the message text by setting `html_message` instead of `message`. If both
+`html_message` and `message` are set, the latter takes priority.
+
-### Configuration options
+#### Configuration options
- * `cmd` - **[required]** The executable command
- * `args` - **[optional]** An array of arguments for the command
- * `sh` - **[optional]** If `true`, the combined command and arguments will be passed to `/bin/sh`. Default `true`.
- * `cwd` - **[optional]** The working directory for the command. E.g. what `.` resolves to.
- * `env` - **[optional]** An array of environment variables and their values to set
- * `errorMatch` - **[optional]** A regular expression to match output to a file, row and col. See [Error matching](#error-match) for details.
+Option | Required | Description
+------------------|----------------|-----------------------
+`cmd` | **[required]** | The executable command
+`name` | *[optional]* | The name of the target. Viewed in the targets list (toggled by `build:select-active-target`).
+`args` | *[optional]* | An array of arguments for the command
+`sh` | *[optional]* | If `true`, the combined command and arguments will be passed to `/bin/sh`. Default `true`.
+`cwd` | *[optional]* | The working directory for the command. E.g. what `.` resolves to.
+`env` | *[optional]* | An object of environment variables and their values to set
+`errorMatch` | *[optional]* | A (list of) regular expressions to match output to a file, row and col. See [Error matching](#error-match) for details.
+`warningMatch` | *[optional]* | Like `errorMatch`, but is reported as just a warning
+`functionMatch` | *[optional]* | A (list of) javascript functions that return a list of match objects
+`keymap` | *[optional]* | A keymap string as defined by [`Atom`](https://atom.io/docs/latest/behind-atom-keymaps-in-depth). Pressing this key combination will trigger the target. Examples: `ctrl-alt-k` or `cmd-U`.
+`killSignals` | *[optional]* | An array of signals. The signals will be sent, one after each time `Escape` is pressed until the process has been terminated. The default value is `SIGINT` -> `SIGTERM` -> `SIGKILL`. The only signal which is guaranteed to terminate the process is `SIGKILL` so it is recommended to include that in the list.
+`atomCommandName` | *[optional]* | Command name to register which should be on the form of `namespace:command`. Read more about [Atom CommandRegistry](https://atom.io/docs/api/v1.4.1/CommandRegistry). The command will be available in the command palette and can be trigger from there. If this is returned by a build provider, the command can programatically be triggered by [dispatching](https://atom.io/docs/api/v1.4.1/CommandRegistry#instance-dispatch).
+`targets` | *[optional]* | Additional targets which can be used to build variations of your project.
+`preBuild` | *[optional]* | **JS only**. A function which will be called *before* executing `cmd`. No arguments. `this` will be the build configuration.
+`postBuild` | *[optional]* | **JS only**. A function which will be called *after* executing `cmd`. It will be passed 3 arguments: `bool buildOutcome` indicating outcome of the running `cmd`, `string stdout` containing the contents of `stdout`, and `string stderr` containing the contents of `stderr`. `this` will be the build configuration.
-### Replacements
+#### Replacements
The following parameters will be replaced in `cmd`, any entry in `args`, `cwd` and
values of `env`. They should all be enclosed in curly brackets `{}`
@@ -75,45 +234,79 @@ values of `env`. They should all be enclosed in curly brackets `{}`
* `{FILE_ACTIVE_PATH}` - Full path to the folder where the currently active file is. E.g. `/home/noseglid/github/atom-build/lib`
* `{FILE_ACTIVE_NAME}` - Full name and extension of active file. E.g., `build.js`
* `{FILE_ACTIVE_NAME_BASE}` - Name of active file WITHOUT extension. E.g., `build`
+ * `{FILE_ACTIVE_CURSOR_ROW}` - Line number where the last inserted cursor sits. E.g, `21`
+ * `{FILE_ACTIVE_CURSOR_COLUMN}` - Column number where the last inserted cursor sits. E.g, `42`
* `{PROJECT_PATH}` - Full path to the root of the project. This is normally the path Atom has as root. E.g `/home/noseglid/github/atom-build`
- * `{REPO_BRANCH_SHORT}` - Short name of the current active branch (if project is backed by git). E.g `master` or `v0.9.1`.
+ * `{REPO_BRANCH_SHORT}` - Short name of the current active branch (if project is backed by git). E.g `master` or `v0.9.1`
+ * `{SELECTION}` - Selected text.
+
+### Creating a build provider
+Creating a build provider require very little code in the easiest case, and can
+be as complicated as necessary to achieve the correct functionality.
+Read more about building your own provider in [the create provider documentation](create-provider.md).
## Error matching
-Error matching let's you specify a regular expression which captures
-the output of your build command and opens the correct file, row and column of
-the error. For instance:
+Error matching lets you specify a single regular expression or a list of
+regular expressions, which capture the output of your build command and open the
+correct file, row and column of the error. For instance:
```bash
-a.c:4:26: error: expected ';' after expression
+../foo/bar/a.c:4:26: error: expected ';' after expression
printf("hello world\n")
^
;
1 error generated.
```
-Would be matched with the regular expression: `^(?[^\\.]+.c):(?\\d+):(?\\d+)`.
-After the build has failed, pressing `cmd-alt-g` (OS X) or `ctrl-alt-g` (Linux/Windows), `a.c` would be
-opened and the cursor would be placed at row 4, column 26.
+Would be matched with the regular expression: `(?[\\/0-9a-zA-Z\\._]+):(?\\d+):(?\\d+):\\s+(?.+)`.
+After the build has failed, pressing Cmd Alt G (OS X) or Ctrl Alt G (Linux/Windows)
+(or F4 on either platform), `a.c` would be opened and the cursor would be placed at row 4, column 26.
Note the syntax for match groups. This is from the [XRegExp](http://xregexp.com/) package
and has the syntax for named groups: `(? RE )` where `name` would be the name of the group
matched by the regular expression `RE`.
The following named groups can be matched from the output:
- * `file` - **[required]** the file to open. `(? RE)`.
- * `line` - **[optional]** the line the error resides on. `(? RE)`.
- * `col` - **[optional]** the column the error resides on. `(? RE)`.
-
-Since the regular expression is written in a JSON file, backslashes must be escaped.
+ * `file` - **[required]** the file to open. May be relative `cwd` or absolute. `(? RE)`.
+ * `line` - *[optional]* the line the error starts on. `(? RE)`.
+ * `col` - *[optional]* the column the error starts on. `(? RE)`.
+ * `line_end` - *[optional]* the line the error ends on. `(? RE)`.
+ * `col_end` - *[optional]* the column the error ends on. `(? RE)`.
+ * `message` - *[optional]* Catch the humanized error message. `(? RE)`.
The `file` should be relative the `cwd` specified. If no `cwd` has been specified, then
the `file` should be relative the project root (e.g. the top most directory shown in the
Atom Editor).
-If your build outputs multiple errors, all will be matched. Press `cmd-alt-g` (OS X) or `ctrl-alt-g` (Linux/Windows)
-to cycle through the errors (in the order they appear, first on stderr then on stdout).
+If your build outputs multiple errors, all will be matched. Press Cmd Alt G (OS X) or Ctrl Alt G (Linux/Windows)
+to cycle through the errors (in the order they appear, first on stderr then on stdout), or you can use the
+Atom Linter integration discussed in the next section.
Often, the first error is the most interesting since other errors tend to be secondary faults caused by that first one.
-To jump to the first error you can use `cmd-alt-h` (OS X) or `ctrl-alt-h` (Linux/Windows) at any point to go to the first error.
+To jump to the first error you can use Cmd Alt H (OS X) or Shift F4 (Linux/Windows) at any point to go to the first error.
+
+### Error matching and Atom Linter
+
+Install [Atom Linter](https://atom.io/packages/linter) and all your matched errors will listed in a neat panel.
+
+
+
+## Analytics
+
+The `atom-build` package uses google analytics to keep track of which features are in use
+and at what frequency. This gives the maintainers a sense of what parts of the
+package is most important and what parts can be removed.
+
+The data is fully anonymous and can not be tracked back to you in any way.
+This is what is collected
+
+ * Version of package used.
+ * Build triggered, succeeded or failed.
+ * Which build tool was used.
+ * Visibility of UI components.
+
+If you really do not want to share this information, you can opt out by disabling
+the [metrics package](https://atom.io/packages/metrics). This will disable all analytics
+collection, including the one from `atom-build`.
diff --git a/appveyor.yml b/appveyor.yml
new file mode 100644
index 00000000..518c683b
--- /dev/null
+++ b/appveyor.yml
@@ -0,0 +1,25 @@
+version: "{build}"
+
+platform: x64
+
+branches:
+ only:
+ - master
+
+skip_tags: true
+
+environment:
+ APM_TEST_PACKAGES:
+
+ matrix:
+ - ATOM_CHANNEL: stable
+ - ATOM_CHANNEL: beta
+
+install:
+ - ps: Install-Product node 5
+
+build_script:
+ - ps: iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/atom/ci/master/build-package.ps1'))
+
+test: off
+deploy: off
diff --git a/create-provider.md b/create-provider.md
new file mode 100644
index 00000000..c8d6ecad
--- /dev/null
+++ b/create-provider.md
@@ -0,0 +1,141 @@
+# Creating a build provider
+
+## Service API
+
+Another package may provide build information to the `build`-package by implementing its service API.
+The package should integrate via the service API. This is typically done in `package.json`:
+
+```javascript
+{
+ "providedServices": {
+ "builder": {
+ "description": "Description of the build configurations this package gives",
+ "versions": {
+ "2.0.0": "providingFunction"
+ }
+ }
+ }
+},
+```
+
+The `build`-package will then call `providingFunction` when activated and expects an
+ES6 class or an array of classes in return. The next section describes in detail how that class is
+expected to operate.
+
+## The provider implementation
+```javascript
+class MyBuildProvider {
+
+ constructor(cwd) {
+ // OPTIONAL: setup here
+ // cwd is the project root this provider will operate in, so store `cwd` in `this`.
+ }
+
+ destructor() {
+ // OPTIONAL: tear down here.
+ // destructor is not part of ES6. This is called by `build` like any
+ // other method before deactivating.
+ return 'void';
+ }
+
+ getNiceName() {
+ // REQUIRED: return a nice readable name of this provider.
+ return 'string';
+ }
+
+ isEligible() {
+ // REQUIRED: Perform operations to determine if this build provider can
+ // build the project in `cwd` (which was specified in `constructor`).
+ return 'boolean';
+ }
+
+ settings() {
+ // REQUIRED: Return an array of objects which each define a build description.
+ return 'array of objects'; // [ { ... }, { ... }, ]
+ }
+
+ on(event, cb) {
+ // OPTIONAL: The build provider can let `build` know when it is time to
+ // refresh targets.
+ return 'void';
+ }
+
+ removeAllListeners(event) {
+ // OPTIONAL: (required if `on` is defined) removes all listeners registered in `on`
+ return 'void';
+ }
+}
+```
+
+`constructor` _[optional]_ - is used in ES6 classes to initialize the class. The path
+where this instance of the build provider will operate is provided.
+Please note that the build provider will be instanced once per project folder.
+
+---
+
+`destructor` _[optional]_ - will be called before `build` is deactivated and gives you a chance
+to release any resources claimed.
+
+---
+
+`getNiceName` - aesthetic only and should be a `string` which is a human readable
+description of the build configuration is provided.
+
+---
+
+`isEligible` - should be a function which must return synchronously.
+It should return `true` or `false` indicating if it can build the folder specified
+in the constructor into something sensible. Typically look for the existence of a
+build file such as `gulpfile.js` or `Makefile`.
+
+---
+
+`settings` - can return a Promise or an array of objects.
+It can provide anything which is allowed by the [custom build configuration](README.md#custom-build-config).
+This includes the command, `cmd`, to execute, any arguments, `args`, and so on.
+
+---
+
+`on` _[optional]_ - will be called with a string which is the name of an event the build tool provider can emit. The build
+tool provider should call the `callback` when the specified event occurs.
+The easiest way to use this is to extends [NodeJS's event emitter](https://nodejs.org/api/events.html#events_class_events_eventemitter) and simply issue `this.emit(event)`.
+Events `build` may ask for include:
+ * `refresh` - call the callback if you want `build` to refresh all targets.
+ this is common after the build file has been altered.
+
+Note: If you extend `EventEmitter` you don't need to implement this method.
+
+---
+
+`removeAllListeners` _[optional]_ - will be called when `build` is no longer interested in that event. It may be because
+`build` is being deactivated, or refreshing its state. `build` will never call `removeAllListeners` for an event unless it has
+previously registered a listener via `on` first.
+
+Note: If you extend `EventEmitter` you don't need to implement this method.
+
+## Operations
+
+Before `settings` is called, the build provider will always be given a chance to
+let `build` know if it can do anything with the project folder by returning `true` or `false`
+from the `isEligible` method. Checks for eligibility should always be performed here as
+the content of the project folder may have changed between two calls.
+
+`build` will refresh targets for a variety of events:
+ * Atom is started, `build` will instance one build provider for every project root
+ folder in Atom and ask for build targets.
+ * A project root folder is added, `build` will instance a new build provider for this
+ folder and ask for build targets.
+ * Any build provider emits the `refresh`, in which case all providers in that folder
+ will be asked for targets.
+ * The user (or any other package) issues `build:refresh-targets` (e.g. via the command palette).
+
+## Publication
+
+If you want to share your provider (please do, if you needed it, chances are others will as well)
+go to the [AtomBuild project for the homepage](https://github.com/AtomBuild/atombuild.github.io)
+and follow the instructions there. Your tool will then be visisble on [https://atombuild.github.io](https://atombuild.github.io). This is also a great source to look
+for existing build providers
+
+---
+
+Happy coding!
diff --git a/keymaps/build.json b/keymaps/build.json
index 45d38e4d..5a3e6fc5 100644
--- a/keymaps/build.json
+++ b/keymaps/build.json
@@ -1,15 +1,24 @@
{
- ".platform-darwin": {
+ ".platform-darwin atom-workspace, .platform-darwin atom-text-editor": {
"cmd-alt-b": "build:trigger",
"cmd-alt-v": "build:toggle-panel",
"cmd-alt-g": "build:error-match",
- "cmd-alt-h": "build:error-match-first"
+ "cmd-alt-h": "build:error-match-first",
+ "cmd-alt-t": "build:select-active-target"
},
- ".platform-linux, .platform-win32": {
+ ".platform-linux atom-workspace, .platform-linux atom-text-editor, .platform-win32 atom-workspace, .platform-win32 atom-text-editor": {
"ctrl-alt-b": "build:trigger",
"ctrl-alt-v": "build:toggle-panel",
"ctrl-alt-g": "build:error-match",
- "ctrl-alt-h": "build:error-match-first"
+ "ctrl-alt-h": "build:error-match-first",
+ "ctrl-alt-t": "build:select-active-target"
+ },
+ "atom-workspace, atom-text-editor": {
+ "f9": "build:trigger",
+ "f8": "build:toggle-panel",
+ "f4": "build:error-match",
+ "shift-f4": "build:error-match-first",
+ "f7": "build:select-active-target"
},
".build": {
"escape": "build:stop"
diff --git a/lib/atom-build.js b/lib/atom-build.js
new file mode 100644
index 00000000..ec70bf41
--- /dev/null
+++ b/lib/atom-build.js
@@ -0,0 +1,97 @@
+'use babel';
+
+import EventEmitter from 'events';
+
+function getConfig(file) {
+ const fs = require('fs');
+ const realFile = fs.realpathSync(file);
+ delete require.cache[realFile];
+ switch (require('path').extname(file)) {
+ case '.json':
+ case '.js':
+ return require(realFile);
+
+ case '.cson':
+ return require('cson-parser').parse(fs.readFileSync(realFile));
+
+ case '.yaml':
+ case '.yml':
+ return require('js-yaml').safeLoad(fs.readFileSync(realFile));
+ }
+
+ return {};
+}
+
+function createBuildConfig(build, name) {
+ const conf = {
+ name: 'Custom: ' + name,
+ exec: build.cmd,
+ env: build.env,
+ args: build.args,
+ cwd: build.cwd,
+ sh: build.sh,
+ errorMatch: build.errorMatch,
+ functionMatch: build.functionMatch,
+ warningMatch: build.warningMatch,
+ atomCommandName: build.atomCommandName,
+ keymap: build.keymap,
+ killSignals: build.killSignals
+ };
+
+ if (typeof build.postBuild === 'function') {
+ conf.postBuild = build.postBuild;
+ }
+
+ if (typeof build.preBuild === 'function') {
+ conf.preBuild = build.preBuild;
+ }
+
+ return conf;
+}
+
+export default class CustomFile extends EventEmitter {
+ constructor(cwd) {
+ super();
+ this.cwd = cwd;
+ this.fileWatchers = [];
+ }
+
+ destructor() {
+ this.fileWatchers.forEach(fw => fw.close());
+ }
+
+ getNiceName() {
+ return 'Custom file';
+ }
+
+ isEligible() {
+ const os = require('os');
+ const fs = require('fs');
+ const path = require('path');
+ this.files = [].concat.apply([], [ 'json', 'cson', 'yaml', 'yml', 'js' ].map(ext => [
+ path.join(this.cwd, `.atom-build.${ext}`),
+ path.join(os.homedir(), `.atom-build.${ext}`)
+ ])).filter(fs.existsSync);
+ return 0 < this.files.length;
+ }
+
+ settings() {
+ const fs = require('fs');
+ this.fileWatchers.forEach(fw => fw.close());
+ // On Linux, closing a watcher triggers a new callback, which causes an infinite loop
+ // fallback to `watchFile` here which polls instead.
+ this.fileWatchers = this.files.map(file =>
+ (require('os').platform() === 'linux' ? fs.watchFile : fs.watch)(file, () => this.emit('refresh'))
+ );
+
+ const config = [];
+ this.files.map(getConfig).forEach(build => {
+ config.push(
+ createBuildConfig(build, build.name || 'default'),
+ ...Object.keys(build.targets || {}).map(name => createBuildConfig(build.targets[name], name))
+ );
+ });
+
+ return config;
+ }
+}
diff --git a/lib/build-error.js b/lib/build-error.js
new file mode 100644
index 00000000..80b403c3
--- /dev/null
+++ b/lib/build-error.js
@@ -0,0 +1,10 @@
+'use babel';
+
+export default class BuildError extends Error {
+ constructor(name, message) {
+ super(message);
+ this.name = name;
+ this.message = message;
+ Error.captureStackTrace(this, BuildError);
+ }
+}
diff --git a/lib/build-view.js b/lib/build-view.js
index 95b77bbd..09498f8c 100644
--- a/lib/build-view.js
+++ b/lib/build-view.js
@@ -1,189 +1,361 @@
-'use strict';
-
-var _ = require('lodash');
-var View = require('atom-space-pen-views').View;
-var cscompatability = require('./cscompatability');
-var Convert = require('ansi-to-html');
-
-module.exports = (function() {
- function BuildView() {
- View.apply(this, arguments);
- this.titleLoop = [
- 'Building',
- 'Building.',
- 'Building..',
- 'Building...'
- ];
- this.titleLoopIndex = 0;
- this.a2h = new Convert();
- this.monocle = false;
- this.attach();
+'use babel';
+
+import { View, $ } from 'atom-space-pen-views';
- atom.config.observe('build.panelVisibility', this.visibleFromConfig.bind(this));
- atom.config.observe('build.monocleHeight', this.heightFromConfig.bind(this));
- atom.config.observe('build.minimizedHeight', this.heightFromConfig.bind(this));
+export default class BuildView extends View {
- atom.commands.add('atom-workspace', 'build:toggle-panel', this.toggle.bind(this));
+ static initialTimerText() {
+ return '0.0 s';
}
- cscompatability.extends(BuildView, View);
+ static initialHeadingText() {
+ return 'Atom Build';
+ }
- BuildView.content = function() {
- BuildView.div({ tabIndex: -1, class: 'build tool-panel panel-bottom native-key-bindings' }, function() {
- BuildView.div({ class: 'btn-container pull-right' }, function() {
- BuildView.button({ class: 'btn btn-default icon icon-x', outlet: 'closeButton', click: 'close' });
- BuildView.button({ class: 'btn btn-default icon icon-chevron-up', outlet: 'monocleButton', click: 'toggleMonocle' });
- BuildView.button({ class: 'btn btn-default icon icon-trashcan new-row', outlet: 'clearButton', click: 'clear' });
- BuildView.button({ class: 'btn btn-default icon icon-zap', outlet: 'triggerButton', click: 'build', title: 'Build current project' });
+ static content() {
+ this.div({ tabIndex: -1, class: 'build tool-panel native-key-bindings' }, () => {
+ this.div({ class: 'heading', outlet: 'panelHeading' }, () => {
+ this.div({ class: 'control-container opaque-hover' }, () => {
+ this.button({ class: 'btn btn-default icon icon-zap', click: 'build', title: 'Build current project' });
+ this.button({ class: 'btn btn-default icon icon-trashcan', click: 'clearOutput' });
+ this.button({ class: 'btn btn-default icon icon-x', click: 'close' });
+ this.div({ class: 'title', outlet: 'title' }, () => {
+ this.span({ class: 'build-timer', outlet: 'buildTimer' }, this.initialTimerText());
+ });
+ });
+ this.div({ class: 'icon heading-text', outlet: 'heading' }, this.initialHeadingText());
});
- BuildView.div(function() {
- BuildView.ol({ class: 'output panel-body', outlet: 'output' });
- });
+ this.div({ class: 'output panel-body', outlet: 'output' });
+ this.div({ class: 'resizer', outlet: 'resizer' });
+ });
+ }
- BuildView.div(function() {
- BuildView.h1({ class: 'title panel-heading', outlet: 'title' }, 'Ready');
- });
+ constructor(...args) {
+ super(...args);
+ const Terminal = require('term.js');
+ this.starttime = new Date();
+ this.terminal = new Terminal({
+ cursorBlink: false,
+ convertEol: true,
+ useFocus: false,
+ termName: 'xterm-256color',
+ scrollback: atom.config.get('build.terminalScrollback')
+ });
+
+ // On some systems, prependListern and prependOnceListener is expected to exist. Add them until terminal replacement is here.
+ this.terminal.prependListener = (...a) => {
+ this.terminal.addListener(...a);
+ };
+ this.terminal.prependOnceListener = (...a) => {
+ this.terminal.addOnceListener(...a);
+ };
+
+ this.terminal.getContent = function () {
+ return this.lines.reduce((m1, line) => {
+ return m1 + line.reduce((m2, col) => m2 + col[1], '') + '\n';
+ }, '');
+ };
+
+ this.fontGeometry = { w: 15, h: 15 };
+ this.terminal.open(this.output[0]);
+ this.destroyTerminal = ::(this.terminal).destroy;
+ this.terminal.destroy = this.terminal.destroySoon = () => {}; // This terminal will be open forever and reset when necessary
+ this.terminalEl = $(this.terminal.element);
+ this.terminalEl[0].terminal = this.terminal; // For testing purposes
+
+ this.resizeStarted = ::this.resizeStarted;
+ this.resizeMoved = ::this.resizeMoved;
+ this.resizeEnded = ::this.resizeEnded;
+
+ atom.config.observe('build.panelVisibility', ::this.visibleFromConfig);
+ atom.config.observe('build.panelOrientation', ::this.orientationFromConfig);
+ atom.config.observe('build.hidePanelHeading', (hide) => {
+ hide && this.panelHeading.hide() || this.panelHeading.show();
});
- };
+ atom.config.observe('build.overrideThemeColors', (override) => {
+ this.output.removeClass('override-theme');
+ override && this.output.addClass('override-theme');
+ });
+ atom.config.observe('editor.fontSize', ::this.fontSizeFromConfig);
+ atom.config.observe('editor.fontFamily', ::this.fontFamilyFromConfig);
+ atom.commands.add('atom-workspace', 'build:toggle-panel', ::this.toggle);
+ }
+
+ destroy() {
+ this.destroyTerminal();
+ clearInterval(this.detectResizeInterval);
+ }
+
+ resizeStarted() {
+ document.body.style['-webkit-user-select'] = 'none';
+ document.addEventListener('mousemove', this.resizeMoved);
+ document.addEventListener('mouseup', this.resizeEnded);
+ }
+
+ resizeMoved(ev) {
+ const { h } = this.fontGeometry;
+
+ switch (atom.config.get('build.panelOrientation')) {
+ case 'Bottom': {
+ const delta = this.resizer.get(0).getBoundingClientRect().top - ev.y;
+ if (Math.abs(delta) < (h * 5 / 6)) return;
+
+ const nearestRowHeight = Math.round((this.terminalEl.height() + delta) / h) * h;
+ const maxHeight = $('.item-views').height() + $('.build .output').height();
+ this.terminalEl.css('height', `${Math.min(maxHeight, nearestRowHeight)}px`);
+ break;
+ }
+
+ case 'Top': {
+ const delta = this.resizer.get(0).getBoundingClientRect().top - ev.y;
+ if (Math.abs(delta) < (h * 5 / 6)) return;
+
+ const nearestRowHeight = Math.round((this.terminalEl.height() - delta) / h) * h;
+ const maxHeight = $('.item-views').height() + $('.build .output').height();
+ this.terminalEl.css('height', `${Math.min(maxHeight, nearestRowHeight)}px`);
+ break;
+ }
+
+ case 'Left': {
+ const delta = this.resizer.get(0).getBoundingClientRect().right - ev.x;
+ this.css('width', `${this.width() - delta - this.resizer.outerWidth()}px`);
+ break;
+ }
+
+ case 'Right': {
+ const delta = this.resizer.get(0).getBoundingClientRect().left - ev.x;
+ this.css('width', `${this.width() + delta}px`);
+ break;
+ }
+ }
+
+ this.resizeTerminal();
+ }
+
+ resizeEnded() {
+ document.body.style['-webkit-user-select'] = 'text';
+ document.removeEventListener('mousemove', this.resizeMoved);
+ document.removeEventListener('mouseup', this.resizeEnded);
+ }
+
+ resizeToNearestRow() {
+ if (-1 !== [ 'Top', 'Bottom' ].indexOf(atom.config.get('build.panelOrientation'))) {
+ this.fixTerminalElHeight();
+ }
+ this.resizeTerminal();
+ }
- BuildView.prototype.attach = function(force) {
- if (!force && 'Show on Error' === atom.config.get('build.panelVisibility')) {
+ getFontGeometry() {
+ const o = $('A
')
+ .addClass('terminal')
+ .addClass('terminal-test')
+ .appendTo(this.output);
+ const w = o[0].getBoundingClientRect().width;
+ const h = o[0].getBoundingClientRect().height;
+ o.remove();
+ return { w, h };
+ }
+
+ resizeTerminal() {
+ this.fontGeometry = this.getFontGeometry();
+ const { w, h } = this.fontGeometry;
+ if (0 === w || 0 === h) {
return;
}
+ const terminalWidth = Math.floor((this.terminalEl.width()) / w);
+ const terminalHeight = Math.floor((this.terminalEl.height()) / h);
+
+ this.terminal.resize(terminalWidth, terminalHeight);
+ }
+
+ getContent() {
+ return this.terminal.getContent();
+ }
+
+ attach(force = false) {
+ if (!force) {
+ switch (atom.config.get('build.panelVisibility')) {
+ case 'Hidden':
+ case 'Show on Error':
+ return;
+ }
+ }
+
if (this.panel) {
this.panel.destroy();
}
- this.panel = atom.workspace.addBottomPanel({ item: this });
- this.height = this.output.offset().top + this.output.height();
- };
- BuildView.prototype.detach = function(force) {
- force = force || false;
- if (atom.views.getView(atom.workspace)) {
+ const addfn = {
+ Top: atom.workspace.addTopPanel,
+ Bottom: atom.workspace.addBottomPanel,
+ Left: atom.workspace.addLeftPanel,
+ Right: atom.workspace.addRightPanel
+ };
+ const orientation = atom.config.get('build.panelOrientation') || 'Bottom';
+ this.panel = addfn[orientation].call(atom.workspace, { item: this });
+ this.fixTerminalElHeight();
+ this.resizeToNearestRow();
+ }
+
+ fixTerminalElHeight() {
+ const nearestRowHeight = $('.build .output').height();
+ this.terminalEl.css('height', `${nearestRowHeight}px`);
+ }
+
+ detach(force) {
+ force = force || false;
+ if (atom.views.getView(atom.workspace) && document.activeElement === this[0]) {
atom.views.getView(atom.workspace).focus();
}
if (this.panel && (force || 'Keep Visible' !== atom.config.get('build.panelVisibility'))) {
this.panel.destroy();
this.panel = null;
}
- };
+ }
- BuildView.prototype.isAttached = function() {
+ isAttached() {
return !!this.panel;
- };
-
- BuildView.prototype.heightFromConfig = function(val) {
- if (this.monocle) {
- this.setHeightPercent(atom.config.get('build.monocleHeight'));
- } else {
- this.setHeightPercent(atom.config.get('build.minimizedHeight'));
- }
- };
+ }
- BuildView.prototype.visibleFromConfig = function(val) {
+ visibleFromConfig(val) {
switch (val) {
case 'Toggle':
case 'Show on Error':
- if (!this.title.hasClass('error')) {
+ if (!this.terminalEl.hasClass('error')) {
this.detach();
}
+ return;
+ }
+
+ this.attach();
+ }
+
+ orientationFromConfig(orientation) {
+ const isVisible = this.isVisible();
+ this.detach(true);
+ if (isVisible) {
+ this.attach();
+ }
+
+ this.resizer.get(0).removeEventListener('mousedown', this.resizeStarted);
+
+ switch (orientation) {
+ case 'Top':
+ case 'Bottom':
+ this.get(0).style.width = null;
+ this.resizer.get(0).addEventListener('mousedown', this.resizeStarted);
break;
- case 'Keep Visible':
- this.attach();
+ case 'Left':
+ case 'Right':
+ this.terminalEl.get(0).style.height = null;
+ this.resizer.get(0).addEventListener('mousedown', this.resizeStarted);
break;
}
- };
- BuildView.prototype.reset = function() {
+ this.resizeTerminal();
+ }
+
+ fontSizeFromConfig(size) {
+ this.css({ 'font-size': size });
+ this.resizeToNearestRow();
+ }
+
+ fontFamilyFromConfig(family) {
+ this.css({ 'font-family': family });
+ this.resizeToNearestRow();
+ }
+
+ reset() {
clearTimeout(this.titleTimer);
+ this.buildTimer.text(BuildView.initialTimerText());
this.titleTimer = 0;
- this.title.removeClass('success error warning');
- this.output.empty();
- this.title.text('Cleared.');
+ this.terminal.reset();
+
+ this.panelHeading.removeClass('success error');
+ this.title.removeClass('success error');
+
this.detach();
- };
+ }
- BuildView.prototype.updateTitle = function() {
- this.title.text(this.titleLoop[this.titleLoopIndex]);
- this.titleLoopIndex = (this.titleLoopIndex + 1) % this.titleLoop.length;
- this.titleTimer = setTimeout(this.updateTitle.bind(this), 200);
- };
+ updateTitle() {
+ this.buildTimer.text(((new Date() - this.starttime) / 1000).toFixed(1) + ' s');
+ this.titleTimer = setTimeout(this.updateTitle.bind(this), 100);
+ }
- BuildView.prototype.close = function(event, element) {
+ close() {
this.detach(true);
- };
+ }
- BuildView.prototype.toggle = function(event, element) {
- this.isAttached() ? this.detach(true) : this.attach(true);
- };
+ toggle() {
+ require('./google-analytics').sendEvent('view', 'panel toggled');
+ this.isAttached() ? this.detach(true) : this.attach(true);
+ }
- BuildView.prototype.clear = function(event, element) {
- this.reset();
- this.attach();
- };
+ clearOutput() {
+ this.terminal.reset();
+ }
- BuildView.prototype.build = function(event, element) {
+ build() {
atom.commands.dispatch(atom.views.getView(atom.workspace), 'build:trigger');
- };
-
- BuildView.prototype.setHeightPercent = function(percent) {
- var newHeight = percent * this.height;
- this.output.css('height', newHeight + 'px');
- };
-
- BuildView.prototype.toggleMonocle = function(event, element) {
- if (!this.monocle) {
- this.setHeightPercent(atom.config.get('build.monocleHeight'));
- this.monocleButton.removeClass('icon-chevron-up').addClass('icon-chevron-down');
- } else {
- this.setHeightPercent(atom.config.get('build.minimizedHeight'));
- this.monocleButton.removeClass('icon-chevron-down').addClass('icon-chevron-up');
- }
- this.monocle = !this.monocle;
- };
+ }
- BuildView.prototype.buildStarted = function() {
+ setHeading(heading) {
+ this.heading.text(heading);
+ }
+
+ buildStarted() {
+ this.starttime = new Date();
this.reset();
this.attach();
- this.focus();
+ if (atom.config.get('build.stealFocus')) {
+ this.focus();
+ }
this.updateTitle();
- };
+ }
- BuildView.prototype.buildFinished = function(success) {
- if (!success) {
- this.attach(true);
+ buildFinished(success) {
+ if (!success && !this.isAttached()) {
+ this.attach(atom.config.get('build.panelVisibility') === 'Show on Error');
}
- this.title.text(success ? 'Build finished.' : 'Build failed.');
- this.title.addClass(success ? 'success' : 'error');
- clearTimeout(this.titleTimer);
- };
+ this.finalizeBuild(success);
+ }
- BuildView.prototype.buildAbortInitiated = function() {
- this.title.text('Build process termination imminent...');
- clearTimeout(this.titleTimer);
- this.title.addClass('error');
- };
+ buildAbortInitiated() {
+ this.heading.addClass('icon-stop');
+ }
- BuildView.prototype.buildAborted = function() {
- this.title.text('Aborted!');
- };
+ buildAborted() {
+ this.finalizeBuild(false);
+ }
+
+ finalizeBuild(success) {
+ this.title.addClass(success ? 'success' : 'error');
+ this.panelHeading.addClass(success ? 'success' : 'error');
+ this.heading.removeClass('icon-stop');
+ clearTimeout(this.titleTimer);
+ }
- BuildView.prototype.errorMessage = function(title, error) {
- this.title.text(title);
- if (error) {
- this.title.addClass('error');
+ scrollTo(text) {
+ const content = this.getContent();
+ let endPos = -1;
+ let curPos = text.length;
+ // We need to decrease the size of `text` until we find a match. This is because
+ // terminal will insert line breaks ('\r\n') when width of terminal is reached.
+ // It may have been that the middle of a matched error is on a line break.
+ while (-1 === endPos && curPos > 0) {
+ endPos = content.indexOf(text.substring(0, curPos--));
}
- this.attach();
- };
- BuildView.prototype.append = function(line) {
- line = _.escape(line.toString());
- this.output.append('' + (this.a2h.toHtml(line)) + '');
- this.output.scrollTop(this.output[0].scrollHeight);
- };
+ if (curPos === 0) {
+ // No match - which is weird. Oh well - rather be defensive
+ return;
+ }
- return BuildView;
-})();
+ const row = content.slice(0, endPos).split('\n').length;
+ this.terminal.ydisp = 0;
+ this.terminal.scrollDisp(row - 1);
+ }
+}
diff --git a/lib/build.js b/lib/build.js
index e3ce31a6..5102a3aa 100644
--- a/lib/build.js
+++ b/lib/build.js
@@ -1,333 +1,340 @@
-'use strict';
-
-var child_process = require('child_process');
-var fs = require('fs');
-var path = require('path');
-var _ = require('lodash');
-var XRegExp = require('xregexp').XRegExp;
-
-var SaveConfirmView = require('./save-confirm-view');
-var BuildView = require('./build-view');
-var tools = require('./tools');
-
-module.exports = {
- config: {
- panelVisibility: {
- title: 'Panel Visibility',
- description: 'Set when the build panel should be visible.',
- type: 'string',
- default: 'Toggle',
- enum: [ 'Toggle', 'Keep Visible', 'Show on Error' ],
- order: 1
- },
- buildOnSave: {
- title: 'Automatically build on save',
- description: 'Autmatically build your project each time an editor is saved.',
- type: 'boolean',
- default: false,
- order: 2
- },
- saveOnBuild: {
- title: 'Automatically save on build',
- description: 'Automatically save all edited files when triggering a build.',
- type: 'boolean',
- default: false,
- order: 3
- },
- monocleHeight: {
- title: 'Monocle Height',
- description: 'How much of the workspace to use for build panel when it is "maximized".',
- type: 'number',
- default: 0.75,
- minimum: 0.1,
- maximum: 0.9,
- order: 4
- },
- minimizedHeight: {
- title: 'Minimized Height',
- description: 'How much of the workspace to use for build panel when it is "minimized".',
- type: 'number',
- default: 0.15,
- minimum: 0.1,
- maximum: 0.9,
- order: 5
- }
- },
+'use babel';
+
+export default {
+ config: require('./config'),
- activate: function(state) {
- // Manually append /usr/local/bin as it may not be set on some systems,
- // and it's common to have node installed here. Keep it at end so it won't
- // accidentially override any other node installation
- process.env.PATH += ':/usr/local/bin';
+ activate() {
+ if (!/^win/.test(process.platform)) {
+ // Manually append /usr/local/bin as it may not be set on some systems,
+ // and it's common to have node installed here. Keep it at end so it won't
+ // accidentially override any other node installation
- /* Migration from 0.29.0. Remove after next version */
- if (atom.config.get('build.keepVisible')) {
- atom.config.set('build.panelVisibility', 'Keep Visible');
- atom.config.unset('build.keepVisible');
+ // Note: This should probably be removed in a end-user friendly way...
+ process.env.PATH += ':/usr/local/bin';
}
- this.buildView = new BuildView();
- this.cmd = {};
- this.match = [];
- this.stdout = new Buffer(0);
- this.stderr = new Buffer(0);
- atom.commands.add('atom-workspace', 'build:trigger', this.build.bind(this));
- atom.commands.add('atom-workspace', 'build:error-match', this.errorMatch.bind(this));
- atom.commands.add('atom-workspace', 'build:error-match-first', this.errorMatchFirst.bind(this));
- atom.commands.add('atom-workspace', 'build:stop', this.stop.bind(this));
- atom.commands.add('atom-workspace', 'build:confirm', function() {
+ require('atom-package-deps').install('build');
+
+ this.tools = [ require('./atom-build') ];
+ this.linter = null;
+
+ this.setupTargetManager();
+ this.setupBuildView();
+ this.setupErrorMatcher();
+
+ atom.commands.add('atom-workspace', 'build:trigger', () => this.build('trigger'));
+ atom.commands.add('atom-workspace', 'build:stop', () => this.stop());
+ atom.commands.add('atom-workspace', 'build:confirm', () => {
+ require('./google-analytics').sendEvent('build', 'confirmed');
document.activeElement.click();
});
- atom.commands.add('atom-workspace', 'build:no-confirm', function() {
- this.saveConfirmView.cancel();
- }.bind(this));
+ atom.commands.add('atom-workspace', 'build:no-confirm', () => {
+ if (this.saveConfirmView) {
+ require('./google-analytics').sendEvent('build', 'not confirmed');
+ this.saveConfirmView.cancel();
+ }
+ });
- atom.workspace.observeTextEditors(function(editor) {
- editor.onDidSave(function(event) {
+ atom.workspace.observeTextEditors((editor) => {
+ editor.onDidSave(() => {
if (atom.config.get('build.buildOnSave')) {
- var workspaceElement = atom.views.getView(atom.workspace);
- atom.commands.dispatch(workspaceElement, 'build:trigger');
+ this.build('save');
}
});
});
- },
- deactivate: function() {
- if (this.child) {
- this.child.kill('SIGKILL');
- }
- clearTimeout(this.finishedTimer);
+ atom.workspace.onDidChangeActivePaneItem(() => this.updateStatusBar());
+ atom.packages.onDidActivateInitialPackages(() => this.targetManager.refreshTargets());
},
- buildCommand: function() {
- var path;
- var textEditor = atom.workspace.getActiveTextEditor();
- if (!textEditor || !textEditor.getPath()) {
- /* default to building the first one if no editor is active */
- path = atom.project.getPaths()[0];
- } else {
- /* otherwise, build the one in the root of the active editor */
- path = _.find(atom.project.getPaths(), function (path) {
- var realpath = fs.realpathSync(path);
- return textEditor.getPath().substr(0, realpath.length) === realpath;
- });
- }
+ setupTargetManager() {
+ const TargetManager = require('./target-manager');
+ this.targetManager = new TargetManager();
+ this.targetManager.setTools(this.tools);
+ this.targetManager.on('refresh-complete', () => {
+ this.updateStatusBar();
+ });
+ this.targetManager.on('new-active-target', (path, target) => {
+ this.updateStatusBar();
- var cmd = {
- env: {},
- args: [],
- cwd: path,
- sh: true,
- errorMatch: ''
- };
- _.find(tools, function (tool) {
- if (!tool.isEligable(path)) {
- return;
+ if (atom.config.get('build.selectTriggers')) {
+ this.build('trigger');
}
- cmd = _.defaults(tool.settings(path), cmd);
- return true;
});
+ this.targetManager.on('trigger', atomCommandName => this.build('trigger', atomCommandName));
+ },
- return cmd;
+ setupBuildView() {
+ const BuildView = require('./build-view');
+ this.buildView = new BuildView();
},
- replace: function(value) {
- var editor = atom.workspace.getActiveTextEditor();
- if (editor && 'untitled' !== editor.getTitle()) {
- var activeFile = fs.realpathSync(editor.getPath());
- value = value.replace('{FILE_ACTIVE}', activeFile);
- value = value.replace('{FILE_ACTIVE_PATH}', path.dirname(activeFile));
- value = value.replace('{FILE_ACTIVE_NAME}', path.basename(activeFile));
- value = value.replace('{FILE_ACTIVE_NAME_BASE}', path.basename(activeFile, path.extname(activeFile)));
- }
+ setupErrorMatcher() {
+ const ErrorMatcher = require('./error-matcher');
+ this.errorMatcher = new ErrorMatcher();
+ this.errorMatcher.on('error', (message) => {
+ atom.notifications.addError('Error matching failed!', { detail: message });
+ });
+ this.errorMatcher.on('matched', (match) => {
+ match[0] && this.buildView.scrollTo(match[0]);
+ });
+ },
- value = value.replace('{PROJECT_PATH}', fs.realpathSync(atom.project.getPaths()[0]));
- if (atom.project.getRepositories[0]) {
- value = value.replace('{REPO_BRANCH_SHORT}', atom.project.getRepositories()[0].getShortHead());
+ deactivate() {
+ if (this.child) {
+ this.child.removeAllListeners();
+ require('tree-kill')(this.child.pid, 'SIGKILL');
+ this.child = null;
}
- return value;
+ this.statusBarView && this.statusBarView.destroy();
+ this.buildView && this.buildView.destroy();
+ this.saveConfirmView && this.saveConfirmView.destroy();
+ this.linter && this.linter.destroy();
+ this.targetManager.destroy();
+
+ clearTimeout(this.finishedTimer);
},
- errorParse: function() {
- this.match = [];
- var regex = XRegExp(this.cmd.errorMatch);
+ updateStatusBar() {
+ const path = require('./utils').activePath();
+ const activeTarget = this.targetManager.getActiveTarget(path);
+ this.statusBarView && activeTarget && this.statusBarView.setTarget(activeTarget.name);
+ },
- var matchErr, matchOut;
+ startNewBuild(source, atomCommandName) {
+ const BuildError = require('./build-error');
+ const path = require('./utils').activePath();
+ let buildTitle = '';
+ this.linter && this.linter.clear();
- matchErr = XRegExp.forEach(this.stderr.toString('utf8'), regex, function (match) {
- return this.push(match);
- }, []);
+ Promise.resolve(this.targetManager.getTargets(path)).then(targets => {
+ if (!targets || 0 === targets.length) {
+ throw new BuildError('No eligible build target.', 'No configuration to build this project exists.');
+ }
- matchOut = XRegExp.forEach(this.stdout.toString('utf8'), regex, function (match) {
- return this.push(match);
- }, []);
+ let target = targets.find(t => t.atomCommandName === atomCommandName);
+ if (!target) {
+ target = this.targetManager.getActiveTarget(path);
+ }
+ require('./google-analytics').sendEvent('build', 'triggered');
- this.match = matchErr.concat(matchOut);
- },
+ if (!target.exec) {
+ throw new BuildError('Invalid build file.', 'No executable command specified.');
+ }
- errorMatch: function() {
- if (!this.cmd.errorMatch) {
- return;
- }
+ this.statusBarView && this.statusBarView.buildStarted();
+ this.busyProvider && this.busyProvider.add(`Build: ${target.name}`);
+ this.buildView.buildStarted();
+ this.buildView.setHeading('Running preBuild...');
+
+ return Promise.resolve(target.preBuild ? target.preBuild() : null).then(() => target);
+ }).then(target => {
+ const replace = require('./utils').replace;
+ const env = Object.assign({}, process.env, target.env);
+ Object.keys(env).forEach(key => {
+ env[key] = replace(env[key], target.env);
+ });
- if (this.match.length === 0) {
- this.errorParse();
- if (this.match.length === 0) {
- return;
+ const exec = replace(target.exec, target.env);
+ const args = target.args.map(arg => replace(arg, target.env));
+ const cwd = replace(target.cwd, target.env);
+ const isWin = process.platform === 'win32';
+ const shCmd = isWin ? 'cmd' : '/bin/sh';
+ const shCmdArg = isWin ? '/C' : '-c';
+
+ // Store this as we need to re-set it after postBuild
+ buildTitle = [ (target.sh ? `${shCmd} ${shCmdArg} ${exec}` : exec ), ...args, '\n'].join(' ');
+
+ this.buildView.setHeading(buildTitle);
+ if (target.sh) {
+ this.child = require('child_process').spawn(
+ shCmd,
+ [ shCmdArg, [ exec ].concat(args).join(' ')],
+ { cwd: cwd, env: env, stdio: ['ignore', null, null] }
+ );
+ } else {
+ this.child = require('cross-spawn').spawn(
+ exec,
+ args,
+ { cwd: cwd, env: env, stdio: ['ignore', null, null] }
+ );
}
- }
- atom.workspace.open(this.cmd.cwd + path.sep + this.match[0].file, {
- initialLine: this.match[0].line ? this.match[0].line - 1 : 0, /* Because atom is zero-based */
- initialColumn: this.match[0].col ? this.match[0].col - 1 : 0 /* Because atom is zero-based */
- });
+ let stdout = '';
+ let stderr = '';
+ this.child.stdout.setEncoding('utf8');
+ this.child.stderr.setEncoding('utf8');
+ this.child.stdout.on('data', d => (stdout += d));
+ this.child.stderr.on('data', d => (stderr += d));
+ this.child.stdout.pipe(this.buildView.terminal);
+ this.child.stderr.pipe(this.buildView.terminal);
+ this.child.killSignals = (target.killSignals || [ 'SIGINT', 'SIGTERM', 'SIGKILL' ]).slice();
+
+ this.child.on('error', (err) => {
+ this.buildView.terminal.write((target.sh ? 'Unable to execute with shell: ' : 'Unable to execute: ') + exec + '\n');
+
+ if (/\s/.test(exec) && !target.sh) {
+ this.buildView.terminal.write('`cmd` cannot contain space. Use `args` for arguments.\n');
+ }
- this.match.push(this.match.shift());
- },
+ if ('ENOENT' === err.code) {
+ this.buildView.terminal.write(`Make sure cmd:'${exec}' and cwd:'${cwd}' exists and have correct access permissions.\n`);
+ this.buildView.terminal.write(`Binaries are found in these folders: ${process.env.PATH}\n`);
+ }
+ });
- errorMatchFirst: function() {
- if (!this.cmd.errorMatch) {
- return;
- }
- this.errorParse();
- if (this.match.length === 0) {
- return;
- }
+ this.child.on('close', (exitCode) => {
+ this.child = null;
+ this.errorMatcher.set(target, cwd, stdout + stderr);
- atom.workspace.open(this.cmd.cwd + path.sep + this.match[0].file, {
- initialLine: this.match[0].line ? this.match[0].line - 1 : 0, /* Because atom is zero-based */
- initialColumn: this.match[0].col ? this.match[0].col - 1 : 0 /* Because atom is zero-based */
- });
+ let success = (0 === exitCode);
+ if (atom.config.get('build.matchedErrorFailsBuild')) {
+ success = success && !this.errorMatcher.getMatches().some(match => match.type && match.type.toLowerCase() === 'error');
+ }
- this.match.push(this.match.shift());
- },
+ this.linter && this.linter.processMessages(this.errorMatcher.getMatches(), cwd);
- startNewBuild: function() {
- this.cmd = {};
- this.match = [];
- try {
- this.cmd = this.buildCommand();
- } catch (error) {
- this.buildView.reset();
- this.buildView.errorMessage('You have a syntax error in your build file.', true);
- this.buildView.append(error.message);
- return;
- }
+ if (atom.config.get('build.beepWhenDone')) {
+ atom.beep();
+ }
- if (!this.cmd.exec) {
- return;
- }
+ this.buildView.setHeading('Running postBuild...');
+ return Promise.resolve(target.postBuild ? target.postBuild(success, stdout, stderr) : null).then(() => {
+ this.buildView.setHeading(buildTitle);
+
+ this.busyProvider && this.busyProvider.remove(`Build: ${target.name}`, success);
+ this.buildView.buildFinished(success);
+ this.statusBarView && this.statusBarView.setBuildSuccess(success);
+ if (success) {
+ require('./google-analytics').sendEvent('build', 'succeeded');
+ this.finishedTimer = setTimeout(() => {
+ this.buildView.detach();
+ }, 1200);
+ } else {
+ if (atom.config.get('build.scrollOnError')) {
+ this.errorMatcher.matchFirst();
+ }
+ require('./google-analytics').sendEvent('build', 'failed');
+ }
+
+ this.nextBuild && this.nextBuild();
+ this.nextBuild = null;
+ });
+ });
+ }).catch((err) => {
+ if (err instanceof BuildError) {
+ if (source === 'save') {
+ // If there is no eligible build tool, and cause of build was a save, stay quiet.
+ return;
+ }
- var env = _.extend(process.env, this.cmd.env);
- _.each(env, function(value, key, list) {
- list[key] = this.replace(value);
- }.bind(this));
-
- var args = _.map(this.cmd.args, this.replace);
-
- this.cmd.exec = this.replace(this.cmd.exec);
-
- this.child = child_process.spawn(
- this.cmd.sh ? '/bin/sh' : this.cmd.exec,
- this.cmd.sh ? [ '-c', [ this.cmd.exec ].concat(args).join(' ') ] : args,
- { cwd: this.replace(this.cmd.cwd), env: env }
- );
-
- this.stdout = new Buffer(0);
- this.child.stdout.on('data', function (buffer) {
- this.stdout = Buffer.concat([ this.stdout, buffer ]);
- this.buildView.append(buffer);
- }.bind(this));
-
- this.stderr = new Buffer(0);
- this.child.stderr.on('data', function (buffer) {
- this.stderr = Buffer.concat([ this.stderr, buffer ]);
- this.buildView.append(buffer);
- }.bind(this));
-
- this.child.on('error', function(err) {
- this.buildView.append((this.cmd.sh ? 'Unable to execute with sh: ' : 'Unable to execute: ') + this.cmd.exec);
- this.buildView.append(/\s/.test(this.cmd.exec) ? '`cmd` cannot contain space. Use `args` for arguments.' : '');
- }.bind(this));
-
- this.child.on('close', function(exitCode) {
- this.buildView.buildFinished(0 === exitCode);
- if (0 === exitCode) {
- this.finishedTimer = setTimeout(function() {
- this.buildView.detach();
- }.bind(this), 1000);
+ atom.notifications.addWarning(err.name, { detail: err.message, stack: err.stack });
+ } else {
+ atom.notifications.addError('Failed to build.', { detail: err.message, stack: err.stack });
}
- this.child = null;
- }.bind(this));
+ });
+ },
- this.buildView.buildStarted();
- this.buildView.append((this.cmd.sh ? 'Executing with sh: ' : 'Executing: ') + this.cmd.exec + [ ' ' ].concat(args).join(' '));
+ sendNextSignal() {
+ try {
+ const signal = this.child.killSignals.shift();
+ require('tree-kill')(this.child.pid, signal);
+ } catch (e) {
+ /* Something may have happened to the child (e.g. terminated by itself). Ignore this. */
+ }
},
- abort: function(cb) {
- this.child.removeAllListeners('close');
- this.child.on('close', function() {
- this.child = null;
- if (cb) {
- cb();
- }
- }.bind(this));
- this.child.kill();
- this.child.killed = true;
+ abort(cb) {
+ if (!this.child.killed) {
+ this.buildView.buildAbortInitiated();
+ this.child.killed = true;
+ this.child.on('exit', () => {
+ this.child = null;
+ cb && cb();
+ });
+ }
+
+ this.sendNextSignal();
},
- build: function() {
+ build(source, event) {
clearTimeout(this.finishedTimer);
- this.doSaveConfirm(this.unsavedTextEditors(), function() {
+ this.doSaveConfirm(this.unsavedTextEditors(), () => {
+ const nextBuild = this.startNewBuild.bind(this, source, event ? event.type : null);
if (this.child) {
- this.abort(this.startNewBuild.bind(this));
- } else {
- this.startNewBuild();
+ this.nextBuild = nextBuild;
+ return this.abort();
}
- }.bind(this));
+ return nextBuild();
+ });
},
- doSaveConfirm: function(modifiedTextEditors, continuecb, cancelcb) {
- var saveAndContinue = function(save) {
- _.each(modifiedTextEditors, function(textEditor) {
- save && textEditor.save();
- });
+ doSaveConfirm(modifiedTextEditors, continuecb, cancelcb) {
+ const saveAndContinue = (save) => {
+ modifiedTextEditors.forEach((textEditor) => save && textEditor.save());
continuecb();
};
- if (0 === _.size(modifiedTextEditors) || atom.config.get('build.saveOnBuild')) {
- return saveAndContinue(true);
+ if (0 === modifiedTextEditors.length || atom.config.get('build.saveOnBuild')) {
+ saveAndContinue(true);
+ return;
+ }
+
+ if (this.saveConfirmView) {
+ this.saveConfirmView.destroy();
}
+ const SaveConfirmView = require('./save-confirm-view');
this.saveConfirmView = new SaveConfirmView();
this.saveConfirmView.show(saveAndContinue, cancelcb);
},
- unsavedTextEditors: function() {
- return _.filter(atom.workspace.getTextEditors(), function(textEditor) {
- return textEditor.isModified() && ('untitled' !== textEditor.getTitle());
+ unsavedTextEditors() {
+ return atom.workspace.getTextEditors().filter((textEditor) => {
+ return textEditor.isModified() && (undefined !== textEditor.getPath());
});
},
- stop: function() {
-
+ stop() {
+ this.nextBuild = null;
clearTimeout(this.finishedTimer);
if (this.child) {
- if (this.child.killed){
- // This child has been killed, but hasn't terminated. Hide it from user.
- this.child.removeAllListeners();
- this.child = null;
+ this.abort(() => {
this.buildView.buildAborted();
- return;
- }
-
- this.abort(this.buildView.buildAborted.bind(this.buildView));
-
- this.buildView.buildAbortInitiated();
+ this.statusBarView && this.statusBarView.buildAborted();
+ });
} else {
this.buildView.reset();
}
+ },
+
+ consumeLinterRegistry(registry) {
+ this.linter && this.linter.destroy();
+ const Linter = require('./linter-integration');
+ this.linter = new Linter(registry);
+ },
+
+ consumeBuilder(builder) {
+ if (Array.isArray(builder)) this.tools.push(...builder); else this.tools.push(builder);
+ this.targetManager.setTools(this.tools);
+ const Disposable = require('atom').Disposable;
+ return new Disposable(() => {
+ this.tools = this.tools.filter(Array.isArray(builder) ? tool => builder.indexOf(tool) === -1 : tool => tool !== builder);
+ this.targetManager.setTools(this.tools);
+ });
+ },
+
+ consumeStatusBar(statusBar) {
+ const StatusBarView = require('./status-bar-view');
+ this.statusBarView = new StatusBarView(statusBar);
+ this.statusBarView.onClick(() => this.targetManager.selectActiveTarget());
+ this.statusBarView.attach();
+ },
+
+ consumeBusySignal(registry) {
+ this.busyProvider = registry.create();
+ this.targetManager.setBusyProvider(this.busyProvider);
}
};
diff --git a/lib/config.js b/lib/config.js
new file mode 100644
index 00000000..49700030
--- /dev/null
+++ b/lib/config.js
@@ -0,0 +1,119 @@
+'use babel';
+
+export default {
+ panelVisibility: {
+ title: 'Panel Visibility',
+ description: 'Set when the build panel should be visible.',
+ type: 'string',
+ default: 'Toggle',
+ enum: [ 'Toggle', 'Keep Visible', 'Show on Error', 'Hidden' ],
+ order: 1
+ },
+ hidePanelHeading: {
+ title: 'Hide panel heading',
+ description: 'Set whether to hide the build command and control buttons in the build panel',
+ type: 'boolean',
+ default: false,
+ order: 2
+ },
+ buildOnSave: {
+ title: 'Automatically build on save',
+ description: 'Automatically build your project each time an editor is saved.',
+ type: 'boolean',
+ default: false,
+ order: 3
+ },
+ saveOnBuild: {
+ title: 'Automatically save on build',
+ description: 'Automatically save all edited files when triggering a build.',
+ type: 'boolean',
+ default: false,
+ order: 4
+ },
+ matchedErrorFailsBuild: {
+ title: 'Any matched error will fail the build',
+ description: 'Even if the build has a return code of zero it is marked as "failed" if any error is being matched in the output.',
+ type: 'boolean',
+ default: true,
+ order: 5
+ },
+ scrollOnError: {
+ title: 'Automatically scroll on build error',
+ description: 'Automatically scroll to first matched error when a build failed.',
+ type: 'boolean',
+ default: false,
+ order: 6
+ },
+ stealFocus: {
+ title: 'Steal Focus',
+ description: 'Steal focus when opening build panel.',
+ type: 'boolean',
+ default: true,
+ order: 7
+ },
+ overrideThemeColors: {
+ title: 'Override Theme Colors',
+ description: 'Override theme background- and text color inside the terminal',
+ type: 'boolean',
+ default: true,
+ order: 8
+ },
+ selectTriggers: {
+ title: 'Selecting new target triggers the build',
+ description: 'When selecting a new target (through status-bar, cmd-alt-t, etc), the newly selected target will be triggered.',
+ type: 'boolean',
+ default: true,
+ order: 9
+ },
+ refreshOnShowTargetList: {
+ title: 'Refresh targets when the target list is shown',
+ description: 'When opening the targets menu, the targets will be refreshed.',
+ type: 'boolean',
+ default: false,
+ order: 10
+ },
+ notificationOnRefresh: {
+ title: 'Show notification when targets are refreshed',
+ description: 'When targets are refreshed a notification with information about the number of targets will be displayed.',
+ type: 'boolean',
+ default: false,
+ order: 11
+ },
+ beepWhenDone: {
+ title: 'Beep when the build completes',
+ description: 'Make a "beep" notification sound when the build is complete - in success or failure.',
+ type: 'boolean',
+ default: false,
+ order: 12
+ },
+ panelOrientation: {
+ title: 'Panel Orientation',
+ description: 'Where to attach the build panel',
+ type: 'string',
+ default: 'Bottom',
+ enum: [ 'Bottom', 'Top', 'Left', 'Right' ],
+ order: 13
+ },
+ statusBar: {
+ title: 'Status Bar',
+ description: 'Where to place the status bar. Set to `Disable` to disable status bar display.',
+ type: 'string',
+ default: 'Left',
+ enum: [ 'Left', 'Right', 'Disable' ],
+ order: 14
+ },
+ statusBarPriority: {
+ title: 'Priority on Status Bar',
+ description: 'Lower priority tiles are placed further to the left/right, depends on where you choose to place Status Bar.',
+ type: 'number',
+ default: -1000,
+ order: 15
+ },
+ terminalScrollback: {
+ title: 'Terminal Scrollback Size',
+ description: 'Max number of lines of build log kept in the terminal',
+ type: 'number',
+ default: 1000,
+ order: 16
+ }
+};
diff --git a/lib/cscompatability.js b/lib/cscompatability.js
deleted file mode 100644
index 3a3c0887..00000000
--- a/lib/cscompatability.js
+++ /dev/null
@@ -1,20 +0,0 @@
-'use strict';
-
-/* jshint newcap:false */
-var __hasProp = {}.hasOwnProperty;
-
-module.exports.extends = function(child, parent) {
- for (var key in parent) {
- if (__hasProp.call(parent, key)) {
- child[key] = parent[key];
- }
- }
- function ctor() {
- /* jshint validthis:true */
- this.constructor = child;
- }
- ctor.prototype = parent.prototype;
- child.prototype = new ctor();
- child.__super__ = parent.prototype;
- return child;
-};
diff --git a/lib/error-matcher.js b/lib/error-matcher.js
new file mode 100644
index 00000000..46f35082
--- /dev/null
+++ b/lib/error-matcher.js
@@ -0,0 +1,155 @@
+'use babel';
+
+import { EventEmitter } from 'events';
+
+export default class ErrorMatcher extends EventEmitter {
+
+ constructor() {
+ super();
+ this.regex = null;
+ this.cwd = null;
+ this.stdout = null;
+ this.stderr = null;
+ this.currentMatch = [];
+ this.firstMatchId = null;
+
+ atom.commands.add('atom-workspace', 'build:error-match', ::this.match);
+ atom.commands.add('atom-workspace', 'build:error-match-first', ::this.matchFirst);
+ }
+
+ _gotoNext() {
+ if (0 === this.currentMatch.length) {
+ return;
+ }
+
+ this.goto(this.currentMatch[0].id);
+ }
+
+ goto(id) {
+ const match = this.currentMatch.find(m => m.id === id);
+ if (!match) {
+ this.emit('error', 'Can\'t find match with id ' + id);
+ return;
+ }
+
+ // rotate to next match
+ while (this.currentMatch[0] !== match) {
+ this.currentMatch.push(this.currentMatch.shift());
+ }
+ this.currentMatch.push(this.currentMatch.shift());
+
+ let file = match.file;
+ if (!file) {
+ this.emit('error', 'Did not match any file. Don\'t know what to open.');
+ return;
+ }
+
+ const path = require('path');
+ if (!path.isAbsolute(file)) {
+ file = this.cwd + path.sep + file;
+ }
+
+ const row = match.line ? match.line - 1 : 0; /* Because atom is zero-based */
+ const col = match.col ? match.col - 1 : 0; /* Because atom is zero-based */
+
+ require('fs').exists(file, (exists) => {
+ if (!exists) {
+ this.emit('error', 'Matched file does not exist: ' + file);
+ return;
+ }
+ atom.workspace.open(file, {
+ initialLine: row,
+ initialColumn: col,
+ searchAllPanes: true
+ });
+ this.emit('matched', match);
+ });
+ }
+
+ _parse() {
+ this.currentMatch = [];
+
+ // first run all functional matches
+ this.functions && this.functions.forEach((f, functionIndex) => {
+ this.currentMatch = this.currentMatch.concat(f(this.output).map((match, matchIndex) => {
+ match.id = 'error-match-function-' + functionIndex + '-' + matchIndex;
+ match.type = match.type || 'Error';
+ return match;
+ }));
+ });
+ // then for all match kinds
+ Object.keys(this.regex).forEach(kind => {
+ // run all matches
+ this.regex[kind] && this.regex[kind].forEach((regex, i) => {
+ regex && require('xregexp').forEach(this.output, regex, (match, matchIndex) => {
+ match.id = 'error-match-' + i + '-' + matchIndex;
+ match.type = kind;
+ this.currentMatch.push(match);
+ });
+ });
+ });
+
+ this.currentMatch.sort((a, b) => a.index - b.index);
+
+ this.firstMatchId = (this.currentMatch.length > 0) ? this.currentMatch[0].id : null;
+ }
+
+ _prepareRegex(regex) {
+ regex = regex || [];
+ regex = (regex instanceof Array) ? regex : [ regex ];
+
+ return regex.map(r => {
+ try {
+ const XRegExp = require('xregexp');
+ return XRegExp(r);
+ } catch (err) {
+ this.emit('error', 'Error parsing regex. ' + err.message);
+ return null;
+ }
+ });
+ }
+
+ set(target, cwd, output) {
+ if (target.functionMatch) {
+ this.functions = ((target.functionMatch instanceof Array) ? target.functionMatch : [ target.functionMatch ]).filter(f => {
+ if (typeof f !== 'function') {
+ this.emit('error', 'found functionMatch that is no function: ' + typeof f);
+ return false;
+ }
+ return true;
+ });
+ }
+ this.regex = {
+ Error: this._prepareRegex(target.errorMatch),
+ Warning: this._prepareRegex(target.warningMatch)
+ };
+
+ this.cwd = cwd;
+ this.output = output;
+ this.currentMatch = [];
+
+ this._parse();
+ }
+
+ match() {
+ require('./google-analytics').sendEvent('errorMatch', 'match');
+
+ this._gotoNext();
+ }
+
+ matchFirst() {
+ require('./google-analytics').sendEvent('errorMatch', 'first');
+
+ if (this.firstMatchId) {
+ this.goto(this.firstMatchId);
+ }
+ }
+
+ hasMatch() {
+ return 0 !== this.currentMatch.length;
+ }
+
+ getMatches() {
+ return this.currentMatch;
+ }
+}
diff --git a/lib/google-analytics.js b/lib/google-analytics.js
new file mode 100644
index 00000000..e2fef63e
--- /dev/null
+++ b/lib/google-analytics.js
@@ -0,0 +1,79 @@
+'use babel';
+
+function uuid() {
+ function s4() {
+ return Math.floor((1 + Math.random()) * 0x10000).toString(16).substring(1);
+ }
+ return `${s4()}${s4()}-${s4()}-${s4()}-${s4()}-${s4()}${s4()}${s4()}`;
+}
+
+export default class GoogleAnalytics {
+ static getCid(cb) {
+ if (this.cid) {
+ cb(this.cid);
+ return;
+ }
+
+ require('getmac').getMac((error, macAddress) => {
+ return error ?
+ cb(this.cid = uuid()) :
+ cb(this.cid = require('crypto').createHash('sha1').update(macAddress, 'utf8').digest('hex'));
+ });
+ }
+
+ static sendEvent(category, action, label, value) {
+ const params = {
+ t: 'event',
+ ec: category,
+ ea: action
+ };
+ if (label) {
+ params.el = label;
+ }
+ if (value) {
+ params.ev = value;
+ }
+
+ this.send(params);
+ }
+
+ static send(params) {
+ if (!atom.packages.getActivePackage('metrics')) {
+ // If the metrics package is disabled, then user has opted out.
+ return;
+ }
+
+ GoogleAnalytics.getCid((cid) => {
+ Object.assign(params, { cid: cid }, GoogleAnalytics.defaultParams());
+ this.request('https://www.google-analytics.com/collect?' + require('querystring').stringify(params));
+ });
+ }
+
+ static request(url) {
+ if (!navigator.onLine) {
+ return;
+ }
+ this.post(url);
+ }
+
+ static post(url) {
+ const xhr = new XMLHttpRequest();
+ xhr.open('POST', url);
+ xhr.send(null);
+ }
+
+ static defaultParams() {
+ // https://developers.google.com/analytics/devguides/collection/protocol/v1/parameters
+ return {
+ v: 1,
+ tid: 'UA-47615700-5'
+ };
+ }
+}
+
+atom.packages.onDidActivatePackage((pkg) => {
+ if ('metrics' === pkg.name) {
+ const buildPackage = atom.packages.getLoadedPackage('build');
+ require('./google-analytics').sendEvent('core', 'activated', buildPackage.metadata.version);
+ }
+});
diff --git a/lib/linter-integration.js b/lib/linter-integration.js
new file mode 100644
index 00000000..924dd14b
--- /dev/null
+++ b/lib/linter-integration.js
@@ -0,0 +1,51 @@
+'use babel';
+
+class Linter {
+ constructor(registry) {
+ this.linter = registry.register({ name: 'Build' });
+ }
+ destroy() {
+ this.linter.dispose();
+ }
+ clear() {
+ this.linter.deleteMessages();
+ }
+ processMessages(messages, cwd) {
+ function extractRange(json) {
+ return [
+ [ (json.line || 1) - 1, (json.col || 1) - 1 ],
+ [ (json.line_end || json.line || 1) - 1, (json.col_end || json.col || 1) - 1 ]
+ ];
+ }
+ function normalizePath(p) {
+ return require('path').isAbsolute(p) ? p : require('path').join(cwd, p);
+ }
+ function typeToSeverity(type) {
+ switch (type && type.toLowerCase()) {
+ case 'err':
+ case 'error': return 'error';
+ case 'warn':
+ case 'warning': return 'warning';
+ default: return null;
+ }
+ }
+ this.linter.setMessages(messages.map(match => ({
+ type: match.type || 'Error',
+ text: !match.message && !match.html_message ? 'Error from build' : match.message,
+ html: match.message ? undefined : match.html_message,
+ filePath: normalizePath(match.file),
+ severity: typeToSeverity(match.type),
+ range: extractRange(match),
+ trace: match.trace && match.trace.map(trace => ({
+ type: trace.type || 'Trace',
+ text: !trace.message && !trace.html_message ? 'Trace in build' : trace.message,
+ html: trace.message ? undefined : trace.html_message,
+ filePath: trace.file && normalizePath(trace.file),
+ severity: typeToSeverity(trace.type) || 'info',
+ range: extractRange(trace)
+ }))
+ })));
+ }
+}
+
+export default Linter;
diff --git a/lib/save-confirm-view.js b/lib/save-confirm-view.js
index 4bd16fc6..366c26a2 100644
--- a/lib/save-confirm-view.js
+++ b/lib/save-confirm-view.js
@@ -1,38 +1,31 @@
-'use strict';
+'use babel';
-var View = require('atom-space-pen-views').View;
-var cscompatability = require('./cscompatability');
+import { View } from 'atom-space-pen-views';
-module.exports = (function() {
- function SaveConfirmView() {
- View.apply(this, arguments);
- }
-
- cscompatability.extends(SaveConfirmView, View);
-
- SaveConfirmView.content = function() {
- SaveConfirmView.div({ class: 'build-confirm overlay from-top' }, function() {
- SaveConfirmView.h3('You have unsaved changes');
- SaveConfirmView.div({ class: 'btn-container pull-right' }, function() {
- SaveConfirmView.button({ class: 'btn btn-success', outlet: 'saveBuildButton', title: 'Save and Build', click: 'saveAndConfirm' }, 'Save and build');
- SaveConfirmView.button({ class: 'btn btn-info', title: 'Build Without Saving', click: 'confirmWithoutSave' }, 'Build Without Saving');
+export default class SaveConfirmView extends View {
+ static content() {
+ this.div({ class: 'build-confirm overlay from-top' }, () => {
+ this.h3('You have unsaved changes');
+ this.div({ class: 'btn-container pull-right' }, () => {
+ this.button({ class: 'btn btn-success', outlet: 'saveBuildButton', title: 'Save and Build', click: 'saveAndConfirm' }, 'Save and build');
+ this.button({ class: 'btn btn-info', title: 'Build Without Saving', click: 'confirmWithoutSave' }, 'Build Without Saving');
});
- SaveConfirmView.div({ class: 'btn-container pull-left' }, function() {
- SaveConfirmView.button({ class: 'btn btn-info', title: 'Cancel', click: 'cancel' }, 'Cancel');
+ this.div({ class: 'btn-container pull-left' }, () => {
+ this.button({ class: 'btn btn-info', title: 'Cancel', click: 'cancel' }, 'Cancel');
});
});
- };
+ }
- SaveConfirmView.prototype.destroy = function() {
+ destroy() {
this.confirmcb = undefined;
this.cancelcb = undefined;
if (this.panel) {
this.panel.destroy();
this.panel = null;
}
- };
+ }
- SaveConfirmView.prototype.show = function(confirmcb, cancelcb) {
+ show(confirmcb, cancelcb) {
this.confirmcb = confirmcb;
this.cancelcb = cancelcb;
@@ -40,28 +33,26 @@ module.exports = (function() {
item: this
});
this.saveBuildButton.focus();
- };
+ }
- SaveConfirmView.prototype.cancel = function() {
+ cancel() {
this.destroy();
if (this.cancelcb) {
this.cancelcb();
}
- };
+ }
- SaveConfirmView.prototype.saveAndConfirm = function() {
+ saveAndConfirm() {
if (this.confirmcb) {
this.confirmcb(true);
}
this.destroy();
- };
+ }
- SaveConfirmView.prototype.confirmWithoutSave = function() {
+ confirmWithoutSave() {
if (this.confirmcb) {
this.confirmcb(false);
}
this.destroy();
- };
-
- return SaveConfirmView;
-})();
+ }
+}
diff --git a/lib/status-bar-view.js b/lib/status-bar-view.js
new file mode 100644
index 00000000..34b6478f
--- /dev/null
+++ b/lib/status-bar-view.js
@@ -0,0 +1,87 @@
+'use babel';
+
+import { View } from 'atom-space-pen-views';
+
+export default class StatusBarView extends View {
+ constructor(statusBar, ...args) {
+ super(...args);
+ this.statusBar = statusBar;
+ atom.config.observe('build.statusBar', () => this.attach());
+ atom.config.observe('build.statusBarPriority', () => this.attach());
+ }
+
+ attach() {
+ this.destroy();
+
+ const orientation = atom.config.get('build.statusBar');
+ if ('Disable' === orientation) {
+ return;
+ }
+
+ this.statusBarTile = this.statusBar[`add${orientation}Tile`]({
+ item: this,
+ priority: atom.config.get('build.statusBarPriority')
+ });
+
+ this.tooltip = atom.tooltips.add(this, {
+ title: () => this.tooltipMessage()
+ });
+ }
+
+ destroy() {
+ if (this.statusBarTile) {
+ this.statusBarTile.destroy();
+ this.statusBarTile = null;
+ }
+
+ if (this.tooltip) {
+ this.tooltip.dispose();
+ this.tooltip = null;
+ }
+ }
+
+ static content() {
+ this.div({ id: 'build-status-bar', class: 'inline-block' }, () => {
+ this.a({ click: 'clicked', outlet: 'message'});
+ });
+ }
+
+ tooltipMessage() {
+ return `Current build target is '${this.element.textContent}'`;
+ }
+
+ setClasses(classes) {
+ this.removeClass('status-unknown status-success status-error');
+ this.addClass(classes);
+ }
+
+ setTarget(t) {
+ if (this.target === t) {
+ return;
+ }
+
+ this.target = t;
+ this.message.text(t || '');
+ this.setClasses();
+ }
+
+ buildAborted() {
+ this.setBuildSuccess(false);
+ }
+
+ setBuildSuccess(success) {
+ this.setClasses(success ? 'status-success' : 'status-error');
+ }
+
+ buildStarted() {
+ this.setClasses();
+ }
+
+ onClick(cb) {
+ this.onClick = cb;
+ }
+
+ clicked() {
+ this.onClick && this.onClick();
+ }
+}
diff --git a/lib/target-manager.js b/lib/target-manager.js
new file mode 100644
index 00000000..ecad7f08
--- /dev/null
+++ b/lib/target-manager.js
@@ -0,0 +1,243 @@
+'use babel';
+
+import EventEmitter from 'events';
+
+class TargetManager extends EventEmitter {
+ constructor() {
+ super();
+
+ let projectPaths = atom.project.getPaths();
+
+ this.pathTargets = projectPaths.map(path => this._defaultPathTarget(path));
+
+ atom.project.onDidChangePaths(newProjectPaths => {
+ const addedPaths = newProjectPaths.filter(el => projectPaths.indexOf(el) === -1);
+ const removedPaths = projectPaths.filter(el => newProjectPaths.indexOf(el) === -1);
+ addedPaths.forEach(path => this.pathTargets.push(this._defaultPathTarget(path)));
+ this.pathTargets = this.pathTargets.filter(pt => -1 === removedPaths.indexOf(pt.path));
+ this.refreshTargets(addedPaths);
+ projectPaths = newProjectPaths;
+ });
+
+ atom.commands.add('atom-workspace', 'build:refresh-targets', () => this.refreshTargets());
+ atom.commands.add('atom-workspace', 'build:select-active-target', () => this.selectActiveTarget());
+ }
+
+ setBusyProvider(busyProvider) {
+ this.busyProvider = busyProvider;
+ }
+
+ _defaultPathTarget(path) {
+ const CompositeDisposable = require('atom').CompositeDisposable;
+ return {
+ path: path,
+ loading: false,
+ targets: [],
+ instancedTools: [],
+ activeTarget: null,
+ tools: [],
+ subscriptions: new CompositeDisposable()
+ };
+ }
+
+ destroy() {
+ this.pathTargets.forEach(pathTarget => pathTarget.tools.map(tool => {
+ tool.removeAllListeners && tool.removeAllListeners('refresh');
+ tool.destructor && tool.destructor();
+ }));
+ }
+
+ setTools(tools) {
+ this.tools = tools || [];
+ }
+
+ refreshTargets(refreshPaths) {
+ refreshPaths = refreshPaths || atom.project.getPaths();
+
+ this.busyProvider && this.busyProvider.add(`Refreshing targets for ${refreshPaths.join(',')}`);
+ const pathPromises = refreshPaths.map((path) => {
+ const pathTarget = this.pathTargets.find(pt => pt.path === path);
+ pathTarget.loading = true;
+
+ pathTarget.instancedTools = pathTarget.instancedTools
+ .map(t => t.removeAllListeners && t.removeAllListeners('refresh'))
+ .filter(() => false); // Just empty the array
+
+ const settingsPromise = this.tools
+ .map(Tool => new Tool(path))
+ .filter(tool => tool.isEligible())
+ .map(tool => {
+ pathTarget.instancedTools.push(tool);
+ require('./google-analytics').sendEvent('build', 'tool eligible', tool.getNiceName());
+
+ tool.on && tool.on('refresh', this.refreshTargets.bind(this, [ path ]));
+ return Promise.resolve()
+ .then(() => tool.settings())
+ .catch(err => {
+ if (err instanceof SyntaxError) {
+ atom.notifications.addError('Invalid build file.', {
+ detail: 'You have a syntax error in your build file: ' + err.message,
+ dismissable: true
+ });
+ } else {
+ const toolName = tool.getNiceName();
+ atom.notifications.addError('Ooops. Something went wrong' + (toolName ? ' in the ' + toolName + ' build provider' : '') + '.', {
+ detail: err.message,
+ stack: err.stack,
+ dismissable: true
+ });
+ }
+ });
+ });
+
+ const CompositeDisposable = require('atom').CompositeDisposable;
+ return Promise.all(settingsPromise).then((settings) => {
+ settings = require('./utils').uniquifySettings([].concat.apply([], settings)
+ .filter(Boolean)
+ .map(setting => require('./utils').getDefaultSettings(path, setting)));
+
+ if (null === pathTarget.activeTarget || !settings.find(s => s.name === pathTarget.activeTarget)) {
+ /* Active target has been removed or not set. Set it to the highest prio target */
+ pathTarget.activeTarget = settings[0] ? settings[0].name : undefined;
+ }
+
+ // CompositeDisposable cannot be reused, so we must create a new instance on every refresh
+ pathTarget.subscriptions.dispose();
+ pathTarget.subscriptions = new CompositeDisposable();
+
+ settings.forEach((setting, index) => {
+ if (setting.keymap && !setting.atomCommandName) {
+ setting.atomCommandName = `build:trigger:${setting.name}`;
+ }
+
+ if (setting.atomCommandName) {
+ pathTarget.subscriptions.add(atom.commands.add('atom-workspace', setting.atomCommandName, atomCommandName => this.emit('trigger', atomCommandName)));
+ }
+
+ if (setting.keymap) {
+ require('./google-analytics').sendEvent('keymap', 'registered', setting.keymap);
+ const keymapSpec = { 'atom-workspace, atom-text-editor': {} };
+ keymapSpec['atom-workspace, atom-text-editor'][setting.keymap] = setting.atomCommandName;
+ pathTarget.subscriptions.add(atom.keymaps.add(setting.name, keymapSpec));
+ }
+ });
+
+ pathTarget.targets = settings;
+ pathTarget.loading = false;
+
+ return pathTarget;
+ }).catch(err => {
+ atom.notifications.addError('Ooops. Something went wrong.', {
+ detail: err.message,
+ stack: err.stack,
+ dismissable: true
+ });
+ });
+ });
+
+ return Promise.all(pathPromises).then(pathTargets => {
+ this.fillTargets(require('./utils').activePath(), false);
+ this.emit('refresh-complete');
+ this.busyProvider && this.busyProvider.remove(`Refreshing targets for ${refreshPaths.join(',')}`);
+
+ if (pathTargets.length === 0) {
+ return;
+ }
+
+ if (atom.config.get('build.notificationOnRefresh')) {
+ const rows = refreshPaths.map(path => {
+ const pathTarget = this.pathTargets.find(pt => pt.path === path);
+ if (!pathTarget) {
+ return `Targets ${path} no longer exists. Is build deactivated?`;
+ }
+ return `${pathTarget.targets.length} targets at: ${path}`;
+ });
+ atom.notifications.addInfo('Build targets parsed.', {
+ detail: rows.join('\n')
+ });
+ }
+ }).catch(err => {
+ atom.notifications.addError('Ooops. Something went wrong.', {
+ detail: err.message,
+ stack: err.stack,
+ dismissable: true
+ });
+ });
+ }
+
+ fillTargets(path, refreshOnEmpty = true) {
+ if (!this.targetsView) {
+ return;
+ }
+
+ const activeTarget = this.getActiveTarget(path);
+ activeTarget && this.targetsView.setActiveTarget(activeTarget.name);
+
+ this.getTargets(path, refreshOnEmpty)
+ .then(targets => targets.map(t => t.name))
+ .then(targetNames => this.targetsView && this.targetsView.setItems(targetNames));
+ }
+
+ selectActiveTarget() {
+ if (atom.config.get('build.refreshOnShowTargetList')) {
+ this.refreshTargets();
+ }
+
+ const path = require('./utils').activePath();
+ if (!path) {
+ atom.notifications.addWarning('Unable to build.', {
+ detail: 'Open file is not part of any open project in Atom'
+ });
+ return;
+ }
+
+ const TargetsView = require('./targets-view');
+ this.targetsView = new TargetsView();
+
+ if (this.isLoading(path)) {
+ this.targetsView.setLoading('Loading project build targets\u2026');
+ } else {
+ this.fillTargets(path);
+ }
+
+ this.targetsView.awaitSelection().then(newTarget => {
+ this.setActiveTarget(path, newTarget);
+
+ this.targetsView = null;
+ }).catch((err) => {
+ this.targetsView.setError(err.message);
+ this.targetsView = null;
+ });
+ }
+
+ getTargets(path, refreshOnEmpty = true) {
+ const pathTarget = this.pathTargets.find(pt => pt.path === path);
+ if (!pathTarget) {
+ return Promise.resolve([]);
+ }
+
+ if (refreshOnEmpty && pathTarget.targets.length === 0) {
+ return this.refreshTargets([ pathTarget.path ]).then(() => pathTarget.targets);
+ }
+ return Promise.resolve(pathTarget.targets);
+ }
+
+ getActiveTarget(path) {
+ const pathTarget = this.pathTargets.find(pt => pt.path === path);
+ if (!pathTarget) {
+ return null;
+ }
+ return pathTarget.targets.find(target => target.name === pathTarget.activeTarget);
+ }
+
+ setActiveTarget(path, targetName) {
+ this.pathTargets.find(pt => pt.path === path).activeTarget = targetName;
+ this.emit('new-active-target', path, this.getActiveTarget(path));
+ }
+
+ isLoading(path) {
+ return this.pathTargets.find(pt => pt.path === path).loading;
+ }
+}
+
+export default TargetManager;
diff --git a/lib/targets-view.js b/lib/targets-view.js
new file mode 100644
index 00000000..c542a3c5
--- /dev/null
+++ b/lib/targets-view.js
@@ -0,0 +1,71 @@
+'use babel';
+
+import { SelectListView } from 'atom-space-pen-views';
+
+export default class TargetsView extends SelectListView {
+
+ constructor() {
+ super(...arguments);
+ this.show();
+ }
+
+ initialize() {
+ super.initialize(...arguments);
+ this.addClass('build-target');
+ this.list.addClass('mark-active');
+ }
+
+ show() {
+ this.panel = atom.workspace.addModalPanel({ item: this });
+ this.panel.show();
+ this.focusFilterEditor();
+ }
+
+ hide() {
+ this.panel.hide();
+ }
+
+ setItems() {
+ super.setItems(...arguments);
+
+ const activeItemView = this.find('.active');
+ if (0 < activeItemView.length) {
+ this.selectItemView(activeItemView);
+ this.scrollToItemView(activeItemView);
+ }
+ }
+
+ setActiveTarget(target) {
+ this.activeTarget = target;
+ }
+
+ viewForItem(targetName) {
+ const activeTarget = this.activeTarget;
+ return TargetsView.render(function () {
+ const activeClass = (targetName === activeTarget ? 'active' : '');
+ this.li({ class: activeClass + ' build-target' }, targetName);
+ });
+ }
+
+ getEmptyMessage(itemCount) {
+ return (0 === itemCount) ? 'No targets found.' : 'No matches';
+ }
+
+ awaitSelection() {
+ return new Promise((resolve, reject) => {
+ this.resolveFunction = resolve;
+ });
+ }
+
+ confirmed(target) {
+ if (this.resolveFunction) {
+ this.resolveFunction(target);
+ this.resolveFunction = null;
+ }
+ this.hide();
+ }
+
+ cancelled() {
+ this.hide();
+ }
+}
diff --git a/lib/tools/Cargo.js b/lib/tools/Cargo.js
deleted file mode 100644
index a64d8152..00000000
--- a/lib/tools/Cargo.js
+++ /dev/null
@@ -1,16 +0,0 @@
-'use strict';
-
-var fs = require('fs');
-
-module.exports.isEligable = function (path) {
- return fs.existsSync(path + '/Cargo.toml');
-};
-
-module.exports.settings = function (path) {
- return {
- exec: 'cargo',
- args: [ 'build' ],
- sh: false,
- errorMatch: '^(?[^\\.]+.rs):(?\\d+):(?\\d+):'
- };
-};
diff --git a/lib/tools/Elixir.js b/lib/tools/Elixir.js
deleted file mode 100644
index c4fe402a..00000000
--- a/lib/tools/Elixir.js
+++ /dev/null
@@ -1,15 +0,0 @@
-'use strict';
-
-var fs = require('fs');
-
-module.exports.isEligable = function (path) {
- return fs.existsSync(path + '/mix.exs');
-};
-
-module.exports.settings = function (path) {
- return {
- exec: 'mix',
- args: [ 'compile' ],
- sh: false
- };
-};
diff --git a/lib/tools/Grunt.js b/lib/tools/Grunt.js
deleted file mode 100644
index 0ce41750..00000000
--- a/lib/tools/Grunt.js
+++ /dev/null
@@ -1,14 +0,0 @@
-'use strict';
-
-var fs = require('fs');
-
-module.exports.isEligable = function (path) {
- return fs.existsSync(path + '/Gruntfile.js');
-};
-
-module.exports.settings = function (path) {
- return {
- exec: fs.existsSync(path + '/node_modules/.bin/grunt') ? path + '/node_modules/.bin/grunt' : 'grunt',
- sh: false
- };
-};
diff --git a/lib/tools/atom-build.js b/lib/tools/atom-build.js
deleted file mode 100644
index 4ba67c35..00000000
--- a/lib/tools/atom-build.js
+++ /dev/null
@@ -1,22 +0,0 @@
-'use strict';
-
-var fs = require('fs');
-
-module.exports.isEligable = function (path) {
- return fs.existsSync(path + '/.atom-build.json');
-};
-
-module.exports.settings = function (path) {
- var realAtomBuild = fs.realpathSync(path + '/.atom-build.json');
- delete require.cache[realAtomBuild];
-
- var build = require(realAtomBuild);
- return {
- exec: build.cmd,
- env: build.env,
- args: build.args,
- cwd: build.cwd,
- sh: build.sh,
- errorMatch: build.errorMatch
- };
-};
diff --git a/lib/tools/gulp.js b/lib/tools/gulp.js
deleted file mode 100644
index 96739c7a..00000000
--- a/lib/tools/gulp.js
+++ /dev/null
@@ -1,14 +0,0 @@
-'use strict';
-
-var fs = require('fs');
-
-module.exports.isEligable = function (path) {
- return fs.existsSync(path + '/gulpfile.js');
-};
-
-module.exports.settings = function (path) {
- return {
- exec: fs.existsSync(path + '/node_modules/.bin/gulp') ? path + '/node_modules/.bin/gulp' : 'gulp',
- sh: false
- };
-};
diff --git a/lib/tools/index.js b/lib/tools/index.js
deleted file mode 100644
index 5771357b..00000000
--- a/lib/tools/index.js
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
-Build tools available to atom-build.
-These are sorted in order of priority
-and divided into groups as seen by comments below
-*/
-module.exports = [
- /* generic (can be configured to do anything) */
- require('./atom-build'),
-
- /* semi-generic (may trigger other build scripts) */
- require('./npm_apm'),
- require('./Grunt'),
- require('./gulp'),
- require('./make'),
-
- /* specific (builds only one thing) */
- require('./Elixir'),
- require('./Cargo')
-];
diff --git a/lib/tools/make.js b/lib/tools/make.js
deleted file mode 100644
index 9a56bfb4..00000000
--- a/lib/tools/make.js
+++ /dev/null
@@ -1,14 +0,0 @@
-'use strict';
-
-var fs = require('fs');
-
-module.exports.isEligable = function (path) {
- return fs.existsSync(path + '/Makefile');
-};
-
-module.exports.settings = function (path) {
- return {
- exec: 'make',
- sh: false
- };
-};
diff --git a/lib/tools/npm_apm.js b/lib/tools/npm_apm.js
deleted file mode 100644
index 43865b37..00000000
--- a/lib/tools/npm_apm.js
+++ /dev/null
@@ -1,30 +0,0 @@
-'use strict';
-
-var fs = require('fs');
-
-module.exports.isEligable = function (path) {
- if (!fs.existsSync(path + '/package.json')) {
- return false;
- }
-
- var realPackage = fs.realpathSync(path + '/package.json');
- delete require.cache[realPackage];
- var pkg = require(realPackage);
-
- if (!pkg.engines || (!pkg.engines.atom && !pkg.engines.node)) {
- return false;
- }
-
- return true;
-};
-
-module.exports.settings = function (path) {
- var realPackage = fs.realpathSync(path + '/package.json');
- var pkg = require(realPackage);
-
- return {
- exec: pkg.engines.node ? 'npm' : 'apm',
- args: [ '--color=always', 'install' ],
- sh: false
- };
-};
diff --git a/lib/utils.js b/lib/utils.js
new file mode 100644
index 00000000..6b701cd1
--- /dev/null
+++ b/lib/utils.js
@@ -0,0 +1,94 @@
+'use babel';
+
+import fs from 'fs';
+import path from 'path';
+
+const uniquifySettings = (settings) => {
+ const genName = (name, index) => `${name} - ${index}`;
+ const newSettings = [];
+ settings.forEach(setting => {
+ let i = 0;
+ let testName = setting.name;
+ while (newSettings.find(ns => ns.name === testName)) { // eslint-disable-line no-loop-func
+ testName = genName(setting.name, ++i);
+ }
+ newSettings.push({ ...setting, name: testName });
+ });
+ return newSettings;
+};
+
+const activePath = () => {
+ const textEditor = atom.workspace.getActiveTextEditor();
+ if (!textEditor || !textEditor.getPath()) {
+ /* default to building the first one if no editor is active */
+ if (0 === atom.project.getPaths().length) {
+ return false;
+ }
+
+ return atom.project.getPaths()[0];
+ }
+
+ /* otherwise, build the one in the root of the active editor */
+ return atom.project.getPaths().sort((a, b) => (b.length - a.length)).find(p => {
+ try {
+ const realpath = fs.realpathSync(p);
+ return fs.realpathSync(textEditor.getPath()).substr(0, realpath.length) === realpath;
+ } catch (err) {
+ /* Path no longer available. Possible network volume has gone down */
+ return false;
+ }
+ });
+};
+
+const getDefaultSettings = (cwd, setting) => {
+ return Object.assign({}, setting, {
+ env: setting.env || {},
+ args: setting.args || [],
+ cwd: setting.cwd || cwd,
+ sh: (undefined === setting.sh) ? true : setting.sh,
+ errorMatch: setting.errorMatch || ''
+ });
+};
+
+const replace = (value = '', targetEnv) => {
+ if (!(typeof value === 'string')) {
+ return value;
+ }
+
+ const env = Object.assign({}, process.env, targetEnv);
+ value = value.replace(/\$(\w+)/g, function (match, name) {
+ return name in env ? env[name] : match;
+ });
+
+ const editor = atom.workspace.getActiveTextEditor();
+
+ const projectPaths = atom.project.getPaths().map(projectPath => {
+ try {
+ return fs.realpathSync(projectPath);
+ } catch (e) { /* Do nothing. */ }
+ return null;
+ });
+
+ let projectPath = projectPaths[0];
+ if (editor && (undefined !== editor.getPath())) {
+ const activeFile = fs.realpathSync(editor.getPath());
+ const activeFilePath = path.dirname(activeFile);
+ projectPath = projectPaths.find(p => activeFilePath && activeFilePath.startsWith(p));
+ value = value.replace(/{FILE_ACTIVE}/g, activeFile);
+ value = value.replace(/{FILE_ACTIVE_PATH}/g, activeFilePath);
+ value = value.replace(/{FILE_ACTIVE_NAME}/g, path.basename(activeFile));
+ value = value.replace(/{FILE_ACTIVE_NAME_BASE}/g, path.basename(activeFile, path.extname(activeFile)));
+ value = value.replace(/{SELECTION}/g, editor.getSelectedText());
+ const cursorScreenPosition = editor.getCursorScreenPosition();
+ value = value.replace(/{FILE_ACTIVE_CURSOR_ROW}/g, cursorScreenPosition.row + 1);
+ value = value.replace(/{FILE_ACTIVE_CURSOR_COLUMN}/g, cursorScreenPosition.column + 1);
+ }
+ value = value.replace(/{PROJECT_PATH}/g, projectPath);
+ if (atom.project.getRepositories[0]) {
+ value = value.replace(/{REPO_BRANCH_SHORT}/g, atom.project.getRepositories()[0].getShortHead());
+ }
+
+ return value;
+};
+
+export { uniquifySettings, activePath, getDefaultSettings, replace };
diff --git a/menus/build.json b/menus/build.json
index 4960ad67..1b9c4508 100644
--- a/menus/build.json
+++ b/menus/build.json
@@ -4,12 +4,24 @@
"submenu": [ {
"label": "Build",
"submenu": [ {
- "label": "Build project...",
+ "label": "Build project",
"command": "build:trigger"
},
{
- "label": "Terminate build.",
+ "label": "Terminate build",
"command": "build:stop"
+ },
+ {
+ "label": "Select active target",
+ "command": "build:select-active-target"
+ },
+ {
+ "label": "Refresh targets",
+ "command": "build:refresh-targets"
+ },
+ {
+ "label": "Toggle panel",
+ "command": "build:toggle-panel"
} ]
} ]
} ],
diff --git a/package.json b/package.json
index 94c22293..8a6b52be 100644
--- a/package.json
+++ b/package.json
@@ -1,33 +1,65 @@
{
"name": "build",
"main": "./lib/build",
- "version": "0.30.0",
+ "version": "0.70.0",
"description": "Build your current project, directly from Atom",
"repository": "https://github.com/noseglid/atom-build",
"license": "MIT",
"engines": {
- "atom": ">=0.50.0"
+ "atom": ">=1.0.0"
},
"dependencies": {
- "lodash": "^2.4.1",
- "ansi-to-html": "^0.3.0",
- "temp": "^0.8.1",
- "fs-plus": "^2.4.0",
+ "atom-package-deps": "^4.0.1",
"atom-space-pen-views": "^2.0.3",
- "xregexp": "^2.0.0"
+ "cross-spawn": "^4.0.2",
+ "cson-parser": "^1.3.0",
+ "getmac": "^1.0.7",
+ "js-yaml": "^3.4.6",
+ "term.js": "https://github.com/jeremyramin/term.js/tarball/de1635fc2695e7d8165012d3b1d007d7ce60eea2",
+ "tree-kill": "^1.0.0",
+ "xregexp": "^3.1.0"
},
"devDependencies": {
- "jshint": "^2.5.11",
- "jscs": "^1.9.0"
+ "atom-build-spec-helpers": "^0.4.0",
+ "babel-eslint": "^6.0.0",
+ "eslint": "^2.10.1",
+ "eslint-config-atom-build": "^3.0.0",
+ "fs-extra": "^2.1.2",
+ "temp": "^0.8.1"
+ },
+ "package-deps": [
+ "busy-signal"
+ ],
+ "consumedServices": {
+ "builder": {
+ "versions": {
+ "^2.0.0": "consumeBuilder"
+ }
+ },
+ "status-bar": {
+ "versions": {
+ "^1.0.0": "consumeStatusBar"
+ }
+ },
+ "busy-signal": {
+ "versions": {
+ "^1.0.0": "consumeBusySignal"
+ }
+ },
+ "linter-indie": {
+ "versions": {
+ "1.0.0": "consumeLinterRegistry"
+ }
+ }
},
"scripts": {
- "test": "./node_modules/.bin/jscs lib/*.js spec/*.js && ./node_modules/.bin/jshint lib/*.js spec/*.js"
+ "test": "eslint ."
},
"keywords": [
"build",
"compile",
"gulp",
"make",
- "process"
+ "productivity"
]
}
diff --git a/spec/.eslintrc b/spec/.eslintrc
new file mode 100644
index 00000000..0840b9c9
--- /dev/null
+++ b/spec/.eslintrc
@@ -0,0 +1,5 @@
+{
+ "rules": {
+ "no-console": [ "error", { "allow": [ "warn", "error" ] } ]
+ }
+}
diff --git a/spec/build-atomCommandName-spec.js b/spec/build-atomCommandName-spec.js
new file mode 100644
index 00000000..9f0e04de
--- /dev/null
+++ b/spec/build-atomCommandName-spec.js
@@ -0,0 +1,68 @@
+'use babel';
+
+import fs from 'fs-extra';
+import temp from 'temp';
+import specHelpers from 'atom-build-spec-helpers';
+import os from 'os';
+
+describe('AtomCommandName', () => {
+ const originalHomedirFn = os.homedir;
+ let directory = null;
+ let workspaceElement = null;
+
+ temp.track();
+
+ beforeEach(() => {
+ const createdHomeDir = temp.mkdirSync('atom-build-spec-home');
+ os.homedir = () => createdHomeDir;
+ directory = fs.realpathSync(temp.mkdirSync({ prefix: 'atom-build-spec-' }));
+ atom.project.setPaths([ directory ]);
+
+ atom.config.set('build.buildOnSave', false);
+ atom.config.set('build.panelVisibility', 'Toggle');
+ atom.config.set('build.saveOnBuild', false);
+ atom.config.set('build.notificationOnRefresh', true);
+
+ jasmine.unspy(window, 'setTimeout');
+ jasmine.unspy(window, 'clearTimeout');
+
+ runs(() => {
+ workspaceElement = atom.views.getView(atom.workspace);
+ workspaceElement.setAttribute('style', 'width:9999px');
+ jasmine.attachToDOM(workspaceElement);
+ });
+
+ waitsForPromise(() => {
+ return atom.packages.activatePackage('build');
+ });
+ });
+
+ afterEach(() => {
+ os.homedir = originalHomedirFn;
+ try { fs.removeSync(directory); } catch (e) { console.warn('Failed to clean up: ', e); }
+ });
+
+ describe('when atomCommandName is specified in build config', () => {
+ it('it should register that command to atom', () => {
+ fs.writeFileSync(`${directory}/.atom-build.json`, JSON.stringify({
+ name: 'The default build',
+ cmd: 'echo default',
+ atomCommandName: 'someProvider:customCommand'
+ }));
+
+ waitsForPromise(() => specHelpers.refreshAwaitTargets());
+
+ runs(() => atom.commands.dispatch(workspaceElement, 'someProvider:customCommand'));
+
+ waitsFor(() => {
+ return workspaceElement.querySelector('.build .title') &&
+ workspaceElement.querySelector('.build .title').classList.contains('success');
+ });
+
+ runs(() => {
+ expect(workspaceElement.querySelector('.terminal').terminal.getContent()).toMatch(/default/);
+ atom.commands.dispatch(workspaceElement, 'build:toggle-panel');
+ });
+ });
+ });
+});
diff --git a/spec/build-confirm-spec.js b/spec/build-confirm-spec.js
new file mode 100644
index 00000000..e53b7eac
--- /dev/null
+++ b/spec/build-confirm-spec.js
@@ -0,0 +1,268 @@
+'use babel';
+
+import fs from 'fs-extra';
+import temp from 'temp';
+import os from 'os';
+
+describe('Confirm', () => {
+ let directory = null;
+ let workspaceElement = null;
+ const cat = process.platform === 'win32' ? 'type' : 'cat';
+ const waitTime = process.env.CI ? 2400 : 200;
+ const originalHomedirFn = os.homedir;
+
+ temp.track();
+
+ beforeEach(() => {
+ const createdHomeDir = temp.mkdirSync('atom-build-spec-home');
+ os.homedir = () => createdHomeDir;
+ directory = fs.realpathSync(temp.mkdirSync({ prefix: 'atom-build-spec-' })) + '/';
+ atom.project.setPaths([ directory ]);
+
+ atom.config.set('build.buildOnSave', false);
+ atom.config.set('build.panelVisibility', 'Toggle');
+ atom.config.set('build.saveOnBuild', false);
+ atom.config.set('build.notificationOnRefresh', true);
+
+ jasmine.unspy(window, 'setTimeout');
+ jasmine.unspy(window, 'clearTimeout');
+
+ runs(() => {
+ workspaceElement = atom.views.getView(atom.workspace);
+ workspaceElement.setAttribute('style', 'width:9999px');
+ jasmine.attachToDOM(workspaceElement);
+ });
+
+ waitsForPromise(() => {
+ return atom.packages.activatePackage('build');
+ });
+ });
+
+ afterEach(() => {
+ os.homedir = originalHomedirFn;
+ try { fs.removeSync(directory); } catch (e) { console.warn('Failed to clean up: ', e); }
+ });
+
+ describe('when the text editor is modified', () => {
+ it('should show the save confirmation', () => {
+ expect(workspaceElement.querySelector('.build-confirm')).not.toExist();
+
+ fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({
+ cmd: 'echo Surprising is the passing of time but not so, as the time of passing.'
+ }));
+
+ waitsForPromise(() => {
+ return atom.workspace.open('.atom-build.json');
+ });
+
+ runs(() => {
+ const editor = atom.workspace.getActiveTextEditor();
+ editor.insertText('hello kansas');
+ atom.commands.dispatch(workspaceElement, 'build:trigger');
+ });
+
+ waitsFor(() => {
+ return workspaceElement.querySelector('.build-confirm');
+ });
+
+ runs(() => {
+ expect(document.activeElement.classList.contains('btn-success')).toEqual(true);
+ });
+ });
+
+ it('should cancel the confirm window when pressing escape', () => {
+ expect(workspaceElement.querySelector('.build-confirm')).not.toExist();
+
+ fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({
+ cmd: 'echo Surprising is the passing of time but not so, as the time of passing.'
+ }));
+
+ waitsForPromise(() => {
+ return atom.workspace.open('.atom-build.json');
+ });
+
+ runs(() => {
+ const editor = atom.workspace.getActiveTextEditor();
+ editor.insertText('hello kansas');
+ atom.commands.dispatch(workspaceElement, 'build:trigger');
+ });
+
+ waitsFor(() => workspaceElement.querySelector('.build-confirm'));
+
+ runs(() => {
+ atom.commands.dispatch(workspaceElement, 'build:no-confirm');
+ expect(workspaceElement.querySelector('.build-confirm')).not.toExist();
+ });
+ });
+
+ it('should not do anything if issuing no-confirm whithout the dialog', () => {
+ expect(workspaceElement.querySelector('.build-confirm')).not.toExist();
+ atom.commands.dispatch(workspaceElement, 'build:no-confirm');
+ });
+
+ it('should not confirm if a TextEditor edits an unsaved file', () => {
+ expect(workspaceElement.querySelector('.build-confirm')).not.toExist();
+
+ fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({
+ cmd: 'echo Surprising is the passing of time but not so, as the time of passing.'
+ }));
+
+ waitsForPromise(() => {
+ return Promise.all([
+ atom.workspace.open('.atom-build.json'),
+ atom.workspace.open()
+ ]);
+ });
+
+ runs(() => {
+ const editor = atom.workspace.getTextEditors().find(textEditor => {
+ return ('untitled' === textEditor.getTitle());
+ });
+ editor.insertText('Just some temporary place to write stuff');
+ atom.commands.dispatch(workspaceElement, 'build:trigger');
+ });
+
+ waitsFor(() => {
+ return workspaceElement.querySelector('.build .title') &&
+ workspaceElement.querySelector('.build .title').classList.contains('success');
+ });
+
+ runs(() => {
+ expect(workspaceElement.querySelector('.build')).toExist();
+ expect(workspaceElement.querySelector('.terminal').terminal.getContent()).toMatch(/Surprising is the passing of time but not so, as the time of passing/);
+ });
+ });
+
+ it('should save and build when selecting save and build', () => {
+ expect(workspaceElement.querySelector('.build-confirm')).not.toExist();
+
+ fs.writeFileSync(directory + 'catme', 'Surprising is the passing of time but not so, as the time of passing.');
+ fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({
+ cmd: `${cat} catme`
+ }));
+
+ waitsForPromise(() => atom.workspace.open('catme'));
+
+ runs(() => {
+ const editor = atom.workspace.getActiveTextEditor();
+ editor.setText('kansas');
+ atom.commands.dispatch(workspaceElement, 'build:trigger');
+ });
+
+ waitsFor(() => workspaceElement.querySelector('.build-confirm'));
+ runs(() => document.activeElement.click());
+
+ waitsFor(() => {
+ return workspaceElement.querySelector('.build .title') &&
+ workspaceElement.querySelector('.build .title').classList.contains('success');
+ });
+
+ runs(() => {
+ const editor = atom.workspace.getActiveTextEditor();
+ expect(workspaceElement.querySelector('.build')).toExist();
+ expect(workspaceElement.querySelector('.build .output').innerHTML).toMatch(/kansas/);
+ expect(!editor.isModified());
+ });
+ });
+
+ it('should build but not save when opting so', () => {
+ expect(workspaceElement.querySelector('.build-confirm')).not.toExist();
+
+ fs.writeFileSync(directory + 'catme', 'Surprising is the passing of time but not so, as the time of passing.');
+ fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({
+ cmd: `${cat} catme`
+ }));
+
+ waitsForPromise(() => atom.workspace.open('catme'));
+
+ runs(() => {
+ const editor = atom.workspace.getActiveTextEditor();
+ editor.setText('catme');
+ atom.commands.dispatch(workspaceElement, 'build:trigger');
+ });
+
+ waitsFor(() => workspaceElement.querySelector('.build-confirm'));
+
+ runs(() => {
+ workspaceElement.querySelector('button[click="confirmWithoutSave"]').click();
+ });
+
+ waitsFor(() => {
+ return workspaceElement.querySelector('.build .title') &&
+ workspaceElement.querySelector('.build .title').classList.contains('success');
+ });
+
+ runs(() => {
+ const editor = atom.workspace.getActiveTextEditor();
+ expect(workspaceElement.querySelector('.build')).toExist();
+ expect(workspaceElement.querySelector('.build .output').innerHTML).not.toMatch(/kansas/);
+ expect(editor.isModified());
+ });
+ });
+
+ it('should do nothing when cancelling', () => {
+ expect(workspaceElement.querySelector('.build-confirm')).not.toExist();
+
+ fs.writeFileSync(directory + 'catme', 'Surprising is the passing of time but not so, as the time of passing.');
+ fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({
+ cmd: `${cat} catme`
+ }));
+
+ waitsForPromise(() => atom.workspace.open('catme'));
+
+ runs(() => {
+ const editor = atom.workspace.getActiveTextEditor();
+ editor.setText('kansas');
+ atom.commands.dispatch(workspaceElement, 'build:trigger');
+ });
+
+ waitsFor(() => workspaceElement.querySelector('.build-confirm'));
+
+ runs(() => {
+ workspaceElement.querySelector('button[click="cancel"]').click();
+ });
+
+ waits(waitTime);
+
+ runs(() => {
+ const editor = atom.workspace.getActiveTextEditor();
+ expect(workspaceElement.querySelector('.build')).not.toExist();
+ expect(editor.isModified());
+ });
+ });
+ });
+
+ describe('when build is triggered without answering confirm dialog', function () {
+ it('should only keep at maximum 1 dialog open', function () {
+ expect(workspaceElement.querySelector('.build-confirm')).not.toExist();
+
+ fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({
+ cmd: 'echo Surprising is the passing of time but not so, as the time of passing.'
+ }));
+
+ waitsForPromise(() => atom.workspace.open('.atom-build.json'));
+
+ runs(() => {
+ const editor = atom.workspace.getActiveTextEditor();
+ editor.setText(JSON.stringify({
+ cmd: 'echo kansas'
+ }));
+ atom.commands.dispatch(workspaceElement, 'build:trigger');
+ });
+
+ waitsFor(() => {
+ return workspaceElement.querySelector('.build-confirm');
+ });
+
+ runs(() => {
+ atom.commands.dispatch(workspaceElement, 'build:trigger');
+ });
+
+ waits(waitTime); // Everything is the same so we can't know when second build:trigger has been handled
+
+ runs(() => {
+ expect(workspaceElement.querySelectorAll('.build-confirm').length).toEqual(1);
+ });
+ });
+ });
+});
diff --git a/spec/build-error-match-spec.js b/spec/build-error-match-spec.js
new file mode 100644
index 00000000..b4da2877
--- /dev/null
+++ b/spec/build-error-match-spec.js
@@ -0,0 +1,720 @@
+'use babel';
+
+import fs from 'fs-extra';
+import path from 'path';
+import temp from 'temp';
+import os from 'os';
+import { sleep } from './helpers';
+
+describe('Error Match', () => {
+ const errorMatchAtomBuildFile = __dirname + '/fixture/.atom-build.error-match.json';
+ const errorMatchNoFileBuildFile = __dirname + '/fixture/.atom-build.error-match-no-file.json';
+ const errorMatchNLCAtomBuildFile = __dirname + '/fixture/.atom-build.error-match-no-line-col.json';
+ const errorMatchMultiAtomBuildFile = __dirname + '/fixture/.atom-build.error-match-multiple.json';
+ const errorMatchMultiFirstAtomBuildFile = __dirname + '/fixture/.atom-build.error-match-multiple-first.json';
+ const errorMatchLongOutputAtomBuildFile = __dirname + '/fixture/.atom-build.error-match-long-output.json';
+ const errorMatchMultiMatcherAtomBuildFile = __dirname + '/fixture/.atom-build.error-match-multiple-errorMatch.json';
+ const errorMatchFunction = __dirname + '/fixture/.atom-build.error-match-function.js';
+ const matchFunctionWarning = __dirname + '/fixture/.atom-build.match-function-warning.js';
+ const warningMatchAtomBuildFile = __dirname + '/fixture/.atom-build.warning-match.json';
+ const functionChangeDirs = __dirname + '/fixture/.atom-build.match-function-change-dirs.js';
+ const originalHomedirFn = os.homedir;
+
+ let directory = null;
+ let workspaceElement = null;
+ const waitTime = process.env.CI ? 2400 : 200;
+
+ temp.track();
+
+ beforeEach(() => {
+ const createdHomeDir = temp.mkdirSync('atom-build-spec-home');
+ os.homedir = () => createdHomeDir;
+ directory = fs.realpathSync(temp.mkdirSync({ prefix: 'atom-build-spec-' })) + path.sep;
+ atom.project.setPaths([ directory ]);
+
+ atom.config.set('build.buildOnSave', false);
+ atom.config.set('build.panelVisibility', 'Toggle');
+ atom.config.set('build.saveOnBuild', false);
+ atom.config.set('build.scrollOnError', false);
+ atom.config.set('build.notificationOnRefresh', true);
+ atom.config.set('editor.fontSize', 14);
+ atom.notifications.clear();
+
+ jasmine.unspy(window, 'setTimeout');
+ jasmine.unspy(window, 'clearTimeout');
+
+ runs(() => {
+ workspaceElement = atom.views.getView(atom.workspace);
+ workspaceElement.setAttribute('style', 'width:9999px');
+ jasmine.attachToDOM(workspaceElement);
+ });
+
+ waitsForPromise(() => {
+ return atom.packages.activatePackage('build');
+ });
+ });
+
+ afterEach(() => {
+ os.homedir = originalHomedirFn;
+ try { fs.removeSync(directory); } catch (e) { console.warn('Failed to clean up: ', e); }
+ });
+
+ describe('when error matcher is configured incorrectly', () => {
+ it('should show an error if regex is invalid', () => {
+ fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({
+ cmd: 'return 1',
+ errorMatch: '(invalidRegex'
+ }));
+
+ runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger'));
+
+ waitsFor(() => {
+ return workspaceElement.querySelector('.build .title') &&
+ workspaceElement.querySelector('.build .title').classList.contains('error');
+ });
+
+ runs(() => {
+ const notification = atom.notifications.getNotifications().find(n => n.getMessage() === 'Error matching failed!');
+ expect(notification).not.toBe(undefined);
+ expect(notification.getType()).toEqual('error');
+ expect(notification.options.detail).toMatch(/Unterminated group/);
+ });
+ });
+ });
+
+ describe('when output is captured to show editor on error', () => {
+ it('should place the line and column on error in correct file', () => {
+ expect(workspaceElement.querySelector('.build')).not.toExist();
+
+ fs.writeFileSync(directory + '.atom-build.json', fs.readFileSync(errorMatchAtomBuildFile));
+
+ runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger'));
+
+ waitsFor(() => {
+ return workspaceElement.querySelector('.build .title') &&
+ workspaceElement.querySelector('.build .title').classList.contains('error');
+ });
+
+ runs(() => {
+ atom.commands.dispatch(workspaceElement, 'build:error-match');
+ });
+
+ waitsFor(() => {
+ return atom.workspace.getActiveTextEditor();
+ });
+
+ runs(() => {
+ const editor = atom.workspace.getActiveTextEditor();
+ const bufferPosition = editor.getCursorBufferPosition();
+ expect(editor.getTitle()).toEqual('.atom-build.json');
+ expect(bufferPosition.row).toEqual(2);
+ expect(bufferPosition.column).toEqual(7);
+ });
+ });
+
+ it('should place the line and column on warning in correct file', () => {
+ expect(workspaceElement.querySelector('.build')).not.toExist();
+ atom.config.set('build.matchedErrorFailsBuild', true);
+
+ fs.writeFileSync(directory + '.atom-build.json', fs.readFileSync(warningMatchAtomBuildFile));
+
+ runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger'));
+
+ waitsFor(() => {
+ return workspaceElement.querySelector('.build .title') &&
+ workspaceElement.querySelector('.build .title').classList.contains('success');
+ });
+
+ runs(() => {
+ expect(workspaceElement.querySelector('.build .title').classList.contains('error')).not.toExist();
+ atom.commands.dispatch(workspaceElement, 'build:error-match');
+ });
+
+ waitsFor(() => {
+ return atom.workspace.getActiveTextEditor();
+ });
+
+ runs(() => {
+ const editor = atom.workspace.getActiveTextEditor();
+ const bufferPosition = editor.getCursorBufferPosition();
+ expect(editor.getTitle()).toEqual('.atom-build.json');
+ expect(bufferPosition.row).toEqual(2);
+ expect(bufferPosition.column).toEqual(7);
+ });
+ });
+
+ it('should give an error if matched file does not exist', () => {
+ expect(workspaceElement.querySelector('.build')).not.toExist();
+
+ fs.writeFileSync(directory + '.atom-build.json', fs.readFileSync(errorMatchNoFileBuildFile));
+
+ runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger'));
+
+ waitsFor(() => {
+ return workspaceElement.querySelector('.build .title') &&
+ workspaceElement.querySelector('.build .title').classList.contains('error');
+ });
+
+ runs(() => {
+ atom.commands.dispatch(workspaceElement, 'build:error-match');
+ });
+
+ waitsFor(() => atom.notifications.getNotifications().find(n => n.getMessage() === 'Error matching failed!'));
+
+ runs(() => {
+ const notification = atom.notifications.getNotifications().find(n => n.getMessage() === 'Error matching failed!');
+ expect(notification).not.toBe(undefined);
+ expect(notification.getType()).toEqual('error');
+ expect(notification.getMessage()).toEqual('Error matching failed!');
+ });
+ });
+
+ it('should open just the file if line and column is not available', () => {
+ expect(workspaceElement.querySelector('.build')).not.toExist();
+
+ fs.writeFileSync(directory + '.atom-build.json', fs.readFileSync(errorMatchNLCAtomBuildFile));
+
+ runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger'));
+
+ waitsFor(() => {
+ return workspaceElement.querySelector('.build .title') &&
+ workspaceElement.querySelector('.build .title').classList.contains('error');
+ });
+
+ runs(() => {
+ atom.commands.dispatch(workspaceElement, 'build:error-match');
+ });
+
+ waitsFor(() => {
+ return atom.workspace.getActiveTextEditor();
+ });
+
+ runs(() => {
+ const editor = atom.workspace.getActiveTextEditor();
+ expect(editor.getTitle()).toEqual('.atom-build.json');
+ });
+ });
+
+ it('should cycle through the file if multiple error occurred', () => {
+ expect(workspaceElement.querySelector('.build')).not.toExist();
+
+ fs.writeFileSync(directory + '.atom-build.json', fs.readFileSync(errorMatchMultiAtomBuildFile));
+
+ runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger'));
+
+ waitsFor(() => {
+ return workspaceElement.querySelector('.build .title') &&
+ workspaceElement.querySelector('.build .title').classList.contains('error');
+ });
+
+ runs(() => {
+ atom.commands.dispatch(workspaceElement, 'build:error-match');
+ });
+
+ waitsFor(() => {
+ return atom.workspace.getActiveTextEditor();
+ });
+
+ runs(() => {
+ const editor = atom.workspace.getActiveTextEditor();
+ const bufferPosition = editor.getCursorBufferPosition();
+ expect(editor.getTitle()).toEqual('.atom-build.json');
+ expect(bufferPosition.row).toEqual(2);
+ expect(bufferPosition.column).toEqual(7);
+ atom.workspace.getActivePane().destroy();
+ });
+
+ runs(() => {
+ atom.commands.dispatch(workspaceElement, 'build:error-match');
+ });
+
+ waitsFor(() => {
+ return atom.workspace.getActiveTextEditor();
+ });
+
+ runs(() => {
+ const editor = atom.workspace.getActiveTextEditor();
+ const bufferPosition = editor.getCursorBufferPosition();
+ expect(editor.getTitle()).toEqual('.atom-build.json');
+ expect(bufferPosition.row).toEqual(1);
+ expect(bufferPosition.column).toEqual(4);
+ atom.workspace.getActivePane().destroyActiveItem();
+ });
+
+ runs(() => {
+ atom.commands.dispatch(workspaceElement, 'build:error-match');
+ });
+
+ waitsFor(() => {
+ return atom.workspace.getActiveTextEditor();
+ });
+
+ runs(() => {
+ const editor = atom.workspace.getActiveTextEditor();
+ const bufferPosition = editor.getCursorBufferPosition();
+ expect(editor.getTitle()).toEqual('.atom-build.json');
+ expect(bufferPosition.row).toEqual(2);
+ expect(bufferPosition.column).toEqual(7);
+ });
+ });
+
+ it('should jump to first error', () => {
+ expect(workspaceElement.querySelector('.build')).not.toExist();
+
+ fs.writeFileSync(directory + '.atom-build.json', fs.readFileSync(errorMatchMultiFirstAtomBuildFile));
+
+ runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger'));
+
+ waitsFor(() => {
+ return workspaceElement.querySelector('.build .title') &&
+ workspaceElement.querySelector('.build .title').classList.contains('error');
+ });
+
+ runs(() => {
+ atom.commands.dispatch(workspaceElement, 'build:error-match-first');
+ });
+
+ waitsFor(() => {
+ return atom.workspace.getActiveTextEditor();
+ });
+
+ runs(() => {
+ const editor = atom.workspace.getActiveTextEditor();
+ const bufferPosition = editor.getCursorBufferPosition();
+ expect(editor.getTitle()).toEqual('.atom-build.json');
+ expect(bufferPosition.row).toEqual(2);
+ expect(bufferPosition.column).toEqual(7);
+ atom.workspace.getActivePane().destroy();
+ });
+
+ runs(() => {
+ atom.commands.dispatch(workspaceElement, 'build:error-match');
+ });
+
+ waitsFor(() => {
+ return atom.workspace.getActiveTextEditor();
+ });
+
+ runs(() => {
+ const editor = atom.workspace.getActiveTextEditor();
+ const bufferPosition = editor.getCursorBufferPosition();
+ expect(editor.getTitle()).toEqual('.atom-build.json');
+ expect(bufferPosition.row).toEqual(1);
+ expect(bufferPosition.column).toEqual(4);
+ atom.workspace.getActivePane().destroyActiveItem();
+ });
+
+ runs(() => {
+ atom.commands.dispatch(workspaceElement, 'build:error-match-first');
+ });
+
+ waitsFor(() => {
+ return atom.workspace.getActiveTextEditor();
+ });
+
+ runs(() => {
+ const editor = atom.workspace.getActiveTextEditor();
+ const bufferPosition = editor.getCursorBufferPosition();
+ expect(editor.getTitle()).toEqual('.atom-build.json');
+ expect(bufferPosition.row).toEqual(2);
+ expect(bufferPosition.column).toEqual(7);
+ });
+ });
+
+ it('should open the file even if tool gives absolute path', () => {
+ fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({
+ cmd: 'echo __' + directory + '.atom-build.json__ && exit 1',
+ errorMatch: '__(?.+)__'
+ }));
+
+ runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger'));
+
+ waitsFor(() => {
+ return workspaceElement.querySelector('.build .title') &&
+ workspaceElement.querySelector('.build .title').classList.contains('error');
+ });
+
+ runs(() => {
+ return atom.commands.dispatch(workspaceElement, 'build:error-match-first');
+ });
+
+ waitsFor(() => {
+ return atom.workspace.getActiveTextEditor();
+ });
+
+ runs(() => {
+ const editor = atom.workspace.getActiveTextEditor();
+ expect(editor.getPath()).toEqual(directory + '.atom-build.json');
+ });
+ });
+
+ it('should prepend `cwd` to the relative matched file if set', () => {
+ const atomBuild = {
+ cmd: 'echo __.atom-build.json__ && exit 1',
+ cwd: directory,
+ errorMatch: '__(?.+)__'
+ };
+ fs.writeFileSync(directory + '.atom-build.json', JSON.stringify(atomBuild));
+
+ runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger'));
+
+ waitsFor(() => {
+ return workspaceElement.querySelector('.build .title') &&
+ workspaceElement.querySelector('.build .title').classList.contains('error');
+ });
+
+ runs(() => {
+ return atom.commands.dispatch(workspaceElement, 'build:error-match-first');
+ });
+
+ waitsFor(() => {
+ return atom.workspace.getActiveTextEditor();
+ });
+
+ runs(() => {
+ // Error match one more time to make sure `cwd` isn't prepended multiple times
+ atom.workspace.getActivePaneItem().destroy();
+ });
+
+ waitsFor(() => {
+ return !atom.workspace.getActiveTextEditor();
+ });
+
+ runs(() => {
+ return atom.commands.dispatch(workspaceElement, 'build:error-match-first');
+ });
+
+ waitsFor(() => {
+ return atom.workspace.getActiveTextEditor();
+ });
+
+ runs(() => {
+ const editor = atom.workspace.getActiveTextEditor();
+ expect(editor.getPath()).toEqual(directory + '.atom-build.json');
+ });
+ });
+
+ it('should auto match error on failed build when config is set', () => {
+ atom.config.set('build.scrollOnError', true);
+
+ fs.writeFileSync(directory + '.atom-build.json', fs.readFileSync(errorMatchAtomBuildFile));
+
+ runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger'));
+
+ waitsFor(() => {
+ return workspaceElement.querySelector('.build .title') &&
+ workspaceElement.querySelector('.build .title').classList.contains('error');
+ });
+
+ waitsFor(() => {
+ return atom.workspace.getActiveTextEditor();
+ });
+
+ runs(() => {
+ const editor = atom.workspace.getActiveTextEditor();
+ const bufferPosition = editor.getCursorBufferPosition();
+ expect(editor.getTitle()).toEqual('.atom-build.json');
+ expect(bufferPosition.row).toEqual(2);
+ expect(bufferPosition.column).toEqual(7);
+ });
+ });
+
+ it('should scroll the build panel to the text of the error', () => {
+ expect(workspaceElement.querySelector('.build')).not.toExist();
+ fs.writeFileSync(directory + '.atom-build.json', fs.readFileSync(errorMatchLongOutputAtomBuildFile));
+
+ runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger'));
+
+ waitsFor(() => {
+ return workspaceElement.querySelector('.build .title') &&
+ workspaceElement.querySelector('.build .title').classList.contains('error');
+ });
+
+ runs(() => {
+ atom.commands.dispatch(workspaceElement, 'build:error-match');
+ });
+
+ waits(waitTime);
+ runs(() => {
+ expect(workspaceElement.querySelector('.terminal').terminal.ydisp).toEqual(6);
+ atom.commands.dispatch(workspaceElement, 'build:error-match');
+ });
+
+ waits(waitTime);
+ runs(() => {
+ expect(workspaceElement.querySelector('.terminal').terminal.ydisp).toEqual(12);
+ atom.commands.dispatch(workspaceElement, 'build:error-match');
+ });
+
+ waits(waitTime);
+ runs(() => {
+ /* Should wrap around to first match */
+ expect(workspaceElement.querySelector('.terminal').terminal.ydisp).toEqual(6);
+ });
+ });
+
+ it('match-first should scroll the build panel', () => {
+ expect(workspaceElement.querySelector('.build')).not.toExist();
+ fs.writeFileSync(directory + '.atom-build.json', fs.readFileSync(errorMatchLongOutputAtomBuildFile));
+
+ runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger'));
+
+ waitsFor(() => {
+ return workspaceElement.querySelector('.build .title') &&
+ workspaceElement.querySelector('.build .title').classList.contains('error');
+ });
+
+ runs(() => {
+ atom.commands.dispatch(workspaceElement, 'build:error-match');
+ });
+
+ waits(waitTime);
+ runs(() => {
+ expect(workspaceElement.querySelector('.terminal').terminal.ydisp).toEqual(6);
+ atom.commands.dispatch(workspaceElement, 'build:error-match');
+ });
+
+ waits(waitTime);
+ runs(() => {
+ expect(workspaceElement.querySelector('.terminal').terminal.ydisp).toEqual(12);
+ atom.commands.dispatch(workspaceElement, 'build:error-match-first');
+ });
+
+ waits(waitTime);
+ runs(() => {
+ expect(workspaceElement.querySelector('.terminal').terminal.ydisp).toEqual(6);
+ });
+ });
+
+ it('should match multiple regexes in the correct order', () => {
+ expect(workspaceElement.querySelector('.build')).not.toExist();
+
+ fs.writeFileSync(directory + '.atom-build.json', fs.readFileSync(errorMatchMultiMatcherAtomBuildFile));
+
+ runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger'));
+
+ waitsFor(() => {
+ return workspaceElement.querySelector('.build .title') &&
+ workspaceElement.querySelector('.build .title').classList.contains('error');
+ });
+
+ runs(() => {
+ atom.commands.dispatch(workspaceElement, 'build:error-match');
+ });
+
+ waitsFor(() => {
+ return atom.workspace.getActiveTextEditor();
+ });
+
+ runs(() => {
+ const editor = atom.workspace.getActiveTextEditor();
+ const bufferPosition = editor.getCursorBufferPosition();
+ expect(editor.getTitle()).toEqual('.atom-build.json');
+ expect(bufferPosition.row).toEqual(2);
+ expect(bufferPosition.column).toEqual(7);
+ atom.workspace.getActivePane().destroyActiveItem();
+ });
+
+ runs(() => {
+ atom.commands.dispatch(workspaceElement, 'build:error-match');
+ });
+
+ waitsFor(() => {
+ return atom.workspace.getActiveTextEditor();
+ });
+
+ runs(() => {
+ const editor = atom.workspace.getActiveTextEditor();
+ const bufferPosition = editor.getCursorBufferPosition();
+ expect(editor.getTitle()).toEqual('.atom-build.json');
+ expect(bufferPosition.row).toEqual(0);
+ expect(bufferPosition.column).toEqual(1);
+ atom.workspace.getActivePane().destroyActiveItem();
+ });
+
+ runs(() => {
+ atom.commands.dispatch(workspaceElement, 'build:error-match');
+ });
+
+ waitsFor(() => {
+ return atom.workspace.getActiveTextEditor();
+ });
+
+ runs(() => {
+ const editor = atom.workspace.getActiveTextEditor();
+ const bufferPosition = editor.getCursorBufferPosition();
+ expect(editor.getTitle()).toEqual('.atom-build.json');
+ expect(bufferPosition.row).toEqual(1);
+ expect(bufferPosition.column).toEqual(4);
+ });
+ });
+
+ it('should run javascript functions that return matches', () => {
+ expect(workspaceElement.querySelector('.build')).not.toExist();
+
+ fs.writeFileSync(directory + '.atom-build.js', fs.readFileSync(errorMatchFunction));
+
+ runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger'));
+
+ waitsFor(() => {
+ return workspaceElement.querySelector('.build .title') &&
+ workspaceElement.querySelector('.build .title').classList.contains('error');
+ });
+
+ runs(() => {
+ atom.commands.dispatch(workspaceElement, 'build:error-match');
+ });
+
+ waitsFor(() => {
+ return atom.workspace.getActiveTextEditor();
+ });
+
+ runs(() => {
+ const editor = atom.workspace.getActiveTextEditor();
+ const bufferPosition = editor.getCursorBufferPosition();
+ expect(editor.getTitle()).toEqual('.atom-build.js');
+ expect(bufferPosition.row).toEqual(0);
+ expect(bufferPosition.column).toEqual(4);
+ atom.workspace.getActivePane().destroyActiveItem();
+ });
+
+ runs(() => {
+ atom.commands.dispatch(workspaceElement, 'build:error-match');
+ });
+
+ waitsFor(() => {
+ return atom.workspace.getActiveTextEditor();
+ });
+
+ runs(() => {
+ const editor = atom.workspace.getActiveTextEditor();
+ const bufferPosition = editor.getCursorBufferPosition();
+ expect(editor.getTitle()).toEqual('.atom-build.js');
+ expect(bufferPosition.row).toEqual(1);
+ expect(bufferPosition.column).toEqual(0);
+ atom.workspace.getActivePane().destroyActiveItem();
+ });
+
+ runs(() => {
+ atom.commands.dispatch(workspaceElement, 'build:error-match');
+ });
+
+ waitsFor(() => {
+ return atom.workspace.getActiveTextEditor();
+ });
+
+ runs(() => {
+ const editor = atom.workspace.getActiveTextEditor();
+ const bufferPosition = editor.getCursorBufferPosition();
+ expect(editor.getTitle()).toEqual('.atom-build.js');
+ expect(bufferPosition.row).toEqual(4);
+ expect(bufferPosition.column).toEqual(0);
+ });
+ });
+
+ it('should be possible to change the type of the match to something other than `Error`', () => {
+ expect(workspaceElement.querySelector('.build')).not.toExist();
+
+ fs.writeFileSync(directory + '.atom-build.js', fs.readFileSync(matchFunctionWarning));
+
+ runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger'));
+
+ waitsFor(() => {
+ return workspaceElement.querySelector('.build .title') &&
+ workspaceElement.querySelector('.build .title').classList.contains('success');
+ });
+
+ runs(() => {
+ atom.commands.dispatch(workspaceElement, 'build:error-match');
+ });
+
+ waitsFor(() => {
+ return atom.workspace.getActiveTextEditor();
+ });
+
+ runs(() => {
+ const editor = atom.workspace.getActiveTextEditor();
+ const bufferPosition = editor.getCursorBufferPosition();
+ expect(editor.getTitle()).toEqual('.atom-build.js');
+ expect(bufferPosition.row).toEqual(4);
+ expect(bufferPosition.column).toEqual(0);
+ });
+ });
+ });
+
+ describe('when using function matches', () => {
+ it('should be possible to keep state from previous lines', () => {
+ expect(workspaceElement.querySelector('.build')).not.toExist();
+ fs.writeFileSync(directory + '.atom-build.js', fs.readFileSync(functionChangeDirs));
+ fs.writeFileSync(directory + 'change_dir_output.txt', fs.readFileSync(__dirname + '/fixture/change_dir_output.txt'));
+ fs.mkdirSync(directory + 'foo');
+ fs.mkdirSync(directory + 'foo/src');
+ fs.writeFileSync(directory + 'foo/src/testmake.c', 'lorem ipsum\naquarium laudanum\nbabaorum petibonum\nthe cake is a lie');
+
+ runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger'));
+
+ waitsFor(() => {
+ return workspaceElement.querySelector('.build .title') &&
+ workspaceElement.querySelector('.build .title').classList.contains('error');
+ });
+ runs(() => {
+ atom.commands.dispatch(workspaceElement, 'build:error-match');
+ });
+
+ waitsFor(() => {
+ return atom.workspace.getActiveTextEditor();
+ });
+
+ runs(() => {
+ const editor = atom.workspace.getActiveTextEditor();
+ const bufferPosition = editor.getCursorBufferPosition();
+ expect(editor.getTitle()).toEqual('testmake.c');
+ expect(bufferPosition.row).toEqual(2);
+ expect(bufferPosition.column).toEqual(4);
+ });
+ });
+ });
+
+ describe('when build is cancelled', () => {
+ it('should still be possible to errormatch', () => {
+ expect(workspaceElement.querySelector('.build')).not.toExist();
+
+ fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({
+ cmd: `echo ".atom-build.json:1:5." && ${sleep(30)} && echo "Done!"`,
+ errorMatch: '(?.atom-build.json):(?1):(?5)'
+ }));
+
+ runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger'));
+
+ // Let build run for one second before we terminate it
+ waits(1000);
+
+ runs(() => {
+ expect(workspaceElement.querySelector('.build')).toExist();
+ atom.commands.dispatch(workspaceElement, 'build:stop');
+ atom.commands.dispatch(workspaceElement, 'build:stop');
+ });
+
+ waitsFor(() => {
+ return workspaceElement.querySelector('.build .title') &&
+ workspaceElement.querySelector('.build .title').classList.contains('error');
+ });
+
+ runs(() => {
+ atom.commands.dispatch(workspaceElement, 'build:error-match');
+ });
+
+ waitsFor(() => {
+ return atom.workspace.getActiveTextEditor();
+ });
+
+ runs(() => {
+ const editor = atom.workspace.getActiveTextEditor();
+ const bufferPosition = editor.getCursorBufferPosition();
+ expect(editor.getTitle()).toEqual('.atom-build.json');
+ expect(bufferPosition.row).toEqual(0);
+ expect(bufferPosition.column).toEqual(4);
+ });
+ });
+ });
+});
diff --git a/spec/build-hooks-spec.js b/spec/build-hooks-spec.js
new file mode 100644
index 00000000..b42a9fa1
--- /dev/null
+++ b/spec/build-hooks-spec.js
@@ -0,0 +1,107 @@
+'use babel';
+
+import fs from 'fs-extra';
+import temp from 'temp';
+import specHelpers from 'atom-build-spec-helpers';
+
+describe('Hooks', () => {
+ let directory = null;
+ let workspaceElement = null;
+ const succeedingCommandName = 'build:hook-test:succeeding';
+ const failingCommandName = 'build:hook-test:failing';
+ const dummyPackageName = 'atom-build-hooks-dummy-package';
+ const dummyPackagePath = __dirname + '/fixture/' + dummyPackageName;
+
+ temp.track();
+
+ beforeEach(() => {
+ directory = fs.realpathSync(temp.mkdirSync({ prefix: 'atom-build-spec-' }));
+ atom.project.setPaths([ directory ]);
+
+ atom.config.set('build.buildOnSave', false);
+ atom.config.set('build.panelVisibility', 'Toggle');
+ atom.config.set('build.saveOnBuild', false);
+ atom.config.set('build.notificationOnRefresh', true);
+
+ jasmine.unspy(window, 'setTimeout');
+ jasmine.unspy(window, 'clearTimeout');
+
+ runs(() => {
+ workspaceElement = atom.views.getView(atom.workspace);
+ jasmine.attachToDOM(workspaceElement);
+ });
+
+ waitsForPromise(() => {
+ return Promise.resolve()
+ .then(() => atom.packages.activatePackage('build'))
+ .then(() => atom.packages.activatePackage(dummyPackagePath));
+ });
+
+ waitsForPromise(() => specHelpers.refreshAwaitTargets());
+ });
+
+ afterEach(() => {
+ try { fs.removeSync(directory); } catch (e) { console.warn('Failed to clean up: ', e); }
+ });
+
+ it('should call preBuild', () => {
+ let pkg;
+
+ runs(() => {
+ pkg = atom.packages.getActivePackage(dummyPackageName).mainModule;
+ spyOn(pkg.hooks, 'preBuild');
+
+ atom.commands.dispatch(workspaceElement, succeedingCommandName);
+ });
+
+ waitsFor(() => {
+ return workspaceElement.querySelector('.build .title');
+ });
+
+ runs(() => {
+ expect(pkg.hooks.preBuild).toHaveBeenCalled();
+ });
+ });
+
+ describe('postBuild', () => {
+ it('should be called with `true` as an argument when build succeded', () => {
+ let pkg;
+
+ runs(() => {
+ pkg = atom.packages.getActivePackage(dummyPackageName).mainModule;
+ spyOn(pkg.hooks, 'postBuild');
+
+ atom.commands.dispatch(workspaceElement, succeedingCommandName);
+ });
+
+ waitsFor(() => {
+ return workspaceElement.querySelector('.build .title') &&
+ workspaceElement.querySelector('.build .title').classList.contains('success');
+ });
+
+ runs(() => {
+ expect(pkg.hooks.postBuild).toHaveBeenCalledWith(true);
+ });
+ });
+
+ it('should be called with `false` as an argument when build failed', () => {
+ let pkg;
+
+ runs(() => {
+ pkg = atom.packages.getActivePackage(dummyPackageName).mainModule;
+ spyOn(pkg.hooks, 'postBuild');
+
+ atom.commands.dispatch(workspaceElement, failingCommandName);
+ });
+
+ waitsFor(() => {
+ return workspaceElement.querySelector('.build .title') &&
+ workspaceElement.querySelector('.build .title').classList.contains('error');
+ });
+
+ runs(() => {
+ expect(pkg.hooks.postBuild).toHaveBeenCalledWith(false);
+ });
+ });
+ });
+});
diff --git a/spec/build-keymap-spec.js b/spec/build-keymap-spec.js
new file mode 100644
index 00000000..abe612a7
--- /dev/null
+++ b/spec/build-keymap-spec.js
@@ -0,0 +1,233 @@
+'use babel';
+
+import fs from 'fs-extra';
+import path from 'path';
+import temp from 'temp';
+import specHelpers from 'atom-build-spec-helpers';
+import os from 'os';
+
+describe('Keymap', () => {
+ const originalHomedirFn = os.homedir;
+ let directory = null;
+ let workspaceElement = null;
+
+ temp.track();
+
+ beforeEach(() => {
+ const createdHomeDir = temp.mkdirSync('atom-build-spec-home');
+ os.homedir = () => createdHomeDir;
+ directory = fs.realpathSync(temp.mkdirSync({ prefix: 'atom-build-spec-' })) + path.sep;
+ atom.project.setPaths([ directory ]);
+
+ atom.config.set('build.buildOnSave', false);
+ atom.config.set('build.panelVisibility', 'Toggle');
+ atom.config.set('build.saveOnBuild', false);
+ atom.config.set('build.notificationOnRefresh', true);
+
+ jasmine.unspy(window, 'setTimeout');
+ jasmine.unspy(window, 'clearTimeout');
+
+ runs(() => {
+ workspaceElement = atom.views.getView(atom.workspace);
+ workspaceElement.setAttribute('style', 'width:9999px');
+ jasmine.attachToDOM(workspaceElement);
+ });
+
+ waitsForPromise(() => {
+ return atom.packages.activatePackage('build');
+ });
+ });
+
+ afterEach(() => {
+ os.homedir = originalHomedirFn;
+ try { fs.removeSync(directory); } catch (e) { console.warn('Failed to clean up: ', e); }
+ });
+
+ describe('when custom keymap is defined in .atom-build.json', () => {
+ it('should trigger the build when that key combination is pressed', () => {
+ fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({
+ name: 'The default build',
+ cmd: 'echo default',
+ targets: {
+ 'keymapped build': {
+ cmd: 'echo keymapped',
+ keymap: 'ctrl-alt-k'
+ }
+ }
+ }));
+
+ runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger'));
+
+ waitsFor(() => {
+ return workspaceElement.querySelector('.build .title') &&
+ workspaceElement.querySelector('.build .title').classList.contains('success');
+ });
+
+ runs(() => {
+ expect(workspaceElement.querySelector('.terminal').terminal.getContent()).toMatch(/default/);
+ atom.commands.dispatch(workspaceElement, 'build:toggle-panel');
+ });
+
+ waitsFor(() => {
+ return !workspaceElement.querySelector('.build .title');
+ });
+
+ runs(() => {
+ const key = atom.keymaps.constructor.buildKeydownEvent('k', { ctrl: true, alt: true, target: workspaceElement });
+ atom.keymaps.handleKeyboardEvent(key);
+ });
+
+ waitsFor(() => {
+ return workspaceElement.querySelector('.build .title') &&
+ workspaceElement.querySelector('.build .title').classList.contains('success');
+ });
+
+ runs(() => {
+ expect(workspaceElement.querySelector('.terminal').terminal.getContent()).toMatch(/keymapped/);
+ });
+ });
+
+ it('should not changed the set active build', () => {
+ fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({
+ name: 'The default build',
+ cmd: 'echo default',
+ targets: {
+ 'keymapped build': {
+ cmd: 'echo keymapped',
+ keymap: 'ctrl-alt-k'
+ }
+ }
+ }));
+
+ runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger'));
+
+ waitsFor(() => {
+ return workspaceElement.querySelector('.build .title') &&
+ workspaceElement.querySelector('.build .title').classList.contains('success');
+ });
+
+ runs(() => {
+ expect(workspaceElement.querySelector('.terminal').terminal.getContent()).toMatch(/default/);
+ atom.commands.dispatch(workspaceElement, 'build:toggle-panel');
+ });
+
+ waitsFor(() => {
+ return !workspaceElement.querySelector('.build .title');
+ });
+
+ runs(() => {
+ const key = atom.keymaps.constructor.buildKeydownEvent('k', { ctrl: true, alt: true, target: workspaceElement });
+ atom.keymaps.handleKeyboardEvent(key);
+ });
+
+ waitsFor(() => {
+ return workspaceElement.querySelector('.build .title') &&
+ workspaceElement.querySelector('.build .title').classList.contains('success');
+ });
+
+ runs(() => {
+ expect(workspaceElement.querySelector('.terminal').terminal.getContent()).toMatch(/keymapped/);
+ atom.commands.dispatch(workspaceElement, 'build:toggle-panel');
+ });
+
+ waitsFor(() => {
+ return !workspaceElement.querySelector('.build .title');
+ });
+
+ runs(() => {
+ atom.commands.dispatch(workspaceElement, 'build:trigger');
+ });
+
+ waitsFor(() => {
+ return workspaceElement.querySelector('.build .title') &&
+ workspaceElement.querySelector('.build .title').classList.contains('success');
+ });
+
+ runs(() => {
+ expect(workspaceElement.querySelector('.terminal').terminal.getContent()).toMatch(/default/);
+ atom.commands.dispatch(workspaceElement, 'build:toggle-panel');
+ });
+ });
+
+ it('should dispose keymap when reloading targets', () => {
+ fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({
+ name: 'The default build',
+ cmd: 'echo default',
+ targets: {
+ 'keymapped build': {
+ cmd: 'echo keymapped',
+ keymap: 'ctrl-alt-k'
+ }
+ }
+ }));
+
+ runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger'));
+
+ waitsFor(() => {
+ return workspaceElement.querySelector('.build .title') &&
+ workspaceElement.querySelector('.build .title').classList.contains('success');
+ });
+
+ runs(() => {
+ expect(workspaceElement.querySelector('.terminal').terminal.getContent()).toMatch(/default/);
+ });
+
+ waitsFor(() => {
+ return !workspaceElement.querySelector('.build .title');
+ });
+
+ runs(() => {
+ const key = atom.keymaps.constructor.buildKeydownEvent('k', { ctrl: true, alt: true, target: workspaceElement });
+ atom.keymaps.handleKeyboardEvent(key);
+ });
+
+ waitsFor(() => {
+ return workspaceElement.querySelector('.build .title') &&
+ workspaceElement.querySelector('.build .title').classList.contains('success');
+ });
+
+ runs(() => {
+ expect(workspaceElement.querySelector('.terminal').terminal.getContent()).toMatch(/keymapped/);
+ atom.commands.dispatch(workspaceElement, 'build:toggle-panel');
+ fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({
+ name: 'The default build',
+ cmd: 'echo default',
+ targets: {
+ 'keymapped build': {
+ cmd: 'echo ctrl-x new file',
+ keymap: 'ctrl-x'
+ }
+ }
+ }));
+ });
+
+ waitsForPromise(() => specHelpers.awaitTargets());
+
+ waitsFor(() => {
+ return !workspaceElement.querySelector('.build .title');
+ });
+
+ runs(() => {
+ const key = atom.keymaps.constructor.buildKeydownEvent('k', { ctrl: true, alt: true, target: workspaceElement });
+ atom.keymaps.handleKeyboardEvent(key);
+ });
+
+ waits(300);
+
+ runs(() => {
+ expect(workspaceElement.querySelector('.build')).not.toExist();
+ const key = atom.keymaps.constructor.buildKeydownEvent('x', { ctrl: true, target: workspaceElement });
+ atom.keymaps.handleKeyboardEvent(key);
+ });
+
+ waitsFor(() => {
+ return workspaceElement.querySelector('.build .title') &&
+ workspaceElement.querySelector('.build .title').classList.contains('success');
+ });
+
+ runs(() => {
+ expect(workspaceElement.querySelector('.terminal').terminal.getContent()).toMatch(/ctrl-x new file/);
+ });
+ });
+ });
+});
diff --git a/spec/build-spec.js b/spec/build-spec.js
index 3ce735d7..857762de 100644
--- a/spec/build-spec.js
+++ b/spec/build-spec.js
@@ -1,983 +1,581 @@
-var fs = require('fs-plus');
-var path = require('path');
-var temp = require('temp');
-var _ = require('lodash');
-
-describe('Build', function() {
- 'use strict';
-
- var goodMakefile = __dirname + '/fixture/Makefile.good';
- var badMakefile = __dirname + '/fixture/Makefile.bad';
- var longMakefile = __dirname + '/fixture/Makefile.long';
- var escapeMakefile = __dirname + '/fixture/Makefile.escape';
- var goodGruntfile = __dirname + '/fixture/Gruntfile.js';
- var goodGulpfile = __dirname + '/fixture/gulpfile.js';
- var goodNodefile = __dirname + '/fixture/package.json.node';
- var goodAtomfile = __dirname + '/fixture/package.json.atom';
- var badPackageJsonfile = __dirname + '/fixture/package.json.noengine';
- var goodAtomBuildfile = __dirname + '/fixture/.atom-build.json';
- var shellAtomBuildfile = __dirname + '/fixture/.atom-build.shell.json';
- var replaceAtomBuildFile = __dirname + '/fixture/.atom-build.replace.json';
- var shFalseAtomBuildFile = __dirname + '/fixture/.atom-build.sh-false.json';
- var shTrueAtomBuildFile = __dirname + '/fixture/.atom-build.sh-true.json';
- var shDefaultAtomBuildFile = __dirname + '/fixture/.atom-build.sh-default.json';
- var syntaxErrorAtomBuildFile = __dirname + '/fixture/.atom-build.syntax-error.json';
- var errorMatchAtomBuildFile = __dirname + '/fixture/.atom-build.error-match.json';
- var errorMatchNLCAtomBuildFile = __dirname + '/fixture/.atom-build.error-match-no-line-col.json';
- var errorMatchMultiAtomBuildFile = __dirname + '/fixture/.atom-build.error-match-multiple.json';
- var errorMatchMultiFirstAtomBuildFile = __dirname + '/fixture/.atom-build.error-match-multiple-first.json';
-
- var directory = null;
- var workspaceElement = null;
+'use babel';
+
+import fs from 'fs-extra';
+import path from 'path';
+import temp from 'temp';
+import specHelpers from 'atom-build-spec-helpers';
+import os from 'os';
+import { sleep, cat, shellCmd, waitTime } from './helpers';
+
+describe('Build', () => {
+ const goodAtomBuildfile = __dirname + '/fixture/.atom-build.json';
+ const shellAtomBuildfile = __dirname + '/fixture/.atom-build.shell.json';
+ const replaceAtomBuildFile = __dirname + '/fixture/.atom-build.replace.json';
+ const shFalseAtomBuildFile = __dirname + '/fixture/.atom-build.sh-false.json';
+ const shTrueAtomBuildFile = __dirname + '/fixture/.atom-build.sh-true.json';
+ const shDefaultAtomBuildFile = __dirname + '/fixture/.atom-build.sh-default.json';
+ const syntaxErrorAtomBuildFile = __dirname + '/fixture/.atom-build.syntax-error.json';
+ const originalHomedirFn = os.homedir;
+
+ let directory = null;
+ let workspaceElement = null;
temp.track();
- beforeEach(function() {
- directory = fs.realpathSync(temp.mkdirSync({ prefix: 'atom-build-spec-' })) + '/';
- atom.project.setPaths([ directory ]);
-
+ beforeEach(() => {
atom.config.set('build.buildOnSave', false);
atom.config.set('build.panelVisibility', 'Toggle');
atom.config.set('build.saveOnBuild', false);
+ atom.config.set('build.stealFocus', true);
+ atom.config.set('build.notificationOnRefresh', true);
+ atom.notifications.clear();
- // Set up dependencies
- fs.copySync(path.join(__dirname, 'fixture', 'node_modules'), path.join(directory, 'node_modules'));
-
- // Set up grunt
- var binGrunt = path.join(directory, 'node_modules', '.bin', 'grunt');
- var realGrunt = path.join(directory, 'node_modules', 'grunt-cli', 'bin', 'grunt');
- fs.unlinkSync(binGrunt);
- fs.chmodSync(realGrunt, parseInt('0700', 8));
- fs.symlinkSync(realGrunt, binGrunt);
-
- // Set up gulp
- var binGulp = path.join(directory, 'node_modules', '.bin', 'gulp');
- var realGulp = path.join(directory, 'node_modules', 'gulp', 'bin', 'gulp.js');
- fs.unlinkSync(binGulp);
- fs.chmodSync(realGulp, parseInt('0700', 8));
- fs.symlinkSync(realGulp, binGulp);
-
+ workspaceElement = atom.views.getView(atom.workspace);
+ workspaceElement.setAttribute('style', 'width:9999px');
+ jasmine.attachToDOM(workspaceElement);
jasmine.unspy(window, 'setTimeout');
jasmine.unspy(window, 'clearTimeout');
- runs(function() {
- workspaceElement = atom.views.getView(atom.workspace);
- jasmine.attachToDOM(workspaceElement);
- });
-
- waitsForPromise(function() {
- return atom.packages.activatePackage('build');
- });
- });
-
- afterEach(function() {
- fs.removeSync(directory);
- });
-
- describe('when panel visibility is set to show on error', function() {
- it('should only show an the build panel if a build fails', function () {
- atom.config.set('build.panelVisibility', 'Show on Error');
-
- fs.writeFileSync(directory + 'Makefile', fs.readFileSync(goodMakefile));
- atom.commands.dispatch(workspaceElement, 'build:trigger');
-
- /* Give it some reasonable time to show itself if there is a bug */
- waits(1000);
-
- runs(function() {
- expect(workspaceElement.querySelector('.build')).not.toExist();
- });
-
- runs(function () {
- fs.writeFileSync(directory + 'Makefile', fs.readFileSync(badMakefile));
- atom.commands.dispatch(workspaceElement, 'build:trigger');
- });
-
- waitsFor(function() {
- return workspaceElement.querySelector('.build');
- });
-
- runs(function() {
- expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/Very bad\.\.\./);
+ waitsForPromise(() => {
+ return specHelpers.vouch(temp.mkdir, 'atom-build-spec-').then( (dir) => {
+ return specHelpers.vouch(fs.realpath, dir);
+ }).then( (dir) => {
+ directory = dir + path.sep;
+ atom.project.setPaths([ directory ]);
+ return specHelpers.vouch(temp.mkdir, 'atom-build-spec-home');
+ }).then( (dir) => {
+ return specHelpers.vouch(fs.realpath, dir);
+ }).then( (dir) => {
+ os.homedir = () => dir;
+ return atom.packages.activatePackage('build');
});
});
});
- describe('when package is activated', function() {
- it('should not show build window if panelVisibility is Toggle ', function() {
- expect(workspaceElement.querySelector('.build')).not.toExist();
- });
+ afterEach(() => {
+ os.homedir = originalHomedirFn;
+ try { fs.removeSync(directory); } catch (e) { console.warn('Failed to clean up: ', e); }
});
- describe('when build is triggered twice', function() {
- it('should not leave multiple panels behind', function() {
+ describe('when package is activated', () => {
+ it('should not show build window if panelVisibility is Toggle ', () => {
expect(workspaceElement.querySelector('.build')).not.toExist();
-
- atom.config.set('build.panelVisibility', 'Keep Visible');
-
- fs.writeFileSync(directory + 'Makefile', fs.readFileSync(goodMakefile));
- atom.commands.dispatch(workspaceElement, 'build:trigger');
-
- waitsFor(function() {
- return workspaceElement.querySelector('.build .title').classList.contains('success');
- });
-
- runs(function() {
- expect(workspaceElement.querySelectorAll('.bottom.tool-panel.panel-bottom').length).toBe(1);
- atom.commands.dispatch(workspaceElement, 'build:trigger');
- });
-
- waitsFor(function() {
- return workspaceElement.querySelector('.build .title').classList.contains('success');
- });
-
- runs(function() {
- expect(workspaceElement.querySelectorAll('.bottom.tool-panel.panel-bottom').length).toBe(1);
- });
});
});
- describe('when build is triggered with Makefile', function() {
- it('should not show the build window if no buildfile exists', function() {
+ describe('when building', () => {
+ it('should show build failed if build fails', () => {
expect(workspaceElement.querySelector('.build')).not.toExist();
- atom.commands.dispatch(workspaceElement, 'build:trigger');
+ fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({
+ cmd: 'echo Very bad... && exit 1'
+ }));
- runs(function() {
- expect(workspaceElement.querySelector('.build')).not.toExist();
- });
- });
+ runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger'));
- it('should show the build window if buildfile exists', function() {
- expect(workspaceElement.querySelector('.build')).not.toExist();
-
- fs.writeFileSync(directory + 'Makefile', fs.readFileSync(goodMakefile));
- atom.commands.dispatch(workspaceElement, 'build:trigger');
-
- waitsFor(function() {
- return workspaceElement.querySelector('.build .title').classList.contains('success');
+ waitsFor(() => {
+ return workspaceElement.querySelector('.build .title') &&
+ workspaceElement.querySelector('.build .title').classList.contains('error');
});
- runs(function() {
+ runs(() => {
expect(workspaceElement.querySelector('.build')).toExist();
- expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/Surprising is the passing of time\nbut not so, as the time of passing/);
+ expect(workspaceElement.querySelector('.terminal').terminal.getContent()).toMatch(/Very bad\.\.\./);
});
});
- it('should show build failed if build fails', function() {
+ it('should fail build, if errors are matched', () => {
expect(workspaceElement.querySelector('.build')).not.toExist();
- fs.writeFileSync(directory + 'Makefile', fs.readFileSync(badMakefile));
- atom.commands.dispatch(workspaceElement, 'build:trigger');
+ fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({
+ cmd: 'echo __ERROR__ && exit 0',
+ errorMatch: 'ERROR'
+ }));
- waitsFor(function() {
- return workspaceElement.querySelector('.build .title').classList.contains('error');
- });
+ runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger'));
- runs(function() {
- expect(workspaceElement.querySelector('.build')).toExist();
- expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/Very bad\.\.\./);
+ waitsFor(() => {
+ return workspaceElement.querySelector('.build .title') &&
+ workspaceElement.querySelector('.build .title').classList.contains('error');
});
});
- it('should cancel build when stopping it, and remove when stopping again', function() {
+ it('should cancel build when stopping it, and remove when stopping again', () => {
expect(workspaceElement.querySelector('.build')).not.toExist();
- fs.writeFileSync(directory + 'Makefile', fs.readFileSync(longMakefile));
- atom.commands.dispatch(workspaceElement, 'build:trigger');
+ fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({
+ cmd: `echo "Building, this will take some time..." && ${sleep(30)} && echo "Done!"`
+ }));
+
+ runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger'));
// Let build run for one second before we terminate it
waits(1000);
- runs(function() {
+ runs(() => {
expect(workspaceElement.querySelector('.build')).toExist();
- expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/Building, this will take some time.../);
+ expect(workspaceElement.querySelector('.terminal').terminal.getContent()).toMatch(/Building, this will take some time.../);
+ atom.commands.dispatch(workspaceElement, 'build:stop');
atom.commands.dispatch(workspaceElement, 'build:stop');
});
- waitsFor(function() {
- return workspaceElement.querySelector('.build .title').classList.contains('error');
+ waitsFor(() => {
+ return workspaceElement.querySelector('.build .title') &&
+ workspaceElement.querySelector('.build .title').classList.contains('error');
});
- runs(function() {
+ runs(() => {
atom.commands.dispatch(workspaceElement, 'build:stop');
});
- waitsFor(function() {
- return (workspaceElement.querySelector('.build .title').textContent == 'Aborted!');
+ waitsFor(() => {
+ return (!workspaceElement.querySelector('.build .title'));
});
});
- });
- describe('when build is triggered with grunt file', function() {
- it('should show the build window', function() {
+ it('should not show the build panel if no build file exists', () => {
expect(workspaceElement.querySelector('.build')).not.toExist();
- fs.writeFileSync(directory + 'Gruntfile.js', fs.readFileSync(goodGruntfile));
atom.commands.dispatch(workspaceElement, 'build:trigger');
- waitsFor(function() {
- return workspaceElement.querySelector('.build .title').classList.contains('success');
- });
+ /* Give it some time here. There's nothing to probe for as we expect the exact same state when done. */
+ waits(waitTime);
- runs(function() {
- expect(workspaceElement.querySelector('.build')).toExist();
- expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/Surprising is the passing of time. But not so, as the time of passing/);
+ runs(() => {
+ expect(workspaceElement.querySelector('.build')).not.toExist();
});
});
- });
- describe('when build is triggered with package.json file', function() {
- it('should show the build window if it is node engine', function() {
+ it('should automatically refresh if build is triggered an no targets are found', () => {
expect(workspaceElement.querySelector('.build')).not.toExist();
- fs.writeFileSync(directory + 'package.json', fs.readFileSync(goodNodefile));
+ fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({
+ cmd: 'echo hello world'
+ }));
+
atom.commands.dispatch(workspaceElement, 'build:trigger');
- waitsFor(function() {
- return workspaceElement.querySelector('.build .title').classList.contains('success');
- });
+ waitsFor(() =>
+ workspaceElement.querySelector('.build .title') &&
+ workspaceElement.querySelector('.build .title').classList.contains('success'));
- runs(function() {
- expect(workspaceElement.querySelector('.build')).toExist();
- expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/^Executing: npm/);
+ runs(() => {
+ expect(workspaceElement.querySelector('.terminal').terminal.getContent()).toMatch(/hello world/);
});
});
+ });
- it('should show the build window if it is atom engine', function() {
- if (process.env.TRAVIS) {
- return;
- }
-
+ describe('when build is triggered twice', () => {
+ it('should not leave multiple panels behind', () => {
expect(workspaceElement.querySelector('.build')).not.toExist();
- fs.writeFileSync(directory + 'package.json', fs.readFileSync(goodAtomfile));
- atom.commands.dispatch(workspaceElement, 'build:trigger');
+ atom.commands.dispatch(workspaceElement, 'build:toggle-panel');
- waitsFor(function() {
- return workspaceElement.querySelector('.build .title').classList.contains('success');
- }, 'build to be successful', 10000);
+ fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({
+ cmd: 'echo hello world'
+ }));
- runs(function() {
- expect(workspaceElement.querySelector('.build')).toExist();
- expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/^Executing: apm/);
+ runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger'));
+
+ waitsFor(() => {
+ return workspaceElement.querySelector('.build .title').classList.contains('success');
});
- });
- it('should not do anything if engines are not available in the file', function() {
- expect(workspaceElement.querySelector('.build')).not.toExist();
+ waits(50);
- fs.writeFileSync(directory + 'package.json', fs.readFileSync(badPackageJsonfile));
- atom.commands.dispatch(workspaceElement, 'build:trigger');
+ runs(() => {
+ expect(workspaceElement.querySelectorAll('.bottom.tool-panel.panel-bottom').length).toBe(1);
+ atom.commands.dispatch(workspaceElement, 'build:trigger');
+ });
- waits(1000);
+ waits(50);
- runs(function() {
- expect(workspaceElement.querySelector('.build')).not.toExist();
+ runs(() => {
+ expect(workspaceElement.querySelectorAll('.bottom.tool-panel.panel-bottom').length).toBe(1);
});
});
});
- describe('when custom .atom-build.json is available', function() {
- it('should show the build window', function() {
+ describe('when custom .atom-build.json is available', () => {
+ it('should show the build window', () => {
expect(workspaceElement.querySelector('.build')).not.toExist();
- fs.writeFileSync(directory + '.atom-build.json', fs.readFileSync(goodAtomBuildfile));
- atom.commands.dispatch(workspaceElement, 'build:trigger');
+ fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({
+ cmd: cat(),
+ args: [ '.atom-build.json' ]
+ }));
- waitsFor(function() {
- return workspaceElement.querySelector('.build .title').classList.contains('success');
+ runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger'));
+
+ waitsFor(() => {
+ return workspaceElement.querySelector('.build .title') &&
+ workspaceElement.querySelector('.build .title').classList.contains('success');
});
- runs(function() {
+ runs(() => {
expect(workspaceElement.querySelector('.build')).toExist();
- expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/"cmd": "dd"/);
+ expect(workspaceElement.querySelector('.terminal').terminal.getContent()).toMatch(/"args":\[".atom-build.json"\]/);
});
});
- it('should be possible to exec shell commands with wildcard expansion', function() {
+ it('should be possible to exec shell commands with wildcard expansion', () => {
expect(workspaceElement.querySelector('.build')).not.toExist();
fs.writeFileSync(directory + '.atom-build.json', fs.readFileSync(shellAtomBuildfile));
- atom.commands.dispatch(workspaceElement, 'build:trigger');
- waitsFor(function() {
- return workspaceElement.querySelector('.build .title').classList.contains('success');
+ runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger'));
+
+ waitsFor(() => {
+ return workspaceElement.querySelector('.build .title') &&
+ workspaceElement.querySelector('.build .title').classList.contains('success');
});
- runs(function() {
+ runs(() => {
expect(workspaceElement.querySelector('.build')).toExist();
- expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/Good news, everyone!/);
+ expect(workspaceElement.querySelector('.terminal').terminal.getContent()).toMatch(/Good news, everyone!/);
});
});
- it('should show sh message if sh is true', function() {
+ it('should show sh message if sh is true', () => {
expect(workspaceElement.querySelector('.build')).not.toExist();
fs.writeFileSync(directory + '.atom-build.json', fs.readFileSync(shTrueAtomBuildFile));
- atom.commands.dispatch(workspaceElement, 'build:trigger');
- waitsFor(function() {
- return workspaceElement.querySelector('.build .title').classList.contains('success');
+ runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger'));
+
+ waitsFor(() => {
+ return workspaceElement.querySelector('.build .title') &&
+ workspaceElement.querySelector('.build .title').classList.contains('success');
});
- runs(function() {
+ runs(() => {
expect(workspaceElement.querySelector('.build')).toExist();
- expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/Executing with sh:/);
+ expect(workspaceElement.querySelector('.build .heading-text').textContent).toMatch(new RegExp(`^${shellCmd}`));
});
});
- it('should not show sh message if sh is false', function() {
+ it('should not show sh message if sh is false', () => {
+ if (process.platform === 'win32') return;
+
expect(workspaceElement.querySelector('.build')).not.toExist();
fs.writeFileSync(directory + '.atom-build.json', fs.readFileSync(shFalseAtomBuildFile));
- atom.commands.dispatch(workspaceElement, 'build:trigger');
- waitsFor(function() {
- return workspaceElement.querySelector('.build .title').classList.contains('success');
+ runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger'));
+
+ waitsFor(() => {
+ return workspaceElement.querySelector('.build .title') &&
+ workspaceElement.querySelector('.build .title').classList.contains('success');
});
- runs(function() {
+ runs(() => {
expect(workspaceElement.querySelector('.build')).toExist();
- expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/Executing:/);
+ expect(workspaceElement.querySelector('.build .heading-text').textContent).toMatch(/^echo/);
});
});
- it('should show sh message if sh is unspecified', function() {
+ it('should show sh message if sh is unspecified', () => {
expect(workspaceElement.querySelector('.build')).not.toExist();
fs.writeFileSync(directory + '.atom-build.json', fs.readFileSync(shDefaultAtomBuildFile));
- atom.commands.dispatch(workspaceElement, 'build:trigger');
- waitsFor(function() {
- return workspaceElement.querySelector('.build .title').classList.contains('success');
+ runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger'));
+
+ waitsFor(() => {
+ return workspaceElement.querySelector('.build .title') &&
+ workspaceElement.querySelector('.build .title').classList.contains('success');
});
- runs(function() {
+ runs(() => {
expect(workspaceElement.querySelector('.build')).toExist();
- expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/Executing with sh:/);
+ expect(workspaceElement.querySelector('.build .heading-text').textContent).toMatch(new RegExp(`^${shellCmd}`));
});
});
- it('should show graphical error message if build-file contains syntax errors', function() {
+ it('should show graphical error message if build-file contains syntax errors', () => {
expect(workspaceElement.querySelector('.build')).not.toExist();
fs.writeFileSync(directory + '.atom-build.json', fs.readFileSync(syntaxErrorAtomBuildFile));
- atom.commands.dispatch(workspaceElement, 'build:trigger');
- waitsFor(function() {
- return workspaceElement.querySelector('.build .title').classList.contains('error');
- });
+ runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger'));
- runs(function() {
- expect(workspaceElement.querySelector('.build')).toExist();
- expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/Unexpected token t/);
- expect(workspaceElement.querySelector('.build .title').textContent).toBe('You have a syntax error in your build file.');
- });
- });
- });
-
- describe('when build is triggered with gulp file', function() {
- it('should show the build window', function() {
- expect(workspaceElement.querySelector('.build')).not.toExist();
-
- fs.writeFileSync(directory + 'gulpfile.js', fs.readFileSync(goodGulpfile));
- atom.commands.dispatch(workspaceElement, 'build:trigger');
-
- waitsFor(function() {
- return workspaceElement.querySelector('.build .title').classList.contains('success');
+ waitsFor(() => {
+ return atom.notifications.getNotifications().find(n => n.getType() === 'error');
});
- runs(function() {
- expect(workspaceElement.querySelector('.build')).toExist();
- expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/gulp built/);
+ runs(() => {
+ const notification = atom.notifications.getNotifications().find(n => n.getType() === 'error');
+ expect(notification.getType()).toEqual('error');
+ expect(notification.getMessage()).toEqual('Invalid build file.');
+ expect(notification.options.detail).toMatch(/Unexpected token t/);
});
});
- });
- describe('when multiple build options are available', function() {
- it('should prioritise .atom-build.json over node', function() {
+ it('should not cache the contents of the build file', () => {
expect(workspaceElement.querySelector('.build')).not.toExist();
- fs.writeFileSync(directory + '.atom-build.json', fs.readFileSync(goodAtomBuildfile));
- fs.writeFileSync(directory + 'package.json', fs.readFileSync(goodNodefile));
- atom.commands.dispatch(workspaceElement, 'build:trigger');
-
- waitsFor(function() {
- return workspaceElement.querySelector('.build .title').classList.contains('success');
- });
-
- runs(function() {
- expect(workspaceElement.querySelector('.build')).toExist();
- expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/"cmd": "dd"/);
- });
- });
-
- it('should prioritise grunt over make', function() {
- expect(workspaceElement.querySelector('.build')).not.toExist();
+ fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({
+ cmd: 'echo first'
+ }));
- fs.writeFileSync(directory + 'Gruntfile.js', fs.readFileSync(goodGruntfile));
- fs.writeFileSync(directory + 'Makefile', fs.readFileSync(goodMakefile));
atom.commands.dispatch(workspaceElement, 'build:trigger');
- waitsFor(function() {
- return workspaceElement.querySelector('.build .title').classList.contains('success');
+ waitsFor(() => {
+ return workspaceElement.querySelector('.build .title') &&
+ workspaceElement.querySelector('.build .title').classList.contains('success');
});
- runs(function() {
- expect(workspaceElement.querySelector('.build')).toExist();
- expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/Running "default" task/);
+ runs(() => {
+ expect(workspaceElement.querySelector('.terminal').terminal.getContent()).toMatch(/first/);
});
- });
- it('should prioritise node over grunt', function() {
- expect(workspaceElement.querySelector('.build')).not.toExist();
-
- fs.writeFileSync(directory + 'Gruntfile.js', fs.readFileSync(goodGruntfile));
- fs.writeFileSync(directory + 'package.json', fs.readFileSync(goodNodefile));
- atom.commands.dispatch(workspaceElement, 'build:trigger');
-
- waitsFor(function() {
- return workspaceElement.querySelector('.build .title').classList.contains('success');
+ waitsFor(() => {
+ return !workspaceElement.querySelector('.build .title');
});
- runs(function() {
- expect(workspaceElement.querySelector('.build')).toExist();
- expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/^Executing: npm/);
+ runs(() => {
+ fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({
+ cmd: 'echo second'
+ }));
});
- });
- it('should prioritise atom over grunt', function() {
- if (process.env.TRAVIS) {
- return;
- }
- expect(workspaceElement.querySelector('.build')).not.toExist();
-
- fs.writeFileSync(directory + 'Gruntfile.js', fs.readFileSync(goodGruntfile));
- fs.writeFileSync(directory + 'package.json', fs.readFileSync(goodAtomfile));
- atom.commands.dispatch(workspaceElement, 'build:trigger');
+ waitsForPromise(() => specHelpers.refreshAwaitTargets());
- waitsFor(function() {
- return workspaceElement.querySelector('.build .title').classList.contains('success');
- }, 'build to be successful', 10000);
+ runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger'));
- runs(function() {
- expect(workspaceElement.querySelector('.build')).toExist();
- expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/^Executing: apm/);
+ waitsFor(() => {
+ return workspaceElement.querySelector('.build .title') &&
+ workspaceElement.querySelector('.build .title').classList.contains('success');
});
- });
- });
- describe('when package.json exists, but without engines and Makefile is present', function() {
- it('(Issue#3) should run Makefile without any npm arguments', function() {
- expect(workspaceElement.querySelector('.build')).not.toExist();
-
- fs.writeFileSync(directory + 'package.json', fs.readFileSync(badPackageJsonfile));
- fs.writeFileSync(directory + 'Makefile', fs.readFileSync(goodMakefile));
-
- atom.commands.dispatch(workspaceElement, 'build:trigger');
-
- waitsFor(function() {
- return workspaceElement.querySelector('.build .title').classList.contains('success');
- });
-
- runs(function() {
- expect(workspaceElement.querySelector('.build')).toExist();
- expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/Surprising is the passing of time\nbut not so, as the time of passing/);
+ runs(() => {
+ expect(workspaceElement.querySelector('.terminal').terminal.getContent()).toMatch(/second/);
});
});
});
- describe('when replacements are specified in the atom-build.json file', function() {
- it('should replace those with their dynamic value', function() {
-
+ describe('when replacements are specified in the atom-build.json file', () => {
+ it('should replace those with their dynamic value', () => {
expect(workspaceElement.querySelector('.build')).not.toExist();
+ process.env.FROM_PROCESS_ENV = '{FILE_ACTIVE}';
fs.writeFileSync(directory + '.atom-build.json', fs.readFileSync(replaceAtomBuildFile));
- waitsForPromise(function() {
- return atom.workspace.open('.atom-build.json');
- });
+ waitsForPromise(() => atom.workspace.open('.atom-build.json'));
- runs(function() {
- atom.commands.dispatch(workspaceElement, 'build:trigger');
- });
+ runs(() => atom.workspace.getActiveTextEditor().setSelectedBufferRange([[1, 3], [1, 6]]));
- waitsFor(function() {
- return workspaceElement.querySelector('.build .title').classList.contains('success');
+ runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger'));
+
+ waitsFor(() => {
+ return workspaceElement.querySelector('.build .title') &&
+ workspaceElement.querySelector('.build .title').classList.contains('success');
});
- runs(function() {
+ runs(() => {
expect(workspaceElement.querySelector('.build')).toExist();
- var output = workspaceElement.querySelector('.build .output').textContent;
-
+ const output = workspaceElement.querySelector('.terminal').terminal.getContent();
expect(output.indexOf('PROJECT_PATH=' + directory.substring(0, -1))).not.toBe(-1);
expect(output.indexOf('FILE_ACTIVE=' + directory + '.atom-build.json')).not.toBe(-1);
expect(output.indexOf('FROM_ENV=' + directory + '.atom-build.json')).not.toBe(-1);
+ expect(output.indexOf('FROM_PROCESS_ENV=' + directory + '.atom-build.json')).not.toBe(-1);
expect(output.indexOf('FILE_ACTIVE_NAME=.atom-build.json')).not.toBe(-1);
expect(output.indexOf('FILE_ACTIVE_NAME_BASE=.atom-build')).not.toBe(-1);
+ expect(output.indexOf('FILE_ACTIVE_CURSOR_ROW=2')).not.toBe(-1);
+ expect(output.indexOf('FILE_ACTIVE_CURSOR_COLUMN=7')).not.toBe(-1);
+ expect(output.indexOf('SELECTION=cmd')).not.toBe(-1);
});
});
});
- describe('when output from build contains HTML characters', function() {
- it('should escape those properly so the output is not garbled or missing', function() {
- expect(workspaceElement.querySelector('.build')).not.toExist();
-
- fs.writeFileSync(directory + 'Makefile', fs.readFileSync(escapeMakefile));
- atom.commands.dispatch(workspaceElement, 'build:trigger');
-
- waitsFor(function() {
- return workspaceElement.querySelector('.build .title').classList.contains('success');
- });
-
- runs(function() {
- expect(workspaceElement.querySelector('.build')).toExist();
- expect(workspaceElement.querySelector('.build .output').innerHTML).toMatch(/<script type="text\/javascript">alert\('XSS!'\)<\/script>/);
- });
- });
- });
-
- describe('when the text editor is modified', function() {
- it('should show the save confirmation', function() {
- expect(workspaceElement.querySelector('.build-confirm')).not.toExist();
+ describe('when the text editor is saved', () => {
+ it('should build when buildOnSave is true', () => {
+ atom.config.set('build.buildOnSave', true);
- fs.writeFileSync(directory + 'Makefile', fs.readFileSync(goodMakefile));
+ fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({
+ cmd: 'echo Surprising is the passing of time but not so, as the time of passing.'
+ }));
- waitsForPromise(function() {
- return atom.workspace.open('Makefile');
- });
+ waitsForPromise(() => atom.workspace.open('dummy'));
- runs(function() {
- var editor = atom.workspace.getActiveTextEditor();
- editor.insertText('hello kansas');
- atom.commands.dispatch(workspaceElement, 'build:trigger');
+ waitsForPromise(() => {
+ const editor = atom.workspace.getActiveTextEditor();
+ return editor.save();
});
- waitsFor(function() {
- return workspaceElement.querySelector(':focus');
+ waitsFor(() => {
+ return workspaceElement.querySelector('.build .title') &&
+ workspaceElement.querySelector('.build .title').classList.contains('success');
});
- runs(function() {
- expect(workspaceElement.querySelector('.btn-success:focus')).toExist();
+ runs(() => {
+ expect(workspaceElement.querySelector('.build')).toExist();
+ expect(workspaceElement.querySelector('.terminal').terminal.getContent()).toMatch(/Surprising is the passing of time but not so, as the time of passing/);
});
});
- it('should cancel the confirm window when pressing escape', function() {
- expect(workspaceElement.querySelector('.build-confirm')).not.toExist();
-
- fs.writeFileSync(directory + 'Makefile', fs.readFileSync(goodMakefile));
+ it('should not build when buildOnSave is false', () => {
+ atom.config.set('build.buildOnSave', false);
- waitsForPromise(function() {
- return atom.workspace.open('Makefile');
+ fs.writeFileSync(directory + '.atom-build.json', {
+ cmd: 'echo "hello, world"'
});
- runs(function() {
- var editor = atom.workspace.getActiveTextEditor();
- editor.insertText('hello kansas');
- atom.commands.dispatch(workspaceElement, 'build:trigger');
- });
+ waitsForPromise(() => atom.workspace.open('dummy'));
- waitsFor(function() {
- return workspaceElement.querySelector(':focus');
+ waitsForPromise(() => {
+ const editor = atom.workspace.getActiveTextEditor();
+ return editor.save();
});
- runs(function() {
- atom.commands.dispatch(workspaceElement, 'build:no-confirm');
- expect(workspaceElement.querySelector('.btn-success:focus')).not.toExist();
+ runs(() => {
+ expect(workspaceElement.querySelector('.build')).not.toExist();
});
});
- it('should not confirm if a TextEditor edits an unsaved file', function() {
- expect(workspaceElement.querySelector('.build-confirm')).not.toExist();
-
- fs.writeFileSync(directory + 'Makefile', fs.readFileSync(goodMakefile));
+ it('should not attempt to build if buildOnSave is true and no build tool exists', () => {
+ atom.config.set('build.buildOnSave', true);
- waitsForPromise(function() {
- return atom.workspace.open('Makefile');
+ fs.writeFileSync(directory + '.atom-build.json', {
+ cmd: 'echo "hello, world"'
});
- waitsForPromise(function() {
- return atom.workspace.open();
+ waitsForPromise(() => {
+ return atom.workspace.open('dummy');
});
- runs(function() {
- var editor = _.find(atom.workspace.getTextEditors(), function(textEditor) {
- return ('untitled' === textEditor.getTitle());
- });
- editor.insertText('Just some temporary place to write stuff');
- atom.commands.dispatch(workspaceElement, 'build:trigger');
+ runs(() => {
+ atom.workspace.getActiveTextEditor().save();
});
- waitsFor(function() {
- return workspaceElement.querySelector('.build .title').classList.contains('success');
- });
+ waits(waitTime);
- runs(function() {
- expect(workspaceElement.querySelector('.build')).toExist();
- expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/Surprising is the passing of time\nbut not so, as the time of passing/);
+ runs(() => {
+ expect(workspaceElement.querySelector('.build')).not.toExist();
});
});
+ });
- it('should save and build when selecting save and build', function() {
- expect(workspaceElement.querySelector('.build-confirm')).not.toExist();
+ describe('when multiple project roots are open', () => {
+ it('should run the second root if a file there is active', () => {
+ const directory2 = fs.realpathSync(temp.mkdirSync({ prefix: 'atom-build-spec-' })) + '/';
+ atom.project.addPath(directory2);
+ expect(workspaceElement.querySelector('.build')).not.toExist();
- fs.writeFileSync(directory + 'Makefile', fs.readFileSync(goodMakefile));
+ fs.writeFileSync(directory2 + '.atom-build.json', JSON.stringify({
+ cmd: cat(),
+ args: [ '.atom-build.json' ]
+ }));
- waitsForPromise(function() {
- return atom.workspace.open('Makefile');
- });
+ waitsForPromise(() => atom.workspace.open(directory2 + '/main.c'));
- runs(function() {
- var editor = atom.workspace.getActiveTextEditor();
- editor.insertText('dummy:\n\techo kansas\n');
+ runs(() => {
+ atom.workspace.getActiveTextEditor().save();
atom.commands.dispatch(workspaceElement, 'build:trigger');
});
- waitsFor(function() {
- return workspaceElement.querySelector(':focus');
- });
-
- runs(function() {
- workspaceElement.querySelector(':focus').click();
+ waitsFor(() => {
+ return workspaceElement.querySelector('.build .title') &&
+ workspaceElement.querySelector('.build .title').classList.contains('success');
});
- waitsFor(function() {
- return workspaceElement.querySelector('.build .title').classList.contains('success');
- });
-
- runs(function() {
- var editor = atom.workspace.getActiveTextEditor();
+ runs(() => {
expect(workspaceElement.querySelector('.build')).toExist();
- expect(workspaceElement.querySelector('.build .output').innerHTML).toMatch(/kansas/);
- expect(!editor.isModified());
+ expect(workspaceElement.querySelector('.terminal').terminal.getContent()).toMatch(/"args":\[".atom-build.json"\]/);
});
});
- it('should build but not save when opting so', function() {
- expect(workspaceElement.querySelector('.build-confirm')).not.toExist();
+ it('should scan new project roots when they are added', () => {
+ const directory2 = fs.realpathSync(temp.mkdirSync({ prefix: 'atom-build-spec-' })) + '/';
+ fs.writeFileSync(directory2 + '.atom-build.json', JSON.stringify({
+ cmd: cat(),
+ args: [ '.atom-build.json' ]
+ }));
- fs.writeFileSync(directory + 'Makefile', fs.readFileSync(goodMakefile));
+ waitsForPromise(() => specHelpers.refreshAwaitTargets());
- waitsForPromise(function() {
- return atom.workspace.open('Makefile');
+ waitsForPromise(() => {
+ const promise = specHelpers.awaitTargets();
+ atom.project.addPath(directory2);
+ return Promise.all([ promise, atom.workspace.open(directory2 + '/main.c') ]);
});
- runs(function() {
- var editor = atom.workspace.getActiveTextEditor();
- editor.insertText('dummy:\n\techo kansas\n');
+ runs(() => {
+ atom.workspace.getActiveTextEditor().save();
atom.commands.dispatch(workspaceElement, 'build:trigger');
});
- waitsFor(function() {
- return workspaceElement.querySelector(':focus');
- });
-
- runs(function() {
- workspaceElement.querySelector('button[click="confirmWithoutSave"]').click();
+ waitsFor(() => {
+ return workspaceElement.querySelector('.build .title') &&
+ workspaceElement.querySelector('.build .title').classList.contains('success');
});
- waitsFor(function() {
- return workspaceElement.querySelector('.build .title').classList.contains('success');
- });
-
- runs(function() {
- var editor = atom.workspace.getActiveTextEditor();
+ runs(() => {
expect(workspaceElement.querySelector('.build')).toExist();
- expect(workspaceElement.querySelector('.build .output').innerHTML).not.toMatch(/kansas/);
- expect(editor.isModified());
- });
- });
-
- it('should do nothing when cancelling', function() {
- expect(workspaceElement.querySelector('.build-confirm')).not.toExist();
-
- fs.writeFileSync(directory + 'Makefile', fs.readFileSync(goodMakefile));
-
- waitsForPromise(function() {
- return atom.workspace.open('Makefile');
- });
-
- runs(function() {
- var editor = atom.workspace.getActiveTextEditor();
- editor.insertText('dummy:\n\techo kansas\n');
- atom.commands.dispatch(workspaceElement, 'build:trigger');
- });
-
- waitsFor(function() {
- return workspaceElement.querySelector(':focus');
- });
-
- runs(function() {
- workspaceElement.querySelector('button[click="cancel"]').click();
- });
-
- waits(2);
-
- runs(function() {
- var editor = atom.workspace.getActiveTextEditor();
- expect(workspaceElement.querySelector('.build')).not.toExist();
- expect(editor.isModified());
+ expect(workspaceElement.querySelector('.terminal').terminal.getContent()).toMatch(/"args":\[".atom-build.json"\]/);
});
});
});
- describe('when the text editor is saved', function() {
- it('should build when buildOnSave is true', function() {
- atom.config.set('build.buildOnSave', true);
-
- fs.writeFileSync(directory + 'Makefile', fs.readFileSync(goodMakefile));
-
- waitsForPromise(function() {
- return atom.workspace.open('dummy');
- });
-
- runs(function() {
- var editor = atom.workspace.getActiveTextEditor();
- editor.save();
- });
-
- waitsFor(function() {
- expect(workspaceElement.querySelector('.build')).toExist();
- return workspaceElement.querySelector('.build .title').classList.contains('success');
- });
-
- runs(function() {
- expect(workspaceElement.querySelector('.build')).toExist();
- expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/Surprising is the passing of time\nbut not so, as the time of passing/);
- });
- });
-
- it('should not build when buildOnSave is false', function() {
- atom.config.set('build.buildOnSave', false);
-
- fs.writeFileSync(directory + 'Makefile', fs.readFileSync(goodMakefile));
-
- waitsForPromise(function() {
- return atom.workspace.open('dummy');
- });
+ describe('when build panel is toggled and it is not visible', () => {
+ it('should show the build panel', () => {
+ expect(workspaceElement.querySelector('.build')).not.toExist();
- runs(function() {
- var editor = atom.workspace.getActiveTextEditor();
- editor.save();
- });
+ atom.commands.dispatch(workspaceElement, 'build:toggle-panel');
- runs(function() {
- expect(workspaceElement.querySelector('.build')).not.toExist();
- });
+ expect(workspaceElement.querySelector('.build')).toExist();
});
});
- describe('when output is captured to show editor on error', function () {
- it('should place the line and column on error in correct file', function () {
- expect(workspaceElement.querySelector('.build-confirm')).not.toExist();
-
- fs.writeFileSync(directory + '.atom-build.json', fs.readFileSync(errorMatchAtomBuildFile));
- atom.commands.dispatch(workspaceElement, 'build:trigger');
-
- waitsFor(function() {
- return workspaceElement.querySelector('.build .title').classList.contains('error');
- });
-
- runs(function() {
- atom.commands.dispatch(workspaceElement, 'build:error-match');
- });
-
- waitsFor(function() {
- return atom.workspace.getActiveTextEditor();
- });
-
- runs(function() {
- var editor = atom.workspace.getActiveTextEditor();
- var bufferPosition = editor.getCursorBufferPosition();
- expect(editor.getTitle()).toEqual('.atom-build.json');
- expect(bufferPosition.row).toEqual(2);
- expect(bufferPosition.column).toEqual(7);
- });
- });
-
- it('should open just the file if line and column is not available', function () {
- expect(workspaceElement.querySelector('.build-confirm')).not.toExist();
-
- fs.writeFileSync(directory + '.atom-build.json', fs.readFileSync(errorMatchNLCAtomBuildFile));
- atom.commands.dispatch(workspaceElement, 'build:trigger');
-
- waitsFor(function() {
- return workspaceElement.querySelector('.build .title').classList.contains('error');
- });
-
- runs(function() {
- atom.commands.dispatch(workspaceElement, 'build:error-match');
- });
-
- waitsFor(function() {
- return atom.workspace.getActiveTextEditor();
- });
-
- runs(function() {
- var editor = atom.workspace.getActiveTextEditor();
- expect(editor.getTitle()).toEqual('.atom-build.json');
- });
- });
-
- it('should cycle through the file if multiple error occurred', function () {
- expect(workspaceElement.querySelector('.build-confirm')).not.toExist();
-
- fs.writeFileSync(directory + '.atom-build.json', fs.readFileSync(errorMatchMultiAtomBuildFile));
- atom.commands.dispatch(workspaceElement, 'build:trigger');
-
- waitsFor(function() {
- return workspaceElement.querySelector('.build .title').classList.contains('error');
- });
-
- runs(function() {
- atom.commands.dispatch(workspaceElement, 'build:error-match');
- });
-
- waitsFor(function() {
- return atom.workspace.getActiveTextEditor();
- });
-
- runs(function() {
- var editor = atom.workspace.getActiveTextEditor();
- var bufferPosition = editor.getCursorBufferPosition();
- expect(editor.getTitle()).toEqual('.atom-build.json');
- expect(bufferPosition.row).toEqual(2);
- expect(bufferPosition.column).toEqual(7);
- atom.workspace.getActivePane().destroyActiveItem();
- });
-
- runs(function() {
- atom.commands.dispatch(workspaceElement, 'build:error-match');
- });
-
- waitsFor(function() {
- return atom.workspace.getActiveTextEditor();
- });
+ describe('when build is triggered, focus should adhere the stealFocus config', () => {
+ it('should focus the build panel if stealFocus is true', () => {
+ expect(workspaceElement.querySelector('.build')).not.toExist();
- runs(function() {
- var editor = atom.workspace.getActiveTextEditor();
- var bufferPosition = editor.getCursorBufferPosition();
- expect(editor.getTitle()).toEqual('.atom-build.json');
- expect(bufferPosition.row).toEqual(1);
- expect(bufferPosition.column).toEqual(4);
- atom.workspace.getActivePane().destroyActiveItem();
- });
+ fs.writeFileSync(directory + '.atom-build.json', fs.readFileSync(goodAtomBuildfile));
- runs(function() {
- atom.commands.dispatch(workspaceElement, 'build:error-match');
- });
+ runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger'));
- waitsFor(function() {
- return atom.workspace.getActiveTextEditor();
+ waitsFor(() => {
+ return workspaceElement.querySelector('.build');
});
- runs(function() {
- var editor = atom.workspace.getActiveTextEditor();
- var bufferPosition = editor.getCursorBufferPosition();
- expect(editor.getTitle()).toEqual('.atom-build.json');
- expect(bufferPosition.row).toEqual(2);
- expect(bufferPosition.column).toEqual(7);
+ runs(() => {
+ expect(document.activeElement).toHaveClass('build');
});
});
- it('should jump to first error', function () {
- expect(workspaceElement.querySelector('.build-confirm')).not.toExist();
-
- fs.writeFileSync(directory + '.atom-build.json', fs.readFileSync(errorMatchMultiFirstAtomBuildFile));
- atom.commands.dispatch(workspaceElement, 'build:trigger');
-
- waitsFor(function() {
- return workspaceElement.querySelector('.build .title').classList.contains('error');
- });
-
- runs(function() {
- atom.commands.dispatch(workspaceElement, 'build:error-match-first');
- });
-
- waitsFor(function() {
- return atom.workspace.getActiveTextEditor();
- });
-
- runs(function() {
- var editor = atom.workspace.getActiveTextEditor();
- var bufferPosition = editor.getCursorBufferPosition();
- expect(editor.getTitle()).toEqual('.atom-build.json');
- expect(bufferPosition.row).toEqual(2);
- expect(bufferPosition.column).toEqual(7);
- atom.workspace.getActivePane().destroyActiveItem();
- });
-
- runs(function() {
- atom.commands.dispatch(workspaceElement, 'build:error-match');
- });
-
- waitsFor(function() {
- return atom.workspace.getActiveTextEditor();
- });
-
- runs(function() {
- var editor = atom.workspace.getActiveTextEditor();
- var bufferPosition = editor.getCursorBufferPosition();
- expect(editor.getTitle()).toEqual('.atom-build.json');
- expect(bufferPosition.row).toEqual(1);
- expect(bufferPosition.column).toEqual(4);
- atom.workspace.getActivePane().destroyActiveItem();
- });
-
- runs(function() {
- atom.commands.dispatch(workspaceElement, 'build:error-match-first');
- });
-
- waitsFor(function() {
- return atom.workspace.getActiveTextEditor();
- });
-
- runs(function() {
- var editor = atom.workspace.getActiveTextEditor();
- var bufferPosition = editor.getCursorBufferPosition();
- expect(editor.getTitle()).toEqual('.atom-build.json');
- expect(bufferPosition.row).toEqual(2);
- expect(bufferPosition.column).toEqual(7);
- });
- });
- });
+ it('should leave focus untouched if stealFocus is false', () => {
+ expect(workspaceElement.querySelector('.build')).not.toExist();
- describe('when multiple project roots are open', function () {
- it('should run the second root if a file there is active', function () {
- var directory2 = fs.realpathSync(temp.mkdirSync({ prefix: 'atom-build-spec-' })) + '/';
- atom.project.addPath(directory2);
- expect(workspaceElement.querySelector('.build-confirm')).not.toExist();
+ atom.config.set('build.stealFocus', false);
+ const activeElement = document.activeElement;
- fs.writeFileSync(directory2 + '.atom-build.json', fs.readFileSync(goodAtomBuildfile));
- waitsForPromise(function () {
- return atom.workspace.open(directory2 + '/main.c');
- });
+ fs.writeFileSync(directory + '.atom-build.json', fs.readFileSync(goodAtomBuildfile));
- runs(function() {
- atom.workspace.getActiveTextEditor().save();
- atom.commands.dispatch(workspaceElement, 'build:trigger');
- });
+ runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger'));
- waitsFor(function() {
- expect(workspaceElement.querySelector('.build ')).toExist();
- return workspaceElement.querySelector('.build .title').classList.contains('success');
+ waitsFor(() => {
+ return workspaceElement.querySelector('.build');
});
- runs(function() {
- expect(workspaceElement.querySelector('.build')).toExist();
- expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/"cmd": "dd"/);
+ runs(() => {
+ expect(document.activeElement).toEqual(activeElement);
+ expect(document.activeElement).not.toHaveClass('build');
});
});
});
- describe('when build panel is toggled and it is not visible', function() {
- it('should show the build panel', function() {
+ describe('when no build tools are available', () => {
+ it('should show a warning', () => {
expect(workspaceElement.querySelector('.build')).not.toExist();
+ atom.commands.dispatch(workspaceElement, 'build:trigger');
- atom.commands.dispatch(workspaceElement, 'build:toggle-panel');
+ waitsFor(() => atom.notifications.getNotifications().find(n => n.getMessage() === 'No eligible build target.'));
- expect(workspaceElement.querySelector('.build')).toExist();
+ runs(() => {
+ const notification = atom.notifications.getNotifications().find(n => n.getMessage() === 'No eligible build target.');
+ expect(notification.getType()).toEqual('warning');
+ });
});
});
});
diff --git a/spec/build-targets-spec.js b/spec/build-targets-spec.js
new file mode 100644
index 00000000..b4b28fba
--- /dev/null
+++ b/spec/build-targets-spec.js
@@ -0,0 +1,223 @@
+'use babel';
+
+import fs from 'fs-extra';
+import temp from 'temp';
+import path from 'path';
+import specHelpers from 'atom-build-spec-helpers';
+import os from 'os';
+
+describe('Target', () => {
+ const originalHomedirFn = os.homedir;
+ let directory = null;
+ let workspaceElement = null;
+
+ temp.track();
+
+ beforeEach(() => {
+ atom.config.set('build.buildOnSave', false);
+ atom.config.set('build.panelVisibility', 'Toggle');
+ atom.config.set('build.saveOnBuild', false);
+ atom.config.set('build.notificationOnRefresh', true);
+ atom.config.set('build.refreshOnShowTargetList', true);
+
+ jasmine.unspy(window, 'setTimeout');
+ jasmine.unspy(window, 'clearTimeout');
+
+ workspaceElement = atom.views.getView(atom.workspace);
+ workspaceElement.setAttribute('style', 'width:9999px');
+ jasmine.attachToDOM(workspaceElement);
+
+ waitsForPromise(() => {
+ return specHelpers.vouch(temp.mkdir, { prefix: 'atom-build-spec-' }).then((dir) => {
+ return specHelpers.vouch(fs.realpath, dir);
+ }).then((dir) => {
+ directory = dir + '/';
+ atom.project.setPaths([ directory ]);
+ return specHelpers.vouch(temp.mkdir, 'atom-build-spec-home');
+ }).then( (dir) => {
+ return specHelpers.vouch(fs.realpath, dir);
+ }).then( (dir) => {
+ os.homedir = () => dir;
+ return atom.packages.activatePackage('build');
+ });
+ });
+ });
+
+ afterEach(() => {
+ os.homedir = originalHomedirFn;
+ try { fs.removeSync(directory); } catch (e) { console.warn('Failed to clean up: ', e); }
+ });
+
+ describe('when no targets exists', () => {
+ it('should show a notification', () => {
+ runs(() => {
+ atom.commands.dispatch(workspaceElement, 'build:select-active-target');
+ });
+
+ waitsFor(() => {
+ return workspaceElement.querySelector('.select-list.build-target');
+ });
+
+ runs(() => {
+ const targets = [ ...workspaceElement.querySelectorAll('.select-list li.build-target') ].map(el => el.textContent);
+ expect(targets).toEqual([]);
+ });
+ });
+ });
+
+ describe('when multiple targets exists', () => {
+ it('should list those targets in a SelectListView (from .atom-build.json)', () => {
+ waitsForPromise(() => {
+ const file = __dirname + '/fixture/.atom-build.targets.json';
+ return specHelpers.vouch(fs.copy, file, directory + '/.atom-build.json');
+ });
+
+ runs(() => {
+ atom.commands.dispatch(workspaceElement, 'build:select-active-target');
+ });
+
+ waitsFor(() => {
+ return workspaceElement.querySelector('.select-list li.build-target');
+ });
+
+ runs(() => {
+ const targets = [ ...workspaceElement.querySelectorAll('.select-list li.build-target') ].map(el => el.textContent);
+ expect(targets).toEqual([ 'Custom: The default build', 'Custom: Some customized build' ]);
+ });
+ });
+
+ it('should mark the first target as active', () => {
+ waitsForPromise(() => {
+ const file = __dirname + '/fixture/.atom-build.targets.json';
+ return specHelpers.vouch(fs.copy, file, directory + '/.atom-build.json');
+ });
+
+ runs(() => {
+ atom.commands.dispatch(workspaceElement, 'build:select-active-target');
+ });
+
+ waitsFor(() => {
+ return workspaceElement.querySelector('.select-list li.build-target');
+ });
+
+ runs(() => {
+ const el = workspaceElement.querySelector('.select-list li.build-target'); // querySelector selects the first element
+ expect(el).toHaveClass('selected');
+ expect(el).toHaveClass('active');
+ });
+ });
+
+ it('should run the selected build', () => {
+ waitsForPromise(() => {
+ const file = __dirname + '/fixture/.atom-build.targets.json';
+ return specHelpers.vouch(fs.copy, file, directory + '/.atom-build.json');
+ });
+
+ runs(() => {
+ atom.commands.dispatch(workspaceElement, 'build:select-active-target');
+ });
+
+ waitsFor(() => {
+ return workspaceElement.querySelector('.select-list li.build-target');
+ });
+
+ runs(() => {
+ atom.commands.dispatch(workspaceElement.querySelector('.select-list'), 'core:confirm');
+ });
+
+ waitsFor(() => {
+ return workspaceElement.querySelector('.build .title') &&
+ workspaceElement.querySelector('.build .title').classList.contains('success');
+ });
+
+ runs(() => {
+ expect(workspaceElement.querySelector('.terminal').terminal.getContent()).toMatch(/default/);
+ });
+ });
+
+ it('should run the default target if no selection has been made', () => {
+ waitsForPromise(() => {
+ const file = __dirname + '/fixture/.atom-build.targets.json';
+ return specHelpers.vouch(fs.copy, file, directory + '/.atom-build.json');
+ });
+
+ runs(() => {
+ atom.commands.dispatch(workspaceElement, 'build:trigger');
+ });
+
+ waitsFor(() => {
+ return workspaceElement.querySelector('.build .title') &&
+ workspaceElement.querySelector('.build .title').classList.contains('success');
+ });
+
+ runs(() => {
+ expect(workspaceElement.querySelector('.terminal').terminal.getContent()).toMatch(/default/);
+ });
+ });
+
+ it('run the selected target if selection has changed, and subsequent build should run that target', () => {
+ waitsForPromise(() => {
+ const file = __dirname + '/fixture/.atom-build.targets.json';
+ return specHelpers.vouch(fs.copy, file, directory + '/.atom-build.json');
+ });
+
+ runs(() => {
+ atom.commands.dispatch(workspaceElement, 'build:select-active-target');
+ });
+
+ waitsFor(() => {
+ return workspaceElement.querySelector('.select-list li.build-target');
+ });
+
+ runs(() => {
+ atom.commands.dispatch(workspaceElement.querySelector('.select-list'), 'core:move-down');
+ });
+
+ waitsFor(() => {
+ return workspaceElement.querySelector('.select-list li.selected').textContent === 'Custom: Some customized build';
+ });
+
+ runs(() => {
+ atom.commands.dispatch(workspaceElement.querySelector('.select-list'), 'core:confirm');
+ });
+
+ waitsFor(() => {
+ return workspaceElement.querySelector('.build .title') &&
+ workspaceElement.querySelector('.build .title').classList.contains('success');
+ });
+
+ runs(() => {
+ expect(workspaceElement.querySelector('.terminal').terminal.getContent()).toMatch(/customized/);
+ atom.commands.dispatch(workspaceElement.querySelector('.build'), 'build:stop');
+ });
+
+ waitsFor(() => {
+ return !workspaceElement.querySelector('.build');
+ });
+
+ runs(() => {
+ atom.commands.dispatch(workspaceElement, 'build:trigger');
+ });
+
+ waitsFor(() => {
+ return workspaceElement.querySelector('.build .title') &&
+ workspaceElement.querySelector('.build .title').classList.contains('success');
+ });
+
+ runs(() => {
+ expect(workspaceElement.querySelector('.terminal').terminal.getContent()).toMatch(/customized/);
+ });
+ });
+
+ it('should show a warning if current file is not part of an open Atom project', () => {
+ waitsForPromise(() => atom.workspace.open(path.join('..', 'randomFile')));
+ waitsForPromise(() => specHelpers.refreshAwaitTargets());
+ runs(() => atom.commands.dispatch(workspaceElement, 'build:select-active-target'));
+ waitsFor(() => atom.notifications.getNotifications().find(n => n.message === 'Unable to build.'));
+ runs(() => {
+ const not = atom.notifications.getNotifications().find(n => n.message === 'Unable to build.');
+ expect(not.type).toBe('warning');
+ });
+ });
+ });
+});
diff --git a/spec/build-view-spec.js b/spec/build-view-spec.js
new file mode 100644
index 00000000..c1648ac7
--- /dev/null
+++ b/spec/build-view-spec.js
@@ -0,0 +1,236 @@
+'use babel';
+
+import fs from 'fs-extra';
+import temp from 'temp';
+import specHelpers from 'atom-build-spec-helpers';
+import os from 'os';
+import { sleep } from './helpers';
+
+describe('BuildView', () => {
+ const originalHomedirFn = os.homedir;
+ let directory = null;
+ let workspaceElement = null;
+
+ temp.track();
+
+ beforeEach(() => {
+ atom.config.set('build.buildOnSave', false);
+ atom.config.set('build.panelVisibility', 'Toggle');
+ atom.config.set('build.saveOnBuild', false);
+ atom.config.set('build.stealFocus', true);
+ atom.config.set('build.notificationOnRefresh', true);
+ atom.config.set('editor.fontSize', 14);
+ atom.notifications.clear();
+
+ workspaceElement = atom.views.getView(atom.workspace);
+ workspaceElement.setAttribute('style', 'width:9999px');
+ jasmine.attachToDOM(workspaceElement);
+ jasmine.unspy(window, 'setTimeout');
+ jasmine.unspy(window, 'clearTimeout');
+
+ runs(() => {
+ workspaceElement = atom.views.getView(atom.workspace);
+ jasmine.attachToDOM(workspaceElement);
+ });
+
+ waitsForPromise(() => {
+ return specHelpers.vouch(temp.mkdir, { prefix: 'atom-build-spec-' }).then( (dir) => {
+ return specHelpers.vouch(fs.realpath, dir);
+ }).then( (dir) => {
+ directory = dir + '/';
+ atom.project.setPaths([ directory ]);
+ return specHelpers.vouch(temp.mkdir, 'atom-build-spec-home');
+ }).then( (dir) => {
+ return specHelpers.vouch(fs.realpath, dir);
+ }).then( (dir) => {
+ os.homedir = () => dir;
+ return atom.packages.activatePackage('build');
+ });
+ });
+ });
+
+ afterEach(() => {
+ os.homedir = originalHomedirFn;
+ try { fs.removeSync(directory); } catch (e) { console.warn('Failed to clean up: ', e); }
+ });
+
+ describe('when output from build command should be viewed', () => {
+ it('should output data even if no line break exists', () => {
+ fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({
+ cmd: 'node',
+ args: [ '-e', 'process.stdout.write(\'data without linebreak\');' ],
+ sh: false
+ }));
+
+ runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger'));
+
+ waitsFor(() => {
+ return workspaceElement.querySelector('.build .title') &&
+ workspaceElement.querySelector('.build .title').classList.contains('success');
+ });
+
+ runs(() => {
+ expect(workspaceElement.querySelector('.terminal').terminal.getContent()).toMatch(/data without linebreak/);
+ });
+ });
+
+ it('should escape HTML chars so the output is not garbled or missing', () => {
+ expect(workspaceElement.querySelector('.build')).not.toExist();
+
+ fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({
+ cmd: 'echo ""'
+ }));
+
+ runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger'));
+
+ waitsFor(() => {
+ return workspaceElement.querySelector('.build .title') &&
+ workspaceElement.querySelector('.build .title').classList.contains('success');
+ });
+
+ runs(() => {
+ expect(workspaceElement.querySelector('.build')).toExist();
+ expect(workspaceElement.querySelector('.terminal').terminal.getContent()).toMatch(//);
+ });
+ });
+ });
+
+ describe('when a build is triggered', () => {
+ it('should include a timer of the build', () => {
+ expect(workspaceElement.querySelector('.build')).not.toExist();
+
+ fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({
+ cmd: `echo "Building, this will take some time..." && ${sleep(30)} && echo "Done!"`
+ }));
+
+ runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger'));
+
+ // Let build run for 1.5 second. This should set the timer at "at least" 1.5
+ // which is expected below. If this waits longer than 2000 ms, we're in trouble.
+ waits(1500);
+
+ runs(() => {
+ expect(workspaceElement.querySelector('.build-timer').textContent).toMatch(/1.\d/);
+
+ // stop twice to abort the build
+ atom.commands.dispatch(workspaceElement, 'build:stop');
+ atom.commands.dispatch(workspaceElement, 'build:stop');
+ });
+ });
+ });
+
+ describe('when panel orientation is altered', () => {
+ it('should show the panel at the bottom spot', () => {
+ expect(workspaceElement.querySelector('.build')).not.toExist();
+ atom.config.set('build.panelOrientation', 'Bottom');
+
+ fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({
+ cmd: 'echo this will fail && exit 1'
+ }));
+
+ runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger'));
+
+ waitsFor(() => {
+ return workspaceElement.querySelector('.build .title') &&
+ workspaceElement.querySelector('.build .title').classList.contains('error');
+ });
+
+ runs(() => {
+ const bottomPanels = atom.workspace.getBottomPanels();
+ expect(bottomPanels.length).toEqual(1);
+ expect(bottomPanels[0].item.constructor.name).toEqual('BuildView');
+ });
+ });
+
+ it('should show the panel at the top spot', () => {
+ expect(workspaceElement.querySelector('.build')).not.toExist();
+ atom.config.set('build.panelOrientation', 'Top');
+
+ fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({
+ cmd: 'echo this will fail && exit 1'
+ }));
+
+ runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger'));
+
+ waitsFor(() => {
+ return workspaceElement.querySelector('.build .title') &&
+ workspaceElement.querySelector('.build .title').classList.contains('error');
+ });
+
+ runs(() => {
+ const panels = atom.workspace.getTopPanels();
+ expect(panels.length).toEqual(1);
+ expect(panels[0].item.constructor.name).toEqual('BuildView');
+ });
+ });
+ });
+
+ describe('when build fails', () => {
+ it('should keep the build scrolled to bottom', () => {
+ expect(workspaceElement.querySelector('.build')).not.toExist();
+
+ fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({
+ cmd: 'echo a && echo b && echo c && echo d && echo e && echo f && echo g && echo h && exit 1'
+ }));
+
+ runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger'));
+
+ waitsFor(() => {
+ return workspaceElement.querySelector('.build .title') &&
+ workspaceElement.querySelector('.build .title').classList.contains('error');
+ });
+
+ runs(() => {
+ expect(workspaceElement.querySelector('.terminal').terminal.ydisp).toBeGreaterThan(0);
+ });
+ });
+ });
+
+ describe('when hidePanelHeading is set', () => {
+ beforeEach(() => {
+ atom.config.set('build.hidePanelHeading', true);
+ });
+
+ afterEach(() => {
+ atom.config.set('build.hidePanelHeading', false);
+ });
+
+ it('should not show the panel heading', () => {
+ expect(workspaceElement.querySelector('.build')).not.toExist();
+
+ fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({
+ cmd: 'echo hello && exit 1'
+ }));
+
+ runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger'));
+
+ waitsFor(() => {
+ return workspaceElement.querySelector('.build');
+ });
+
+ runs(() => {
+ expect(workspaceElement.querySelector('.build .heading')).toBeHidden();
+ });
+ });
+
+ it('should show the heading when hidden is disabled', () => {
+ expect(workspaceElement.querySelector('.build')).not.toExist();
+
+ fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({
+ cmd: 'echo hello && exit 1'
+ }));
+
+ runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger'));
+
+ waitsFor(() => {
+ return workspaceElement.querySelector('.build');
+ });
+
+ runs(() => {
+ expect(workspaceElement.querySelector('.build .heading')).toBeHidden();
+ atom.config.set('build.hidePanelHeading', false);
+ expect(workspaceElement.querySelector('.build .heading')).toBeVisible();
+ });
+ });
+ });
+});
diff --git a/spec/build-visible-spec.js b/spec/build-visible-spec.js
index ab468975..c86c05e9 100644
--- a/spec/build-visible-spec.js
+++ b/spec/build-visible-spec.js
@@ -1,35 +1,194 @@
+'use babel';
-describe('Build', function() {
- 'use strict';
+import fs from 'fs-extra';
+import temp from 'temp';
+import specHelpers from 'atom-build-spec-helpers';
+import os from 'os';
- var workspaceElement = null;
+describe('Visible', () => {
+ let directory = null;
+ let workspaceElement = null;
+ const waitTime = process.env.CI ? 2400 : 200;
+ const originalHomedirFn = os.homedir;
- beforeEach(function() {
- atom.config.set('build.panelVisibility', 'Keep Visible');
+ temp.track();
- runs(function() {
+ beforeEach(() => {
+ atom.config.set('build.buildOnSave', false);
+ atom.config.set('build.panelVisibility', 'Toggle');
+ atom.config.set('build.saveOnBuild', false);
+ atom.config.set('build.stealFocus', true);
+ atom.config.set('build.notificationOnRefresh', true);
+ atom.notifications.clear();
+
+ workspaceElement = atom.views.getView(atom.workspace);
+ workspaceElement.setAttribute('style', 'width:9999px');
+ jasmine.attachToDOM(workspaceElement);
+ jasmine.unspy(window, 'setTimeout');
+ jasmine.unspy(window, 'clearTimeout');
+
+ runs(() => {
workspaceElement = atom.views.getView(atom.workspace);
jasmine.attachToDOM(workspaceElement);
});
- waitsForPromise(function() {
- return atom.packages.activatePackage('build');
+ waitsForPromise(() => {
+ return specHelpers.vouch(temp.mkdir, { prefix: 'atom-build-spec-' }).then( (dir) => {
+ return specHelpers.vouch(fs.realpath, dir);
+ }).then( (dir) => {
+ directory = dir + '/';
+ atom.project.setPaths([ directory ]);
+ return specHelpers.vouch(temp.mkdir, 'atom-build-spec-home');
+ }).then( (dir) => {
+ return specHelpers.vouch(fs.realpath, dir);
+ }).then( (dir) => {
+ os.homedir = () => dir;
+ });
});
});
- describe('when package is activated', function() {
- it('should show build window', function() {
+ afterEach(() => {
+ os.homedir = originalHomedirFn;
+ try { fs.removeSync(directory); } catch (e) { console.warn('Failed to clean up: ', e); }
+ });
+
+ describe('when package is activated with panel visibility set to Keep Visible', () => {
+ beforeEach(() => {
+ atom.config.set('build.panelVisibility', 'Keep Visible');
+ waitsForPromise(() => {
+ return atom.packages.activatePackage('build');
+ });
+ });
+
+ it('should show build window', () => {
expect(workspaceElement.querySelector('.build')).toExist();
});
});
- describe('when build panel is toggled and it is visible', function() {
- it('should hide the build panel', function() {
- expect(workspaceElement.querySelector('.build')).toExist();
+ describe('when package is activated with panel visibility set to Toggle', () => {
+ beforeEach(() => {
+ atom.config.set('build.panelVisibility', 'Toggle');
+ waitsForPromise(() => {
+ return atom.packages.activatePackage('build');
+ });
+ });
+
+ describe('when build panel is toggled and it is visible', () => {
+ beforeEach(() => {
+ atom.commands.dispatch(workspaceElement, 'build:toggle-panel');
+ });
+
+ it('should hide the build panel', () => {
+ expect(workspaceElement.querySelector('.build')).toExist();
+
+ atom.commands.dispatch(workspaceElement, 'build:toggle-panel');
+
+ expect(workspaceElement.querySelector('.build')).not.toExist();
+ });
+ });
+
+ describe('when panel visibility is set to Show on Error', () => {
+ it('should only show the build panel if a build fails', () => {
+ atom.config.set('build.panelVisibility', 'Show on Error');
+
+ fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({
+ cmd: 'echo Surprising is the passing of time but not so, as the time of passing.'
+ }));
+
+ runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger'));
+
+ /* Give it some reasonable time to show itself if there is a bug */
+ waits(waitTime);
+
+ runs(() => {
+ expect(workspaceElement.querySelector('.build')).not.toExist();
+ });
+
+ runs(() => {
+ fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({
+ cmd: 'echo Very bad... && exit 1'
+ }));
+ });
+
+ // .atom-build.json is updated asynchronously... give it some time
+ waitsForPromise(() => specHelpers.refreshAwaitTargets());
+
+ runs(() => {
+ atom.commands.dispatch(workspaceElement, 'build:trigger');
+ });
+
+ waitsFor(() => {
+ return workspaceElement.querySelector('.build .title') &&
+ workspaceElement.querySelector('.build .title').classList.contains('error');
+ });
+
+ waits(waitTime);
+
+ runs(() => {
+ expect(workspaceElement.querySelector('.terminal').terminal.getContent()).toMatch(/Very bad\.\.\./);
+ });
+ });
+ });
+
+ describe('when panel visibility is set to Hidden', () => {
+ it('should not show the build panel if build succeeeds', () => {
+ atom.config.set('build.panelVisibility', 'Hidden');
+
+ fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({
+ cmd: 'echo Surprising is the passing of time but not so, as the time of passing.'
+ }));
+
+ runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger'));
+
+ /* Give it some reasonable time to show itself if there is a bug */
+ waits(waitTime);
+
+ runs(() => {
+ expect(workspaceElement.querySelector('.build')).not.toExist();
+ });
+ });
+
+ it('should not show the build panel if build fails', () => {
+ atom.config.set('build.panelVisibility', 'Hidden');
+
+ fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({
+ cmd: 'echo "Very bad..." && exit 2'
+ }));
+
+ runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger'));
+
+ /* Give it some reasonable time to show itself if there is a bug */
+ waits(waitTime);
+
+ runs(() => {
+ expect(workspaceElement.querySelector('.build')).not.toExist();
+ });
+ });
+
+ it('should show the build panel if it is toggled', () => {
+ atom.config.set('build.panelVisibility', 'Hidden');
+
+ fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({
+ cmd: 'echo Surprising is the passing of time but not so, as the time of passing.'
+ }));
+
+ runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger'));
+
+ waits(waitTime); // Let build finish. Since UI component is not visible yet, there's nothing to poll.
+
+ runs(() => {
+ atom.commands.dispatch(workspaceElement, 'build:toggle-panel');
+ });
- atom.commands.dispatch(workspaceElement, 'build:toggle-panel');
+ waitsFor(() => {
+ return workspaceElement.querySelector('.build .title') &&
+ workspaceElement.querySelector('.build .title').classList.contains('success');
+ });
- expect(workspaceElement.querySelector('.build')).not.toExist();
+ runs(() => {
+ expect(workspaceElement.querySelector('.terminal').terminal.getContent()).toMatch(/Surprising is the passing of time but not so, as the time of passing/);
+ });
+ });
});
});
});
diff --git a/spec/custom-provider-spec.js b/spec/custom-provider-spec.js
new file mode 100644
index 00000000..6dd14881
--- /dev/null
+++ b/spec/custom-provider-spec.js
@@ -0,0 +1,147 @@
+'use babel';
+
+import fs from 'fs-extra';
+import temp from 'temp';
+import CustomFile from '../lib/atom-build.js';
+import os from 'os';
+
+describe('custom provider', () => {
+ const originalHomedirFn = os.homedir;
+ let builder;
+ let directory = null;
+ let createdHomeDir;
+
+ temp.track();
+
+ beforeEach(() => {
+ createdHomeDir = temp.mkdirSync('atom-build-spec-home');
+ os.homedir = () => createdHomeDir;
+ directory = fs.realpathSync(temp.mkdirSync({ prefix: 'atom-build-spec-' })) + '/';
+ atom.project.setPaths([ directory ]);
+ builder = new CustomFile(directory);
+ });
+
+ afterEach(() => {
+ os.homedir = originalHomedirFn;
+ try { fs.removeSync(directory); } catch (e) { console.warn('Failed to clean up: ', e); }
+ });
+
+ describe('when there is no .atom-build config file in any elegible directory', () => {
+ it('should not be eligible', () => {
+ expect(builder.isEligible()).toEqual(false);
+ });
+ });
+
+ describe('when .atom-build config is on home directory', () => {
+ it('should find json file in home directory', () => {
+ fs.writeFileSync(createdHomeDir + '/.atom-build.json', fs.readFileSync(__dirname + '/fixture/.atom-build.json'));
+ expect(builder.isEligible()).toEqual(true);
+ });
+ it('should find cson file in home directory', () => {
+ fs.writeFileSync(createdHomeDir + '/.atom-build.cson', fs.readFileSync(__dirname + '/fixture/.atom-build.cson'));
+ expect(builder.isEligible()).toEqual(true);
+ });
+ it('should find yml file in home directory', () => {
+ fs.writeFileSync(createdHomeDir + '/.atom-build.yml', fs.readFileSync(__dirname + '/fixture/.atom-build.yml'));
+ expect(builder.isEligible()).toEqual(true);
+ });
+ });
+
+ describe('when .atom-build config is on project directory', () => {
+ it('should find json file in home directory', () => {
+ fs.writeFileSync(directory + '/.atom-build.json', fs.readFileSync(__dirname + '/fixture/.atom-build.json'));
+ expect(builder.isEligible()).toEqual(true);
+ });
+ it('should find cson file in home directory', () => {
+ fs.writeFileSync(directory + '/.atom-build.cson', fs.readFileSync(__dirname + '/fixture/.atom-build.cson'));
+ expect(builder.isEligible()).toEqual(true);
+ });
+ it('should find yml file in home directory', () => {
+ fs.writeFileSync(directory + '/.atom-build.yml', fs.readFileSync(__dirname + '/fixture/.atom-build.yml'));
+ expect(builder.isEligible()).toEqual(true);
+ });
+ });
+
+ describe('when .atom-build.cson exists', () => {
+ it('it should provide targets', () => {
+ fs.writeFileSync(directory + '.atom-build.cson', fs.readFileSync(__dirname + '/fixture/.atom-build.cson'));
+ expect(builder.isEligible()).toEqual(true);
+
+ waitsForPromise(() => {
+ return Promise.resolve(builder.settings()).then(settings => {
+ const s = settings[0];
+ expect(s.exec).toEqual('echo');
+ expect(s.args).toEqual([ 'arg1', 'arg2' ]);
+ expect(s.name).toEqual('Custom: Compose masterpiece');
+ expect(s.sh).toEqual(false);
+ expect(s.cwd).toEqual('/some/directory');
+ expect(s.errorMatch).toEqual('(?\\w+.js):(?\\d+)');
+ });
+ });
+ });
+ });
+
+ describe('when .atom-build.json exists', () => {
+ it('it should provide targets', () => {
+ fs.writeFileSync(`${directory}.atom-build.json`, fs.readFileSync(`${__dirname}/fixture/.atom-build.json`));
+ expect(builder.isEligible()).toEqual(true);
+
+ waitsForPromise(() => {
+ return Promise.resolve(builder.settings()).then(settings => {
+ const s = settings[0];
+ expect(s.exec).toEqual('dd');
+ expect(s.args).toEqual([ 'if=.atom-build.json' ]);
+ expect(s.name).toEqual('Custom: Fly to moon');
+ });
+ });
+ });
+ });
+
+ describe('when .atom-build.yml exists', () => {
+ it('it should provide targets', () => {
+ fs.writeFileSync(`${directory}.atom-build.yml`, fs.readFileSync(`${__dirname}/fixture/.atom-build.yml`));
+ expect(builder.isEligible()).toEqual(true);
+
+ waitsForPromise(() => {
+ return Promise.resolve(builder.settings()).then(settings => {
+ const s = settings[0];
+ expect(s.exec).toEqual('echo');
+ expect(s.args).toEqual([ 'hello', 'world', 'from', 'yaml' ]);
+ expect(s.name).toEqual('Custom: yaml conf');
+ });
+ });
+ });
+ });
+
+ describe('when .atom-build.yaml exists', () => {
+ it('it should provide targets', () => {
+ fs.writeFileSync(`${directory}.atom-build.yaml`, fs.readFileSync(`${__dirname}/fixture/.atom-build.yml`));
+ expect(builder.isEligible()).toEqual(true);
+
+ waitsForPromise(() => {
+ return Promise.resolve(builder.settings()).then(settings => {
+ const s = settings[0];
+ expect(s.exec).toEqual('echo');
+ expect(s.args).toEqual([ 'hello', 'world', 'from', 'yaml' ]);
+ expect(s.name).toEqual('Custom: yaml conf');
+ });
+ });
+ });
+ });
+
+ describe('when .atom-build.js exists', () => {
+ it('it should provide targets', () => {
+ fs.writeFileSync(`${directory}.atom-build.js`, fs.readFileSync(`${__dirname}/fixture/.atom-build.js`));
+ expect(builder.isEligible()).toEqual(true);
+
+ waitsForPromise(() => {
+ return Promise.resolve(builder.settings()).then(settings => {
+ const s = settings[0];
+ expect(s.exec).toEqual('echo');
+ expect(s.args).toEqual([ 'hello', 'world', 'from', 'js' ]);
+ expect(s.name).toEqual('Custom: from js');
+ });
+ });
+ });
+ });
+});
diff --git a/spec/fixture/.atom-build.cson b/spec/fixture/.atom-build.cson
new file mode 100644
index 00000000..447b6f86
--- /dev/null
+++ b/spec/fixture/.atom-build.cson
@@ -0,0 +1,6 @@
+cmd: "echo"
+args: ["arg1", "arg2"]
+cwd: "/some/directory"
+sh: false
+name: "Compose masterpiece"
+errorMatch: "(?\\w+.js):(?\\d+)"
diff --git a/spec/fixture/.atom-build.error-match-function.js b/spec/fixture/.atom-build.error-match-function.js
new file mode 100644
index 00000000..0630a52c
--- /dev/null
+++ b/spec/fixture/.atom-build.error-match-function.js
@@ -0,0 +1,23 @@
+module.exports = {
+ cmd: 'echo',
+ args: [ 'cake' ],
+ name: 'from js',
+ sh: true,
+ functionMatch: function (terminal_output) {
+ return [
+ {
+ file: '.atom-build.js',
+ line: '1',
+ col: '5',
+ },
+ {
+ file: '.atom-build.js',
+ line: '2',
+ },
+ {
+ file: '.atom-build.js',
+ line: '5',
+ }
+ ];
+ }
+};
diff --git a/spec/fixture/.atom-build.error-match-long-output.json b/spec/fixture/.atom-build.error-match-long-output.json
new file mode 100644
index 00000000..44520260
--- /dev/null
+++ b/spec/fixture/.atom-build.error-match-long-output.json
@@ -0,0 +1,7 @@
+{
+ "cmd": "echo 1 && echo 2 && echo 3 && echo 4 && echo 5 && echo 6 && echo file:$FILE,line:3,column:8 && echo 1 && echo 2 && echo 3 && echo 4 && echo 5 && echo file:$FILE,line:2,column:5 && echo 1 && echo 2 && echo 3 && echo 4 && echo 5 && echo 6 && exit 1",
+ "env": {
+ "FILE": ".atom-build.json"
+ },
+ "errorMatch": "file:(?[^$,]+),line:(?\\d+),column:(?\\d+)"
+}
diff --git a/spec/fixture/.atom-build.error-match-multiple-errorMatch.json b/spec/fixture/.atom-build.error-match-multiple-errorMatch.json
new file mode 100755
index 00000000..2ea9eb0c
--- /dev/null
+++ b/spec/fixture/.atom-build.error-match-multiple-errorMatch.json
@@ -0,0 +1,7 @@
+{
+ "cmd": "echo file:.atom-build.json,line:3,column:8 && echo file:.atom-build.json,line:1,column::::2 && echo file:.atom-build.json,line:2,column:5 && exit 1",
+ "errorMatch": [
+ "file:(?[^,]+),line:(?\\d+),column:(?\\d+)",
+ "file:(?[^,]+),line:(?\\d+),column::::(?\\d+)"
+ ]
+}
diff --git a/spec/fixture/.atom-build.error-match-multiple-first.json b/spec/fixture/.atom-build.error-match-multiple-first.json
index 9e8d77b5..a812e452 100644
--- a/spec/fixture/.atom-build.error-match-multiple-first.json
+++ b/spec/fixture/.atom-build.error-match-multiple-first.json
@@ -1,4 +1,4 @@
{
- "cmd": "echo 'file:.atom-build.json,line:3,column:8\nfile:.atom-build.json,line:2,column:5\nfile:.atom-build.json,line:1,column:1' && return 1",
+ "cmd": "echo file:.atom-build.json,line:3,column:8 && echo file:.atom-build.json,line:2,column:5 && echo file:.atom-build.json,line:1,column:1 && exit 1",
"errorMatch": "file:(?[^,]+),line:(?\\d+),column:(?\\d+)"
}
diff --git a/spec/fixture/.atom-build.error-match-multiple.json b/spec/fixture/.atom-build.error-match-multiple.json
index f4e44d4b..65303b2d 100644
--- a/spec/fixture/.atom-build.error-match-multiple.json
+++ b/spec/fixture/.atom-build.error-match-multiple.json
@@ -1,4 +1,4 @@
{
- "cmd": "echo 'file:.atom-build.json,line:3,column:8\nfile:.atom-build.json,line:2,column:5' && return 1",
+ "cmd": "echo file:.atom-build.json,line:3,column:8 && echo file:.atom-build.json,line:2,column:5 && exit 1",
"errorMatch": "file:(?[^,]+),line:(?\\d+),column:(?\\d+)"
}
diff --git a/spec/fixture/.atom-build.error-match-no-exit1.json b/spec/fixture/.atom-build.error-match-no-exit1.json
new file mode 100644
index 00000000..8e077acd
--- /dev/null
+++ b/spec/fixture/.atom-build.error-match-no-exit1.json
@@ -0,0 +1,4 @@
+{
+ "cmd": "echo 'file:.atom-build.json,line:3,column:8' && exit 0",
+ "errorMatch": "file:(?[^,]+),line:(?\\d+),column:(?\\d+)"
+}
diff --git a/spec/fixture/.atom-build.error-match-no-file.json b/spec/fixture/.atom-build.error-match-no-file.json
new file mode 100644
index 00000000..a9ab0023
--- /dev/null
+++ b/spec/fixture/.atom-build.error-match-no-file.json
@@ -0,0 +1,4 @@
+{
+ "cmd": "echo 'file:black-hole,line:3,column:8' && exit 1",
+ "errorMatch": "file:(?[^,]+),line:(?\\d+),column:(?\\d+)"
+}
diff --git a/spec/fixture/.atom-build.error-match-no-line-col.json b/spec/fixture/.atom-build.error-match-no-line-col.json
index e72fa04d..804d7c8e 100644
--- a/spec/fixture/.atom-build.error-match-no-line-col.json
+++ b/spec/fixture/.atom-build.error-match-no-line-col.json
@@ -1,4 +1,4 @@
{
- "cmd": "echo 'file:.atom-build.json,line:3,column:8' && return 1",
+ "cmd": "echo 'file:.atom-build.json,line:3,column:8' && exit 1",
"errorMatch": "file:(?[^,]+)"
}
diff --git a/spec/fixture/.atom-build.error-match.json b/spec/fixture/.atom-build.error-match.json
index a8d1434f..480ad16e 100644
--- a/spec/fixture/.atom-build.error-match.json
+++ b/spec/fixture/.atom-build.error-match.json
@@ -1,4 +1,4 @@
{
- "cmd": "echo 'file:.atom-build.json,line:3,column:8' && return 1",
+ "cmd": "echo 'file:.atom-build.json,line:3,column:8' && exit 1",
"errorMatch": "file:(?[^,]+),line:(?\\d+),column:(?\\d+)"
}
diff --git a/spec/fixture/.atom-build.error-match.message.json b/spec/fixture/.atom-build.error-match.message.json
new file mode 100644
index 00000000..95b74e04
--- /dev/null
+++ b/spec/fixture/.atom-build.error-match.message.json
@@ -0,0 +1,4 @@
+{
+ "cmd": "echo file:.atom-build.json,line:3,column:8: very bad things&& exit 1",
+ "errorMatch": "file:(?[^,]+),line:(?\\d+),column:(?\\d+):\\s+(?.+)"
+}
diff --git a/spec/fixture/.atom-build.js b/spec/fixture/.atom-build.js
new file mode 100644
index 00000000..60da05f5
--- /dev/null
+++ b/spec/fixture/.atom-build.js
@@ -0,0 +1,5 @@
+module.exports = {
+ cmd: 'echo',
+ args: [ 'hello', 'world', 'from', 'js' ],
+ name: 'from js'
+};
diff --git a/spec/fixture/.atom-build.json b/spec/fixture/.atom-build.json
index 2841ffb4..3f318a6c 100644
--- a/spec/fixture/.atom-build.json
+++ b/spec/fixture/.atom-build.json
@@ -1,4 +1,5 @@
{
"cmd": "dd",
- "args": [ "if=.atom-build.json" ]
+ "args": [ "if=.atom-build.json" ],
+ "name": "Fly to moon"
}
diff --git a/spec/fixture/.atom-build.match-function-change-dirs.js b/spec/fixture/.atom-build.match-function-change-dirs.js
new file mode 100644
index 00000000..4c7ae427
--- /dev/null
+++ b/spec/fixture/.atom-build.match-function-change-dirs.js
@@ -0,0 +1,29 @@
+module.exports = {
+ cmd: 'cat',
+ args: [ 'change_dir_output.txt' ],
+ name: 'change dir',
+ sh: true,
+ functionMatch: function (output) {
+ const enterDir = /^make\[\d+\]: Entering directory '([^']+)'$/;
+ const error = /^([^:]+):(\d+):(\d+): error: (.+)$/;
+ const array = [];
+ var dir = null;
+ output.split(/\r?\n/).forEach(line => {
+ const dir_match = enterDir.exec(line);
+ if (dir_match) {
+ dir = dir_match[1];
+ } else {
+ const error_match = error.exec(line);
+ if (error_match) {
+ array.push({
+ file: dir ? dir + '/' + error_match[1] : error_match[1],
+ line: error_match[2],
+ col: error_match[3],
+ message: error_match[4],
+ });
+ }
+ }
+ });
+ return array;
+ }
+};
diff --git a/spec/fixture/.atom-build.match-function-html.js b/spec/fixture/.atom-build.match-function-html.js
new file mode 100644
index 00000000..376e14c5
--- /dev/null
+++ b/spec/fixture/.atom-build.match-function-html.js
@@ -0,0 +1,16 @@
+module.exports = {
+ cmd: 'echo',
+ args: [ 'doughnut' ],
+ name: 'from js',
+ sh: true,
+ functionMatch: function (terminal_output) {
+ return [
+ {
+ file: '.atom-build.js',
+ line: '5',
+ type: 'Warning',
+ html_message: 'mildly bad things',
+ }
+ ];
+ }
+};
diff --git a/spec/fixture/.atom-build.match-function-message-and-html.js b/spec/fixture/.atom-build.match-function-message-and-html.js
new file mode 100644
index 00000000..92dad53e
--- /dev/null
+++ b/spec/fixture/.atom-build.match-function-message-and-html.js
@@ -0,0 +1,17 @@
+module.exports = {
+ cmd: 'echo',
+ args: [ 'pancake' ],
+ name: 'from js',
+ sh: true,
+ functionMatch: function (terminal_output) {
+ return [
+ {
+ file: '.atom-build.js',
+ line: '5',
+ type: 'Warning',
+ message: 'something happened in plain text',
+ html_message: 'something happened in html',
+ }
+ ];
+ }
+};
diff --git a/spec/fixture/.atom-build.match-function-trace-html.js b/spec/fixture/.atom-build.match-function-trace-html.js
new file mode 100644
index 00000000..0303a9c4
--- /dev/null
+++ b/spec/fixture/.atom-build.match-function-trace-html.js
@@ -0,0 +1,21 @@
+module.exports = {
+ cmd: 'echo',
+ args: [ 'cake' ],
+ name: 'from js',
+ sh: true,
+ functionMatch: function (terminal_output) {
+ return [
+ {
+ file: '.atom-build.js',
+ line: '6',
+ type: 'Error',
+ trace: [
+ {
+ type: 'Explanation',
+ html_message: 'insert great explanation here',
+ }
+ ],
+ }
+ ];
+ }
+};
diff --git a/spec/fixture/.atom-build.match-function-trace-message-and-html.js b/spec/fixture/.atom-build.match-function-trace-message-and-html.js
new file mode 100644
index 00000000..5d4279fd
--- /dev/null
+++ b/spec/fixture/.atom-build.match-function-trace-message-and-html.js
@@ -0,0 +1,22 @@
+module.exports = {
+ cmd: 'echo',
+ args: [ 'pancake' ],
+ name: 'from js',
+ sh: true,
+ functionMatch: function (terminal_output) {
+ return [
+ {
+ file: '.atom-build.js',
+ line: '6',
+ type: 'Error',
+ trace: [
+ {
+ type: 'Explanation',
+ message: 'insert plain text explanation here',
+ html_message: 'insert html explanation here',
+ }
+ ],
+ }
+ ];
+ }
+};
diff --git a/spec/fixture/.atom-build.match-function-trace.js b/spec/fixture/.atom-build.match-function-trace.js
new file mode 100644
index 00000000..b571bc7f
--- /dev/null
+++ b/spec/fixture/.atom-build.match-function-trace.js
@@ -0,0 +1,21 @@
+module.exports = {
+ cmd: 'echo',
+ args: [ 'cake' ],
+ name: 'from js',
+ sh: true,
+ functionMatch: function (terminal_output) {
+ return [
+ {
+ file: '.atom-build.js',
+ line: '6',
+ type: 'Error',
+ trace: [
+ {
+ type: 'Explanation',
+ message: 'insert great explanation here',
+ }
+ ],
+ }
+ ];
+ }
+};
diff --git a/spec/fixture/.atom-build.match-function-warning.js b/spec/fixture/.atom-build.match-function-warning.js
new file mode 100644
index 00000000..6fc332be
--- /dev/null
+++ b/spec/fixture/.atom-build.match-function-warning.js
@@ -0,0 +1,16 @@
+module.exports = {
+ cmd: 'echo',
+ args: [ 'cake' ],
+ name: 'from js',
+ sh: true,
+ functionMatch: function (terminal_output) {
+ return [
+ {
+ file: '.atom-build.js',
+ line: '5',
+ type: 'Warning',
+ message: 'mildly bad things',
+ }
+ ];
+ }
+};
diff --git a/spec/fixture/.atom-build.replace.json b/spec/fixture/.atom-build.replace.json
index b5567ef4..aee45c44 100644
--- a/spec/fixture/.atom-build.replace.json
+++ b/spec/fixture/.atom-build.replace.json
@@ -6,7 +6,11 @@
"REPO_BRANCH_SHORT={REPO_BRANCH_SHORT}",
"FILE_ACTIVE_NAME={FILE_ACTIVE_NAME}",
"FILE_ACTIVE_NAME_BASE={FILE_ACTIVE_NAME_BASE}",
- "FROM_ENV=$FROM_ENV"
+ "FILE_ACTIVE_CURSOR_ROW={FILE_ACTIVE_CURSOR_ROW}",
+ "FILE_ACTIVE_CURSOR_COLUMN={FILE_ACTIVE_CURSOR_COLUMN}",
+ "SELECTION={SELECTION}",
+ "FROM_ENV=$FROM_ENV",
+ "FROM_PROCESS_ENV=$FROM_PROCESS_ENV"
],
"env": {
"FROM_ENV": "{FILE_ACTIVE}"
diff --git a/spec/fixture/.atom-build.targets.json b/spec/fixture/.atom-build.targets.json
new file mode 100644
index 00000000..25250ece
--- /dev/null
+++ b/spec/fixture/.atom-build.targets.json
@@ -0,0 +1,9 @@
+{
+ "name": "The default build",
+ "cmd": "echo default",
+ "targets": {
+ "Some customized build": {
+ "cmd": "echo customized"
+ }
+ }
+}
diff --git a/spec/fixture/.atom-build.warning-match.json b/spec/fixture/.atom-build.warning-match.json
new file mode 100644
index 00000000..d4c7be6c
--- /dev/null
+++ b/spec/fixture/.atom-build.warning-match.json
@@ -0,0 +1,4 @@
+{
+ "cmd": "echo file:.atom-build.json,line:3,column:8 && echo file:.atom-build.json,line:2,column:5 && exit 0",
+ "warningMatch": "file:(?[^,]+),line:(?\\d+),column:(?\\d+)"
+}
diff --git a/spec/fixture/.atom-build.yml b/spec/fixture/.atom-build.yml
new file mode 100644
index 00000000..44b897f0
--- /dev/null
+++ b/spec/fixture/.atom-build.yml
@@ -0,0 +1,7 @@
+cmd: echo
+args:
+ - hello
+ - world
+ - from
+ - yaml
+name: yaml conf
diff --git a/spec/fixture/Gruntfile.js b/spec/fixture/Gruntfile.js
deleted file mode 100644
index b512db48..00000000
--- a/spec/fixture/Gruntfile.js
+++ /dev/null
@@ -1,6 +0,0 @@
-module.exports = function(grunt) {
- grunt.initConfig({});
- grunt.registerTask('default', function() {
- console.log('Surprising is the passing of time. But not so, as the time of passing');
- });
-};
diff --git a/spec/fixture/Makefile.bad b/spec/fixture/Makefile.bad
deleted file mode 100644
index 216e7a16..00000000
--- a/spec/fixture/Makefile.bad
+++ /dev/null
@@ -1,3 +0,0 @@
-all:
- @echo "Very bad..."
- @exit 2
diff --git a/spec/fixture/Makefile.escape b/spec/fixture/Makefile.escape
deleted file mode 100644
index c91bfa67..00000000
--- a/spec/fixture/Makefile.escape
+++ /dev/null
@@ -1,2 +0,0 @@
-all:
- @echo ""
diff --git a/spec/fixture/Makefile.good b/spec/fixture/Makefile.good
deleted file mode 100644
index ef0a4f11..00000000
--- a/spec/fixture/Makefile.good
+++ /dev/null
@@ -1,3 +0,0 @@
-all:
- @echo "Surprising is the passing of time"
- @echo "but not so, as the time of passing"
diff --git a/spec/fixture/Makefile.long b/spec/fixture/Makefile.long
deleted file mode 100644
index ddcaa9ed..00000000
--- a/spec/fixture/Makefile.long
+++ /dev/null
@@ -1,4 +0,0 @@
-all:
- @echo "Building, this will take some time..."
- @sleep 30
- @echo "Done!"
diff --git a/spec/fixture/atom-build-hooks-dummy-package/main.js b/spec/fixture/atom-build-hooks-dummy-package/main.js
new file mode 100644
index 00000000..e1136b9e
--- /dev/null
+++ b/spec/fixture/atom-build-hooks-dummy-package/main.js
@@ -0,0 +1,41 @@
+'use babel';
+
+const hooks = {
+ preBuild: () => {},
+ postBuild: () => {}
+};
+
+class Builder {
+ getNiceName() {
+ return 'Build with hooks';
+ }
+
+ isEligible() {
+ return true;
+ }
+
+ settings() {
+ return [
+ {
+ exec: 'exit',
+ args: ['0'],
+ atomCommandName: 'build:hook-test:succeeding',
+ preBuild: () => hooks.preBuild(),
+ postBuild: (success) => hooks.postBuild(success)
+ },
+ {
+ exec: 'exit',
+ args: ['1'],
+ atomCommandName: 'build:hook-test:failing',
+ preBuild: () => hooks.preBuild(),
+ postBuild: (success) => hooks.postBuild(success)
+ }
+ ];
+ }
+}
+
+module.exports = {
+ activate: () => {},
+ provideBuilder: () => Builder,
+ hooks: hooks
+};
diff --git a/spec/fixture/atom-build-hooks-dummy-package/package.json b/spec/fixture/atom-build-hooks-dummy-package/package.json
new file mode 100644
index 00000000..a2dd4608
--- /dev/null
+++ b/spec/fixture/atom-build-hooks-dummy-package/package.json
@@ -0,0 +1,11 @@
+{
+ "name": "atom-build-hooks-dummy-package",
+ "main": "main",
+ "providedServices": {
+ "builder": {
+ "versions": {
+ "2.0.0": "provideBuilder"
+ }
+ }
+ }
+}
diff --git a/spec/fixture/atom-build-spec-linter/atom-build-spec-linter.js b/spec/fixture/atom-build-spec-linter/atom-build-spec-linter.js
new file mode 100644
index 00000000..5d920396
--- /dev/null
+++ b/spec/fixture/atom-build-spec-linter/atom-build-spec-linter.js
@@ -0,0 +1,33 @@
+'use babel';
+
+class Linter {
+ constructor() {
+ this.messages = [];
+ }
+ dispose() {}
+ setMessages(msg) {
+ this.messages = this.messages.concat(msg);
+ }
+ deleteMessages() {
+ this.messages = [];
+ }
+}
+
+module.exports = {
+ activate: () => {},
+ provideIndie: () => ({
+ register: (obj) => {
+ this.registered = obj;
+ this.linter = new Linter();
+ return this.linter;
+ }
+ }),
+
+ hasRegistered: () => {
+ return this.registered !== undefined;
+ },
+
+ getLinter: () => {
+ return this.linter;
+ }
+};
diff --git a/spec/fixture/atom-build-spec-linter/package.json b/spec/fixture/atom-build-spec-linter/package.json
new file mode 100644
index 00000000..7789ca93
--- /dev/null
+++ b/spec/fixture/atom-build-spec-linter/package.json
@@ -0,0 +1,11 @@
+{
+ "name": "atom-build-spec-linter",
+ "main": "atom-build-spec-linter",
+ "providedServices": {
+ "linter-indie": {
+ "versions": {
+ "1.0.0": "provideIndie"
+ }
+ }
+ }
+}
diff --git a/spec/fixture/change_dir_output.txt b/spec/fixture/change_dir_output.txt
new file mode 100644
index 00000000..33c9b946
--- /dev/null
+++ b/spec/fixture/change_dir_output.txt
@@ -0,0 +1,9 @@
+make all-recursive
+make[1]: Entering directory 'foo'
+Making all in src
+make[2]: Entering directory 'foo/src'
+ CC testmake.o
+testmake.c: In function 'main':
+testmake.c:3:5: error: unknown type name 'error'
+ error is here!
+ ^
diff --git a/spec/fixture/gulpfile.js b/spec/fixture/gulpfile.js
deleted file mode 100644
index 6e8717ac..00000000
--- a/spec/fixture/gulpfile.js
+++ /dev/null
@@ -1,5 +0,0 @@
-var gulp = require('gulp');
-
-gulp.task('default', function() {
- console.log('gulp built');
-});
diff --git a/spec/fixture/node_modules/.bin/grunt b/spec/fixture/node_modules/.bin/grunt
deleted file mode 120000
index 1ac2c4d3..00000000
--- a/spec/fixture/node_modules/.bin/grunt
+++ /dev/null
@@ -1 +0,0 @@
-../grunt-cli/bin/grunt
\ No newline at end of file
diff --git a/spec/fixture/node_modules/.bin/gulp b/spec/fixture/node_modules/.bin/gulp
deleted file mode 120000
index 5de73328..00000000
--- a/spec/fixture/node_modules/.bin/gulp
+++ /dev/null
@@ -1 +0,0 @@
-../gulp/bin/gulp.js
\ No newline at end of file
diff --git a/spec/fixture/node_modules/grunt-cli/.npmignore b/spec/fixture/node_modules/grunt-cli/.npmignore
deleted file mode 100644
index b785247e..00000000
--- a/spec/fixture/node_modules/grunt-cli/.npmignore
+++ /dev/null
@@ -1,3 +0,0 @@
-node_modules
-npm-debug.log
-tmp
diff --git a/spec/fixture/node_modules/grunt-cli/.travis.yml b/spec/fixture/node_modules/grunt-cli/.travis.yml
deleted file mode 100644
index a12e3f0f..00000000
--- a/spec/fixture/node_modules/grunt-cli/.travis.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-language: node_js
-node_js:
- - "0.8"
- - "0.10"
\ No newline at end of file
diff --git a/spec/fixture/node_modules/grunt-cli/AUTHORS b/spec/fixture/node_modules/grunt-cli/AUTHORS
deleted file mode 100644
index a9a36590..00000000
--- a/spec/fixture/node_modules/grunt-cli/AUTHORS
+++ /dev/null
@@ -1,4 +0,0 @@
-Tyler Kellen (http://goingslowly.com)
-Ben Alman (http://gruntjs.com)
-Scott González (http://nemikor.com)
-Forbes Lindesay (https://github.com/)
diff --git a/spec/fixture/node_modules/grunt-cli/Gruntfile.js b/spec/fixture/node_modules/grunt-cli/Gruntfile.js
deleted file mode 100644
index 02fc2ffc..00000000
--- a/spec/fixture/node_modules/grunt-cli/Gruntfile.js
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * grunt-cli
- * http://gruntjs.com/
- *
- * Copyright (c) 2012 Tyler Kellen, contributors
- * Licensed under the MIT license.
- * https://github.com/gruntjs/grunt-init/blob/master/LICENSE-MIT
- */
-
-'use strict';
-
-module.exports = function(grunt) {
-
- // Project configuration.
- grunt.initConfig({
- jshint: {
- all: [
- 'Gruntfile.js',
- 'lib/**/*.js',
- 'bin/*',
- ],
- options: {
- curly: true,
- eqeqeq: true,
- immed: true,
- latedef: true,
- newcap: true,
- noarg: true,
- sub: true,
- undef: true,
- unused: true,
- boss: true,
- eqnull: true,
- node: true,
- es5: true
- }
- },
- });
-
- // These plugins provide necessary tasks.
- grunt.loadNpmTasks('grunt-contrib-jshint');
-
- // "npm test" runs these tasks
- grunt.registerTask('test', ['jshint']);
-
- // Default task.
- grunt.registerTask('default', ['test']);
-
-};
diff --git a/spec/fixture/node_modules/grunt-cli/LICENSE-MIT b/spec/fixture/node_modules/grunt-cli/LICENSE-MIT
deleted file mode 100644
index 91df6e9b..00000000
--- a/spec/fixture/node_modules/grunt-cli/LICENSE-MIT
+++ /dev/null
@@ -1,22 +0,0 @@
-Copyright (c) 2012 Tyler Kellen, contributors
-
-Permission is hereby granted, free of charge, to any person
-obtaining a copy of this software and associated documentation
-files (the "Software"), to deal in the Software without
-restriction, including without limitation the rights to use,
-copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the
-Software is furnished to do so, subject to the following
-conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-OTHER DEALINGS IN THE SOFTWARE.
diff --git a/spec/fixture/node_modules/grunt-cli/README.md b/spec/fixture/node_modules/grunt-cli/README.md
deleted file mode 100644
index 8a0b9fec..00000000
--- a/spec/fixture/node_modules/grunt-cli/README.md
+++ /dev/null
@@ -1,30 +0,0 @@
-# grunt-cli [](http://travis-ci.org/gruntjs/grunt-cli)
-> The Grunt command line interface.
-
-Install this globally and you'll have access to the `grunt` command anywhere on your system.
-
-```shell
-npm install -g grunt-cli
-```
-
-**Note:** The job of the `grunt` command is to load and run the version of Grunt you have installed locally to your project, irrespective of its version. Starting with Grunt v0.4, you should never install Grunt itself globally. For more information about why, [please read this](http://blog.nodejs.org/2011/03/23/npm-1-0-global-vs-local-installation).
-
-See the [Getting Started](http://gruntjs.com/getting-started) guide for more information.
-
-## Shell tab auto-completion
-To enable tab auto-completion for Grunt, add one of the following lines to your `~/.bashrc` or `~/.zshrc` file.
-
-```bash
-# Bash, ~/.bashrc
-eval "$(grunt --completion=bash)"
-```
-
-```bash
-# Zsh, ~/.zshrc
-eval "$(grunt --completion=zsh)"
-```
-
-## Installing grunt-cli locally
-If you prefer the idiomatic Node.js method to get started with a project (`npm install && npm test`) then install grunt-cli locally with `npm install grunt-cli --save-dev`. Then add a script to your `package.json` to run the associated grunt command: `"scripts": { "test": "grunt test" } `. Now `npm test` will use the locally installed `./node_modules/.bin/grunt` executable to run your Grunt commands.
-
-To read more about npm scripts, please visit the npm docs: [https://npmjs.org/doc/misc/npm-scripts.html](https://npmjs.org/doc/misc/npm-scripts.html).
diff --git a/spec/fixture/node_modules/grunt-cli/bin/grunt b/spec/fixture/node_modules/grunt-cli/bin/grunt
deleted file mode 100755
index 691f875e..00000000
--- a/spec/fixture/node_modules/grunt-cli/bin/grunt
+++ /dev/null
@@ -1,45 +0,0 @@
-#!/usr/bin/env node
-
-'use strict';
-
-process.title = 'grunt';
-
-// Especially badass external libs.
-var findup = require('findup-sync');
-var resolve = require('resolve').sync;
-
-// Internal libs.
-var options = require('../lib/cli').options;
-var completion = require('../lib/completion');
-var info = require('../lib/info');
-var path = require('path');
-
-
-var basedir = process.cwd();
-var gruntpath;
-
-// Do stuff based on CLI options.
-if ('completion' in options) {
- completion.print(options.completion);
-} else if (options.version) {
- info.version();
-} else if (options.base && !options.gruntfile) {
- basedir = path.resolve(options.base);
-} else if (options.gruntfile) {
- basedir = path.resolve(path.dirname(options.gruntfile));
-}
-
-try {
- gruntpath = resolve('grunt', {basedir: basedir});
-} catch (ex) {
- gruntpath = findup('lib/grunt.js');
- // No grunt install found!
- if (!gruntpath) {
- if (options.version) { process.exit(); }
- if (options.help) { info.help(); }
- info.fatal('Unable to find local grunt.', 99);
- }
-}
-
-// Everything looks good. Require local grunt and run it.
-require(gruntpath).cli();
diff --git a/spec/fixture/node_modules/grunt-cli/completion/bash b/spec/fixture/node_modules/grunt-cli/completion/bash
deleted file mode 100755
index 99a96b5b..00000000
--- a/spec/fixture/node_modules/grunt-cli/completion/bash
+++ /dev/null
@@ -1,49 +0,0 @@
-#!/bin/bash
-
-# grunt-cli
-# http://gruntjs.com/
-#
-# Copyright (c) 2012 Tyler Kellen, contributors
-# Licensed under the MIT license.
-# https://github.com/gruntjs/grunt/blob/master/LICENSE-MIT
-
-# Usage:
-#
-# To enable bash completion for grunt, add the following line (minus the
-# leading #, which is the bash comment character) to your ~/.bashrc file:
-#
-# eval "$(grunt --completion=bash)"
-
-# Search the current directory and all parent directories for a gruntfile.
-function _grunt_gruntfile() {
- local curpath="$PWD"
- while [[ "$curpath" ]]; do
- for gruntfile in "$curpath/"{G,g}runtfile.{js,coffee}; do
- if [[ -e "$gruntfile" ]]; then
- echo "$gruntfile"
- return
- fi
- done
- curpath="${curpath%/*}"
- done
- return 1
-}
-
-# Enable bash autocompletion.
-function _grunt_completions() {
- # The currently-being-completed word.
- local cur="${COMP_WORDS[COMP_CWORD]}"
- # The current gruntfile, if it exists.
- local gruntfile="$(_grunt_gruntfile)"
- # The current grunt version, available tasks, options, etc.
- local gruntinfo="$(grunt --version --verbose 2>/dev/null)"
- # Options and tasks.
- local opts="$(echo "$gruntinfo" | awk '/Available options: / {$1=$2=""; print $0}')"
- local compls="$(echo "$gruntinfo" | awk '/Available tasks: / {$1=$2=""; print $0}')"
- # Only add -- or - options if the user has started typing -
- [[ "$cur" == -* ]] && compls="$compls $opts"
- # Tell complete what stuff to show.
- COMPREPLY=($(compgen -W "$compls" -- "$cur"))
-}
-
-complete -o default -F _grunt_completions grunt
diff --git a/spec/fixture/node_modules/grunt-cli/completion/zsh b/spec/fixture/node_modules/grunt-cli/completion/zsh
deleted file mode 100755
index f39cca26..00000000
--- a/spec/fixture/node_modules/grunt-cli/completion/zsh
+++ /dev/null
@@ -1,37 +0,0 @@
-#!/bin/zsh
-
-# grunt-cli
-# http://gruntjs.com/
-#
-# Copyright (c) 2012 Tyler Kellen, contributors
-# Licensed under the MIT license.
-# https://github.com/gruntjs/grunt/blob/master/LICENSE-MIT
-
-# Usage:
-#
-# To enable zsh completion for grunt, add the following line (minus the
-# leading #, which is the zsh comment character) to your ~/.zshrc file:
-#
-# eval "$(grunt --completion=zsh)"
-
-# Enable zsh autocompletion.
-function _grunt_completion() {
- local completions
- # The currently-being-completed word.
- local cur="${words[@]}"
- # The current grunt version, available tasks, options, etc.
- local gruntinfo="$(grunt --version --verbose 2>/dev/null)"
- # Options and tasks.
- local opts="$(echo "$gruntinfo" | awk '/Available options: / {$1=$2=""; print $0}')"
- local compls="$(echo "$gruntinfo" | awk '/Available tasks: / {$1=$2=""; print $0}')"
- # Only add -- or - options if the user has started typing -
- [[ "$cur" == -* ]] && compls="$compls $opts"
- # Trim whitespace.
- compls=$(echo "$compls" | sed -e 's/^ *//g' -e 's/ *$//g')
- # Turn compls into an array to of completions.
- completions=(${=compls})
- # Tell complete what stuff to show.
- compadd -- $completions
-}
-
-compdef _grunt_completion grunt
diff --git a/spec/fixture/node_modules/grunt-cli/lib/cli.js b/spec/fixture/node_modules/grunt-cli/lib/cli.js
deleted file mode 100644
index fc096d40..00000000
--- a/spec/fixture/node_modules/grunt-cli/lib/cli.js
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * grunt-cli
- * http://gruntjs.com/
- *
- * Copyright (c) 2012 Tyler Kellen, contributors
- * Licensed under the MIT license.
- * https://github.com/gruntjs/grunt-init/blob/master/LICENSE-MIT
- */
-
-'use strict';
-
-// External lib.
-var nopt = require('nopt');
-
-// CLI options we care about.
-exports.known = {help: Boolean, version: Boolean, completion: String};
-exports.aliases = {h: '--help', V: '--version', v: '--verbose'};
-
-// Parse them and return an options object.
-Object.defineProperty(exports, 'options', {
- get: function() {
- return nopt(exports.known, exports.aliases, process.argv, 2);
- }
-});
diff --git a/spec/fixture/node_modules/grunt-cli/lib/completion.js b/spec/fixture/node_modules/grunt-cli/lib/completion.js
deleted file mode 100644
index eecee06f..00000000
--- a/spec/fixture/node_modules/grunt-cli/lib/completion.js
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * grunt-cli
- * http://gruntjs.com/
- *
- * Copyright (c) 2012 Tyler Kellen, contributors
- * Licensed under the MIT license.
- * https://github.com/gruntjs/grunt-init/blob/master/LICENSE-MIT
- */
-
-'use strict';
-
-// Nodejs libs.
-var fs = require('fs');
-var path = require('path');
-
-exports.print = function(name) {
- var code = 0;
- var filepath = path.join(__dirname, '../completion', name);
- var output;
- try {
- // Attempt to read shell completion file.
- output = String(fs.readFileSync(filepath));
- } catch (err) {
- code = 5;
- output = 'echo "Specified grunt shell auto-completion rules ';
- if (name && name !== 'true') {
- output += 'for \'' + name + '\' ';
- }
- output += 'not found."';
- }
-
- console.log(output);
- process.exit(code);
-};
diff --git a/spec/fixture/node_modules/grunt-cli/lib/info.js b/spec/fixture/node_modules/grunt-cli/lib/info.js
deleted file mode 100644
index f128f399..00000000
--- a/spec/fixture/node_modules/grunt-cli/lib/info.js
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * grunt-cli
- * http://gruntjs.com/
- *
- * Copyright (c) 2012 Tyler Kellen, contributors
- * Licensed under the MIT license.
- * https://github.com/gruntjs/grunt-init/blob/master/LICENSE-MIT
- */
-
-'use strict';
-
-// Project metadata.
-var pkg = require('../package.json');
-
-// Display grunt-cli version.
-exports.version = function() {
- console.log('grunt-cli v' + pkg.version);
-};
-
-// Show help, then exit with a message and error code.
-exports.fatal = function(msg, code) {
- exports.helpHeader();
- console.log('Fatal error: ' + msg);
- console.log('');
- exports.helpFooter();
- process.exit(code);
-};
-
-// Show help and exit.
-exports.help = function() {
- exports.helpHeader();
- exports.helpFooter();
- process.exit();
-};
-
-// Help header.
-exports.helpHeader = function() {
- console.log('grunt-cli: ' + pkg.description + ' (v' + pkg.version + ')');
- console.log('');
-};
-
-// Help footer.
-exports.helpFooter = function() {
- [
- 'If you\'re seeing this message, either a Gruntfile wasn\'t found or grunt',
- 'hasn\'t been installed locally to your project. For more information about',
- 'installing and configuring grunt, please see the Getting Started guide:',
- '',
- 'http://gruntjs.com/getting-started',
- ].forEach(function(str) { console.log(str); });
-};
diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/.bin/nopt b/spec/fixture/node_modules/grunt-cli/node_modules/.bin/nopt
deleted file mode 120000
index 6b6566ea..00000000
--- a/spec/fixture/node_modules/grunt-cli/node_modules/.bin/nopt
+++ /dev/null
@@ -1 +0,0 @@
-../nopt/bin/nopt.js
\ No newline at end of file
diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/.jshintrc b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/.jshintrc
deleted file mode 100644
index 87189522..00000000
--- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/.jshintrc
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "loopfunc": true,
- "curly": true,
- "eqeqeq": true,
- "immed": true,
- "latedef": true,
- "newcap": true,
- "noarg": true,
- "sub": true,
- "undef": true,
- "unused": true,
- "boss": true,
- "eqnull": true,
- "node": true
-}
diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/.npmignore b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/.npmignore
deleted file mode 100644
index e69de29b..00000000
diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/.travis.yml b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/.travis.yml
deleted file mode 100644
index b30fcb75..00000000
--- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/.travis.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-language: node_js
-node_js:
- - 0.8
-before_script:
- - npm install -g grunt-cli
diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/Gruntfile.js b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/Gruntfile.js
deleted file mode 100644
index 2f964a5b..00000000
--- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/Gruntfile.js
+++ /dev/null
@@ -1,25 +0,0 @@
-'use strict';
-
-module.exports = function(grunt) {
-
- // Project configuration.
- grunt.initConfig({
- nodeunit: {
- files: ['test/**/*_test.js'],
- },
- jshint: {
- options: {
- jshintrc: '.jshintrc'
- },
- all: ['Gruntfile.js', 'lib/**/*.js', 'test/**/*.js']
- }
- });
-
- // Load plugins.
- grunt.loadNpmTasks('grunt-contrib-jshint');
- grunt.loadNpmTasks('grunt-contrib-nodeunit');
-
- // Default task.
- grunt.registerTask('default', ['jshint', 'nodeunit']);
-
-};
diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/LICENSE-MIT b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/LICENSE-MIT
deleted file mode 100644
index bb2aad6d..00000000
--- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/LICENSE-MIT
+++ /dev/null
@@ -1,22 +0,0 @@
-Copyright (c) 2013 "Cowboy" Ben Alman
-
-Permission is hereby granted, free of charge, to any person
-obtaining a copy of this software and associated documentation
-files (the "Software"), to deal in the Software without
-restriction, including without limitation the rights to use,
-copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the
-Software is furnished to do so, subject to the following
-conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-OTHER DEALINGS IN THE SOFTWARE.
diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/README.md b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/README.md
deleted file mode 100644
index 5459b93f..00000000
--- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/README.md
+++ /dev/null
@@ -1,45 +0,0 @@
-# findup-sync [](http://travis-ci.org/cowboy/node-findup-sync)
-
-Find the first file matching a given pattern in the current directory or the nearest ancestor directory.
-
-## Getting Started
-Install the module with: `npm install findup-sync`
-
-```js
-var findup = require('findup-sync');
-
-// Start looking in the CWD.
-var filepath1 = findup('{a,b}*.txt');
-
-// Start looking somewhere else, and ignore case (probably a good idea).
-var filepath2 = findup('{a,b}*.txt', {cwd: '/some/path', nocase: true});
-```
-
-## Usage
-
-```js
-findup(patternOrPatterns [, minimatchOptions])
-```
-
-### patternOrPatterns
-Type: `String` or `Array`
-Default: none
-
-One or more wildcard glob patterns. Or just filenames.
-
-### minimatchOptions
-Type: `Object`
-Default: `{}`
-
-Options to be passed to [minimatch](https://github.com/isaacs/minimatch).
-
-Note that if you want to start in a different directory than the current working directory, specify a `cwd` property here.
-
-## Contributing
-In lieu of a formal styleguide, take care to maintain the existing coding style. Add unit tests for any new or changed functionality. Lint and test your code using [Grunt](http://gruntjs.com/).
-
-## Release History
-2014-03-14 - v0.1.3 - Updated dependencies.
-2013-03-08 - v0.1.2 - Updated dependencies. Fixed a Node 0.9.x bug. Updated unit tests to work cross-platform.
-2012-11-15 - v0.1.1 - Now works without an options object.
-2012-11-01 - v0.1.0 - Initial release.
diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/lib/findup-sync.js b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/lib/findup-sync.js
deleted file mode 100644
index 742a4781..00000000
--- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/lib/findup-sync.js
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * findup-sync
- * https://github.com/cowboy/node-findup-sync
- *
- * Copyright (c) 2013 "Cowboy" Ben Alman
- * Licensed under the MIT license.
- */
-
-'use strict';
-
-// Nodejs libs.
-var path = require('path');
-
-// External libs.
-var glob = require('glob');
-var _ = require('lodash');
-
-// Search for a filename in the given directory or all parent directories.
-module.exports = function(patterns, options) {
- // Normalize patterns to an array.
- if (!Array.isArray(patterns)) { patterns = [patterns]; }
- // Create globOptions so that it can be modified without mutating the
- // original object.
- var globOptions = Object.create(options || {});
- globOptions.maxDepth = 1;
- globOptions.cwd = path.resolve(globOptions.cwd || '.');
-
- var files, lastpath;
- do {
- // Search for files matching patterns.
- files = _(patterns).map(function(pattern) {
- return glob.sync(pattern, globOptions);
- }).flatten().uniq().value();
- // Return file if found.
- if (files.length > 0) {
- return path.resolve(path.join(globOptions.cwd, files[0]));
- }
- // Go up a directory.
- lastpath = globOptions.cwd;
- globOptions.cwd = path.resolve(globOptions.cwd, '..');
- // If parentpath is the same as basedir, we can't go any higher.
- } while (globOptions.cwd !== lastpath);
-
- // No files were found!
- return null;
-};
diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/.npmignore b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/.npmignore
deleted file mode 100644
index 2af4b71c..00000000
--- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/.npmignore
+++ /dev/null
@@ -1,2 +0,0 @@
-.*.swp
-test/a/
diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/.travis.yml b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/.travis.yml
deleted file mode 100644
index baa0031d..00000000
--- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/.travis.yml
+++ /dev/null
@@ -1,3 +0,0 @@
-language: node_js
-node_js:
- - 0.8
diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/LICENSE b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/LICENSE
deleted file mode 100644
index 0c44ae71..00000000
--- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/LICENSE
+++ /dev/null
@@ -1,27 +0,0 @@
-Copyright (c) Isaac Z. Schlueter ("Author")
-All rights reserved.
-
-The BSD License
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
-2. 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.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 THE AUTHOR OR CONTRIBUTORS
-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.
diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/README.md b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/README.md
deleted file mode 100644
index cc691645..00000000
--- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/README.md
+++ /dev/null
@@ -1,250 +0,0 @@
-# Glob
-
-Match files using the patterns the shell uses, like stars and stuff.
-
-This is a glob implementation in JavaScript. It uses the `minimatch`
-library to do its matching.
-
-## Attention: node-glob users!
-
-The API has changed dramatically between 2.x and 3.x. This library is
-now 100% JavaScript, and the integer flags have been replaced with an
-options object.
-
-Also, there's an event emitter class, proper tests, and all the other
-things you've come to expect from node modules.
-
-And best of all, no compilation!
-
-## Usage
-
-```javascript
-var glob = require("glob")
-
-// options is optional
-glob("**/*.js", options, function (er, files) {
- // files is an array of filenames.
- // If the `nonull` option is set, and nothing
- // was found, then files is ["**/*.js"]
- // er is an error object or null.
-})
-```
-
-## Features
-
-Please see the [minimatch
-documentation](https://github.com/isaacs/minimatch) for more details.
-
-Supports these glob features:
-
-* Brace Expansion
-* Extended glob matching
-* "Globstar" `**` matching
-
-See:
-
-* `man sh`
-* `man bash`
-* `man 3 fnmatch`
-* `man 5 gitignore`
-* [minimatch documentation](https://github.com/isaacs/minimatch)
-
-## glob(pattern, [options], cb)
-
-* `pattern` {String} Pattern to be matched
-* `options` {Object}
-* `cb` {Function}
- * `err` {Error | null}
- * `matches` {Array} filenames found matching the pattern
-
-Perform an asynchronous glob search.
-
-## glob.sync(pattern, [options])
-
-* `pattern` {String} Pattern to be matched
-* `options` {Object}
-* return: {Array} filenames found matching the pattern
-
-Perform a synchronous glob search.
-
-## Class: glob.Glob
-
-Create a Glob object by instanting the `glob.Glob` class.
-
-```javascript
-var Glob = require("glob").Glob
-var mg = new Glob(pattern, options, cb)
-```
-
-It's an EventEmitter, and starts walking the filesystem to find matches
-immediately.
-
-### new glob.Glob(pattern, [options], [cb])
-
-* `pattern` {String} pattern to search for
-* `options` {Object}
-* `cb` {Function} Called when an error occurs, or matches are found
- * `err` {Error | null}
- * `matches` {Array} filenames found matching the pattern
-
-Note that if the `sync` flag is set in the options, then matches will
-be immediately available on the `g.found` member.
-
-### Properties
-
-* `minimatch` The minimatch object that the glob uses.
-* `options` The options object passed in.
-* `error` The error encountered. When an error is encountered, the
- glob object is in an undefined state, and should be discarded.
-* `aborted` Boolean which is set to true when calling `abort()`. There
- is no way at this time to continue a glob search after aborting, but
- you can re-use the statCache to avoid having to duplicate syscalls.
-* `statCache` Collection of all the stat results the glob search
- performed.
-* `cache` Convenience object. Each field has the following possible
- values:
- * `false` - Path does not exist
- * `true` - Path exists
- * `1` - Path exists, and is not a directory
- * `2` - Path exists, and is a directory
- * `[file, entries, ...]` - Path exists, is a directory, and the
- array value is the results of `fs.readdir`
-
-### Events
-
-* `end` When the matching is finished, this is emitted with all the
- matches found. If the `nonull` option is set, and no match was found,
- then the `matches` list contains the original pattern. The matches
- are sorted, unless the `nosort` flag is set.
-* `match` Every time a match is found, this is emitted with the matched.
-* `error` Emitted when an unexpected error is encountered, or whenever
- any fs error occurs if `options.strict` is set.
-* `abort` When `abort()` is called, this event is raised.
-
-### Methods
-
-* `abort` Stop the search.
-
-### Options
-
-All the options that can be passed to Minimatch can also be passed to
-Glob to change pattern matching behavior. Also, some have been added,
-or have glob-specific ramifications.
-
-All options are false by default, unless otherwise noted.
-
-All options are added to the glob object, as well.
-
-* `cwd` The current working directory in which to search. Defaults
- to `process.cwd()`.
-* `root` The place where patterns starting with `/` will be mounted
- onto. Defaults to `path.resolve(options.cwd, "/")` (`/` on Unix
- systems, and `C:\` or some such on Windows.)
-* `dot` Include `.dot` files in normal matches and `globstar` matches.
- Note that an explicit dot in a portion of the pattern will always
- match dot files.
-* `nomount` By default, a pattern starting with a forward-slash will be
- "mounted" onto the root setting, so that a valid filesystem path is
- returned. Set this flag to disable that behavior.
-* `mark` Add a `/` character to directory matches. Note that this
- requires additional stat calls.
-* `nosort` Don't sort the results.
-* `stat` Set to true to stat *all* results. This reduces performance
- somewhat, and is completely unnecessary, unless `readdir` is presumed
- to be an untrustworthy indicator of file existence. It will cause
- ELOOP to be triggered one level sooner in the case of cyclical
- symbolic links.
-* `silent` When an unusual error is encountered
- when attempting to read a directory, a warning will be printed to
- stderr. Set the `silent` option to true to suppress these warnings.
-* `strict` When an unusual error is encountered
- when attempting to read a directory, the process will just continue on
- in search of other matches. Set the `strict` option to raise an error
- in these cases.
-* `cache` See `cache` property above. Pass in a previously generated
- cache object to save some fs calls.
-* `statCache` A cache of results of filesystem information, to prevent
- unnecessary stat calls. While it should not normally be necessary to
- set this, you may pass the statCache from one glob() call to the
- options object of another, if you know that the filesystem will not
- change between calls. (See "Race Conditions" below.)
-* `sync` Perform a synchronous glob search.
-* `nounique` In some cases, brace-expanded patterns can result in the
- same file showing up multiple times in the result set. By default,
- this implementation prevents duplicates in the result set.
- Set this flag to disable that behavior.
-* `nonull` Set to never return an empty set, instead returning a set
- containing the pattern itself. This is the default in glob(3).
-* `nocase` Perform a case-insensitive match. Note that case-insensitive
- filesystems will sometimes result in glob returning results that are
- case-insensitively matched anyway, since readdir and stat will not
- raise an error.
-* `debug` Set to enable debug logging in minimatch and glob.
-* `globDebug` Set to enable debug logging in glob, but not minimatch.
-
-## Comparisons to other fnmatch/glob implementations
-
-While strict compliance with the existing standards is a worthwhile
-goal, some discrepancies exist between node-glob and other
-implementations, and are intentional.
-
-If the pattern starts with a `!` character, then it is negated. Set the
-`nonegate` flag to suppress this behavior, and treat leading `!`
-characters normally. This is perhaps relevant if you wish to start the
-pattern with a negative extglob pattern like `!(a|B)`. Multiple `!`
-characters at the start of a pattern will negate the pattern multiple
-times.
-
-If a pattern starts with `#`, then it is treated as a comment, and
-will not match anything. Use `\#` to match a literal `#` at the
-start of a line, or set the `nocomment` flag to suppress this behavior.
-
-The double-star character `**` is supported by default, unless the
-`noglobstar` flag is set. This is supported in the manner of bsdglob
-and bash 4.1, where `**` only has special significance if it is the only
-thing in a path part. That is, `a/**/b` will match `a/x/y/b`, but
-`a/**b` will not.
-
-If an escaped pattern has no matches, and the `nonull` flag is set,
-then glob returns the pattern as-provided, rather than
-interpreting the character escapes. For example,
-`glob.match([], "\\*a\\?")` will return `"\\*a\\?"` rather than
-`"*a?"`. This is akin to setting the `nullglob` option in bash, except
-that it does not resolve escaped pattern characters.
-
-If brace expansion is not disabled, then it is performed before any
-other interpretation of the glob pattern. Thus, a pattern like
-`+(a|{b),c)}`, which would not be valid in bash or zsh, is expanded
-**first** into the set of `+(a|b)` and `+(a|c)`, and those patterns are
-checked for validity. Since those two are valid, matching proceeds.
-
-## Windows
-
-**Please only use forward-slashes in glob expressions.**
-
-Though windows uses either `/` or `\` as its path separator, only `/`
-characters are used by this glob implementation. You must use
-forward-slashes **only** in glob expressions. Back-slashes will always
-be interpreted as escape characters, not path separators.
-
-Results from absolute patterns such as `/foo/*` are mounted onto the
-root setting using `path.join`. On windows, this will by default result
-in `/foo/*` matching `C:\foo\bar.txt`.
-
-## Race Conditions
-
-Glob searching, by its very nature, is susceptible to race conditions,
-since it relies on directory walking and such.
-
-As a result, it is possible that a file that exists when glob looks for
-it may have been deleted or modified by the time it returns the result.
-
-As part of its internal implementation, this program caches all stat
-and readdir calls that it makes, in order to cut down on system
-overhead. However, this also makes it even more susceptible to races,
-especially if the cache or statCache objects are reused between glob
-calls.
-
-Users are thus advised not to use a glob result as a guarantee of
-filesystem state in the face of rapid changes. For the vast majority
-of operations, this is never a problem.
diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/examples/g.js b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/examples/g.js
deleted file mode 100644
index be122df0..00000000
--- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/examples/g.js
+++ /dev/null
@@ -1,9 +0,0 @@
-var Glob = require("../").Glob
-
-var pattern = "test/a/**/[cg]/../[cg]"
-console.log(pattern)
-
-var mg = new Glob(pattern, {mark: true, sync:true}, function (er, matches) {
- console.log("matches", matches)
-})
-console.log("after")
diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/examples/usr-local.js b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/examples/usr-local.js
deleted file mode 100644
index 327a425e..00000000
--- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/examples/usr-local.js
+++ /dev/null
@@ -1,9 +0,0 @@
-var Glob = require("../").Glob
-
-var pattern = "{./*/*,/*,/usr/local/*}"
-console.log(pattern)
-
-var mg = new Glob(pattern, {mark: true}, function (er, matches) {
- console.log("matches", matches)
-})
-console.log("after")
diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/glob.js b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/glob.js
deleted file mode 100644
index f646c448..00000000
--- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/glob.js
+++ /dev/null
@@ -1,728 +0,0 @@
-// Approach:
-//
-// 1. Get the minimatch set
-// 2. For each pattern in the set, PROCESS(pattern)
-// 3. Store matches per-set, then uniq them
-//
-// PROCESS(pattern)
-// Get the first [n] items from pattern that are all strings
-// Join these together. This is PREFIX.
-// If there is no more remaining, then stat(PREFIX) and
-// add to matches if it succeeds. END.
-// readdir(PREFIX) as ENTRIES
-// If fails, END
-// If pattern[n] is GLOBSTAR
-// // handle the case where the globstar match is empty
-// // by pruning it out, and testing the resulting pattern
-// PROCESS(pattern[0..n] + pattern[n+1 .. $])
-// // handle other cases.
-// for ENTRY in ENTRIES (not dotfiles)
-// // attach globstar + tail onto the entry
-// PROCESS(pattern[0..n] + ENTRY + pattern[n .. $])
-//
-// else // not globstar
-// for ENTRY in ENTRIES (not dotfiles, unless pattern[n] is dot)
-// Test ENTRY against pattern[n]
-// If fails, continue
-// If passes, PROCESS(pattern[0..n] + item + pattern[n+1 .. $])
-//
-// Caveat:
-// Cache all stats and readdirs results to minimize syscall. Since all
-// we ever care about is existence and directory-ness, we can just keep
-// `true` for files, and [children,...] for directories, or `false` for
-// things that don't exist.
-
-
-
-module.exports = glob
-
-var fs = require("fs")
-, minimatch = require("minimatch")
-, Minimatch = minimatch.Minimatch
-, inherits = require("inherits")
-, EE = require("events").EventEmitter
-, path = require("path")
-, isDir = {}
-, assert = require("assert").ok
-
-function glob (pattern, options, cb) {
- if (typeof options === "function") cb = options, options = {}
- if (!options) options = {}
-
- if (typeof options === "number") {
- deprecated()
- return
- }
-
- var g = new Glob(pattern, options, cb)
- return g.sync ? g.found : g
-}
-
-glob.fnmatch = deprecated
-
-function deprecated () {
- throw new Error("glob's interface has changed. Please see the docs.")
-}
-
-glob.sync = globSync
-function globSync (pattern, options) {
- if (typeof options === "number") {
- deprecated()
- return
- }
-
- options = options || {}
- options.sync = true
- return glob(pattern, options)
-}
-
-this._processingEmitQueue = false
-
-glob.Glob = Glob
-inherits(Glob, EE)
-function Glob (pattern, options, cb) {
- if (!(this instanceof Glob)) {
- return new Glob(pattern, options, cb)
- }
-
- if (typeof options === "function") {
- cb = options
- options = null
- }
-
- if (typeof cb === "function") {
- this.on("error", cb)
- this.on("end", function (matches) {
- cb(null, matches)
- })
- }
-
- options = options || {}
-
- this._endEmitted = false
- this.EOF = {}
- this._emitQueue = []
-
- this.paused = false
- this._processingEmitQueue = false
-
- this.maxDepth = options.maxDepth || 1000
- this.maxLength = options.maxLength || Infinity
- this.cache = options.cache || {}
- this.statCache = options.statCache || {}
-
- this.changedCwd = false
- var cwd = process.cwd()
- if (!options.hasOwnProperty("cwd")) this.cwd = cwd
- else {
- this.cwd = options.cwd
- this.changedCwd = path.resolve(options.cwd) !== cwd
- }
-
- this.root = options.root || path.resolve(this.cwd, "/")
- this.root = path.resolve(this.root)
- if (process.platform === "win32")
- this.root = this.root.replace(/\\/g, "/")
-
- this.nomount = !!options.nomount
-
- if (!pattern) {
- throw new Error("must provide pattern")
- }
-
- // base-matching: just use globstar for that.
- if (options.matchBase && -1 === pattern.indexOf("/")) {
- if (options.noglobstar) {
- throw new Error("base matching requires globstar")
- }
- pattern = "**/" + pattern
- }
-
- this.strict = options.strict !== false
- this.dot = !!options.dot
- this.mark = !!options.mark
- this.sync = !!options.sync
- this.nounique = !!options.nounique
- this.nonull = !!options.nonull
- this.nosort = !!options.nosort
- this.nocase = !!options.nocase
- this.stat = !!options.stat
-
- this.debug = !!options.debug || !!options.globDebug
- if (this.debug)
- this.log = console.error
-
- this.silent = !!options.silent
-
- var mm = this.minimatch = new Minimatch(pattern, options)
- this.options = mm.options
- pattern = this.pattern = mm.pattern
-
- this.error = null
- this.aborted = false
-
- // list of all the patterns that ** has resolved do, so
- // we can avoid visiting multiple times.
- this._globstars = {}
-
- EE.call(this)
-
- // process each pattern in the minimatch set
- var n = this.minimatch.set.length
-
- // The matches are stored as {: true,...} so that
- // duplicates are automagically pruned.
- // Later, we do an Object.keys() on these.
- // Keep them as a list so we can fill in when nonull is set.
- this.matches = new Array(n)
-
- this.minimatch.set.forEach(iterator.bind(this))
- function iterator (pattern, i, set) {
- this._process(pattern, 0, i, function (er) {
- if (er) this.emit("error", er)
- if (-- n <= 0) this._finish()
- })
- }
-}
-
-Glob.prototype.log = function () {}
-
-Glob.prototype._finish = function () {
- assert(this instanceof Glob)
-
- var nou = this.nounique
- , all = nou ? [] : {}
-
- for (var i = 0, l = this.matches.length; i < l; i ++) {
- var matches = this.matches[i]
- this.log("matches[%d] =", i, matches)
- // do like the shell, and spit out the literal glob
- if (!matches) {
- if (this.nonull) {
- var literal = this.minimatch.globSet[i]
- if (nou) all.push(literal)
- else all[literal] = true
- }
- } else {
- // had matches
- var m = Object.keys(matches)
- if (nou) all.push.apply(all, m)
- else m.forEach(function (m) {
- all[m] = true
- })
- }
- }
-
- if (!nou) all = Object.keys(all)
-
- if (!this.nosort) {
- all = all.sort(this.nocase ? alphasorti : alphasort)
- }
-
- if (this.mark) {
- // at *some* point we statted all of these
- all = all.map(this._mark, this)
- }
-
- this.log("emitting end", all)
-
- this.EOF = this.found = all
- this.emitMatch(this.EOF)
-}
-
-function alphasorti (a, b) {
- a = a.toLowerCase()
- b = b.toLowerCase()
- return alphasort(a, b)
-}
-
-function alphasort (a, b) {
- return a > b ? 1 : a < b ? -1 : 0
-}
-
-Glob.prototype._mark = function (p) {
- var c = this.cache[p]
- var m = p
- if (c) {
- var isDir = c === 2 || Array.isArray(c)
- var slash = p.slice(-1) === '/'
-
- if (isDir && !slash)
- m += '/'
- else if (!isDir && slash)
- m = m.slice(0, -1)
-
- if (m !== p) {
- this.statCache[m] = this.statCache[p]
- this.cache[m] = this.cache[p]
- }
- }
-
- return m
-}
-
-Glob.prototype.abort = function () {
- this.aborted = true
- this.emit("abort")
-}
-
-Glob.prototype.pause = function () {
- if (this.paused) return
- if (this.sync)
- this.emit("error", new Error("Can't pause/resume sync glob"))
- this.paused = true
- this.emit("pause")
-}
-
-Glob.prototype.resume = function () {
- if (!this.paused) return
- if (this.sync)
- this.emit("error", new Error("Can't pause/resume sync glob"))
- this.paused = false
- this.emit("resume")
- this._processEmitQueue()
- //process.nextTick(this.emit.bind(this, "resume"))
-}
-
-Glob.prototype.emitMatch = function (m) {
- this.log('emitMatch', m)
- this._emitQueue.push(m)
- this._processEmitQueue()
-}
-
-Glob.prototype._processEmitQueue = function (m) {
- this.log("pEQ paused=%j processing=%j m=%j", this.paused,
- this._processingEmitQueue, m)
- var done = false
- while (!this._processingEmitQueue &&
- !this.paused) {
- this._processingEmitQueue = true
- var m = this._emitQueue.shift()
- this.log(">processEmitQueue", m === this.EOF ? ":EOF:" : m)
- if (!m) {
- this.log(">processEmitQueue, falsey m")
- this._processingEmitQueue = false
- break
- }
-
- if (m === this.EOF || !(this.mark && !this.stat)) {
- this.log("peq: unmarked, or eof")
- next.call(this, 0, false)
- } else if (this.statCache[m]) {
- var sc = this.statCache[m]
- var exists
- if (sc)
- exists = sc.isDirectory() ? 2 : 1
- this.log("peq: stat cached")
- next.call(this, exists, exists === 2)
- } else {
- this.log("peq: _stat, then next")
- this._stat(m, next)
- }
-
- function next(exists, isDir) {
- this.log("next", m, exists, isDir)
- var ev = m === this.EOF ? "end" : "match"
-
- // "end" can only happen once.
- assert(!this._endEmitted)
- if (ev === "end")
- this._endEmitted = true
-
- if (exists) {
- // Doesn't mean it necessarily doesn't exist, it's possible
- // we just didn't check because we don't care that much, or
- // this is EOF anyway.
- if (isDir && !m.match(/\/$/)) {
- m = m + "/"
- } else if (!isDir && m.match(/\/$/)) {
- m = m.replace(/\/+$/, "")
- }
- }
- this.log("emit", ev, m)
- this.emit(ev, m)
- this._processingEmitQueue = false
- if (done && m !== this.EOF && !this.paused)
- this._processEmitQueue()
- }
- }
- done = true
-}
-
-Glob.prototype._process = function (pattern, depth, index, cb_) {
- assert(this instanceof Glob)
-
- var cb = function cb (er, res) {
- assert(this instanceof Glob)
- if (this.paused) {
- if (!this._processQueue) {
- this._processQueue = []
- this.once("resume", function () {
- var q = this._processQueue
- this._processQueue = null
- q.forEach(function (cb) { cb() })
- })
- }
- this._processQueue.push(cb_.bind(this, er, res))
- } else {
- cb_.call(this, er, res)
- }
- }.bind(this)
-
- if (this.aborted) return cb()
-
- if (depth > this.maxDepth) return cb()
-
- // Get the first [n] parts of pattern that are all strings.
- var n = 0
- while (typeof pattern[n] === "string") {
- n ++
- }
- // now n is the index of the first one that is *not* a string.
-
- // see if there's anything else
- var prefix
- switch (n) {
- // if not, then this is rather simple
- case pattern.length:
- prefix = pattern.join("/")
- this._stat(prefix, function (exists, isDir) {
- // either it's there, or it isn't.
- // nothing more to do, either way.
- if (exists) {
- if (prefix && isAbsolute(prefix) && !this.nomount) {
- if (prefix.charAt(0) === "/") {
- prefix = path.join(this.root, prefix)
- } else {
- prefix = path.resolve(this.root, prefix)
- }
- }
-
- if (process.platform === "win32")
- prefix = prefix.replace(/\\/g, "/")
-
- this.matches[index] = this.matches[index] || {}
- this.matches[index][prefix] = true
- this.emitMatch(prefix)
- }
- return cb()
- })
- return
-
- case 0:
- // pattern *starts* with some non-trivial item.
- // going to readdir(cwd), but not include the prefix in matches.
- prefix = null
- break
-
- default:
- // pattern has some string bits in the front.
- // whatever it starts with, whether that's "absolute" like /foo/bar,
- // or "relative" like "../baz"
- prefix = pattern.slice(0, n)
- prefix = prefix.join("/")
- break
- }
-
- // get the list of entries.
- var read
- if (prefix === null) read = "."
- else if (isAbsolute(prefix) || isAbsolute(pattern.join("/"))) {
- if (!prefix || !isAbsolute(prefix)) {
- prefix = path.join("/", prefix)
- }
- read = prefix = path.resolve(prefix)
-
- // if (process.platform === "win32")
- // read = prefix = prefix.replace(/^[a-zA-Z]:|\\/g, "/")
-
- this.log('absolute: ', prefix, this.root, pattern, read)
- } else {
- read = prefix
- }
-
- this.log('readdir(%j)', read, this.cwd, this.root)
-
- return this._readdir(read, function (er, entries) {
- if (er) {
- // not a directory!
- // this means that, whatever else comes after this, it can never match
- return cb()
- }
-
- // globstar is special
- if (pattern[n] === minimatch.GLOBSTAR) {
- // test without the globstar, and with every child both below
- // and replacing the globstar.
- var s = [ pattern.slice(0, n).concat(pattern.slice(n + 1)) ]
- entries.forEach(function (e) {
- if (e.charAt(0) === "." && !this.dot) return
- // instead of the globstar
- s.push(pattern.slice(0, n).concat(e).concat(pattern.slice(n + 1)))
- // below the globstar
- s.push(pattern.slice(0, n).concat(e).concat(pattern.slice(n)))
- }, this)
-
- s = s.filter(function (pattern) {
- var key = gsKey(pattern)
- var seen = !this._globstars[key]
- this._globstars[key] = true
- return seen
- }, this)
-
- if (!s.length)
- return cb()
-
- // now asyncForEach over this
- var l = s.length
- , errState = null
- s.forEach(function (gsPattern) {
- this._process(gsPattern, depth + 1, index, function (er) {
- if (errState) return
- if (er) return cb(errState = er)
- if (--l <= 0) return cb()
- })
- }, this)
-
- return
- }
-
- // not a globstar
- // It will only match dot entries if it starts with a dot, or if
- // dot is set. Stuff like @(.foo|.bar) isn't allowed.
- var pn = pattern[n]
- var rawGlob = pattern[n]._glob
- , dotOk = this.dot || rawGlob.charAt(0) === "."
-
- entries = entries.filter(function (e) {
- return (e.charAt(0) !== "." || dotOk) &&
- e.match(pattern[n])
- })
-
- // If n === pattern.length - 1, then there's no need for the extra stat
- // *unless* the user has specified "mark" or "stat" explicitly.
- // We know that they exist, since the readdir returned them.
- if (n === pattern.length - 1 &&
- !this.mark &&
- !this.stat) {
- entries.forEach(function (e) {
- if (prefix) {
- if (prefix !== "/") e = prefix + "/" + e
- else e = prefix + e
- }
- if (e.charAt(0) === "/" && !this.nomount) {
- e = path.join(this.root, e)
- }
-
- if (process.platform === "win32")
- e = e.replace(/\\/g, "/")
-
- this.matches[index] = this.matches[index] || {}
- this.matches[index][e] = true
- this.emitMatch(e)
- }, this)
- return cb.call(this)
- }
-
-
- // now test all the remaining entries as stand-ins for that part
- // of the pattern.
- var l = entries.length
- , errState = null
- if (l === 0) return cb() // no matches possible
- entries.forEach(function (e) {
- var p = pattern.slice(0, n).concat(e).concat(pattern.slice(n + 1))
- this._process(p, depth + 1, index, function (er) {
- if (errState) return
- if (er) return cb(errState = er)
- if (--l === 0) return cb.call(this)
- })
- }, this)
- })
-
-}
-
-function gsKey (pattern) {
- return '**' + pattern.map(function (p) {
- return (p === minimatch.GLOBSTAR) ? '**' : (''+p)
- }).join('/')
-}
-
-Glob.prototype._stat = function (f, cb) {
- assert(this instanceof Glob)
- var abs = f
- if (f.charAt(0) === "/") {
- abs = path.join(this.root, f)
- } else if (this.changedCwd) {
- abs = path.resolve(this.cwd, f)
- }
-
- if (f.length > this.maxLength) {
- var er = new Error("Path name too long")
- er.code = "ENAMETOOLONG"
- er.path = f
- return this._afterStat(f, abs, cb, er)
- }
-
- this.log('stat', [this.cwd, f, '=', abs])
-
- if (!this.stat && this.cache.hasOwnProperty(f)) {
- var exists = this.cache[f]
- , isDir = exists && (Array.isArray(exists) || exists === 2)
- if (this.sync) return cb.call(this, !!exists, isDir)
- return process.nextTick(cb.bind(this, !!exists, isDir))
- }
-
- var stat = this.statCache[abs]
- if (this.sync || stat) {
- var er
- try {
- stat = fs.statSync(abs)
- } catch (e) {
- er = e
- }
- this._afterStat(f, abs, cb, er, stat)
- } else {
- fs.stat(abs, this._afterStat.bind(this, f, abs, cb))
- }
-}
-
-Glob.prototype._afterStat = function (f, abs, cb, er, stat) {
- var exists
- assert(this instanceof Glob)
-
- if (abs.slice(-1) === "/" && stat && !stat.isDirectory()) {
- this.log("should be ENOTDIR, fake it")
-
- er = new Error("ENOTDIR, not a directory '" + abs + "'")
- er.path = abs
- er.code = "ENOTDIR"
- stat = null
- }
-
- var emit = !this.statCache[abs]
- this.statCache[abs] = stat
-
- if (er || !stat) {
- exists = false
- } else {
- exists = stat.isDirectory() ? 2 : 1
- if (emit)
- this.emit('stat', f, stat)
- }
- this.cache[f] = this.cache[f] || exists
- cb.call(this, !!exists, exists === 2)
-}
-
-Glob.prototype._readdir = function (f, cb) {
- assert(this instanceof Glob)
- var abs = f
- if (f.charAt(0) === "/") {
- abs = path.join(this.root, f)
- } else if (isAbsolute(f)) {
- abs = f
- } else if (this.changedCwd) {
- abs = path.resolve(this.cwd, f)
- }
-
- if (f.length > this.maxLength) {
- var er = new Error("Path name too long")
- er.code = "ENAMETOOLONG"
- er.path = f
- return this._afterReaddir(f, abs, cb, er)
- }
-
- this.log('readdir', [this.cwd, f, abs])
- if (this.cache.hasOwnProperty(f)) {
- var c = this.cache[f]
- if (Array.isArray(c)) {
- if (this.sync) return cb.call(this, null, c)
- return process.nextTick(cb.bind(this, null, c))
- }
-
- if (!c || c === 1) {
- // either ENOENT or ENOTDIR
- var code = c ? "ENOTDIR" : "ENOENT"
- , er = new Error((c ? "Not a directory" : "Not found") + ": " + f)
- er.path = f
- er.code = code
- this.log(f, er)
- if (this.sync) return cb.call(this, er)
- return process.nextTick(cb.bind(this, er))
- }
-
- // at this point, c === 2, meaning it's a dir, but we haven't
- // had to read it yet, or c === true, meaning it's *something*
- // but we don't have any idea what. Need to read it, either way.
- }
-
- if (this.sync) {
- var er, entries
- try {
- entries = fs.readdirSync(abs)
- } catch (e) {
- er = e
- }
- return this._afterReaddir(f, abs, cb, er, entries)
- }
-
- fs.readdir(abs, this._afterReaddir.bind(this, f, abs, cb))
-}
-
-Glob.prototype._afterReaddir = function (f, abs, cb, er, entries) {
- assert(this instanceof Glob)
- if (entries && !er) {
- this.cache[f] = entries
- // if we haven't asked to stat everything for suresies, then just
- // assume that everything in there exists, so we can avoid
- // having to stat it a second time. This also gets us one step
- // further into ELOOP territory.
- if (!this.mark && !this.stat) {
- entries.forEach(function (e) {
- if (f === "/") e = f + e
- else e = f + "/" + e
- this.cache[e] = true
- }, this)
- }
-
- return cb.call(this, er, entries)
- }
-
- // now handle errors, and cache the information
- if (er) switch (er.code) {
- case "ENOTDIR": // totally normal. means it *does* exist.
- this.cache[f] = 1
- return cb.call(this, er)
- case "ENOENT": // not terribly unusual
- case "ELOOP":
- case "ENAMETOOLONG":
- case "UNKNOWN":
- this.cache[f] = false
- return cb.call(this, er)
- default: // some unusual error. Treat as failure.
- this.cache[f] = false
- if (this.strict) this.emit("error", er)
- if (!this.silent) console.error("glob error", er)
- return cb.call(this, er)
- }
-}
-
-var isAbsolute = process.platform === "win32" ? absWin : absUnix
-
-function absWin (p) {
- if (absUnix(p)) return true
- // pull off the device/UNC bit from a windows path.
- // from node's lib/path.js
- var splitDeviceRe =
- /^([a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/]+[^\\\/]+)?([\\\/])?([\s\S]*?)$/
- , result = splitDeviceRe.exec(p)
- , device = result[1] || ''
- , isUnc = device && device.charAt(1) !== ':'
- , isAbsolute = !!result[2] || isUnc // UNC paths are always absolute
-
- return isAbsolute
-}
-
-function absUnix (p) {
- return p.charAt(0) === "/" || p === ""
-}
diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/inherits/LICENSE b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/inherits/LICENSE
deleted file mode 100644
index dea3013d..00000000
--- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/inherits/LICENSE
+++ /dev/null
@@ -1,16 +0,0 @@
-The ISC License
-
-Copyright (c) Isaac Z. Schlueter
-
-Permission to use, copy, modify, and/or distribute this software for any
-purpose with or without fee is hereby granted, provided that the above
-copyright notice and this permission notice appear in all copies.
-
-THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
-REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
-FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
-INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
-OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-PERFORMANCE OF THIS SOFTWARE.
-
diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/inherits/README.md b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/inherits/README.md
deleted file mode 100644
index b1c56658..00000000
--- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/inherits/README.md
+++ /dev/null
@@ -1,42 +0,0 @@
-Browser-friendly inheritance fully compatible with standard node.js
-[inherits](http://nodejs.org/api/util.html#util_util_inherits_constructor_superconstructor).
-
-This package exports standard `inherits` from node.js `util` module in
-node environment, but also provides alternative browser-friendly
-implementation through [browser
-field](https://gist.github.com/shtylman/4339901). Alternative
-implementation is a literal copy of standard one located in standalone
-module to avoid requiring of `util`. It also has a shim for old
-browsers with no `Object.create` support.
-
-While keeping you sure you are using standard `inherits`
-implementation in node.js environment, it allows bundlers such as
-[browserify](https://github.com/substack/node-browserify) to not
-include full `util` package to your client code if all you need is
-just `inherits` function. It worth, because browser shim for `util`
-package is large and `inherits` is often the single function you need
-from it.
-
-It's recommended to use this package instead of
-`require('util').inherits` for any code that has chances to be used
-not only in node.js but in browser too.
-
-## usage
-
-```js
-var inherits = require('inherits');
-// then use exactly as the standard one
-```
-
-## note on version ~1.0
-
-Version ~1.0 had completely different motivation and is not compatible
-neither with 2.0 nor with standard node.js `inherits`.
-
-If you are using version ~1.0 and planning to switch to ~2.0, be
-careful:
-
-* new version uses `super_` instead of `super` for referencing
- superclass
-* new version overwrites current prototype while old one preserves any
- existing fields on it
diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/inherits/inherits.js b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/inherits/inherits.js
deleted file mode 100644
index 29f5e24f..00000000
--- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/inherits/inherits.js
+++ /dev/null
@@ -1 +0,0 @@
-module.exports = require('util').inherits
diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/inherits/inherits_browser.js b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/inherits/inherits_browser.js
deleted file mode 100644
index c1e78a75..00000000
--- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/inherits/inherits_browser.js
+++ /dev/null
@@ -1,23 +0,0 @@
-if (typeof Object.create === 'function') {
- // implementation from standard node.js 'util' module
- module.exports = function inherits(ctor, superCtor) {
- ctor.super_ = superCtor
- ctor.prototype = Object.create(superCtor.prototype, {
- constructor: {
- value: ctor,
- enumerable: false,
- writable: true,
- configurable: true
- }
- });
- };
-} else {
- // old school shim for old browsers
- module.exports = function inherits(ctor, superCtor) {
- ctor.super_ = superCtor
- var TempCtor = function () {}
- TempCtor.prototype = superCtor.prototype
- ctor.prototype = new TempCtor()
- ctor.prototype.constructor = ctor
- }
-}
diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/inherits/package.json b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/inherits/package.json
deleted file mode 100644
index 754a1144..00000000
--- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/inherits/package.json
+++ /dev/null
@@ -1,51 +0,0 @@
-{
- "name": "inherits",
- "description": "Browser-friendly inheritance fully compatible with standard node.js inherits()",
- "version": "2.0.1",
- "keywords": [
- "inheritance",
- "class",
- "klass",
- "oop",
- "object-oriented",
- "inherits",
- "browser",
- "browserify"
- ],
- "main": "./inherits.js",
- "browser": "./inherits_browser.js",
- "repository": {
- "type": "git",
- "url": "git://github.com/isaacs/inherits"
- },
- "license": "ISC",
- "scripts": {
- "test": "node test"
- },
- "readme": "Browser-friendly inheritance fully compatible with standard node.js\n[inherits](http://nodejs.org/api/util.html#util_util_inherits_constructor_superconstructor).\n\nThis package exports standard `inherits` from node.js `util` module in\nnode environment, but also provides alternative browser-friendly\nimplementation through [browser\nfield](https://gist.github.com/shtylman/4339901). Alternative\nimplementation is a literal copy of standard one located in standalone\nmodule to avoid requiring of `util`. It also has a shim for old\nbrowsers with no `Object.create` support.\n\nWhile keeping you sure you are using standard `inherits`\nimplementation in node.js environment, it allows bundlers such as\n[browserify](https://github.com/substack/node-browserify) to not\ninclude full `util` package to your client code if all you need is\njust `inherits` function. It worth, because browser shim for `util`\npackage is large and `inherits` is often the single function you need\nfrom it.\n\nIt's recommended to use this package instead of\n`require('util').inherits` for any code that has chances to be used\nnot only in node.js but in browser too.\n\n## usage\n\n```js\nvar inherits = require('inherits');\n// then use exactly as the standard one\n```\n\n## note on version ~1.0\n\nVersion ~1.0 had completely different motivation and is not compatible\nneither with 2.0 nor with standard node.js `inherits`.\n\nIf you are using version ~1.0 and planning to switch to ~2.0, be\ncareful:\n\n* new version uses `super_` instead of `super` for referencing\n superclass\n* new version overwrites current prototype while old one preserves any\n existing fields on it\n",
- "readmeFilename": "README.md",
- "bugs": {
- "url": "https://github.com/isaacs/inherits/issues"
- },
- "_id": "inherits@2.0.1",
- "dist": {
- "shasum": "b17d08d326b4423e568eff719f91b0b1cbdf69f1",
- "tarball": "http://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz"
- },
- "_from": "inherits@2",
- "_npmVersion": "1.3.8",
- "_npmUser": {
- "name": "isaacs",
- "email": "i@izs.me"
- },
- "maintainers": [
- {
- "name": "isaacs",
- "email": "i@izs.me"
- }
- ],
- "directories": {},
- "_shasum": "b17d08d326b4423e568eff719f91b0b1cbdf69f1",
- "_resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz",
- "homepage": "https://github.com/isaacs/inherits"
-}
diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/inherits/test.js b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/inherits/test.js
deleted file mode 100644
index fc53012d..00000000
--- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/inherits/test.js
+++ /dev/null
@@ -1,25 +0,0 @@
-var inherits = require('./inherits.js')
-var assert = require('assert')
-
-function test(c) {
- assert(c.constructor === Child)
- assert(c.constructor.super_ === Parent)
- assert(Object.getPrototypeOf(c) === Child.prototype)
- assert(Object.getPrototypeOf(Object.getPrototypeOf(c)) === Parent.prototype)
- assert(c instanceof Child)
- assert(c instanceof Parent)
-}
-
-function Child() {
- Parent.call(this)
- test(this)
-}
-
-function Parent() {}
-
-inherits(Child, Parent)
-
-var c = new Child
-test(c)
-
-console.log('ok')
diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/.npmignore b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/.npmignore
deleted file mode 100644
index 3c3629e6..00000000
--- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/.npmignore
+++ /dev/null
@@ -1 +0,0 @@
-node_modules
diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/LICENSE b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/LICENSE
deleted file mode 100644
index 05a40109..00000000
--- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/LICENSE
+++ /dev/null
@@ -1,23 +0,0 @@
-Copyright 2009, 2010, 2011 Isaac Z. Schlueter.
-All rights reserved.
-
-Permission is hereby granted, free of charge, to any person
-obtaining a copy of this software and associated documentation
-files (the "Software"), to deal in the Software without
-restriction, including without limitation the rights to use,
-copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the
-Software is furnished to do so, subject to the following
-conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-OTHER DEALINGS IN THE SOFTWARE.
diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/README.md b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/README.md
deleted file mode 100644
index 5b3967ea..00000000
--- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/README.md
+++ /dev/null
@@ -1,218 +0,0 @@
-# minimatch
-
-A minimal matching utility.
-
-[](http://travis-ci.org/isaacs/minimatch)
-
-
-This is the matching library used internally by npm.
-
-Eventually, it will replace the C binding in node-glob.
-
-It works by converting glob expressions into JavaScript `RegExp`
-objects.
-
-## Usage
-
-```javascript
-var minimatch = require("minimatch")
-
-minimatch("bar.foo", "*.foo") // true!
-minimatch("bar.foo", "*.bar") // false!
-minimatch("bar.foo", "*.+(bar|foo)", { debug: true }) // true, and noisy!
-```
-
-## Features
-
-Supports these glob features:
-
-* Brace Expansion
-* Extended glob matching
-* "Globstar" `**` matching
-
-See:
-
-* `man sh`
-* `man bash`
-* `man 3 fnmatch`
-* `man 5 gitignore`
-
-## Minimatch Class
-
-Create a minimatch object by instanting the `minimatch.Minimatch` class.
-
-```javascript
-var Minimatch = require("minimatch").Minimatch
-var mm = new Minimatch(pattern, options)
-```
-
-### Properties
-
-* `pattern` The original pattern the minimatch object represents.
-* `options` The options supplied to the constructor.
-* `set` A 2-dimensional array of regexp or string expressions.
- Each row in the
- array corresponds to a brace-expanded pattern. Each item in the row
- corresponds to a single path-part. For example, the pattern
- `{a,b/c}/d` would expand to a set of patterns like:
-
- [ [ a, d ]
- , [ b, c, d ] ]
-
- If a portion of the pattern doesn't have any "magic" in it
- (that is, it's something like `"foo"` rather than `fo*o?`), then it
- will be left as a string rather than converted to a regular
- expression.
-
-* `regexp` Created by the `makeRe` method. A single regular expression
- expressing the entire pattern. This is useful in cases where you wish
- to use the pattern somewhat like `fnmatch(3)` with `FNM_PATH` enabled.
-* `negate` True if the pattern is negated.
-* `comment` True if the pattern is a comment.
-* `empty` True if the pattern is `""`.
-
-### Methods
-
-* `makeRe` Generate the `regexp` member if necessary, and return it.
- Will return `false` if the pattern is invalid.
-* `match(fname)` Return true if the filename matches the pattern, or
- false otherwise.
-* `matchOne(fileArray, patternArray, partial)` Take a `/`-split
- filename, and match it against a single row in the `regExpSet`. This
- method is mainly for internal use, but is exposed so that it can be
- used by a glob-walker that needs to avoid excessive filesystem calls.
-
-All other methods are internal, and will be called as necessary.
-
-## Functions
-
-The top-level exported function has a `cache` property, which is an LRU
-cache set to store 100 items. So, calling these methods repeatedly
-with the same pattern and options will use the same Minimatch object,
-saving the cost of parsing it multiple times.
-
-### minimatch(path, pattern, options)
-
-Main export. Tests a path against the pattern using the options.
-
-```javascript
-var isJS = minimatch(file, "*.js", { matchBase: true })
-```
-
-### minimatch.filter(pattern, options)
-
-Returns a function that tests its
-supplied argument, suitable for use with `Array.filter`. Example:
-
-```javascript
-var javascripts = fileList.filter(minimatch.filter("*.js", {matchBase: true}))
-```
-
-### minimatch.match(list, pattern, options)
-
-Match against the list of
-files, in the style of fnmatch or glob. If nothing is matched, and
-options.nonull is set, then return a list containing the pattern itself.
-
-```javascript
-var javascripts = minimatch.match(fileList, "*.js", {matchBase: true}))
-```
-
-### minimatch.makeRe(pattern, options)
-
-Make a regular expression object from the pattern.
-
-## Options
-
-All options are `false` by default.
-
-### debug
-
-Dump a ton of stuff to stderr.
-
-### nobrace
-
-Do not expand `{a,b}` and `{1..3}` brace sets.
-
-### noglobstar
-
-Disable `**` matching against multiple folder names.
-
-### dot
-
-Allow patterns to match filenames starting with a period, even if
-the pattern does not explicitly have a period in that spot.
-
-Note that by default, `a/**/b` will **not** match `a/.d/b`, unless `dot`
-is set.
-
-### noext
-
-Disable "extglob" style patterns like `+(a|b)`.
-
-### nocase
-
-Perform a case-insensitive match.
-
-### nonull
-
-When a match is not found by `minimatch.match`, return a list containing
-the pattern itself if this option is set. When not set, an empty list
-is returned if there are no matches.
-
-### matchBase
-
-If set, then patterns without slashes will be matched
-against the basename of the path if it contains slashes. For example,
-`a?b` would match the path `/xyz/123/acb`, but not `/xyz/acb/123`.
-
-### nocomment
-
-Suppress the behavior of treating `#` at the start of a pattern as a
-comment.
-
-### nonegate
-
-Suppress the behavior of treating a leading `!` character as negation.
-
-### flipNegate
-
-Returns from negate expressions the same as if they were not negated.
-(Ie, true on a hit, false on a miss.)
-
-
-## Comparisons to other fnmatch/glob implementations
-
-While strict compliance with the existing standards is a worthwhile
-goal, some discrepancies exist between minimatch and other
-implementations, and are intentional.
-
-If the pattern starts with a `!` character, then it is negated. Set the
-`nonegate` flag to suppress this behavior, and treat leading `!`
-characters normally. This is perhaps relevant if you wish to start the
-pattern with a negative extglob pattern like `!(a|B)`. Multiple `!`
-characters at the start of a pattern will negate the pattern multiple
-times.
-
-If a pattern starts with `#`, then it is treated as a comment, and
-will not match anything. Use `\#` to match a literal `#` at the
-start of a line, or set the `nocomment` flag to suppress this behavior.
-
-The double-star character `**` is supported by default, unless the
-`noglobstar` flag is set. This is supported in the manner of bsdglob
-and bash 4.1, where `**` only has special significance if it is the only
-thing in a path part. That is, `a/**/b` will match `a/x/y/b`, but
-`a/**b` will not.
-
-If an escaped pattern has no matches, and the `nonull` flag is set,
-then minimatch.match returns the pattern as-provided, rather than
-interpreting the character escapes. For example,
-`minimatch.match([], "\\*a\\?")` will return `"\\*a\\?"` rather than
-`"*a?"`. This is akin to setting the `nullglob` option in bash, except
-that it does not resolve escaped pattern characters.
-
-If brace expansion is not disabled, then it is performed before any
-other interpretation of the glob pattern. Thus, a pattern like
-`+(a|{b),c)}`, which would not be valid in bash or zsh, is expanded
-**first** into the set of `+(a|b)` and `+(a|c)`, and those patterns are
-checked for validity. Since those two are valid, matching proceeds.
diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/minimatch.js b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/minimatch.js
deleted file mode 100644
index 45396789..00000000
--- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/minimatch.js
+++ /dev/null
@@ -1,1061 +0,0 @@
-;(function (require, exports, module, platform) {
-
-if (module) module.exports = minimatch
-else exports.minimatch = minimatch
-
-if (!require) {
- require = function (id) {
- switch (id) {
- case "sigmund": return function sigmund (obj) {
- return JSON.stringify(obj)
- }
- case "path": return { basename: function (f) {
- f = f.split(/[\/\\]/)
- var e = f.pop()
- if (!e) e = f.pop()
- return e
- }}
- case "lru-cache": return function LRUCache () {
- // not quite an LRU, but still space-limited.
- var cache = {}
- var cnt = 0
- this.set = function (k, v) {
- cnt ++
- if (cnt >= 100) cache = {}
- cache[k] = v
- }
- this.get = function (k) { return cache[k] }
- }
- }
- }
-}
-
-minimatch.Minimatch = Minimatch
-
-var LRU = require("lru-cache")
- , cache = minimatch.cache = new LRU({max: 100})
- , GLOBSTAR = minimatch.GLOBSTAR = Minimatch.GLOBSTAR = {}
- , sigmund = require("sigmund")
-
-var path = require("path")
- // any single thing other than /
- // don't need to escape / when using new RegExp()
- , qmark = "[^/]"
-
- // * => any number of characters
- , star = qmark + "*?"
-
- // ** when dots are allowed. Anything goes, except .. and .
- // not (^ or / followed by one or two dots followed by $ or /),
- // followed by anything, any number of times.
- , twoStarDot = "(?:(?!(?:\\\/|^)(?:\\.{1,2})($|\\\/)).)*?"
-
- // not a ^ or / followed by a dot,
- // followed by anything, any number of times.
- , twoStarNoDot = "(?:(?!(?:\\\/|^)\\.).)*?"
-
- // characters that need to be escaped in RegExp.
- , reSpecials = charSet("().*{}+?[]^$\\!")
-
-// "abc" -> { a:true, b:true, c:true }
-function charSet (s) {
- return s.split("").reduce(function (set, c) {
- set[c] = true
- return set
- }, {})
-}
-
-// normalizes slashes.
-var slashSplit = /\/+/
-
-minimatch.filter = filter
-function filter (pattern, options) {
- options = options || {}
- return function (p, i, list) {
- return minimatch(p, pattern, options)
- }
-}
-
-function ext (a, b) {
- a = a || {}
- b = b || {}
- var t = {}
- Object.keys(b).forEach(function (k) {
- t[k] = b[k]
- })
- Object.keys(a).forEach(function (k) {
- t[k] = a[k]
- })
- return t
-}
-
-minimatch.defaults = function (def) {
- if (!def || !Object.keys(def).length) return minimatch
-
- var orig = minimatch
-
- var m = function minimatch (p, pattern, options) {
- return orig.minimatch(p, pattern, ext(def, options))
- }
-
- m.Minimatch = function Minimatch (pattern, options) {
- return new orig.Minimatch(pattern, ext(def, options))
- }
-
- return m
-}
-
-Minimatch.defaults = function (def) {
- if (!def || !Object.keys(def).length) return Minimatch
- return minimatch.defaults(def).Minimatch
-}
-
-
-function minimatch (p, pattern, options) {
- if (typeof pattern !== "string") {
- throw new TypeError("glob pattern string required")
- }
-
- if (!options) options = {}
-
- // shortcut: comments match nothing.
- if (!options.nocomment && pattern.charAt(0) === "#") {
- return false
- }
-
- // "" only matches ""
- if (pattern.trim() === "") return p === ""
-
- return new Minimatch(pattern, options).match(p)
-}
-
-function Minimatch (pattern, options) {
- if (!(this instanceof Minimatch)) {
- return new Minimatch(pattern, options, cache)
- }
-
- if (typeof pattern !== "string") {
- throw new TypeError("glob pattern string required")
- }
-
- if (!options) options = {}
- pattern = pattern.trim()
-
- // windows: need to use /, not \
- // On other platforms, \ is a valid (albeit bad) filename char.
- if (platform === "win32") {
- pattern = pattern.split("\\").join("/")
- }
-
- // lru storage.
- // these things aren't particularly big, but walking down the string
- // and turning it into a regexp can get pretty costly.
- var cacheKey = pattern + "\n" + sigmund(options)
- var cached = minimatch.cache.get(cacheKey)
- if (cached) return cached
- minimatch.cache.set(cacheKey, this)
-
- this.options = options
- this.set = []
- this.pattern = pattern
- this.regexp = null
- this.negate = false
- this.comment = false
- this.empty = false
-
- // make the set of regexps etc.
- this.make()
-}
-
-Minimatch.prototype.debug = function() {}
-
-Minimatch.prototype.make = make
-function make () {
- // don't do it more than once.
- if (this._made) return
-
- var pattern = this.pattern
- var options = this.options
-
- // empty patterns and comments match nothing.
- if (!options.nocomment && pattern.charAt(0) === "#") {
- this.comment = true
- return
- }
- if (!pattern) {
- this.empty = true
- return
- }
-
- // step 1: figure out negation, etc.
- this.parseNegate()
-
- // step 2: expand braces
- var set = this.globSet = this.braceExpand()
-
- if (options.debug) this.debug = console.error
-
- this.debug(this.pattern, set)
-
- // step 3: now we have a set, so turn each one into a series of path-portion
- // matching patterns.
- // These will be regexps, except in the case of "**", which is
- // set to the GLOBSTAR object for globstar behavior,
- // and will not contain any / characters
- set = this.globParts = set.map(function (s) {
- return s.split(slashSplit)
- })
-
- this.debug(this.pattern, set)
-
- // glob --> regexps
- set = set.map(function (s, si, set) {
- return s.map(this.parse, this)
- }, this)
-
- this.debug(this.pattern, set)
-
- // filter out everything that didn't compile properly.
- set = set.filter(function (s) {
- return -1 === s.indexOf(false)
- })
-
- this.debug(this.pattern, set)
-
- this.set = set
-}
-
-Minimatch.prototype.parseNegate = parseNegate
-function parseNegate () {
- var pattern = this.pattern
- , negate = false
- , options = this.options
- , negateOffset = 0
-
- if (options.nonegate) return
-
- for ( var i = 0, l = pattern.length
- ; i < l && pattern.charAt(i) === "!"
- ; i ++) {
- negate = !negate
- negateOffset ++
- }
-
- if (negateOffset) this.pattern = pattern.substr(negateOffset)
- this.negate = negate
-}
-
-// Brace expansion:
-// a{b,c}d -> abd acd
-// a{b,}c -> abc ac
-// a{0..3}d -> a0d a1d a2d a3d
-// a{b,c{d,e}f}g -> abg acdfg acefg
-// a{b,c}d{e,f}g -> abdeg acdeg abdeg abdfg
-//
-// Invalid sets are not expanded.
-// a{2..}b -> a{2..}b
-// a{b}c -> a{b}c
-minimatch.braceExpand = function (pattern, options) {
- return new Minimatch(pattern, options).braceExpand()
-}
-
-Minimatch.prototype.braceExpand = braceExpand
-function braceExpand (pattern, options) {
- options = options || this.options
- pattern = typeof pattern === "undefined"
- ? this.pattern : pattern
-
- if (typeof pattern === "undefined") {
- throw new Error("undefined pattern")
- }
-
- if (options.nobrace ||
- !pattern.match(/\{.*\}/)) {
- // shortcut. no need to expand.
- return [pattern]
- }
-
- var escaping = false
-
- // examples and comments refer to this crazy pattern:
- // a{b,c{d,e},{f,g}h}x{y,z}
- // expected:
- // abxy
- // abxz
- // acdxy
- // acdxz
- // acexy
- // acexz
- // afhxy
- // afhxz
- // aghxy
- // aghxz
-
- // everything before the first \{ is just a prefix.
- // So, we pluck that off, and work with the rest,
- // and then prepend it to everything we find.
- if (pattern.charAt(0) !== "{") {
- this.debug(pattern)
- var prefix = null
- for (var i = 0, l = pattern.length; i < l; i ++) {
- var c = pattern.charAt(i)
- this.debug(i, c)
- if (c === "\\") {
- escaping = !escaping
- } else if (c === "{" && !escaping) {
- prefix = pattern.substr(0, i)
- break
- }
- }
-
- // actually no sets, all { were escaped.
- if (prefix === null) {
- this.debug("no sets")
- return [pattern]
- }
-
- var tail = braceExpand.call(this, pattern.substr(i), options)
- return tail.map(function (t) {
- return prefix + t
- })
- }
-
- // now we have something like:
- // {b,c{d,e},{f,g}h}x{y,z}
- // walk through the set, expanding each part, until
- // the set ends. then, we'll expand the suffix.
- // If the set only has a single member, then'll put the {} back
-
- // first, handle numeric sets, since they're easier
- var numset = pattern.match(/^\{(-?[0-9]+)\.\.(-?[0-9]+)\}/)
- if (numset) {
- this.debug("numset", numset[1], numset[2])
- var suf = braceExpand.call(this, pattern.substr(numset[0].length), options)
- , start = +numset[1]
- , end = +numset[2]
- , inc = start > end ? -1 : 1
- , set = []
- for (var i = start; i != (end + inc); i += inc) {
- // append all the suffixes
- for (var ii = 0, ll = suf.length; ii < ll; ii ++) {
- set.push(i + suf[ii])
- }
- }
- return set
- }
-
- // ok, walk through the set
- // We hope, somewhat optimistically, that there
- // will be a } at the end.
- // If the closing brace isn't found, then the pattern is
- // interpreted as braceExpand("\\" + pattern) so that
- // the leading \{ will be interpreted literally.
- var i = 1 // skip the \{
- , depth = 1
- , set = []
- , member = ""
- , sawEnd = false
- , escaping = false
-
- function addMember () {
- set.push(member)
- member = ""
- }
-
- this.debug("Entering for")
- FOR: for (i = 1, l = pattern.length; i < l; i ++) {
- var c = pattern.charAt(i)
- this.debug("", i, c)
-
- if (escaping) {
- escaping = false
- member += "\\" + c
- } else {
- switch (c) {
- case "\\":
- escaping = true
- continue
-
- case "{":
- depth ++
- member += "{"
- continue
-
- case "}":
- depth --
- // if this closes the actual set, then we're done
- if (depth === 0) {
- addMember()
- // pluck off the close-brace
- i ++
- break FOR
- } else {
- member += c
- continue
- }
-
- case ",":
- if (depth === 1) {
- addMember()
- } else {
- member += c
- }
- continue
-
- default:
- member += c
- continue
- } // switch
- } // else
- } // for
-
- // now we've either finished the set, and the suffix is
- // pattern.substr(i), or we have *not* closed the set,
- // and need to escape the leading brace
- if (depth !== 0) {
- this.debug("didn't close", pattern)
- return braceExpand.call(this, "\\" + pattern, options)
- }
-
- // x{y,z} -> ["xy", "xz"]
- this.debug("set", set)
- this.debug("suffix", pattern.substr(i))
- var suf = braceExpand.call(this, pattern.substr(i), options)
- // ["b", "c{d,e}","{f,g}h"] ->
- // [["b"], ["cd", "ce"], ["fh", "gh"]]
- var addBraces = set.length === 1
- this.debug("set pre-expanded", set)
- set = set.map(function (p) {
- return braceExpand.call(this, p, options)
- }, this)
- this.debug("set expanded", set)
-
-
- // [["b"], ["cd", "ce"], ["fh", "gh"]] ->
- // ["b", "cd", "ce", "fh", "gh"]
- set = set.reduce(function (l, r) {
- return l.concat(r)
- })
-
- if (addBraces) {
- set = set.map(function (s) {
- return "{" + s + "}"
- })
- }
-
- // now attach the suffixes.
- var ret = []
- for (var i = 0, l = set.length; i < l; i ++) {
- for (var ii = 0, ll = suf.length; ii < ll; ii ++) {
- ret.push(set[i] + suf[ii])
- }
- }
- return ret
-}
-
-// parse a component of the expanded set.
-// At this point, no pattern may contain "/" in it
-// so we're going to return a 2d array, where each entry is the full
-// pattern, split on '/', and then turned into a regular expression.
-// A regexp is made at the end which joins each array with an
-// escaped /, and another full one which joins each regexp with |.
-//
-// Following the lead of Bash 4.1, note that "**" only has special meaning
-// when it is the *only* thing in a path portion. Otherwise, any series
-// of * is equivalent to a single *. Globstar behavior is enabled by
-// default, and can be disabled by setting options.noglobstar.
-Minimatch.prototype.parse = parse
-var SUBPARSE = {}
-function parse (pattern, isSub) {
- var options = this.options
-
- // shortcuts
- if (!options.noglobstar && pattern === "**") return GLOBSTAR
- if (pattern === "") return ""
-
- var re = ""
- , hasMagic = !!options.nocase
- , escaping = false
- // ? => one single character
- , patternListStack = []
- , plType
- , stateChar
- , inClass = false
- , reClassStart = -1
- , classStart = -1
- // . and .. never match anything that doesn't start with .,
- // even when options.dot is set.
- , patternStart = pattern.charAt(0) === "." ? "" // anything
- // not (start or / followed by . or .. followed by / or end)
- : options.dot ? "(?!(?:^|\\\/)\\.{1,2}(?:$|\\\/))"
- : "(?!\\.)"
- , self = this
-
- function clearStateChar () {
- if (stateChar) {
- // we had some state-tracking character
- // that wasn't consumed by this pass.
- switch (stateChar) {
- case "*":
- re += star
- hasMagic = true
- break
- case "?":
- re += qmark
- hasMagic = true
- break
- default:
- re += "\\"+stateChar
- break
- }
- self.debug('clearStateChar %j %j', stateChar, re)
- stateChar = false
- }
- }
-
- for ( var i = 0, len = pattern.length, c
- ; (i < len) && (c = pattern.charAt(i))
- ; i ++ ) {
-
- this.debug("%s\t%s %s %j", pattern, i, re, c)
-
- // skip over any that are escaped.
- if (escaping && reSpecials[c]) {
- re += "\\" + c
- escaping = false
- continue
- }
-
- SWITCH: switch (c) {
- case "/":
- // completely not allowed, even escaped.
- // Should already be path-split by now.
- return false
-
- case "\\":
- clearStateChar()
- escaping = true
- continue
-
- // the various stateChar values
- // for the "extglob" stuff.
- case "?":
- case "*":
- case "+":
- case "@":
- case "!":
- this.debug("%s\t%s %s %j <-- stateChar", pattern, i, re, c)
-
- // all of those are literals inside a class, except that
- // the glob [!a] means [^a] in regexp
- if (inClass) {
- this.debug(' in class')
- if (c === "!" && i === classStart + 1) c = "^"
- re += c
- continue
- }
-
- // if we already have a stateChar, then it means
- // that there was something like ** or +? in there.
- // Handle the stateChar, then proceed with this one.
- self.debug('call clearStateChar %j', stateChar)
- clearStateChar()
- stateChar = c
- // if extglob is disabled, then +(asdf|foo) isn't a thing.
- // just clear the statechar *now*, rather than even diving into
- // the patternList stuff.
- if (options.noext) clearStateChar()
- continue
-
- case "(":
- if (inClass) {
- re += "("
- continue
- }
-
- if (!stateChar) {
- re += "\\("
- continue
- }
-
- plType = stateChar
- patternListStack.push({ type: plType
- , start: i - 1
- , reStart: re.length })
- // negation is (?:(?!js)[^/]*)
- re += stateChar === "!" ? "(?:(?!" : "(?:"
- this.debug('plType %j %j', stateChar, re)
- stateChar = false
- continue
-
- case ")":
- if (inClass || !patternListStack.length) {
- re += "\\)"
- continue
- }
-
- clearStateChar()
- hasMagic = true
- re += ")"
- plType = patternListStack.pop().type
- // negation is (?:(?!js)[^/]*)
- // The others are (?:)
- switch (plType) {
- case "!":
- re += "[^/]*?)"
- break
- case "?":
- case "+":
- case "*": re += plType
- case "@": break // the default anyway
- }
- continue
-
- case "|":
- if (inClass || !patternListStack.length || escaping) {
- re += "\\|"
- escaping = false
- continue
- }
-
- clearStateChar()
- re += "|"
- continue
-
- // these are mostly the same in regexp and glob
- case "[":
- // swallow any state-tracking char before the [
- clearStateChar()
-
- if (inClass) {
- re += "\\" + c
- continue
- }
-
- inClass = true
- classStart = i
- reClassStart = re.length
- re += c
- continue
-
- case "]":
- // a right bracket shall lose its special
- // meaning and represent itself in
- // a bracket expression if it occurs
- // first in the list. -- POSIX.2 2.8.3.2
- if (i === classStart + 1 || !inClass) {
- re += "\\" + c
- escaping = false
- continue
- }
-
- // finish up the class.
- hasMagic = true
- inClass = false
- re += c
- continue
-
- default:
- // swallow any state char that wasn't consumed
- clearStateChar()
-
- if (escaping) {
- // no need
- escaping = false
- } else if (reSpecials[c]
- && !(c === "^" && inClass)) {
- re += "\\"
- }
-
- re += c
-
- } // switch
- } // for
-
-
- // handle the case where we left a class open.
- // "[abc" is valid, equivalent to "\[abc"
- if (inClass) {
- // split where the last [ was, and escape it
- // this is a huge pita. We now have to re-walk
- // the contents of the would-be class to re-translate
- // any characters that were passed through as-is
- var cs = pattern.substr(classStart + 1)
- , sp = this.parse(cs, SUBPARSE)
- re = re.substr(0, reClassStart) + "\\[" + sp[0]
- hasMagic = hasMagic || sp[1]
- }
-
- // handle the case where we had a +( thing at the *end*
- // of the pattern.
- // each pattern list stack adds 3 chars, and we need to go through
- // and escape any | chars that were passed through as-is for the regexp.
- // Go through and escape them, taking care not to double-escape any
- // | chars that were already escaped.
- var pl
- while (pl = patternListStack.pop()) {
- var tail = re.slice(pl.reStart + 3)
- // maybe some even number of \, then maybe 1 \, followed by a |
- tail = tail.replace(/((?:\\{2})*)(\\?)\|/g, function (_, $1, $2) {
- if (!$2) {
- // the | isn't already escaped, so escape it.
- $2 = "\\"
- }
-
- // need to escape all those slashes *again*, without escaping the
- // one that we need for escaping the | character. As it works out,
- // escaping an even number of slashes can be done by simply repeating
- // it exactly after itself. That's why this trick works.
- //
- // I am sorry that you have to see this.
- return $1 + $1 + $2 + "|"
- })
-
- this.debug("tail=%j\n %s", tail, tail)
- var t = pl.type === "*" ? star
- : pl.type === "?" ? qmark
- : "\\" + pl.type
-
- hasMagic = true
- re = re.slice(0, pl.reStart)
- + t + "\\("
- + tail
- }
-
- // handle trailing things that only matter at the very end.
- clearStateChar()
- if (escaping) {
- // trailing \\
- re += "\\\\"
- }
-
- // only need to apply the nodot start if the re starts with
- // something that could conceivably capture a dot
- var addPatternStart = false
- switch (re.charAt(0)) {
- case ".":
- case "[":
- case "(": addPatternStart = true
- }
-
- // if the re is not "" at this point, then we need to make sure
- // it doesn't match against an empty path part.
- // Otherwise a/* will match a/, which it should not.
- if (re !== "" && hasMagic) re = "(?=.)" + re
-
- if (addPatternStart) re = patternStart + re
-
- // parsing just a piece of a larger pattern.
- if (isSub === SUBPARSE) {
- return [ re, hasMagic ]
- }
-
- // skip the regexp for non-magical patterns
- // unescape anything in it, though, so that it'll be
- // an exact match against a file etc.
- if (!hasMagic) {
- return globUnescape(pattern)
- }
-
- var flags = options.nocase ? "i" : ""
- , regExp = new RegExp("^" + re + "$", flags)
-
- regExp._glob = pattern
- regExp._src = re
-
- return regExp
-}
-
-minimatch.makeRe = function (pattern, options) {
- return new Minimatch(pattern, options || {}).makeRe()
-}
-
-Minimatch.prototype.makeRe = makeRe
-function makeRe () {
- if (this.regexp || this.regexp === false) return this.regexp
-
- // at this point, this.set is a 2d array of partial
- // pattern strings, or "**".
- //
- // It's better to use .match(). This function shouldn't
- // be used, really, but it's pretty convenient sometimes,
- // when you just want to work with a regex.
- var set = this.set
-
- if (!set.length) return this.regexp = false
- var options = this.options
-
- var twoStar = options.noglobstar ? star
- : options.dot ? twoStarDot
- : twoStarNoDot
- , flags = options.nocase ? "i" : ""
-
- var re = set.map(function (pattern) {
- return pattern.map(function (p) {
- return (p === GLOBSTAR) ? twoStar
- : (typeof p === "string") ? regExpEscape(p)
- : p._src
- }).join("\\\/")
- }).join("|")
-
- // must match entire pattern
- // ending in a * or ** will make it less strict.
- re = "^(?:" + re + ")$"
-
- // can match anything, as long as it's not this.
- if (this.negate) re = "^(?!" + re + ").*$"
-
- try {
- return this.regexp = new RegExp(re, flags)
- } catch (ex) {
- return this.regexp = false
- }
-}
-
-minimatch.match = function (list, pattern, options) {
- options = options || {}
- var mm = new Minimatch(pattern, options)
- list = list.filter(function (f) {
- return mm.match(f)
- })
- if (mm.options.nonull && !list.length) {
- list.push(pattern)
- }
- return list
-}
-
-Minimatch.prototype.match = match
-function match (f, partial) {
- this.debug("match", f, this.pattern)
- // short-circuit in the case of busted things.
- // comments, etc.
- if (this.comment) return false
- if (this.empty) return f === ""
-
- if (f === "/" && partial) return true
-
- var options = this.options
-
- // windows: need to use /, not \
- // On other platforms, \ is a valid (albeit bad) filename char.
- if (platform === "win32") {
- f = f.split("\\").join("/")
- }
-
- // treat the test path as a set of pathparts.
- f = f.split(slashSplit)
- this.debug(this.pattern, "split", f)
-
- // just ONE of the pattern sets in this.set needs to match
- // in order for it to be valid. If negating, then just one
- // match means that we have failed.
- // Either way, return on the first hit.
-
- var set = this.set
- this.debug(this.pattern, "set", set)
-
- // Find the basename of the path by looking for the last non-empty segment
- var filename;
- for (var i = f.length - 1; i >= 0; i--) {
- filename = f[i]
- if (filename) break
- }
-
- for (var i = 0, l = set.length; i < l; i ++) {
- var pattern = set[i], file = f
- if (options.matchBase && pattern.length === 1) {
- file = [filename]
- }
- var hit = this.matchOne(file, pattern, partial)
- if (hit) {
- if (options.flipNegate) return true
- return !this.negate
- }
- }
-
- // didn't get any hits. this is success if it's a negative
- // pattern, failure otherwise.
- if (options.flipNegate) return false
- return this.negate
-}
-
-// set partial to true to test if, for example,
-// "/a/b" matches the start of "/*/b/*/d"
-// Partial means, if you run out of file before you run
-// out of pattern, then that's fine, as long as all
-// the parts match.
-Minimatch.prototype.matchOne = function (file, pattern, partial) {
- var options = this.options
-
- this.debug("matchOne",
- { "this": this
- , file: file
- , pattern: pattern })
-
- this.debug("matchOne", file.length, pattern.length)
-
- for ( var fi = 0
- , pi = 0
- , fl = file.length
- , pl = pattern.length
- ; (fi < fl) && (pi < pl)
- ; fi ++, pi ++ ) {
-
- this.debug("matchOne loop")
- var p = pattern[pi]
- , f = file[fi]
-
- this.debug(pattern, p, f)
-
- // should be impossible.
- // some invalid regexp stuff in the set.
- if (p === false) return false
-
- if (p === GLOBSTAR) {
- this.debug('GLOBSTAR', [pattern, p, f])
-
- // "**"
- // a/**/b/**/c would match the following:
- // a/b/x/y/z/c
- // a/x/y/z/b/c
- // a/b/x/b/x/c
- // a/b/c
- // To do this, take the rest of the pattern after
- // the **, and see if it would match the file remainder.
- // If so, return success.
- // If not, the ** "swallows" a segment, and try again.
- // This is recursively awful.
- //
- // a/**/b/**/c matching a/b/x/y/z/c
- // - a matches a
- // - doublestar
- // - matchOne(b/x/y/z/c, b/**/c)
- // - b matches b
- // - doublestar
- // - matchOne(x/y/z/c, c) -> no
- // - matchOne(y/z/c, c) -> no
- // - matchOne(z/c, c) -> no
- // - matchOne(c, c) yes, hit
- var fr = fi
- , pr = pi + 1
- if (pr === pl) {
- this.debug('** at the end')
- // a ** at the end will just swallow the rest.
- // We have found a match.
- // however, it will not swallow /.x, unless
- // options.dot is set.
- // . and .. are *never* matched by **, for explosively
- // exponential reasons.
- for ( ; fi < fl; fi ++) {
- if (file[fi] === "." || file[fi] === ".." ||
- (!options.dot && file[fi].charAt(0) === ".")) return false
- }
- return true
- }
-
- // ok, let's see if we can swallow whatever we can.
- WHILE: while (fr < fl) {
- var swallowee = file[fr]
-
- this.debug('\nglobstar while',
- file, fr, pattern, pr, swallowee)
-
- // XXX remove this slice. Just pass the start index.
- if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) {
- this.debug('globstar found match!', fr, fl, swallowee)
- // found a match.
- return true
- } else {
- // can't swallow "." or ".." ever.
- // can only swallow ".foo" when explicitly asked.
- if (swallowee === "." || swallowee === ".." ||
- (!options.dot && swallowee.charAt(0) === ".")) {
- this.debug("dot detected!", file, fr, pattern, pr)
- break WHILE
- }
-
- // ** swallows a segment, and continue.
- this.debug('globstar swallow a segment, and continue')
- fr ++
- }
- }
- // no match was found.
- // However, in partial mode, we can't say this is necessarily over.
- // If there's more *pattern* left, then
- if (partial) {
- // ran out of file
- this.debug("\n>>> no match, partial?", file, fr, pattern, pr)
- if (fr === fl) return true
- }
- return false
- }
-
- // something other than **
- // non-magic patterns just have to match exactly
- // patterns with magic have been turned into regexps.
- var hit
- if (typeof p === "string") {
- if (options.nocase) {
- hit = f.toLowerCase() === p.toLowerCase()
- } else {
- hit = f === p
- }
- this.debug("string match", p, f, hit)
- } else {
- hit = f.match(p)
- this.debug("pattern match", p, f, hit)
- }
-
- if (!hit) return false
- }
-
- // Note: ending in / means that we'll get a final ""
- // at the end of the pattern. This can only match a
- // corresponding "" at the end of the file.
- // If the file ends in /, then it can only match a
- // a pattern that ends in /, unless the pattern just
- // doesn't have any more for it. But, a/b/ should *not*
- // match "a/b/*", even though "" matches against the
- // [^/]*? pattern, except in partial mode, where it might
- // simply not be reached yet.
- // However, a/b/ should still satisfy a/*
-
- // now either we fell off the end of the pattern, or we're done.
- if (fi === fl && pi === pl) {
- // ran out of pattern and filename at the same time.
- // an exact hit!
- return true
- } else if (fi === fl) {
- // ran out of file, but still had pattern left.
- // this is ok if we're doing the match as part of
- // a glob fs traversal.
- return partial
- } else if (pi === pl) {
- // ran out of pattern, still have file left.
- // this is only acceptable if we're on the very last
- // empty segment of a file with a trailing slash.
- // a/* should match a/b/
- var emptyFileEnd = (fi === fl - 1) && (file[fi] === "")
- return emptyFileEnd
- }
-
- // should be unreachable.
- throw new Error("wtf?")
-}
-
-
-// replace stuff like \* with *
-function globUnescape (s) {
- return s.replace(/\\(.)/g, "$1")
-}
-
-
-function regExpEscape (s) {
- return s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&")
-}
-
-})( typeof require === "function" ? require : null,
- this,
- typeof module === "object" ? module : null,
- typeof process === "object" ? process.platform : "win32"
- )
diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/.npmignore b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/.npmignore
deleted file mode 100644
index 07e6e472..00000000
--- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/.npmignore
+++ /dev/null
@@ -1 +0,0 @@
-/node_modules
diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/CONTRIBUTORS b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/CONTRIBUTORS
deleted file mode 100644
index 4a0bc503..00000000
--- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/CONTRIBUTORS
+++ /dev/null
@@ -1,14 +0,0 @@
-# Authors, sorted by whether or not they are me
-Isaac Z. Schlueter
-Brian Cottingham
-Carlos Brito Lage
-Jesse Dailey
-Kevin O'Hara
-Marco Rogers
-Mark Cavage
-Marko Mikulicic
-Nathan Rajlich
-Satheesh Natesan
-Trent Mick
-ashleybrener
-n4kz
diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/LICENSE b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/LICENSE
deleted file mode 100644
index 05a40109..00000000
--- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/LICENSE
+++ /dev/null
@@ -1,23 +0,0 @@
-Copyright 2009, 2010, 2011 Isaac Z. Schlueter.
-All rights reserved.
-
-Permission is hereby granted, free of charge, to any person
-obtaining a copy of this software and associated documentation
-files (the "Software"), to deal in the Software without
-restriction, including without limitation the rights to use,
-copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the
-Software is furnished to do so, subject to the following
-conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-OTHER DEALINGS IN THE SOFTWARE.
diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/README.md b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/README.md
deleted file mode 100644
index 03ee0f98..00000000
--- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/README.md
+++ /dev/null
@@ -1,97 +0,0 @@
-# lru cache
-
-A cache object that deletes the least-recently-used items.
-
-## Usage:
-
-```javascript
-var LRU = require("lru-cache")
- , options = { max: 500
- , length: function (n) { return n * 2 }
- , dispose: function (key, n) { n.close() }
- , maxAge: 1000 * 60 * 60 }
- , cache = LRU(options)
- , otherCache = LRU(50) // sets just the max size
-
-cache.set("key", "value")
-cache.get("key") // "value"
-
-cache.reset() // empty the cache
-```
-
-If you put more stuff in it, then items will fall out.
-
-If you try to put an oversized thing in it, then it'll fall out right
-away.
-
-## Options
-
-* `max` The maximum size of the cache, checked by applying the length
- function to all values in the cache. Not setting this is kind of
- silly, since that's the whole purpose of this lib, but it defaults
- to `Infinity`.
-* `maxAge` Maximum age in ms. Items are not pro-actively pruned out
- as they age, but if you try to get an item that is too old, it'll
- drop it and return undefined instead of giving it to you.
-* `length` Function that is used to calculate the length of stored
- items. If you're storing strings or buffers, then you probably want
- to do something like `function(n){return n.length}`. The default is
- `function(n){return 1}`, which is fine if you want to store `n`
- like-sized things.
-* `dispose` Function that is called on items when they are dropped
- from the cache. This can be handy if you want to close file
- descriptors or do other cleanup tasks when items are no longer
- accessible. Called with `key, value`. It's called *before*
- actually removing the item from the internal cache, so if you want
- to immediately put it back in, you'll have to do that in a
- `nextTick` or `setTimeout` callback or it won't do anything.
-* `stale` By default, if you set a `maxAge`, it'll only actually pull
- stale items out of the cache when you `get(key)`. (That is, it's
- not pre-emptively doing a `setTimeout` or anything.) If you set
- `stale:true`, it'll return the stale value before deleting it. If
- you don't set this, then it'll return `undefined` when you try to
- get a stale entry, as if it had already been deleted.
-
-## API
-
-* `set(key, value)`
-* `get(key) => value`
-
- Both of these will update the "recently used"-ness of the key.
- They do what you think.
-
-* `peek(key)`
-
- Returns the key value (or `undefined` if not found) without
- updating the "recently used"-ness of the key.
-
- (If you find yourself using this a lot, you *might* be using the
- wrong sort of data structure, but there are some use cases where
- it's handy.)
-
-* `del(key)`
-
- Deletes a key out of the cache.
-
-* `reset()`
-
- Clear the cache entirely, throwing away all values.
-
-* `has(key)`
-
- Check if a key is in the cache, without updating the recent-ness
- or deleting it for being stale.
-
-* `forEach(function(value,key,cache), [thisp])`
-
- Just like `Array.prototype.forEach`. Iterates over all the keys
- in the cache, in order of recent-ness. (Ie, more recently used
- items are iterated over first.)
-
-* `keys()`
-
- Return an array of the keys in the cache.
-
-* `values()`
-
- Return an array of the values in the cache.
diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/lib/lru-cache.js b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/lib/lru-cache.js
deleted file mode 100644
index d1d13817..00000000
--- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/lib/lru-cache.js
+++ /dev/null
@@ -1,252 +0,0 @@
-;(function () { // closure for web browsers
-
-if (typeof module === 'object' && module.exports) {
- module.exports = LRUCache
-} else {
- // just set the global for non-node platforms.
- this.LRUCache = LRUCache
-}
-
-function hOP (obj, key) {
- return Object.prototype.hasOwnProperty.call(obj, key)
-}
-
-function naiveLength () { return 1 }
-
-function LRUCache (options) {
- if (!(this instanceof LRUCache))
- return new LRUCache(options)
-
- if (typeof options === 'number')
- options = { max: options }
-
- if (!options)
- options = {}
-
- this._max = options.max
- // Kind of weird to have a default max of Infinity, but oh well.
- if (!this._max || !(typeof this._max === "number") || this._max <= 0 )
- this._max = Infinity
-
- this._lengthCalculator = options.length || naiveLength
- if (typeof this._lengthCalculator !== "function")
- this._lengthCalculator = naiveLength
-
- this._allowStale = options.stale || false
- this._maxAge = options.maxAge || null
- this._dispose = options.dispose
- this.reset()
-}
-
-// resize the cache when the max changes.
-Object.defineProperty(LRUCache.prototype, "max",
- { set : function (mL) {
- if (!mL || !(typeof mL === "number") || mL <= 0 ) mL = Infinity
- this._max = mL
- if (this._length > this._max) trim(this)
- }
- , get : function () { return this._max }
- , enumerable : true
- })
-
-// resize the cache when the lengthCalculator changes.
-Object.defineProperty(LRUCache.prototype, "lengthCalculator",
- { set : function (lC) {
- if (typeof lC !== "function") {
- this._lengthCalculator = naiveLength
- this._length = this._itemCount
- for (var key in this._cache) {
- this._cache[key].length = 1
- }
- } else {
- this._lengthCalculator = lC
- this._length = 0
- for (var key in this._cache) {
- this._cache[key].length = this._lengthCalculator(this._cache[key].value)
- this._length += this._cache[key].length
- }
- }
-
- if (this._length > this._max) trim(this)
- }
- , get : function () { return this._lengthCalculator }
- , enumerable : true
- })
-
-Object.defineProperty(LRUCache.prototype, "length",
- { get : function () { return this._length }
- , enumerable : true
- })
-
-
-Object.defineProperty(LRUCache.prototype, "itemCount",
- { get : function () { return this._itemCount }
- , enumerable : true
- })
-
-LRUCache.prototype.forEach = function (fn, thisp) {
- thisp = thisp || this
- var i = 0;
- for (var k = this._mru - 1; k >= 0 && i < this._itemCount; k--) if (this._lruList[k]) {
- i++
- var hit = this._lruList[k]
- if (this._maxAge && (Date.now() - hit.now > this._maxAge)) {
- del(this, hit)
- if (!this._allowStale) hit = undefined
- }
- if (hit) {
- fn.call(thisp, hit.value, hit.key, this)
- }
- }
-}
-
-LRUCache.prototype.keys = function () {
- var keys = new Array(this._itemCount)
- var i = 0
- for (var k = this._mru - 1; k >= 0 && i < this._itemCount; k--) if (this._lruList[k]) {
- var hit = this._lruList[k]
- keys[i++] = hit.key
- }
- return keys
-}
-
-LRUCache.prototype.values = function () {
- var values = new Array(this._itemCount)
- var i = 0
- for (var k = this._mru - 1; k >= 0 && i < this._itemCount; k--) if (this._lruList[k]) {
- var hit = this._lruList[k]
- values[i++] = hit.value
- }
- return values
-}
-
-LRUCache.prototype.reset = function () {
- if (this._dispose && this._cache) {
- for (var k in this._cache) {
- this._dispose(k, this._cache[k].value)
- }
- }
-
- this._cache = Object.create(null) // hash of items by key
- this._lruList = Object.create(null) // list of items in order of use recency
- this._mru = 0 // most recently used
- this._lru = 0 // least recently used
- this._length = 0 // number of items in the list
- this._itemCount = 0
-}
-
-// Provided for debugging/dev purposes only. No promises whatsoever that
-// this API stays stable.
-LRUCache.prototype.dump = function () {
- return this._cache
-}
-
-LRUCache.prototype.dumpLru = function () {
- return this._lruList
-}
-
-LRUCache.prototype.set = function (key, value) {
- if (hOP(this._cache, key)) {
- // dispose of the old one before overwriting
- if (this._dispose) this._dispose(key, this._cache[key].value)
- if (this._maxAge) this._cache[key].now = Date.now()
- this._cache[key].value = value
- this.get(key)
- return true
- }
-
- var len = this._lengthCalculator(value)
- var age = this._maxAge ? Date.now() : 0
- var hit = new Entry(key, value, this._mru++, len, age)
-
- // oversized objects fall out of cache automatically.
- if (hit.length > this._max) {
- if (this._dispose) this._dispose(key, value)
- return false
- }
-
- this._length += hit.length
- this._lruList[hit.lu] = this._cache[key] = hit
- this._itemCount ++
-
- if (this._length > this._max) trim(this)
- return true
-}
-
-LRUCache.prototype.has = function (key) {
- if (!hOP(this._cache, key)) return false
- var hit = this._cache[key]
- if (this._maxAge && (Date.now() - hit.now > this._maxAge)) {
- return false
- }
- return true
-}
-
-LRUCache.prototype.get = function (key) {
- return get(this, key, true)
-}
-
-LRUCache.prototype.peek = function (key) {
- return get(this, key, false)
-}
-
-LRUCache.prototype.pop = function () {
- var hit = this._lruList[this._lru]
- del(this, hit)
- return hit || null
-}
-
-LRUCache.prototype.del = function (key) {
- del(this, this._cache[key])
-}
-
-function get (self, key, doUse) {
- var hit = self._cache[key]
- if (hit) {
- if (self._maxAge && (Date.now() - hit.now > self._maxAge)) {
- del(self, hit)
- if (!self._allowStale) hit = undefined
- } else {
- if (doUse) use(self, hit)
- }
- if (hit) hit = hit.value
- }
- return hit
-}
-
-function use (self, hit) {
- shiftLU(self, hit)
- hit.lu = self._mru ++
- self._lruList[hit.lu] = hit
-}
-
-function trim (self) {
- while (self._lru < self._mru && self._length > self._max)
- del(self, self._lruList[self._lru])
-}
-
-function shiftLU (self, hit) {
- delete self._lruList[ hit.lu ]
- while (self._lru < self._mru && !self._lruList[self._lru]) self._lru ++
-}
-
-function del (self, hit) {
- if (hit) {
- if (self._dispose) self._dispose(hit.key, hit.value)
- self._length -= hit.length
- self._itemCount --
- delete self._cache[ hit.key ]
- shiftLU(self, hit)
- }
-}
-
-// classy, since V8 prefers predictable objects.
-function Entry (key, value, lu, length, now) {
- this.key = key
- this.value = value
- this.lu = lu
- this.length = length
- this.now = now
-}
-
-})()
diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/package.json b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/package.json
deleted file mode 100644
index 2474729b..00000000
--- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/package.json
+++ /dev/null
@@ -1,50 +0,0 @@
-{
- "name": "lru-cache",
- "description": "A cache object that deletes the least-recently-used items.",
- "version": "2.5.0",
- "author": {
- "name": "Isaac Z. Schlueter",
- "email": "i@izs.me"
- },
- "scripts": {
- "test": "tap test --gc"
- },
- "main": "lib/lru-cache.js",
- "repository": {
- "type": "git",
- "url": "git://github.com/isaacs/node-lru-cache.git"
- },
- "devDependencies": {
- "tap": "",
- "weak": ""
- },
- "license": {
- "type": "MIT",
- "url": "http://github.com/isaacs/node-lru-cache/raw/master/LICENSE"
- },
- "bugs": {
- "url": "https://github.com/isaacs/node-lru-cache/issues"
- },
- "homepage": "https://github.com/isaacs/node-lru-cache",
- "_id": "lru-cache@2.5.0",
- "dist": {
- "shasum": "d82388ae9c960becbea0c73bb9eb79b6c6ce9aeb",
- "tarball": "http://registry.npmjs.org/lru-cache/-/lru-cache-2.5.0.tgz"
- },
- "_from": "lru-cache@2",
- "_npmVersion": "1.3.15",
- "_npmUser": {
- "name": "isaacs",
- "email": "i@izs.me"
- },
- "maintainers": [
- {
- "name": "isaacs",
- "email": "i@izs.me"
- }
- ],
- "directories": {},
- "_shasum": "d82388ae9c960becbea0c73bb9eb79b6c6ce9aeb",
- "_resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.5.0.tgz",
- "readme": "ERROR: No README data found!"
-}
diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/test/basic.js b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/test/basic.js
deleted file mode 100644
index f72697c4..00000000
--- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/test/basic.js
+++ /dev/null
@@ -1,369 +0,0 @@
-var test = require("tap").test
- , LRU = require("../")
-
-test("basic", function (t) {
- var cache = new LRU({max: 10})
- cache.set("key", "value")
- t.equal(cache.get("key"), "value")
- t.equal(cache.get("nada"), undefined)
- t.equal(cache.length, 1)
- t.equal(cache.max, 10)
- t.end()
-})
-
-test("least recently set", function (t) {
- var cache = new LRU(2)
- cache.set("a", "A")
- cache.set("b", "B")
- cache.set("c", "C")
- t.equal(cache.get("c"), "C")
- t.equal(cache.get("b"), "B")
- t.equal(cache.get("a"), undefined)
- t.end()
-})
-
-test("lru recently gotten", function (t) {
- var cache = new LRU(2)
- cache.set("a", "A")
- cache.set("b", "B")
- cache.get("a")
- cache.set("c", "C")
- t.equal(cache.get("c"), "C")
- t.equal(cache.get("b"), undefined)
- t.equal(cache.get("a"), "A")
- t.end()
-})
-
-test("del", function (t) {
- var cache = new LRU(2)
- cache.set("a", "A")
- cache.del("a")
- t.equal(cache.get("a"), undefined)
- t.end()
-})
-
-test("max", function (t) {
- var cache = new LRU(3)
-
- // test changing the max, verify that the LRU items get dropped.
- cache.max = 100
- for (var i = 0; i < 100; i ++) cache.set(i, i)
- t.equal(cache.length, 100)
- for (var i = 0; i < 100; i ++) {
- t.equal(cache.get(i), i)
- }
- cache.max = 3
- t.equal(cache.length, 3)
- for (var i = 0; i < 97; i ++) {
- t.equal(cache.get(i), undefined)
- }
- for (var i = 98; i < 100; i ++) {
- t.equal(cache.get(i), i)
- }
-
- // now remove the max restriction, and try again.
- cache.max = "hello"
- for (var i = 0; i < 100; i ++) cache.set(i, i)
- t.equal(cache.length, 100)
- for (var i = 0; i < 100; i ++) {
- t.equal(cache.get(i), i)
- }
- // should trigger an immediate resize
- cache.max = 3
- t.equal(cache.length, 3)
- for (var i = 0; i < 97; i ++) {
- t.equal(cache.get(i), undefined)
- }
- for (var i = 98; i < 100; i ++) {
- t.equal(cache.get(i), i)
- }
- t.end()
-})
-
-test("reset", function (t) {
- var cache = new LRU(10)
- cache.set("a", "A")
- cache.set("b", "B")
- cache.reset()
- t.equal(cache.length, 0)
- t.equal(cache.max, 10)
- t.equal(cache.get("a"), undefined)
- t.equal(cache.get("b"), undefined)
- t.end()
-})
-
-
-// Note: `.dump()` is a debugging tool only. No guarantees are made
-// about the format/layout of the response.
-test("dump", function (t) {
- var cache = new LRU(10)
- var d = cache.dump();
- t.equal(Object.keys(d).length, 0, "nothing in dump for empty cache")
- cache.set("a", "A")
- var d = cache.dump() // { a: { key: "a", value: "A", lu: 0 } }
- t.ok(d.a)
- t.equal(d.a.key, "a")
- t.equal(d.a.value, "A")
- t.equal(d.a.lu, 0)
-
- cache.set("b", "B")
- cache.get("b")
- d = cache.dump()
- t.ok(d.b)
- t.equal(d.b.key, "b")
- t.equal(d.b.value, "B")
- t.equal(d.b.lu, 2)
-
- t.end()
-})
-
-
-test("basic with weighed length", function (t) {
- var cache = new LRU({
- max: 100,
- length: function (item) { return item.size }
- })
- cache.set("key", {val: "value", size: 50})
- t.equal(cache.get("key").val, "value")
- t.equal(cache.get("nada"), undefined)
- t.equal(cache.lengthCalculator(cache.get("key")), 50)
- t.equal(cache.length, 50)
- t.equal(cache.max, 100)
- t.end()
-})
-
-
-test("weighed length item too large", function (t) {
- var cache = new LRU({
- max: 10,
- length: function (item) { return item.size }
- })
- t.equal(cache.max, 10)
-
- // should fall out immediately
- cache.set("key", {val: "value", size: 50})
-
- t.equal(cache.length, 0)
- t.equal(cache.get("key"), undefined)
- t.end()
-})
-
-test("least recently set with weighed length", function (t) {
- var cache = new LRU({
- max:8,
- length: function (item) { return item.length }
- })
- cache.set("a", "A")
- cache.set("b", "BB")
- cache.set("c", "CCC")
- cache.set("d", "DDDD")
- t.equal(cache.get("d"), "DDDD")
- t.equal(cache.get("c"), "CCC")
- t.equal(cache.get("b"), undefined)
- t.equal(cache.get("a"), undefined)
- t.end()
-})
-
-test("lru recently gotten with weighed length", function (t) {
- var cache = new LRU({
- max: 8,
- length: function (item) { return item.length }
- })
- cache.set("a", "A")
- cache.set("b", "BB")
- cache.set("c", "CCC")
- cache.get("a")
- cache.get("b")
- cache.set("d", "DDDD")
- t.equal(cache.get("c"), undefined)
- t.equal(cache.get("d"), "DDDD")
- t.equal(cache.get("b"), "BB")
- t.equal(cache.get("a"), "A")
- t.end()
-})
-
-test("set returns proper booleans", function(t) {
- var cache = new LRU({
- max: 5,
- length: function (item) { return item.length }
- })
-
- t.equal(cache.set("a", "A"), true)
-
- // should return false for max exceeded
- t.equal(cache.set("b", "donuts"), false)
-
- t.equal(cache.set("b", "B"), true)
- t.equal(cache.set("c", "CCCC"), true)
- t.end()
-})
-
-test("drop the old items", function(t) {
- var cache = new LRU({
- max: 5,
- maxAge: 50
- })
-
- cache.set("a", "A")
-
- setTimeout(function () {
- cache.set("b", "b")
- t.equal(cache.get("a"), "A")
- }, 25)
-
- setTimeout(function () {
- cache.set("c", "C")
- // timed out
- t.notOk(cache.get("a"))
- }, 60)
-
- setTimeout(function () {
- t.notOk(cache.get("b"))
- t.equal(cache.get("c"), "C")
- }, 90)
-
- setTimeout(function () {
- t.notOk(cache.get("c"))
- t.end()
- }, 155)
-})
-
-test("disposal function", function(t) {
- var disposed = false
- var cache = new LRU({
- max: 1,
- dispose: function (k, n) {
- disposed = n
- }
- })
-
- cache.set(1, 1)
- cache.set(2, 2)
- t.equal(disposed, 1)
- cache.set(3, 3)
- t.equal(disposed, 2)
- cache.reset()
- t.equal(disposed, 3)
- t.end()
-})
-
-test("disposal function on too big of item", function(t) {
- var disposed = false
- var cache = new LRU({
- max: 1,
- length: function (k) {
- return k.length
- },
- dispose: function (k, n) {
- disposed = n
- }
- })
- var obj = [ 1, 2 ]
-
- t.equal(disposed, false)
- cache.set("obj", obj)
- t.equal(disposed, obj)
- t.end()
-})
-
-test("has()", function(t) {
- var cache = new LRU({
- max: 1,
- maxAge: 10
- })
-
- cache.set('foo', 'bar')
- t.equal(cache.has('foo'), true)
- cache.set('blu', 'baz')
- t.equal(cache.has('foo'), false)
- t.equal(cache.has('blu'), true)
- setTimeout(function() {
- t.equal(cache.has('blu'), false)
- t.end()
- }, 15)
-})
-
-test("stale", function(t) {
- var cache = new LRU({
- maxAge: 10,
- stale: true
- })
-
- cache.set('foo', 'bar')
- t.equal(cache.get('foo'), 'bar')
- t.equal(cache.has('foo'), true)
- setTimeout(function() {
- t.equal(cache.has('foo'), false)
- t.equal(cache.get('foo'), 'bar')
- t.equal(cache.get('foo'), undefined)
- t.end()
- }, 15)
-})
-
-test("lru update via set", function(t) {
- var cache = LRU({ max: 2 });
-
- cache.set('foo', 1);
- cache.set('bar', 2);
- cache.del('bar');
- cache.set('baz', 3);
- cache.set('qux', 4);
-
- t.equal(cache.get('foo'), undefined)
- t.equal(cache.get('bar'), undefined)
- t.equal(cache.get('baz'), 3)
- t.equal(cache.get('qux'), 4)
- t.end()
-})
-
-test("least recently set w/ peek", function (t) {
- var cache = new LRU(2)
- cache.set("a", "A")
- cache.set("b", "B")
- t.equal(cache.peek("a"), "A")
- cache.set("c", "C")
- t.equal(cache.get("c"), "C")
- t.equal(cache.get("b"), "B")
- t.equal(cache.get("a"), undefined)
- t.end()
-})
-
-test("pop the least used item", function (t) {
- var cache = new LRU(3)
- , last
-
- cache.set("a", "A")
- cache.set("b", "B")
- cache.set("c", "C")
-
- t.equal(cache.length, 3)
- t.equal(cache.max, 3)
-
- // Ensure we pop a, c, b
- cache.get("b", "B")
-
- last = cache.pop()
- t.equal(last.key, "a")
- t.equal(last.value, "A")
- t.equal(cache.length, 2)
- t.equal(cache.max, 3)
-
- last = cache.pop()
- t.equal(last.key, "c")
- t.equal(last.value, "C")
- t.equal(cache.length, 1)
- t.equal(cache.max, 3)
-
- last = cache.pop()
- t.equal(last.key, "b")
- t.equal(last.value, "B")
- t.equal(cache.length, 0)
- t.equal(cache.max, 3)
-
- last = cache.pop()
- t.equal(last, null)
- t.equal(cache.length, 0)
- t.equal(cache.max, 3)
-
- t.end()
-})
diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/test/foreach.js b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/test/foreach.js
deleted file mode 100644
index eefb80d9..00000000
--- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/test/foreach.js
+++ /dev/null
@@ -1,52 +0,0 @@
-var test = require('tap').test
-var LRU = require('../')
-
-test('forEach', function (t) {
- var l = new LRU(5)
- for (var i = 0; i < 10; i ++) {
- l.set(i.toString(), i.toString(2))
- }
-
- var i = 9
- l.forEach(function (val, key, cache) {
- t.equal(cache, l)
- t.equal(key, i.toString())
- t.equal(val, i.toString(2))
- i -= 1
- })
-
- // get in order of most recently used
- l.get(6)
- l.get(8)
-
- var order = [ 8, 6, 9, 7, 5 ]
- var i = 0
-
- l.forEach(function (val, key, cache) {
- var j = order[i ++]
- t.equal(cache, l)
- t.equal(key, j.toString())
- t.equal(val, j.toString(2))
- })
-
- t.end()
-})
-
-test('keys() and values()', function (t) {
- var l = new LRU(5)
- for (var i = 0; i < 10; i ++) {
- l.set(i.toString(), i.toString(2))
- }
-
- t.similar(l.keys(), ['9', '8', '7', '6', '5'])
- t.similar(l.values(), ['1001', '1000', '111', '110', '101'])
-
- // get in order of most recently used
- l.get(6)
- l.get(8)
-
- t.similar(l.keys(), ['8', '6', '9', '7', '5'])
- t.similar(l.values(), ['1000', '110', '1001', '111', '101'])
-
- t.end()
-})
diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/test/memory-leak.js b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/test/memory-leak.js
deleted file mode 100644
index 7af45b02..00000000
--- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/test/memory-leak.js
+++ /dev/null
@@ -1,50 +0,0 @@
-#!/usr/bin/env node --expose_gc
-
-var weak = require('weak');
-var test = require('tap').test
-var LRU = require('../')
-var l = new LRU({ max: 10 })
-var refs = 0
-function X() {
- refs ++
- weak(this, deref)
-}
-
-function deref() {
- refs --
-}
-
-test('no leaks', function (t) {
- // fill up the cache
- for (var i = 0; i < 100; i++) {
- l.set(i, new X);
- // throw some gets in there, too.
- if (i % 2 === 0)
- l.get(i / 2)
- }
-
- gc()
-
- var start = process.memoryUsage()
-
- // capture the memory
- var startRefs = refs
-
- // do it again, but more
- for (var i = 0; i < 10000; i++) {
- l.set(i, new X);
- // throw some gets in there, too.
- if (i % 2 === 0)
- l.get(i / 2)
- }
-
- gc()
-
- var end = process.memoryUsage()
- t.equal(refs, startRefs, 'no leaky refs')
-
- console.error('start: %j\n' +
- 'end: %j', start, end);
- t.pass();
- t.end();
-})
diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/LICENSE b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/LICENSE
deleted file mode 100644
index 0c44ae71..00000000
--- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/LICENSE
+++ /dev/null
@@ -1,27 +0,0 @@
-Copyright (c) Isaac Z. Schlueter ("Author")
-All rights reserved.
-
-The BSD License
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
-2. 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.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 THE AUTHOR OR CONTRIBUTORS
-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.
diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/README.md b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/README.md
deleted file mode 100644
index 7e365129..00000000
--- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/README.md
+++ /dev/null
@@ -1,53 +0,0 @@
-# sigmund
-
-Quick and dirty signatures for Objects.
-
-This is like a much faster `deepEquals` comparison, which returns a
-string key suitable for caches and the like.
-
-## Usage
-
-```javascript
-function doSomething (someObj) {
- var key = sigmund(someObj, maxDepth) // max depth defaults to 10
- var cached = cache.get(key)
- if (cached) return cached)
-
- var result = expensiveCalculation(someObj)
- cache.set(key, result)
- return result
-}
-```
-
-The resulting key will be as unique and reproducible as calling
-`JSON.stringify` or `util.inspect` on the object, but is much faster.
-In order to achieve this speed, some differences are glossed over.
-For example, the object `{0:'foo'}` will be treated identically to the
-array `['foo']`.
-
-Also, just as there is no way to summon the soul from the scribblings
-of a cocain-addled psychoanalyst, there is no way to revive the object
-from the signature string that sigmund gives you. In fact, it's
-barely even readable.
-
-As with `sys.inspect` and `JSON.stringify`, larger objects will
-produce larger signature strings.
-
-Because sigmund is a bit less strict than the more thorough
-alternatives, the strings will be shorter, and also there is a
-slightly higher chance for collisions. For example, these objects
-have the same signature:
-
- var obj1 = {a:'b',c:/def/,g:['h','i',{j:'',k:'l'}]}
- var obj2 = {a:'b',c:'/def/',g:['h','i','{jkl']}
-
-Like a good Freudian, sigmund is most effective when you already have
-some understanding of what you're looking for. It can help you help
-yourself, but you must be willing to do some work as well.
-
-Cycles are handled, and cyclical objects are silently omitted (though
-the key is included in the signature output.)
-
-The second argument is the maximum depth, which defaults to 10,
-because that is the maximum object traversal depth covered by most
-insurance carriers.
diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/bench.js b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/bench.js
deleted file mode 100644
index 5acfd6d9..00000000
--- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/bench.js
+++ /dev/null
@@ -1,283 +0,0 @@
-// different ways to id objects
-// use a req/res pair, since it's crazy deep and cyclical
-
-// sparseFE10 and sigmund are usually pretty close, which is to be expected,
-// since they are essentially the same algorithm, except that sigmund handles
-// regular expression objects properly.
-
-
-var http = require('http')
-var util = require('util')
-var sigmund = require('./sigmund.js')
-var sreq, sres, creq, cres, test
-
-http.createServer(function (q, s) {
- sreq = q
- sres = s
- sres.end('ok')
- this.close(function () { setTimeout(function () {
- start()
- }, 200) })
-}).listen(1337, function () {
- creq = http.get({ port: 1337 })
- creq.on('response', function (s) { cres = s })
-})
-
-function start () {
- test = [sreq, sres, creq, cres]
- // test = sreq
- // sreq.sres = sres
- // sreq.creq = creq
- // sreq.cres = cres
-
- for (var i in exports.compare) {
- console.log(i)
- var hash = exports.compare[i]()
- console.log(hash)
- console.log(hash.length)
- console.log('')
- }
-
- require('bench').runMain()
-}
-
-function customWs (obj, md, d) {
- d = d || 0
- var to = typeof obj
- if (to === 'undefined' || to === 'function' || to === null) return ''
- if (d > md || !obj || to !== 'object') return ('' + obj).replace(/[\n ]+/g, '')
-
- if (Array.isArray(obj)) {
- return obj.map(function (i, _, __) {
- return customWs(i, md, d + 1)
- }).reduce(function (a, b) { return a + b }, '')
- }
-
- var keys = Object.keys(obj)
- return keys.map(function (k, _, __) {
- return k + ':' + customWs(obj[k], md, d + 1)
- }).reduce(function (a, b) { return a + b }, '')
-}
-
-function custom (obj, md, d) {
- d = d || 0
- var to = typeof obj
- if (to === 'undefined' || to === 'function' || to === null) return ''
- if (d > md || !obj || to !== 'object') return '' + obj
-
- if (Array.isArray(obj)) {
- return obj.map(function (i, _, __) {
- return custom(i, md, d + 1)
- }).reduce(function (a, b) { return a + b }, '')
- }
-
- var keys = Object.keys(obj)
- return keys.map(function (k, _, __) {
- return k + ':' + custom(obj[k], md, d + 1)
- }).reduce(function (a, b) { return a + b }, '')
-}
-
-function sparseFE2 (obj, maxDepth) {
- var seen = []
- var soFar = ''
- function ch (v, depth) {
- if (depth > maxDepth) return
- if (typeof v === 'function' || typeof v === 'undefined') return
- if (typeof v !== 'object' || !v) {
- soFar += v
- return
- }
- if (seen.indexOf(v) !== -1 || depth === maxDepth) return
- seen.push(v)
- soFar += '{'
- Object.keys(v).forEach(function (k, _, __) {
- // pseudo-private values. skip those.
- if (k.charAt(0) === '_') return
- var to = typeof v[k]
- if (to === 'function' || to === 'undefined') return
- soFar += k + ':'
- ch(v[k], depth + 1)
- })
- soFar += '}'
- }
- ch(obj, 0)
- return soFar
-}
-
-function sparseFE (obj, maxDepth) {
- var seen = []
- var soFar = ''
- function ch (v, depth) {
- if (depth > maxDepth) return
- if (typeof v === 'function' || typeof v === 'undefined') return
- if (typeof v !== 'object' || !v) {
- soFar += v
- return
- }
- if (seen.indexOf(v) !== -1 || depth === maxDepth) return
- seen.push(v)
- soFar += '{'
- Object.keys(v).forEach(function (k, _, __) {
- // pseudo-private values. skip those.
- if (k.charAt(0) === '_') return
- var to = typeof v[k]
- if (to === 'function' || to === 'undefined') return
- soFar += k
- ch(v[k], depth + 1)
- })
- }
- ch(obj, 0)
- return soFar
-}
-
-function sparse (obj, maxDepth) {
- var seen = []
- var soFar = ''
- function ch (v, depth) {
- if (depth > maxDepth) return
- if (typeof v === 'function' || typeof v === 'undefined') return
- if (typeof v !== 'object' || !v) {
- soFar += v
- return
- }
- if (seen.indexOf(v) !== -1 || depth === maxDepth) return
- seen.push(v)
- soFar += '{'
- for (var k in v) {
- // pseudo-private values. skip those.
- if (k.charAt(0) === '_') continue
- var to = typeof v[k]
- if (to === 'function' || to === 'undefined') continue
- soFar += k
- ch(v[k], depth + 1)
- }
- }
- ch(obj, 0)
- return soFar
-}
-
-function noCommas (obj, maxDepth) {
- var seen = []
- var soFar = ''
- function ch (v, depth) {
- if (depth > maxDepth) return
- if (typeof v === 'function' || typeof v === 'undefined') return
- if (typeof v !== 'object' || !v) {
- soFar += v
- return
- }
- if (seen.indexOf(v) !== -1 || depth === maxDepth) return
- seen.push(v)
- soFar += '{'
- for (var k in v) {
- // pseudo-private values. skip those.
- if (k.charAt(0) === '_') continue
- var to = typeof v[k]
- if (to === 'function' || to === 'undefined') continue
- soFar += k + ':'
- ch(v[k], depth + 1)
- }
- soFar += '}'
- }
- ch(obj, 0)
- return soFar
-}
-
-
-function flatten (obj, maxDepth) {
- var seen = []
- var soFar = ''
- function ch (v, depth) {
- if (depth > maxDepth) return
- if (typeof v === 'function' || typeof v === 'undefined') return
- if (typeof v !== 'object' || !v) {
- soFar += v
- return
- }
- if (seen.indexOf(v) !== -1 || depth === maxDepth) return
- seen.push(v)
- soFar += '{'
- for (var k in v) {
- // pseudo-private values. skip those.
- if (k.charAt(0) === '_') continue
- var to = typeof v[k]
- if (to === 'function' || to === 'undefined') continue
- soFar += k + ':'
- ch(v[k], depth + 1)
- soFar += ','
- }
- soFar += '}'
- }
- ch(obj, 0)
- return soFar
-}
-
-exports.compare =
-{
- // 'custom 2': function () {
- // return custom(test, 2, 0)
- // },
- // 'customWs 2': function () {
- // return customWs(test, 2, 0)
- // },
- 'JSON.stringify (guarded)': function () {
- var seen = []
- return JSON.stringify(test, function (k, v) {
- if (typeof v !== 'object' || !v) return v
- if (seen.indexOf(v) !== -1) return undefined
- seen.push(v)
- return v
- })
- },
-
- 'flatten 10': function () {
- return flatten(test, 10)
- },
-
- // 'flattenFE 10': function () {
- // return flattenFE(test, 10)
- // },
-
- 'noCommas 10': function () {
- return noCommas(test, 10)
- },
-
- 'sparse 10': function () {
- return sparse(test, 10)
- },
-
- 'sparseFE 10': function () {
- return sparseFE(test, 10)
- },
-
- 'sparseFE2 10': function () {
- return sparseFE2(test, 10)
- },
-
- sigmund: function() {
- return sigmund(test, 10)
- },
-
-
- // 'util.inspect 1': function () {
- // return util.inspect(test, false, 1, false)
- // },
- // 'util.inspect undefined': function () {
- // util.inspect(test)
- // },
- // 'util.inspect 2': function () {
- // util.inspect(test, false, 2, false)
- // },
- // 'util.inspect 3': function () {
- // util.inspect(test, false, 3, false)
- // },
- // 'util.inspect 4': function () {
- // util.inspect(test, false, 4, false)
- // },
- // 'util.inspect Infinity': function () {
- // util.inspect(test, false, Infinity, false)
- // }
-}
-
-/** results
-**/
diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/package.json b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/package.json
deleted file mode 100644
index a1f755a7..00000000
--- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/package.json
+++ /dev/null
@@ -1,58 +0,0 @@
-{
- "name": "sigmund",
- "version": "1.0.0",
- "description": "Quick and dirty signatures for Objects.",
- "main": "sigmund.js",
- "directories": {
- "test": "test"
- },
- "dependencies": {},
- "devDependencies": {
- "tap": "~0.3.0"
- },
- "scripts": {
- "test": "tap test/*.js",
- "bench": "node bench.js"
- },
- "repository": {
- "type": "git",
- "url": "git://github.com/isaacs/sigmund"
- },
- "keywords": [
- "object",
- "signature",
- "key",
- "data",
- "psychoanalysis"
- ],
- "author": {
- "name": "Isaac Z. Schlueter",
- "email": "i@izs.me",
- "url": "http://blog.izs.me/"
- },
- "license": "BSD",
- "readme": "# sigmund\n\nQuick and dirty signatures for Objects.\n\nThis is like a much faster `deepEquals` comparison, which returns a\nstring key suitable for caches and the like.\n\n## Usage\n\n```javascript\nfunction doSomething (someObj) {\n var key = sigmund(someObj, maxDepth) // max depth defaults to 10\n var cached = cache.get(key)\n if (cached) return cached)\n\n var result = expensiveCalculation(someObj)\n cache.set(key, result)\n return result\n}\n```\n\nThe resulting key will be as unique and reproducible as calling\n`JSON.stringify` or `util.inspect` on the object, but is much faster.\nIn order to achieve this speed, some differences are glossed over.\nFor example, the object `{0:'foo'}` will be treated identically to the\narray `['foo']`.\n\nAlso, just as there is no way to summon the soul from the scribblings\nof a cocain-addled psychoanalyst, there is no way to revive the object\nfrom the signature string that sigmund gives you. In fact, it's\nbarely even readable.\n\nAs with `sys.inspect` and `JSON.stringify`, larger objects will\nproduce larger signature strings.\n\nBecause sigmund is a bit less strict than the more thorough\nalternatives, the strings will be shorter, and also there is a\nslightly higher chance for collisions. For example, these objects\nhave the same signature:\n\n var obj1 = {a:'b',c:/def/,g:['h','i',{j:'',k:'l'}]}\n var obj2 = {a:'b',c:'/def/',g:['h','i','{jkl']}\n\nLike a good Freudian, sigmund is most effective when you already have\nsome understanding of what you're looking for. It can help you help\nyourself, but you must be willing to do some work as well.\n\nCycles are handled, and cyclical objects are silently omitted (though\nthe key is included in the signature output.)\n\nThe second argument is the maximum depth, which defaults to 10,\nbecause that is the maximum object traversal depth covered by most\ninsurance carriers.\n",
- "_id": "sigmund@1.0.0",
- "dist": {
- "shasum": "66a2b3a749ae8b5fb89efd4fcc01dc94fbe02296",
- "tarball": "http://registry.npmjs.org/sigmund/-/sigmund-1.0.0.tgz"
- },
- "_npmVersion": "1.1.48",
- "_npmUser": {
- "name": "isaacs",
- "email": "i@izs.me"
- },
- "maintainers": [
- {
- "name": "isaacs",
- "email": "i@izs.me"
- }
- ],
- "_shasum": "66a2b3a749ae8b5fb89efd4fcc01dc94fbe02296",
- "_from": "sigmund@~1.0.0",
- "_resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.0.tgz",
- "bugs": {
- "url": "https://github.com/isaacs/sigmund/issues"
- },
- "homepage": "https://github.com/isaacs/sigmund"
-}
diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/sigmund.js b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/sigmund.js
deleted file mode 100644
index 82c7ab8c..00000000
--- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/sigmund.js
+++ /dev/null
@@ -1,39 +0,0 @@
-module.exports = sigmund
-function sigmund (subject, maxSessions) {
- maxSessions = maxSessions || 10;
- var notes = [];
- var analysis = '';
- var RE = RegExp;
-
- function psychoAnalyze (subject, session) {
- if (session > maxSessions) return;
-
- if (typeof subject === 'function' ||
- typeof subject === 'undefined') {
- return;
- }
-
- if (typeof subject !== 'object' || !subject ||
- (subject instanceof RE)) {
- analysis += subject;
- return;
- }
-
- if (notes.indexOf(subject) !== -1 || session === maxSessions) return;
-
- notes.push(subject);
- analysis += '{';
- Object.keys(subject).forEach(function (issue, _, __) {
- // pseudo-private values. skip those.
- if (issue.charAt(0) === '_') return;
- var to = typeof subject[issue];
- if (to === 'function' || to === 'undefined') return;
- analysis += issue;
- psychoAnalyze(subject[issue], session + 1);
- });
- }
- psychoAnalyze(subject, 0);
- return analysis;
-}
-
-// vim: set softtabstop=4 shiftwidth=4:
diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/test/basic.js b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/test/basic.js
deleted file mode 100644
index 50c53a13..00000000
--- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/test/basic.js
+++ /dev/null
@@ -1,24 +0,0 @@
-var test = require('tap').test
-var sigmund = require('../sigmund.js')
-
-
-// occasionally there are duplicates
-// that's an acceptable edge-case. JSON.stringify and util.inspect
-// have some collision potential as well, though less, and collision
-// detection is expensive.
-var hash = '{abc/def/g{0h1i2{jkl'
-var obj1 = {a:'b',c:/def/,g:['h','i',{j:'',k:'l'}]}
-var obj2 = {a:'b',c:'/def/',g:['h','i','{jkl']}
-
-var obj3 = JSON.parse(JSON.stringify(obj1))
-obj3.c = /def/
-obj3.g[2].cycle = obj3
-var cycleHash = '{abc/def/g{0h1i2{jklcycle'
-
-test('basic', function (t) {
- t.equal(sigmund(obj1), hash)
- t.equal(sigmund(obj2), hash)
- t.equal(sigmund(obj3), cycleHash)
- t.end()
-})
-
diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/package.json b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/package.json
deleted file mode 100644
index 0fe147d6..00000000
--- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/package.json
+++ /dev/null
@@ -1,57 +0,0 @@
-{
- "author": {
- "name": "Isaac Z. Schlueter",
- "email": "i@izs.me",
- "url": "http://blog.izs.me"
- },
- "name": "minimatch",
- "description": "a glob matcher in javascript",
- "version": "0.3.0",
- "repository": {
- "type": "git",
- "url": "git://github.com/isaacs/minimatch.git"
- },
- "main": "minimatch.js",
- "scripts": {
- "test": "tap test/*.js"
- },
- "engines": {
- "node": "*"
- },
- "dependencies": {
- "lru-cache": "2",
- "sigmund": "~1.0.0"
- },
- "devDependencies": {
- "tap": ""
- },
- "license": {
- "type": "MIT",
- "url": "http://github.com/isaacs/minimatch/raw/master/LICENSE"
- },
- "bugs": {
- "url": "https://github.com/isaacs/minimatch/issues"
- },
- "homepage": "https://github.com/isaacs/minimatch",
- "_id": "minimatch@0.3.0",
- "_shasum": "275d8edaac4f1bb3326472089e7949c8394699dd",
- "_from": "minimatch@0.3",
- "_npmVersion": "1.4.10",
- "_npmUser": {
- "name": "isaacs",
- "email": "i@izs.me"
- },
- "maintainers": [
- {
- "name": "isaacs",
- "email": "i@izs.me"
- }
- ],
- "dist": {
- "shasum": "275d8edaac4f1bb3326472089e7949c8394699dd",
- "tarball": "http://registry.npmjs.org/minimatch/-/minimatch-0.3.0.tgz"
- },
- "directories": {},
- "_resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.3.0.tgz",
- "readme": "ERROR: No README data found!"
-}
diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/basic.js b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/basic.js
deleted file mode 100644
index ae7ac73c..00000000
--- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/basic.js
+++ /dev/null
@@ -1,399 +0,0 @@
-// http://www.bashcookbook.com/bashinfo/source/bash-1.14.7/tests/glob-test
-//
-// TODO: Some of these tests do very bad things with backslashes, and will
-// most likely fail badly on windows. They should probably be skipped.
-
-var tap = require("tap")
- , globalBefore = Object.keys(global)
- , mm = require("../")
- , files = [ "a", "b", "c", "d", "abc"
- , "abd", "abe", "bb", "bcd"
- , "ca", "cb", "dd", "de"
- , "bdir/", "bdir/cfile"]
- , next = files.concat([ "a-b", "aXb"
- , ".x", ".y" ])
-
-
-var patterns =
- [ "http://www.bashcookbook.com/bashinfo/source/bash-1.14.7/tests/glob-test"
- , ["a*", ["a", "abc", "abd", "abe"]]
- , ["X*", ["X*"], {nonull: true}]
-
- // allow null glob expansion
- , ["X*", []]
-
- // isaacs: Slightly different than bash/sh/ksh
- // \\* is not un-escaped to literal "*" in a failed match,
- // but it does make it get treated as a literal star
- , ["\\*", ["\\*"], {nonull: true}]
- , ["\\**", ["\\**"], {nonull: true}]
- , ["\\*\\*", ["\\*\\*"], {nonull: true}]
-
- , ["b*/", ["bdir/"]]
- , ["c*", ["c", "ca", "cb"]]
- , ["**", files]
-
- , ["\\.\\./*/", ["\\.\\./*/"], {nonull: true}]
- , ["s/\\..*//", ["s/\\..*//"], {nonull: true}]
-
- , "legendary larry crashes bashes"
- , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\\1/"
- , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\\1/"], {nonull: true}]
- , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\1/"
- , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\1/"], {nonull: true}]
-
- , "character classes"
- , ["[a-c]b*", ["abc", "abd", "abe", "bb", "cb"]]
- , ["[a-y]*[^c]", ["abd", "abe", "bb", "bcd",
- "bdir/", "ca", "cb", "dd", "de"]]
- , ["a*[^c]", ["abd", "abe"]]
- , function () { files.push("a-b", "aXb") }
- , ["a[X-]b", ["a-b", "aXb"]]
- , function () { files.push(".x", ".y") }
- , ["[^a-c]*", ["d", "dd", "de"]]
- , function () { files.push("a*b/", "a*b/ooo") }
- , ["a\\*b/*", ["a*b/ooo"]]
- , ["a\\*?/*", ["a*b/ooo"]]
- , ["*\\\\!*", [], {null: true}, ["echo !7"]]
- , ["*\\!*", ["echo !7"], null, ["echo !7"]]
- , ["*.\\*", ["r.*"], null, ["r.*"]]
- , ["a[b]c", ["abc"]]
- , ["a[\\b]c", ["abc"]]
- , ["a?c", ["abc"]]
- , ["a\\*c", [], {null: true}, ["abc"]]
- , ["", [""], { null: true }, [""]]
-
- , "http://www.opensource.apple.com/source/bash/bash-23/" +
- "bash/tests/glob-test"
- , function () { files.push("man/", "man/man1/", "man/man1/bash.1") }
- , ["*/man*/bash.*", ["man/man1/bash.1"]]
- , ["man/man1/bash.1", ["man/man1/bash.1"]]
- , ["a***c", ["abc"], null, ["abc"]]
- , ["a*****?c", ["abc"], null, ["abc"]]
- , ["?*****??", ["abc"], null, ["abc"]]
- , ["*****??", ["abc"], null, ["abc"]]
- , ["?*****?c", ["abc"], null, ["abc"]]
- , ["?***?****c", ["abc"], null, ["abc"]]
- , ["?***?****?", ["abc"], null, ["abc"]]
- , ["?***?****", ["abc"], null, ["abc"]]
- , ["*******c", ["abc"], null, ["abc"]]
- , ["*******?", ["abc"], null, ["abc"]]
- , ["a*cd**?**??k", ["abcdecdhjk"], null, ["abcdecdhjk"]]
- , ["a**?**cd**?**??k", ["abcdecdhjk"], null, ["abcdecdhjk"]]
- , ["a**?**cd**?**??k***", ["abcdecdhjk"], null, ["abcdecdhjk"]]
- , ["a**?**cd**?**??***k", ["abcdecdhjk"], null, ["abcdecdhjk"]]
- , ["a**?**cd**?**??***k**", ["abcdecdhjk"], null, ["abcdecdhjk"]]
- , ["a****c**?**??*****", ["abcdecdhjk"], null, ["abcdecdhjk"]]
- , ["[-abc]", ["-"], null, ["-"]]
- , ["[abc-]", ["-"], null, ["-"]]
- , ["\\", ["\\"], null, ["\\"]]
- , ["[\\\\]", ["\\"], null, ["\\"]]
- , ["[[]", ["["], null, ["["]]
- , ["[", ["["], null, ["["]]
- , ["[*", ["[abc"], null, ["[abc"]]
- , "a right bracket shall lose its special meaning and\n" +
- "represent itself in a bracket expression if it occurs\n" +
- "first in the list. -- POSIX.2 2.8.3.2"
- , ["[]]", ["]"], null, ["]"]]
- , ["[]-]", ["]"], null, ["]"]]
- , ["[a-\z]", ["p"], null, ["p"]]
- , ["??**********?****?", [], { null: true }, ["abc"]]
- , ["??**********?****c", [], { null: true }, ["abc"]]
- , ["?************c****?****", [], { null: true }, ["abc"]]
- , ["*c*?**", [], { null: true }, ["abc"]]
- , ["a*****c*?**", [], { null: true }, ["abc"]]
- , ["a********???*******", [], { null: true }, ["abc"]]
- , ["[]", [], { null: true }, ["a"]]
- , ["[abc", [], { null: true }, ["["]]
-
- , "nocase tests"
- , ["XYZ", ["xYz"], { nocase: true, null: true }
- , ["xYz", "ABC", "IjK"]]
- , ["ab*", ["ABC"], { nocase: true, null: true }
- , ["xYz", "ABC", "IjK"]]
- , ["[ia]?[ck]", ["ABC", "IjK"], { nocase: true, null: true }
- , ["xYz", "ABC", "IjK"]]
-
- // [ pattern, [matches], MM opts, files, TAP opts]
- , "onestar/twostar"
- , ["{/*,*}", [], {null: true}, ["/asdf/asdf/asdf"]]
- , ["{/?,*}", ["/a", "bb"], {null: true}
- , ["/a", "/b/b", "/a/b/c", "bb"]]
-
- , "dots should not match unless requested"
- , ["**", ["a/b"], {}, ["a/b", "a/.d", ".a/.d"]]
-
- // .. and . can only match patterns starting with .,
- // even when options.dot is set.
- , function () {
- files = ["a/./b", "a/../b", "a/c/b", "a/.d/b"]
- }
- , ["a/*/b", ["a/c/b", "a/.d/b"], {dot: true}]
- , ["a/.*/b", ["a/./b", "a/../b", "a/.d/b"], {dot: true}]
- , ["a/*/b", ["a/c/b"], {dot:false}]
- , ["a/.*/b", ["a/./b", "a/../b", "a/.d/b"], {dot: false}]
-
-
- // this also tests that changing the options needs
- // to change the cache key, even if the pattern is
- // the same!
- , ["**", ["a/b","a/.d",".a/.d"], { dot: true }
- , [ ".a/.d", "a/.d", "a/b"]]
-
- , "paren sets cannot contain slashes"
- , ["*(a/b)", ["*(a/b)"], {nonull: true}, ["a/b"]]
-
- // brace sets trump all else.
- //
- // invalid glob pattern. fails on bash4 and bsdglob.
- // however, in this implementation, it's easier just
- // to do the intuitive thing, and let brace-expansion
- // actually come before parsing any extglob patterns,
- // like the documentation seems to say.
- //
- // XXX: if anyone complains about this, either fix it
- // or tell them to grow up and stop complaining.
- //
- // bash/bsdglob says this:
- // , ["*(a|{b),c)}", ["*(a|{b),c)}"], {}, ["a", "ab", "ac", "ad"]]
- // but we do this instead:
- , ["*(a|{b),c)}", ["a", "ab", "ac"], {}, ["a", "ab", "ac", "ad"]]
-
- // test partial parsing in the presence of comment/negation chars
- , ["[!a*", ["[!ab"], {}, ["[!ab", "[ab"]]
- , ["[#a*", ["[#ab"], {}, ["[#ab", "[ab"]]
-
- // like: {a,b|c\\,d\\\|e} except it's unclosed, so it has to be escaped.
- , ["+(a|*\\|c\\\\|d\\\\\\|e\\\\\\\\|f\\\\\\\\\\|g"
- , ["+(a|b\\|c\\\\|d\\\\|e\\\\\\\\|f\\\\\\\\|g"]
- , {}
- , ["+(a|b\\|c\\\\|d\\\\|e\\\\\\\\|f\\\\\\\\|g", "a", "b\\c"]]
-
-
- // crazy nested {,,} and *(||) tests.
- , function () {
- files = [ "a", "b", "c", "d"
- , "ab", "ac", "ad"
- , "bc", "cb"
- , "bc,d", "c,db", "c,d"
- , "d)", "(b|c", "*(b|c"
- , "b|c", "b|cc", "cb|c"
- , "x(a|b|c)", "x(a|c)"
- , "(a|b|c)", "(a|c)"]
- }
- , ["*(a|{b,c})", ["a", "b", "c", "ab", "ac"]]
- , ["{a,*(b|c,d)}", ["a","(b|c", "*(b|c", "d)"]]
- // a
- // *(b|c)
- // *(b|d)
- , ["{a,*(b|{c,d})}", ["a","b", "bc", "cb", "c", "d"]]
- , ["*(a|{b|c,c})", ["a", "b", "c", "ab", "ac", "bc", "cb"]]
-
-
- // test various flag settings.
- , [ "*(a|{b|c,c})", ["x(a|b|c)", "x(a|c)", "(a|b|c)", "(a|c)"]
- , { noext: true } ]
- , ["a?b", ["x/y/acb", "acb/"], {matchBase: true}
- , ["x/y/acb", "acb/", "acb/d/e", "x/y/acb/d"] ]
- , ["#*", ["#a", "#b"], {nocomment: true}, ["#a", "#b", "c#d"]]
-
-
- // begin channelling Boole and deMorgan...
- , "negation tests"
- , function () {
- files = ["d", "e", "!ab", "!abc", "a!b", "\\!a"]
- }
-
- // anything that is NOT a* matches.
- , ["!a*", ["\\!a", "d", "e", "!ab", "!abc"]]
-
- // anything that IS !a* matches.
- , ["!a*", ["!ab", "!abc"], {nonegate: true}]
-
- // anything that IS a* matches
- , ["!!a*", ["a!b"]]
-
- // anything that is NOT !a* matches
- , ["!\\!a*", ["a!b", "d", "e", "\\!a"]]
-
- // negation nestled within a pattern
- , function () {
- files = [ "foo.js"
- , "foo.bar"
- // can't match this one without negative lookbehind.
- , "foo.js.js"
- , "blar.js"
- , "foo."
- , "boo.js.boo" ]
- }
- , ["*.!(js)", ["foo.bar", "foo.", "boo.js.boo"] ]
-
- // https://github.com/isaacs/minimatch/issues/5
- , function () {
- files = [ 'a/b/.x/c'
- , 'a/b/.x/c/d'
- , 'a/b/.x/c/d/e'
- , 'a/b/.x'
- , 'a/b/.x/'
- , 'a/.x/b'
- , '.x'
- , '.x/'
- , '.x/a'
- , '.x/a/b'
- , 'a/.x/b/.x/c'
- , '.x/.x' ]
- }
- , ["**/.x/**", [ '.x/'
- , '.x/a'
- , '.x/a/b'
- , 'a/.x/b'
- , 'a/b/.x/'
- , 'a/b/.x/c'
- , 'a/b/.x/c/d'
- , 'a/b/.x/c/d/e' ] ]
-
- ]
-
-var regexps =
- [ '/^(?:(?=.)a[^/]*?)$/',
- '/^(?:(?=.)X[^/]*?)$/',
- '/^(?:(?=.)X[^/]*?)$/',
- '/^(?:\\*)$/',
- '/^(?:(?=.)\\*[^/]*?)$/',
- '/^(?:\\*\\*)$/',
- '/^(?:(?=.)b[^/]*?\\/)$/',
- '/^(?:(?=.)c[^/]*?)$/',
- '/^(?:(?:(?!(?:\\/|^)\\.).)*?)$/',
- '/^(?:\\.\\.\\/(?!\\.)(?=.)[^/]*?\\/)$/',
- '/^(?:s\\/(?=.)\\.\\.[^/]*?\\/)$/',
- '/^(?:\\/\\^root:\\/\\{s\\/(?=.)\\^[^:][^/]*?:[^:][^/]*?:\\([^:]\\)[^/]*?\\.[^/]*?\\$\\/1\\/)$/',
- '/^(?:\\/\\^root:\\/\\{s\\/(?=.)\\^[^:][^/]*?:[^:][^/]*?:\\([^:]\\)[^/]*?\\.[^/]*?\\$\\/\u0001\\/)$/',
- '/^(?:(?!\\.)(?=.)[a-c]b[^/]*?)$/',
- '/^(?:(?!\\.)(?=.)[a-y][^/]*?[^c])$/',
- '/^(?:(?=.)a[^/]*?[^c])$/',
- '/^(?:(?=.)a[X-]b)$/',
- '/^(?:(?!\\.)(?=.)[^a-c][^/]*?)$/',
- '/^(?:a\\*b\\/(?!\\.)(?=.)[^/]*?)$/',
- '/^(?:(?=.)a\\*[^/]\\/(?!\\.)(?=.)[^/]*?)$/',
- '/^(?:(?!\\.)(?=.)[^/]*?\\\\\\![^/]*?)$/',
- '/^(?:(?!\\.)(?=.)[^/]*?\\![^/]*?)$/',
- '/^(?:(?!\\.)(?=.)[^/]*?\\.\\*)$/',
- '/^(?:(?=.)a[b]c)$/',
- '/^(?:(?=.)a[b]c)$/',
- '/^(?:(?=.)a[^/]c)$/',
- '/^(?:a\\*c)$/',
- 'false',
- '/^(?:(?!\\.)(?=.)[^/]*?\\/(?=.)man[^/]*?\\/(?=.)bash\\.[^/]*?)$/',
- '/^(?:man\\/man1\\/bash\\.1)$/',
- '/^(?:(?=.)a[^/]*?[^/]*?[^/]*?c)$/',
- '/^(?:(?=.)a[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]c)$/',
- '/^(?:(?!\\.)(?=.)[^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/][^/])$/',
- '/^(?:(?!\\.)(?=.)[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/][^/])$/',
- '/^(?:(?!\\.)(?=.)[^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]c)$/',
- '/^(?:(?!\\.)(?=.)[^/][^/]*?[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/]*?[^/]*?c)$/',
- '/^(?:(?!\\.)(?=.)[^/][^/]*?[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/]*?[^/]*?[^/])$/',
- '/^(?:(?!\\.)(?=.)[^/][^/]*?[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/]*?[^/]*?)$/',
- '/^(?:(?!\\.)(?=.)[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?c)$/',
- '/^(?:(?!\\.)(?=.)[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/])$/',
- '/^(?:(?=.)a[^/]*?cd[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/][^/]k)$/',
- '/^(?:(?=.)a[^/]*?[^/]*?[^/][^/]*?[^/]*?cd[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/][^/]k)$/',
- '/^(?:(?=.)a[^/]*?[^/]*?[^/][^/]*?[^/]*?cd[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/][^/]k[^/]*?[^/]*?[^/]*?)$/',
- '/^(?:(?=.)a[^/]*?[^/]*?[^/][^/]*?[^/]*?cd[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/][^/][^/]*?[^/]*?[^/]*?k)$/',
- '/^(?:(?=.)a[^/]*?[^/]*?[^/][^/]*?[^/]*?cd[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/][^/][^/]*?[^/]*?[^/]*?k[^/]*?[^/]*?)$/',
- '/^(?:(?=.)a[^/]*?[^/]*?[^/]*?[^/]*?c[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/][^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?)$/',
- '/^(?:(?!\\.)(?=.)[-abc])$/',
- '/^(?:(?!\\.)(?=.)[abc-])$/',
- '/^(?:\\\\)$/',
- '/^(?:(?!\\.)(?=.)[\\\\])$/',
- '/^(?:(?!\\.)(?=.)[\\[])$/',
- '/^(?:\\[)$/',
- '/^(?:(?=.)\\[(?!\\.)(?=.)[^/]*?)$/',
- '/^(?:(?!\\.)(?=.)[\\]])$/',
- '/^(?:(?!\\.)(?=.)[\\]-])$/',
- '/^(?:(?!\\.)(?=.)[a-z])$/',
- '/^(?:(?!\\.)(?=.)[^/][^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/]*?[^/]*?[^/])$/',
- '/^(?:(?!\\.)(?=.)[^/][^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/]*?[^/]*?c)$/',
- '/^(?:(?!\\.)(?=.)[^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?c[^/]*?[^/]*?[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/]*?[^/]*?)$/',
- '/^(?:(?!\\.)(?=.)[^/]*?c[^/]*?[^/][^/]*?[^/]*?)$/',
- '/^(?:(?=.)a[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?c[^/]*?[^/][^/]*?[^/]*?)$/',
- '/^(?:(?=.)a[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/][^/][^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?)$/',
- '/^(?:\\[\\])$/',
- '/^(?:\\[abc)$/',
- '/^(?:(?=.)XYZ)$/i',
- '/^(?:(?=.)ab[^/]*?)$/i',
- '/^(?:(?!\\.)(?=.)[ia][^/][ck])$/i',
- '/^(?:\\/(?!\\.)(?=.)[^/]*?|(?!\\.)(?=.)[^/]*?)$/',
- '/^(?:\\/(?!\\.)(?=.)[^/]|(?!\\.)(?=.)[^/]*?)$/',
- '/^(?:(?:(?!(?:\\/|^)\\.).)*?)$/',
- '/^(?:a\\/(?!(?:^|\\/)\\.{1,2}(?:$|\\/))(?=.)[^/]*?\\/b)$/',
- '/^(?:a\\/(?=.)\\.[^/]*?\\/b)$/',
- '/^(?:a\\/(?!\\.)(?=.)[^/]*?\\/b)$/',
- '/^(?:a\\/(?=.)\\.[^/]*?\\/b)$/',
- '/^(?:(?:(?!(?:\\/|^)(?:\\.{1,2})($|\\/)).)*?)$/',
- '/^(?:(?!\\.)(?=.)[^/]*?\\(a\\/b\\))$/',
- '/^(?:(?!\\.)(?=.)(?:a|b)*|(?!\\.)(?=.)(?:a|c)*)$/',
- '/^(?:(?=.)\\[(?=.)\\!a[^/]*?)$/',
- '/^(?:(?=.)\\[(?=.)#a[^/]*?)$/',
- '/^(?:(?=.)\\+\\(a\\|[^/]*?\\|c\\\\\\\\\\|d\\\\\\\\\\|e\\\\\\\\\\\\\\\\\\|f\\\\\\\\\\\\\\\\\\|g)$/',
- '/^(?:(?!\\.)(?=.)(?:a|b)*|(?!\\.)(?=.)(?:a|c)*)$/',
- '/^(?:a|(?!\\.)(?=.)[^/]*?\\(b\\|c|d\\))$/',
- '/^(?:a|(?!\\.)(?=.)(?:b|c)*|(?!\\.)(?=.)(?:b|d)*)$/',
- '/^(?:(?!\\.)(?=.)(?:a|b|c)*|(?!\\.)(?=.)(?:a|c)*)$/',
- '/^(?:(?!\\.)(?=.)[^/]*?\\(a\\|b\\|c\\)|(?!\\.)(?=.)[^/]*?\\(a\\|c\\))$/',
- '/^(?:(?=.)a[^/]b)$/',
- '/^(?:(?=.)#[^/]*?)$/',
- '/^(?!^(?:(?=.)a[^/]*?)$).*$/',
- '/^(?:(?=.)\\!a[^/]*?)$/',
- '/^(?:(?=.)a[^/]*?)$/',
- '/^(?!^(?:(?=.)\\!a[^/]*?)$).*$/',
- '/^(?:(?!\\.)(?=.)[^/]*?\\.(?:(?!js)[^/]*?))$/',
- '/^(?:(?:(?!(?:\\/|^)\\.).)*?\\/\\.x\\/(?:(?!(?:\\/|^)\\.).)*?)$/' ]
-var re = 0;
-
-tap.test("basic tests", function (t) {
- var start = Date.now()
-
- // [ pattern, [matches], MM opts, files, TAP opts]
- patterns.forEach(function (c) {
- if (typeof c === "function") return c()
- if (typeof c === "string") return t.comment(c)
-
- var pattern = c[0]
- , expect = c[1].sort(alpha)
- , options = c[2] || {}
- , f = c[3] || files
- , tapOpts = c[4] || {}
-
- // options.debug = true
- var m = new mm.Minimatch(pattern, options)
- var r = m.makeRe()
- var expectRe = regexps[re++]
- tapOpts.re = String(r) || JSON.stringify(r)
- tapOpts.files = JSON.stringify(f)
- tapOpts.pattern = pattern
- tapOpts.set = m.set
- tapOpts.negated = m.negate
-
- var actual = mm.match(f, pattern, options)
- actual.sort(alpha)
-
- t.equivalent( actual, expect
- , JSON.stringify(pattern) + " " + JSON.stringify(expect)
- , tapOpts )
-
- t.equal(tapOpts.re, expectRe, tapOpts)
- })
-
- t.comment("time=" + (Date.now() - start) + "ms")
- t.end()
-})
-
-tap.test("global leak test", function (t) {
- var globalAfter = Object.keys(global)
- t.equivalent(globalAfter, globalBefore, "no new globals, please")
- t.end()
-})
-
-function alpha (a, b) {
- return a > b ? 1 : -1
-}
diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/brace-expand.js b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/brace-expand.js
deleted file mode 100644
index 7ee278a2..00000000
--- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/brace-expand.js
+++ /dev/null
@@ -1,33 +0,0 @@
-var tap = require("tap")
- , minimatch = require("../")
-
-tap.test("brace expansion", function (t) {
- // [ pattern, [expanded] ]
- ; [ [ "a{b,c{d,e},{f,g}h}x{y,z}"
- , [ "abxy"
- , "abxz"
- , "acdxy"
- , "acdxz"
- , "acexy"
- , "acexz"
- , "afhxy"
- , "afhxz"
- , "aghxy"
- , "aghxz" ] ]
- , [ "a{1..5}b"
- , [ "a1b"
- , "a2b"
- , "a3b"
- , "a4b"
- , "a5b" ] ]
- , [ "a{b}c", ["a{b}c"] ]
- ].forEach(function (tc) {
- var p = tc[0]
- , expect = tc[1]
- t.equivalent(minimatch.braceExpand(p), expect, p)
- })
- console.error("ending")
- t.end()
-})
-
-
diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/caching.js b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/caching.js
deleted file mode 100644
index 0fec4b0f..00000000
--- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/caching.js
+++ /dev/null
@@ -1,14 +0,0 @@
-var Minimatch = require("../minimatch.js").Minimatch
-var tap = require("tap")
-tap.test("cache test", function (t) {
- var mm1 = new Minimatch("a?b")
- var mm2 = new Minimatch("a?b")
- t.equal(mm1, mm2, "should get the same object")
- // the lru should drop it after 100 entries
- for (var i = 0; i < 100; i ++) {
- new Minimatch("a"+i)
- }
- mm2 = new Minimatch("a?b")
- t.notEqual(mm1, mm2, "cache should have dropped")
- t.end()
-})
diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/defaults.js b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/defaults.js
deleted file mode 100644
index 75e05712..00000000
--- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/defaults.js
+++ /dev/null
@@ -1,274 +0,0 @@
-// http://www.bashcookbook.com/bashinfo/source/bash-1.14.7/tests/glob-test
-//
-// TODO: Some of these tests do very bad things with backslashes, and will
-// most likely fail badly on windows. They should probably be skipped.
-
-var tap = require("tap")
- , globalBefore = Object.keys(global)
- , mm = require("../")
- , files = [ "a", "b", "c", "d", "abc"
- , "abd", "abe", "bb", "bcd"
- , "ca", "cb", "dd", "de"
- , "bdir/", "bdir/cfile"]
- , next = files.concat([ "a-b", "aXb"
- , ".x", ".y" ])
-
-tap.test("basic tests", function (t) {
- var start = Date.now()
-
- // [ pattern, [matches], MM opts, files, TAP opts]
- ; [ "http://www.bashcookbook.com/bashinfo" +
- "/source/bash-1.14.7/tests/glob-test"
- , ["a*", ["a", "abc", "abd", "abe"]]
- , ["X*", ["X*"], {nonull: true}]
-
- // allow null glob expansion
- , ["X*", []]
-
- // isaacs: Slightly different than bash/sh/ksh
- // \\* is not un-escaped to literal "*" in a failed match,
- // but it does make it get treated as a literal star
- , ["\\*", ["\\*"], {nonull: true}]
- , ["\\**", ["\\**"], {nonull: true}]
- , ["\\*\\*", ["\\*\\*"], {nonull: true}]
-
- , ["b*/", ["bdir/"]]
- , ["c*", ["c", "ca", "cb"]]
- , ["**", files]
-
- , ["\\.\\./*/", ["\\.\\./*/"], {nonull: true}]
- , ["s/\\..*//", ["s/\\..*//"], {nonull: true}]
-
- , "legendary larry crashes bashes"
- , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\\1/"
- , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\\1/"], {nonull: true}]
- , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\1/"
- , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\1/"], {nonull: true}]
-
- , "character classes"
- , ["[a-c]b*", ["abc", "abd", "abe", "bb", "cb"]]
- , ["[a-y]*[^c]", ["abd", "abe", "bb", "bcd",
- "bdir/", "ca", "cb", "dd", "de"]]
- , ["a*[^c]", ["abd", "abe"]]
- , function () { files.push("a-b", "aXb") }
- , ["a[X-]b", ["a-b", "aXb"]]
- , function () { files.push(".x", ".y") }
- , ["[^a-c]*", ["d", "dd", "de"]]
- , function () { files.push("a*b/", "a*b/ooo") }
- , ["a\\*b/*", ["a*b/ooo"]]
- , ["a\\*?/*", ["a*b/ooo"]]
- , ["*\\\\!*", [], {null: true}, ["echo !7"]]
- , ["*\\!*", ["echo !7"], null, ["echo !7"]]
- , ["*.\\*", ["r.*"], null, ["r.*"]]
- , ["a[b]c", ["abc"]]
- , ["a[\\b]c", ["abc"]]
- , ["a?c", ["abc"]]
- , ["a\\*c", [], {null: true}, ["abc"]]
- , ["", [""], { null: true }, [""]]
-
- , "http://www.opensource.apple.com/source/bash/bash-23/" +
- "bash/tests/glob-test"
- , function () { files.push("man/", "man/man1/", "man/man1/bash.1") }
- , ["*/man*/bash.*", ["man/man1/bash.1"]]
- , ["man/man1/bash.1", ["man/man1/bash.1"]]
- , ["a***c", ["abc"], null, ["abc"]]
- , ["a*****?c", ["abc"], null, ["abc"]]
- , ["?*****??", ["abc"], null, ["abc"]]
- , ["*****??", ["abc"], null, ["abc"]]
- , ["?*****?c", ["abc"], null, ["abc"]]
- , ["?***?****c", ["abc"], null, ["abc"]]
- , ["?***?****?", ["abc"], null, ["abc"]]
- , ["?***?****", ["abc"], null, ["abc"]]
- , ["*******c", ["abc"], null, ["abc"]]
- , ["*******?", ["abc"], null, ["abc"]]
- , ["a*cd**?**??k", ["abcdecdhjk"], null, ["abcdecdhjk"]]
- , ["a**?**cd**?**??k", ["abcdecdhjk"], null, ["abcdecdhjk"]]
- , ["a**?**cd**?**??k***", ["abcdecdhjk"], null, ["abcdecdhjk"]]
- , ["a**?**cd**?**??***k", ["abcdecdhjk"], null, ["abcdecdhjk"]]
- , ["a**?**cd**?**??***k**", ["abcdecdhjk"], null, ["abcdecdhjk"]]
- , ["a****c**?**??*****", ["abcdecdhjk"], null, ["abcdecdhjk"]]
- , ["[-abc]", ["-"], null, ["-"]]
- , ["[abc-]", ["-"], null, ["-"]]
- , ["\\", ["\\"], null, ["\\"]]
- , ["[\\\\]", ["\\"], null, ["\\"]]
- , ["[[]", ["["], null, ["["]]
- , ["[", ["["], null, ["["]]
- , ["[*", ["[abc"], null, ["[abc"]]
- , "a right bracket shall lose its special meaning and\n" +
- "represent itself in a bracket expression if it occurs\n" +
- "first in the list. -- POSIX.2 2.8.3.2"
- , ["[]]", ["]"], null, ["]"]]
- , ["[]-]", ["]"], null, ["]"]]
- , ["[a-\z]", ["p"], null, ["p"]]
- , ["??**********?****?", [], { null: true }, ["abc"]]
- , ["??**********?****c", [], { null: true }, ["abc"]]
- , ["?************c****?****", [], { null: true }, ["abc"]]
- , ["*c*?**", [], { null: true }, ["abc"]]
- , ["a*****c*?**", [], { null: true }, ["abc"]]
- , ["a********???*******", [], { null: true }, ["abc"]]
- , ["[]", [], { null: true }, ["a"]]
- , ["[abc", [], { null: true }, ["["]]
-
- , "nocase tests"
- , ["XYZ", ["xYz"], { nocase: true, null: true }
- , ["xYz", "ABC", "IjK"]]
- , ["ab*", ["ABC"], { nocase: true, null: true }
- , ["xYz", "ABC", "IjK"]]
- , ["[ia]?[ck]", ["ABC", "IjK"], { nocase: true, null: true }
- , ["xYz", "ABC", "IjK"]]
-
- // [ pattern, [matches], MM opts, files, TAP opts]
- , "onestar/twostar"
- , ["{/*,*}", [], {null: true}, ["/asdf/asdf/asdf"]]
- , ["{/?,*}", ["/a", "bb"], {null: true}
- , ["/a", "/b/b", "/a/b/c", "bb"]]
-
- , "dots should not match unless requested"
- , ["**", ["a/b"], {}, ["a/b", "a/.d", ".a/.d"]]
-
- // .. and . can only match patterns starting with .,
- // even when options.dot is set.
- , function () {
- files = ["a/./b", "a/../b", "a/c/b", "a/.d/b"]
- }
- , ["a/*/b", ["a/c/b", "a/.d/b"], {dot: true}]
- , ["a/.*/b", ["a/./b", "a/../b", "a/.d/b"], {dot: true}]
- , ["a/*/b", ["a/c/b"], {dot:false}]
- , ["a/.*/b", ["a/./b", "a/../b", "a/.d/b"], {dot: false}]
-
-
- // this also tests that changing the options needs
- // to change the cache key, even if the pattern is
- // the same!
- , ["**", ["a/b","a/.d",".a/.d"], { dot: true }
- , [ ".a/.d", "a/.d", "a/b"]]
-
- , "paren sets cannot contain slashes"
- , ["*(a/b)", ["*(a/b)"], {nonull: true}, ["a/b"]]
-
- // brace sets trump all else.
- //
- // invalid glob pattern. fails on bash4 and bsdglob.
- // however, in this implementation, it's easier just
- // to do the intuitive thing, and let brace-expansion
- // actually come before parsing any extglob patterns,
- // like the documentation seems to say.
- //
- // XXX: if anyone complains about this, either fix it
- // or tell them to grow up and stop complaining.
- //
- // bash/bsdglob says this:
- // , ["*(a|{b),c)}", ["*(a|{b),c)}"], {}, ["a", "ab", "ac", "ad"]]
- // but we do this instead:
- , ["*(a|{b),c)}", ["a", "ab", "ac"], {}, ["a", "ab", "ac", "ad"]]
-
- // test partial parsing in the presence of comment/negation chars
- , ["[!a*", ["[!ab"], {}, ["[!ab", "[ab"]]
- , ["[#a*", ["[#ab"], {}, ["[#ab", "[ab"]]
-
- // like: {a,b|c\\,d\\\|e} except it's unclosed, so it has to be escaped.
- , ["+(a|*\\|c\\\\|d\\\\\\|e\\\\\\\\|f\\\\\\\\\\|g"
- , ["+(a|b\\|c\\\\|d\\\\|e\\\\\\\\|f\\\\\\\\|g"]
- , {}
- , ["+(a|b\\|c\\\\|d\\\\|e\\\\\\\\|f\\\\\\\\|g", "a", "b\\c"]]
-
-
- // crazy nested {,,} and *(||) tests.
- , function () {
- files = [ "a", "b", "c", "d"
- , "ab", "ac", "ad"
- , "bc", "cb"
- , "bc,d", "c,db", "c,d"
- , "d)", "(b|c", "*(b|c"
- , "b|c", "b|cc", "cb|c"
- , "x(a|b|c)", "x(a|c)"
- , "(a|b|c)", "(a|c)"]
- }
- , ["*(a|{b,c})", ["a", "b", "c", "ab", "ac"]]
- , ["{a,*(b|c,d)}", ["a","(b|c", "*(b|c", "d)"]]
- // a
- // *(b|c)
- // *(b|d)
- , ["{a,*(b|{c,d})}", ["a","b", "bc", "cb", "c", "d"]]
- , ["*(a|{b|c,c})", ["a", "b", "c", "ab", "ac", "bc", "cb"]]
-
-
- // test various flag settings.
- , [ "*(a|{b|c,c})", ["x(a|b|c)", "x(a|c)", "(a|b|c)", "(a|c)"]
- , { noext: true } ]
- , ["a?b", ["x/y/acb", "acb/"], {matchBase: true}
- , ["x/y/acb", "acb/", "acb/d/e", "x/y/acb/d"] ]
- , ["#*", ["#a", "#b"], {nocomment: true}, ["#a", "#b", "c#d"]]
-
-
- // begin channelling Boole and deMorgan...
- , "negation tests"
- , function () {
- files = ["d", "e", "!ab", "!abc", "a!b", "\\!a"]
- }
-
- // anything that is NOT a* matches.
- , ["!a*", ["\\!a", "d", "e", "!ab", "!abc"]]
-
- // anything that IS !a* matches.
- , ["!a*", ["!ab", "!abc"], {nonegate: true}]
-
- // anything that IS a* matches
- , ["!!a*", ["a!b"]]
-
- // anything that is NOT !a* matches
- , ["!\\!a*", ["a!b", "d", "e", "\\!a"]]
-
- // negation nestled within a pattern
- , function () {
- files = [ "foo.js"
- , "foo.bar"
- // can't match this one without negative lookbehind.
- , "foo.js.js"
- , "blar.js"
- , "foo."
- , "boo.js.boo" ]
- }
- , ["*.!(js)", ["foo.bar", "foo.", "boo.js.boo"] ]
-
- ].forEach(function (c) {
- if (typeof c === "function") return c()
- if (typeof c === "string") return t.comment(c)
-
- var pattern = c[0]
- , expect = c[1].sort(alpha)
- , options = c[2]
- , f = c[3] || files
- , tapOpts = c[4] || {}
-
- // options.debug = true
- var Class = mm.defaults(options).Minimatch
- var m = new Class(pattern, {})
- var r = m.makeRe()
- tapOpts.re = String(r) || JSON.stringify(r)
- tapOpts.files = JSON.stringify(f)
- tapOpts.pattern = pattern
- tapOpts.set = m.set
- tapOpts.negated = m.negate
-
- var actual = mm.match(f, pattern, options)
- actual.sort(alpha)
-
- t.equivalent( actual, expect
- , JSON.stringify(pattern) + " " + JSON.stringify(expect)
- , tapOpts )
- })
-
- t.comment("time=" + (Date.now() - start) + "ms")
- t.end()
-})
-
-tap.test("global leak test", function (t) {
- var globalAfter = Object.keys(global)
- t.equivalent(globalAfter, globalBefore, "no new globals, please")
- t.end()
-})
-
-function alpha (a, b) {
- return a > b ? 1 : -1
-}
diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/extglob-ending-with-state-char.js b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/extglob-ending-with-state-char.js
deleted file mode 100644
index 6676e262..00000000
--- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/extglob-ending-with-state-char.js
+++ /dev/null
@@ -1,8 +0,0 @@
-var test = require('tap').test
-var minimatch = require('../')
-
-test('extglob ending with statechar', function(t) {
- t.notOk(minimatch('ax', 'a?(b*)'))
- t.ok(minimatch('ax', '?(a*|b)'))
- t.end()
-})
diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/package.json b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/package.json
deleted file mode 100644
index e7ec15f3..00000000
--- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/package.json
+++ /dev/null
@@ -1,58 +0,0 @@
-{
- "author": {
- "name": "Isaac Z. Schlueter",
- "email": "i@izs.me",
- "url": "http://blog.izs.me/"
- },
- "name": "glob",
- "description": "a little globber",
- "version": "3.2.11",
- "repository": {
- "type": "git",
- "url": "git://github.com/isaacs/node-glob.git"
- },
- "main": "glob.js",
- "engines": {
- "node": "*"
- },
- "dependencies": {
- "inherits": "2",
- "minimatch": "0.3"
- },
- "devDependencies": {
- "tap": "~0.4.0",
- "mkdirp": "0",
- "rimraf": "1"
- },
- "scripts": {
- "test": "tap test/*.js",
- "test-regen": "TEST_REGEN=1 node test/00-setup.js"
- },
- "license": "BSD",
- "gitHead": "73f57e99510582b2024b762305970ebcf9b70aa2",
- "bugs": {
- "url": "https://github.com/isaacs/node-glob/issues"
- },
- "homepage": "https://github.com/isaacs/node-glob",
- "_id": "glob@3.2.11",
- "_shasum": "4a973f635b9190f715d10987d5c00fd2815ebe3d",
- "_from": "glob@~3.2.9",
- "_npmVersion": "1.4.10",
- "_npmUser": {
- "name": "isaacs",
- "email": "i@izs.me"
- },
- "maintainers": [
- {
- "name": "isaacs",
- "email": "i@izs.me"
- }
- ],
- "dist": {
- "shasum": "4a973f635b9190f715d10987d5c00fd2815ebe3d",
- "tarball": "http://registry.npmjs.org/glob/-/glob-3.2.11.tgz"
- },
- "directories": {},
- "_resolved": "https://registry.npmjs.org/glob/-/glob-3.2.11.tgz",
- "readme": "ERROR: No README data found!"
-}
diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/00-setup.js b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/00-setup.js
deleted file mode 100644
index 245afafd..00000000
--- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/00-setup.js
+++ /dev/null
@@ -1,176 +0,0 @@
-// just a little pre-run script to set up the fixtures.
-// zz-finish cleans it up
-
-var mkdirp = require("mkdirp")
-var path = require("path")
-var i = 0
-var tap = require("tap")
-var fs = require("fs")
-var rimraf = require("rimraf")
-
-var files =
-[ "a/.abcdef/x/y/z/a"
-, "a/abcdef/g/h"
-, "a/abcfed/g/h"
-, "a/b/c/d"
-, "a/bc/e/f"
-, "a/c/d/c/b"
-, "a/cb/e/f"
-]
-
-var symlinkTo = path.resolve(__dirname, "a/symlink/a/b/c")
-var symlinkFrom = "../.."
-
-files = files.map(function (f) {
- return path.resolve(__dirname, f)
-})
-
-tap.test("remove fixtures", function (t) {
- rimraf(path.resolve(__dirname, "a"), function (er) {
- t.ifError(er, "remove fixtures")
- t.end()
- })
-})
-
-files.forEach(function (f) {
- tap.test(f, function (t) {
- var d = path.dirname(f)
- mkdirp(d, 0755, function (er) {
- if (er) {
- t.fail(er)
- return t.bailout()
- }
- fs.writeFile(f, "i like tests", function (er) {
- t.ifError(er, "make file")
- t.end()
- })
- })
- })
-})
-
-if (process.platform !== "win32") {
- tap.test("symlinky", function (t) {
- var d = path.dirname(symlinkTo)
- console.error("mkdirp", d)
- mkdirp(d, 0755, function (er) {
- t.ifError(er)
- fs.symlink(symlinkFrom, symlinkTo, "dir", function (er) {
- t.ifError(er, "make symlink")
- t.end()
- })
- })
- })
-}
-
-;["foo","bar","baz","asdf","quux","qwer","rewq"].forEach(function (w) {
- w = "/tmp/glob-test/" + w
- tap.test("create " + w, function (t) {
- mkdirp(w, function (er) {
- if (er)
- throw er
- t.pass(w)
- t.end()
- })
- })
-})
-
-
-// generate the bash pattern test-fixtures if possible
-if (process.platform === "win32" || !process.env.TEST_REGEN) {
- console.error("Windows, or TEST_REGEN unset. Using cached fixtures.")
- return
-}
-
-var spawn = require("child_process").spawn;
-var globs =
- // put more patterns here.
- // anything that would be directly in / should be in /tmp/glob-test
- ["test/a/*/+(c|g)/./d"
- ,"test/a/**/[cg]/../[cg]"
- ,"test/a/{b,c,d,e,f}/**/g"
- ,"test/a/b/**"
- ,"test/**/g"
- ,"test/a/abc{fed,def}/g/h"
- ,"test/a/abc{fed/g,def}/**/"
- ,"test/a/abc{fed/g,def}/**///**/"
- ,"test/**/a/**/"
- ,"test/+(a|b|c)/a{/,bc*}/**"
- ,"test/*/*/*/f"
- ,"test/**/f"
- ,"test/a/symlink/a/b/c/a/b/c/a/b/c//a/b/c////a/b/c/**/b/c/**"
- ,"{./*/*,/tmp/glob-test/*}"
- ,"{/tmp/glob-test/*,*}" // evil owl face! how you taunt me!
- ,"test/a/!(symlink)/**"
- ]
-var bashOutput = {}
-var fs = require("fs")
-
-globs.forEach(function (pattern) {
- tap.test("generate fixture " + pattern, function (t) {
- var cmd = "shopt -s globstar && " +
- "shopt -s extglob && " +
- "shopt -s nullglob && " +
- // "shopt >&2; " +
- "eval \'for i in " + pattern + "; do echo $i; done\'"
- var cp = spawn("bash", ["-c", cmd], { cwd: path.dirname(__dirname) })
- var out = []
- cp.stdout.on("data", function (c) {
- out.push(c)
- })
- cp.stderr.pipe(process.stderr)
- cp.on("close", function (code) {
- out = flatten(out)
- if (!out)
- out = []
- else
- out = cleanResults(out.split(/\r*\n/))
-
- bashOutput[pattern] = out
- t.notOk(code, "bash test should finish nicely")
- t.end()
- })
- })
-})
-
-tap.test("save fixtures", function (t) {
- var fname = path.resolve(__dirname, "bash-results.json")
- var data = JSON.stringify(bashOutput, null, 2) + "\n"
- fs.writeFile(fname, data, function (er) {
- t.ifError(er)
- t.end()
- })
-})
-
-function cleanResults (m) {
- // normalize discrepancies in ordering, duplication,
- // and ending slashes.
- return m.map(function (m) {
- return m.replace(/\/+/g, "/").replace(/\/$/, "")
- }).sort(alphasort).reduce(function (set, f) {
- if (f !== set[set.length - 1]) set.push(f)
- return set
- }, []).sort(alphasort).map(function (f) {
- // de-windows
- return (process.platform !== 'win32') ? f
- : f.replace(/^[a-zA-Z]:\\\\/, '/').replace(/\\/g, '/')
- })
-}
-
-function flatten (chunks) {
- var s = 0
- chunks.forEach(function (c) { s += c.length })
- var out = new Buffer(s)
- s = 0
- chunks.forEach(function (c) {
- c.copy(out, s)
- s += c.length
- })
-
- return out.toString().trim()
-}
-
-function alphasort (a, b) {
- a = a.toLowerCase()
- b = b.toLowerCase()
- return a > b ? 1 : a < b ? -1 : 0
-}
diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/bash-comparison.js b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/bash-comparison.js
deleted file mode 100644
index 239ed1a9..00000000
--- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/bash-comparison.js
+++ /dev/null
@@ -1,63 +0,0 @@
-// basic test
-// show that it does the same thing by default as the shell.
-var tap = require("tap")
-, child_process = require("child_process")
-, bashResults = require("./bash-results.json")
-, globs = Object.keys(bashResults)
-, glob = require("../")
-, path = require("path")
-
-// run from the root of the project
-// this is usually where you're at anyway, but be sure.
-process.chdir(path.resolve(__dirname, ".."))
-
-function alphasort (a, b) {
- a = a.toLowerCase()
- b = b.toLowerCase()
- return a > b ? 1 : a < b ? -1 : 0
-}
-
-globs.forEach(function (pattern) {
- var expect = bashResults[pattern]
- // anything regarding the symlink thing will fail on windows, so just skip it
- if (process.platform === "win32" &&
- expect.some(function (m) {
- return /\/symlink\//.test(m)
- }))
- return
-
- tap.test(pattern, function (t) {
- glob(pattern, function (er, matches) {
- if (er)
- throw er
-
- // sort and unmark, just to match the shell results
- matches = cleanResults(matches)
-
- t.deepEqual(matches, expect, pattern)
- t.end()
- })
- })
-
- tap.test(pattern + " sync", function (t) {
- var matches = cleanResults(glob.sync(pattern))
-
- t.deepEqual(matches, expect, "should match shell")
- t.end()
- })
-})
-
-function cleanResults (m) {
- // normalize discrepancies in ordering, duplication,
- // and ending slashes.
- return m.map(function (m) {
- return m.replace(/\/+/g, "/").replace(/\/$/, "")
- }).sort(alphasort).reduce(function (set, f) {
- if (f !== set[set.length - 1]) set.push(f)
- return set
- }, []).sort(alphasort).map(function (f) {
- // de-windows
- return (process.platform !== 'win32') ? f
- : f.replace(/^[a-zA-Z]:[\/\\]+/, '/').replace(/[\\\/]+/g, '/')
- })
-}
diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/bash-results.json b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/bash-results.json
deleted file mode 100644
index 8051c723..00000000
--- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/bash-results.json
+++ /dev/null
@@ -1,351 +0,0 @@
-{
- "test/a/*/+(c|g)/./d": [
- "test/a/b/c/./d"
- ],
- "test/a/**/[cg]/../[cg]": [
- "test/a/abcdef/g/../g",
- "test/a/abcfed/g/../g",
- "test/a/b/c/../c",
- "test/a/c/../c",
- "test/a/c/d/c/../c",
- "test/a/symlink/a/b/c/../c",
- "test/a/symlink/a/b/c/a/b/c/../c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/../c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/../c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c"
- ],
- "test/a/{b,c,d,e,f}/**/g": [],
- "test/a/b/**": [
- "test/a/b",
- "test/a/b/c",
- "test/a/b/c/d"
- ],
- "test/**/g": [
- "test/a/abcdef/g",
- "test/a/abcfed/g"
- ],
- "test/a/abc{fed,def}/g/h": [
- "test/a/abcdef/g/h",
- "test/a/abcfed/g/h"
- ],
- "test/a/abc{fed/g,def}/**/": [
- "test/a/abcdef",
- "test/a/abcdef/g",
- "test/a/abcfed/g"
- ],
- "test/a/abc{fed/g,def}/**///**/": [
- "test/a/abcdef",
- "test/a/abcdef/g",
- "test/a/abcfed/g"
- ],
- "test/**/a/**/": [
- "test/a",
- "test/a/abcdef",
- "test/a/abcdef/g",
- "test/a/abcfed",
- "test/a/abcfed/g",
- "test/a/b",
- "test/a/b/c",
- "test/a/bc",
- "test/a/bc/e",
- "test/a/c",
- "test/a/c/d",
- "test/a/c/d/c",
- "test/a/cb",
- "test/a/cb/e",
- "test/a/symlink",
- "test/a/symlink/a",
- "test/a/symlink/a/b",
- "test/a/symlink/a/b/c",
- "test/a/symlink/a/b/c/a",
- "test/a/symlink/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b"
- ],
- "test/+(a|b|c)/a{/,bc*}/**": [
- "test/a/abcdef",
- "test/a/abcdef/g",
- "test/a/abcdef/g/h",
- "test/a/abcfed",
- "test/a/abcfed/g",
- "test/a/abcfed/g/h"
- ],
- "test/*/*/*/f": [
- "test/a/bc/e/f",
- "test/a/cb/e/f"
- ],
- "test/**/f": [
- "test/a/bc/e/f",
- "test/a/cb/e/f"
- ],
- "test/a/symlink/a/b/c/a/b/c/a/b/c//a/b/c////a/b/c/**/b/c/**": [
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c"
- ],
- "{./*/*,/tmp/glob-test/*}": [
- "./examples/g.js",
- "./examples/usr-local.js",
- "./node_modules/inherits",
- "./node_modules/minimatch",
- "./node_modules/mkdirp",
- "./node_modules/rimraf",
- "./node_modules/tap",
- "./test/00-setup.js",
- "./test/a",
- "./test/bash-comparison.js",
- "./test/bash-results.json",
- "./test/cwd-test.js",
- "./test/globstar-match.js",
- "./test/mark.js",
- "./test/new-glob-optional-options.js",
- "./test/nocase-nomagic.js",
- "./test/pause-resume.js",
- "./test/readme-issue.js",
- "./test/root-nomount.js",
- "./test/root.js",
- "./test/stat.js",
- "./test/zz-cleanup.js",
- "/tmp/glob-test/asdf",
- "/tmp/glob-test/bar",
- "/tmp/glob-test/baz",
- "/tmp/glob-test/foo",
- "/tmp/glob-test/quux",
- "/tmp/glob-test/qwer",
- "/tmp/glob-test/rewq"
- ],
- "{/tmp/glob-test/*,*}": [
- "/tmp/glob-test/asdf",
- "/tmp/glob-test/bar",
- "/tmp/glob-test/baz",
- "/tmp/glob-test/foo",
- "/tmp/glob-test/quux",
- "/tmp/glob-test/qwer",
- "/tmp/glob-test/rewq",
- "examples",
- "glob.js",
- "LICENSE",
- "node_modules",
- "package.json",
- "README.md",
- "test"
- ],
- "test/a/!(symlink)/**": [
- "test/a/abcdef",
- "test/a/abcdef/g",
- "test/a/abcdef/g/h",
- "test/a/abcfed",
- "test/a/abcfed/g",
- "test/a/abcfed/g/h",
- "test/a/b",
- "test/a/b/c",
- "test/a/b/c/d",
- "test/a/bc",
- "test/a/bc/e",
- "test/a/bc/e/f",
- "test/a/c",
- "test/a/c/d",
- "test/a/c/d/c",
- "test/a/c/d/c/b",
- "test/a/cb",
- "test/a/cb/e",
- "test/a/cb/e/f"
- ]
-}
diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/cwd-test.js b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/cwd-test.js
deleted file mode 100644
index 352c27ef..00000000
--- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/cwd-test.js
+++ /dev/null
@@ -1,55 +0,0 @@
-var tap = require("tap")
-
-var origCwd = process.cwd()
-process.chdir(__dirname)
-
-tap.test("changing cwd and searching for **/d", function (t) {
- var glob = require('../')
- var path = require('path')
- t.test('.', function (t) {
- glob('**/d', function (er, matches) {
- t.ifError(er)
- t.like(matches, [ 'a/b/c/d', 'a/c/d' ])
- t.end()
- })
- })
-
- t.test('a', function (t) {
- glob('**/d', {cwd:path.resolve('a')}, function (er, matches) {
- t.ifError(er)
- t.like(matches, [ 'b/c/d', 'c/d' ])
- t.end()
- })
- })
-
- t.test('a/b', function (t) {
- glob('**/d', {cwd:path.resolve('a/b')}, function (er, matches) {
- t.ifError(er)
- t.like(matches, [ 'c/d' ])
- t.end()
- })
- })
-
- t.test('a/b/', function (t) {
- glob('**/d', {cwd:path.resolve('a/b/')}, function (er, matches) {
- t.ifError(er)
- t.like(matches, [ 'c/d' ])
- t.end()
- })
- })
-
- t.test('.', function (t) {
- glob('**/d', {cwd: process.cwd()}, function (er, matches) {
- t.ifError(er)
- t.like(matches, [ 'a/b/c/d', 'a/c/d' ])
- t.end()
- })
- })
-
- t.test('cd -', function (t) {
- process.chdir(origCwd)
- t.end()
- })
-
- t.end()
-})
diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/globstar-match.js b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/globstar-match.js
deleted file mode 100644
index 9b234fa2..00000000
--- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/globstar-match.js
+++ /dev/null
@@ -1,19 +0,0 @@
-var Glob = require("../glob.js").Glob
-var test = require('tap').test
-
-test('globstar should not have dupe matches', function(t) {
- var pattern = 'a/**/[gh]'
- var g = new Glob(pattern, { cwd: __dirname })
- var matches = []
- g.on('match', function(m) {
- console.error('match %j', m)
- matches.push(m)
- })
- g.on('end', function(set) {
- console.error('set', set)
- matches = matches.sort()
- set = set.sort()
- t.same(matches, set, 'should have same set of matches')
- t.end()
- })
-})
diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/mark.js b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/mark.js
deleted file mode 100644
index bf411c0e..00000000
--- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/mark.js
+++ /dev/null
@@ -1,118 +0,0 @@
-var test = require("tap").test
-var glob = require('../')
-process.chdir(__dirname)
-
-// expose timing issues
-var lag = 5
-glob.Glob.prototype._stat = function(o) { return function(f, cb) {
- var args = arguments
- setTimeout(function() {
- o.call(this, f, cb)
- }.bind(this), lag += 5)
-}}(glob.Glob.prototype._stat)
-
-
-test("mark, with **", function (t) {
- glob("a/*b*/**", {mark: true}, function (er, results) {
- if (er)
- throw er
- var expect =
- [ 'a/abcdef/',
- 'a/abcdef/g/',
- 'a/abcdef/g/h',
- 'a/abcfed/',
- 'a/abcfed/g/',
- 'a/abcfed/g/h',
- 'a/b/',
- 'a/b/c/',
- 'a/b/c/d',
- 'a/bc/',
- 'a/bc/e/',
- 'a/bc/e/f',
- 'a/cb/',
- 'a/cb/e/',
- 'a/cb/e/f' ]
-
- t.same(results, expect)
- t.end()
- })
-})
-
-test("mark, no / on pattern", function (t) {
- glob("a/*", {mark: true}, function (er, results) {
- if (er)
- throw er
- var expect = [ 'a/abcdef/',
- 'a/abcfed/',
- 'a/b/',
- 'a/bc/',
- 'a/c/',
- 'a/cb/' ]
-
- if (process.platform !== "win32")
- expect.push('a/symlink/')
-
- t.same(results, expect)
- t.end()
- }).on('match', function(m) {
- t.similar(m, /\/$/)
- })
-})
-
-test("mark=false, no / on pattern", function (t) {
- glob("a/*", function (er, results) {
- if (er)
- throw er
- var expect = [ 'a/abcdef',
- 'a/abcfed',
- 'a/b',
- 'a/bc',
- 'a/c',
- 'a/cb' ]
-
- if (process.platform !== "win32")
- expect.push('a/symlink')
- t.same(results, expect)
- t.end()
- }).on('match', function(m) {
- t.similar(m, /[^\/]$/)
- })
-})
-
-test("mark=true, / on pattern", function (t) {
- glob("a/*/", {mark: true}, function (er, results) {
- if (er)
- throw er
- var expect = [ 'a/abcdef/',
- 'a/abcfed/',
- 'a/b/',
- 'a/bc/',
- 'a/c/',
- 'a/cb/' ]
- if (process.platform !== "win32")
- expect.push('a/symlink/')
- t.same(results, expect)
- t.end()
- }).on('match', function(m) {
- t.similar(m, /\/$/)
- })
-})
-
-test("mark=false, / on pattern", function (t) {
- glob("a/*/", function (er, results) {
- if (er)
- throw er
- var expect = [ 'a/abcdef/',
- 'a/abcfed/',
- 'a/b/',
- 'a/bc/',
- 'a/c/',
- 'a/cb/' ]
- if (process.platform !== "win32")
- expect.push('a/symlink/')
- t.same(results, expect)
- t.end()
- }).on('match', function(m) {
- t.similar(m, /\/$/)
- })
-})
diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/new-glob-optional-options.js b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/new-glob-optional-options.js
deleted file mode 100644
index 3e7dc5ac..00000000
--- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/new-glob-optional-options.js
+++ /dev/null
@@ -1,10 +0,0 @@
-var Glob = require('../glob.js').Glob;
-var test = require('tap').test;
-
-test('new glob, with cb, and no options', function (t) {
- new Glob(__filename, function(er, results) {
- if (er) throw er;
- t.same(results, [__filename]);
- t.end();
- });
-});
diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/nocase-nomagic.js b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/nocase-nomagic.js
deleted file mode 100644
index 2503f231..00000000
--- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/nocase-nomagic.js
+++ /dev/null
@@ -1,113 +0,0 @@
-var fs = require('fs');
-var test = require('tap').test;
-var glob = require('../');
-
-test('mock fs', function(t) {
- var stat = fs.stat
- var statSync = fs.statSync
- var readdir = fs.readdir
- var readdirSync = fs.readdirSync
-
- function fakeStat(path) {
- var ret
- switch (path.toLowerCase()) {
- case '/tmp': case '/tmp/':
- ret = { isDirectory: function() { return true } }
- break
- case '/tmp/a':
- ret = { isDirectory: function() { return false } }
- break
- }
- return ret
- }
-
- fs.stat = function(path, cb) {
- var f = fakeStat(path);
- if (f) {
- process.nextTick(function() {
- cb(null, f)
- })
- } else {
- stat.call(fs, path, cb)
- }
- }
-
- fs.statSync = function(path) {
- return fakeStat(path) || statSync.call(fs, path)
- }
-
- function fakeReaddir(path) {
- var ret
- switch (path.toLowerCase()) {
- case '/tmp': case '/tmp/':
- ret = [ 'a', 'A' ]
- break
- case '/':
- ret = ['tmp', 'tMp', 'tMP', 'TMP']
- }
- return ret
- }
-
- fs.readdir = function(path, cb) {
- var f = fakeReaddir(path)
- if (f)
- process.nextTick(function() {
- cb(null, f)
- })
- else
- readdir.call(fs, path, cb)
- }
-
- fs.readdirSync = function(path) {
- return fakeReaddir(path) || readdirSync.call(fs, path)
- }
-
- t.pass('mocked')
- t.end()
-})
-
-test('nocase, nomagic', function(t) {
- var n = 2
- var want = [ '/TMP/A',
- '/TMP/a',
- '/tMP/A',
- '/tMP/a',
- '/tMp/A',
- '/tMp/a',
- '/tmp/A',
- '/tmp/a' ]
- glob('/tmp/a', { nocase: true }, function(er, res) {
- if (er)
- throw er
- t.same(res.sort(), want)
- if (--n === 0) t.end()
- })
- glob('/tmp/A', { nocase: true }, function(er, res) {
- if (er)
- throw er
- t.same(res.sort(), want)
- if (--n === 0) t.end()
- })
-})
-
-test('nocase, with some magic', function(t) {
- t.plan(2)
- var want = [ '/TMP/A',
- '/TMP/a',
- '/tMP/A',
- '/tMP/a',
- '/tMp/A',
- '/tMp/a',
- '/tmp/A',
- '/tmp/a' ]
- glob('/tmp/*', { nocase: true }, function(er, res) {
- if (er)
- throw er
- t.same(res.sort(), want)
- })
- glob('/tmp/*', { nocase: true }, function(er, res) {
- if (er)
- throw er
- t.same(res.sort(), want)
- })
-})
diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/pause-resume.js b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/pause-resume.js
deleted file mode 100644
index e1ffbab1..00000000
--- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/pause-resume.js
+++ /dev/null
@@ -1,73 +0,0 @@
-// show that no match events happen while paused.
-var tap = require("tap")
-, child_process = require("child_process")
-// just some gnarly pattern with lots of matches
-, pattern = "test/a/!(symlink)/**"
-, bashResults = require("./bash-results.json")
-, patterns = Object.keys(bashResults)
-, glob = require("../")
-, Glob = glob.Glob
-, path = require("path")
-
-// run from the root of the project
-// this is usually where you're at anyway, but be sure.
-process.chdir(path.resolve(__dirname, ".."))
-
-function alphasort (a, b) {
- a = a.toLowerCase()
- b = b.toLowerCase()
- return a > b ? 1 : a < b ? -1 : 0
-}
-
-function cleanResults (m) {
- // normalize discrepancies in ordering, duplication,
- // and ending slashes.
- return m.map(function (m) {
- return m.replace(/\/+/g, "/").replace(/\/$/, "")
- }).sort(alphasort).reduce(function (set, f) {
- if (f !== set[set.length - 1]) set.push(f)
- return set
- }, []).sort(alphasort).map(function (f) {
- // de-windows
- return (process.platform !== 'win32') ? f
- : f.replace(/^[a-zA-Z]:\\\\/, '/').replace(/\\/g, '/')
- })
-}
-
-var globResults = []
-tap.test("use a Glob object, and pause/resume it", function (t) {
- var g = new Glob(pattern)
- , paused = false
- , res = []
- , expect = bashResults[pattern]
-
- g.on("pause", function () {
- console.error("pause")
- })
-
- g.on("resume", function () {
- console.error("resume")
- })
-
- g.on("match", function (m) {
- t.notOk(g.paused, "must not be paused")
- globResults.push(m)
- g.pause()
- t.ok(g.paused, "must be paused")
- setTimeout(g.resume.bind(g), 10)
- })
-
- g.on("end", function (matches) {
- t.pass("reached glob end")
- globResults = cleanResults(globResults)
- matches = cleanResults(matches)
- t.deepEqual(matches, globResults,
- "end event matches should be the same as match events")
-
- t.deepEqual(matches, expect,
- "glob matches should be the same as bash results")
-
- t.end()
- })
-})
-
diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/readme-issue.js b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/readme-issue.js
deleted file mode 100644
index 0b4e0be2..00000000
--- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/readme-issue.js
+++ /dev/null
@@ -1,36 +0,0 @@
-var test = require("tap").test
-var glob = require("../")
-
-var mkdirp = require("mkdirp")
-var fs = require("fs")
-var rimraf = require("rimraf")
-var dir = __dirname + "/package"
-
-test("setup", function (t) {
- mkdirp.sync(dir)
- fs.writeFileSync(dir + "/package.json", "{}", "ascii")
- fs.writeFileSync(dir + "/README", "x", "ascii")
- t.pass("setup done")
- t.end()
-})
-
-test("glob", function (t) {
- var opt = {
- cwd: dir,
- nocase: true,
- mark: true
- }
-
- glob("README?(.*)", opt, function (er, files) {
- if (er)
- throw er
- t.same(files, ["README"])
- t.end()
- })
-})
-
-test("cleanup", function (t) {
- rimraf.sync(dir)
- t.pass("clean")
- t.end()
-})
diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/root-nomount.js b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/root-nomount.js
deleted file mode 100644
index 3ac5979b..00000000
--- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/root-nomount.js
+++ /dev/null
@@ -1,39 +0,0 @@
-var tap = require("tap")
-
-var origCwd = process.cwd()
-process.chdir(__dirname)
-
-tap.test("changing root and searching for /b*/**", function (t) {
- var glob = require('../')
- var path = require('path')
- t.test('.', function (t) {
- glob('/b*/**', { globDebug: true, root: '.', nomount: true }, function (er, matches) {
- t.ifError(er)
- t.like(matches, [])
- t.end()
- })
- })
-
- t.test('a', function (t) {
- glob('/b*/**', { globDebug: true, root: path.resolve('a'), nomount: true }, function (er, matches) {
- t.ifError(er)
- t.like(matches, [ '/b', '/b/c', '/b/c/d', '/bc', '/bc/e', '/bc/e/f' ])
- t.end()
- })
- })
-
- t.test('root=a, cwd=a/b', function (t) {
- glob('/b*/**', { globDebug: true, root: 'a', cwd: path.resolve('a/b'), nomount: true }, function (er, matches) {
- t.ifError(er)
- t.like(matches, [ '/b', '/b/c', '/b/c/d', '/bc', '/bc/e', '/bc/e/f' ])
- t.end()
- })
- })
-
- t.test('cd -', function (t) {
- process.chdir(origCwd)
- t.end()
- })
-
- t.end()
-})
diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/root.js b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/root.js
deleted file mode 100644
index 95c23f99..00000000
--- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/root.js
+++ /dev/null
@@ -1,46 +0,0 @@
-var t = require("tap")
-
-var origCwd = process.cwd()
-process.chdir(__dirname)
-
-var glob = require('../')
-var path = require('path')
-
-t.test('.', function (t) {
- glob('/b*/**', { globDebug: true, root: '.' }, function (er, matches) {
- t.ifError(er)
- t.like(matches, [])
- t.end()
- })
-})
-
-
-t.test('a', function (t) {
- console.error("root=" + path.resolve('a'))
- glob('/b*/**', { globDebug: true, root: path.resolve('a') }, function (er, matches) {
- t.ifError(er)
- var wanted = [
- '/b', '/b/c', '/b/c/d', '/bc', '/bc/e', '/bc/e/f'
- ].map(function (m) {
- return path.join(path.resolve('a'), m).replace(/\\/g, '/')
- })
-
- t.like(matches, wanted)
- t.end()
- })
-})
-
-t.test('root=a, cwd=a/b', function (t) {
- glob('/b*/**', { globDebug: true, root: 'a', cwd: path.resolve('a/b') }, function (er, matches) {
- t.ifError(er)
- t.like(matches, [ '/b', '/b/c', '/b/c/d', '/bc', '/bc/e', '/bc/e/f' ].map(function (m) {
- return path.join(path.resolve('a'), m).replace(/\\/g, '/')
- }))
- t.end()
- })
-})
-
-t.test('cd -', function (t) {
- process.chdir(origCwd)
- t.end()
-})
diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/stat.js b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/stat.js
deleted file mode 100644
index 62917114..00000000
--- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/stat.js
+++ /dev/null
@@ -1,32 +0,0 @@
-var glob = require('../')
-var test = require('tap').test
-var path = require('path')
-
-test('stat all the things', function(t) {
- var g = new glob.Glob('a/*abc*/**', { stat: true, cwd: __dirname })
- var matches = []
- g.on('match', function(m) {
- matches.push(m)
- })
- var stats = []
- g.on('stat', function(m) {
- stats.push(m)
- })
- g.on('end', function(eof) {
- stats = stats.sort()
- matches = matches.sort()
- eof = eof.sort()
- t.same(stats, matches)
- t.same(eof, matches)
- var cache = Object.keys(this.statCache)
- t.same(cache.map(function (f) {
- return path.relative(__dirname, f)
- }).sort(), matches)
-
- cache.forEach(function(c) {
- t.equal(typeof this.statCache[c], 'object')
- }, this)
-
- t.end()
- })
-})
diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/zz-cleanup.js b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/zz-cleanup.js
deleted file mode 100644
index e085f0fa..00000000
--- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/zz-cleanup.js
+++ /dev/null
@@ -1,11 +0,0 @@
-// remove the fixtures
-var tap = require("tap")
-, rimraf = require("rimraf")
-, path = require("path")
-
-tap.test("cleanup fixtures", function (t) {
- rimraf(path.resolve(__dirname, "a"), function (er) {
- t.ifError(er, "removed")
- t.end()
- })
-})
diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/lodash/LICENSE.txt b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/lodash/LICENSE.txt
deleted file mode 100644
index 49869bba..00000000
--- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/lodash/LICENSE.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-Copyright 2012-2013 The Dojo Foundation
-Based on Underscore.js 1.5.2, copyright 2009-2013 Jeremy Ashkenas,
-DocumentCloud and Investigative Reporters & Editors
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\ No newline at end of file
diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/lodash/README.md b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/lodash/README.md
deleted file mode 100644
index 6f9598e8..00000000
--- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/lodash/README.md
+++ /dev/null
@@ -1,163 +0,0 @@
-# Lo-Dash v2.4.1
-A utility library delivering consistency, [customization](http://lodash.com/custom-builds), [performance](http://lodash.com/benchmarks), & [extras](http://lodash.com/#features).
-
-## Download
-
-Check out our [wiki]([https://github.com/lodash/lodash/wiki/build-differences]) for details over the differences between builds.
-
-* Modern builds perfect for newer browsers/environments:
-[Development](https://raw.github.com/lodash/lodash/2.4.1/dist/lodash.js) &
-[Production](https://raw.github.com/lodash/lodash/2.4.1/dist/lodash.min.js)
-
-* Compatibility builds for older environment support too:
-[Development](https://raw.github.com/lodash/lodash/2.4.1/dist/lodash.compat.js) &
-[Production](https://raw.github.com/lodash/lodash/2.4.1/dist/lodash.compat.min.js)
-
-* Underscore builds to use as a drop-in replacement:
-[Development](https://raw.github.com/lodash/lodash/2.4.1/dist/lodash.underscore.js) &
-[Production](https://raw.github.com/lodash/lodash/2.4.1/dist/lodash.underscore.min.js)
-
-CDN copies are available on [cdnjs](http://cdnjs.com/libraries/lodash.js/) & [jsDelivr](http://www.jsdelivr.com/#!lodash). For smaller file sizes, create [custom builds](http://lodash.com/custom-builds) with only the features needed.
-
-Love modules? We’ve got you covered with [lodash-amd](https://npmjs.org/package/lodash-amd), [lodash-es6](https://github.com/lodash/lodash-es6), [lodash-node](https://npmjs.org/package/lodash-node), & [npm packages](https://npmjs.org/browse/keyword/lodash-modularized) per method.
-
-## Dive in
-
-There’s plenty of **[documentation](http://lodash.com/docs)**, [unit tests](http://lodash.com/tests), & [benchmarks](http://lodash.com/benchmarks).
-Check out DevDocs as a fast, organized, & searchable interface for our documentation.
-
-The full changelog for this release is available on our [wiki](https://github.com/lodash/lodash/wiki/Changelog).
-A list of upcoming features is available on our [roadmap](https://github.com/lodash/lodash/wiki/Roadmap).
-
-## Features *not* in Underscore
-
- * AMD loader support ([curl](https://github.com/cujojs/curl), [dojo](http://dojotoolkit.org/), [requirejs](http://requirejs.org/), etc.)
- * [_(…)](http://lodash.com/docs#_) supports intuitive chaining
- * [_.at](http://lodash.com/docs#at) for cherry-picking collection values
- * [_.bindKey](http://lodash.com/docs#bindKey) for binding [*“lazy”*](http://michaux.ca/articles/lazy-function-definition-pattern) defined methods
- * [_.clone](http://lodash.com/docs#clone) supports shallow cloning of `Date` & `RegExp` objects
- * [_.cloneDeep](http://lodash.com/docs#cloneDeep) for deep cloning arrays & objects
- * [_.constant](http://lodash.com/docs#constant) & [_.property](http://lodash.com/docs#property) function generators for composing functions
- * [_.contains](http://lodash.com/docs#contains) accepts a `fromIndex`
- * [_.create](http://lodash.com/docs#create) for easier object inheritance
- * [_.createCallback](http://lodash.com/docs#createCallback) for extending callbacks in methods & mixins
- * [_.curry](http://lodash.com/docs#curry) for creating [curried](http://hughfdjackson.com/javascript/2013/07/06/why-curry-helps/) functions
- * [_.debounce](http://lodash.com/docs#debounce) & [_.throttle](http://lodash.com/docs#throttle) accept additional `options` for more control
- * [_.findIndex](http://lodash.com/docs#findIndex) & [_.findKey](http://lodash.com/docs#findKey) for finding indexes & keys
- * [_.forEach](http://lodash.com/docs#forEach) is chainable & supports exiting early
- * [_.forIn](http://lodash.com/docs#forIn) for iterating own & inherited properties
- * [_.forOwn](http://lodash.com/docs#forOwn) for iterating own properties
- * [_.isPlainObject](http://lodash.com/docs#isPlainObject) for checking if values are created by `Object`
- * [_.mapValues](http://lodash.com/docs#mapValues) for [mapping](http://lodash.com/docs#map) values to an object
- * [_.memoize](http://lodash.com/docs#memoize) exposes the `cache` of memoized functions
- * [_.merge](http://lodash.com/docs#merge) for a deep [_.extend](http://lodash.com/docs#extend)
- * [_.noop](http://lodash.com/docs#noop) for function placeholders
- * [_.now](http://lodash.com/docs#now) as a cross-browser `Date.now` alternative
- * [_.parseInt](http://lodash.com/docs#parseInt) for consistent behavior
- * [_.pull](http://lodash.com/docs#pull) & [_.remove](http://lodash.com/docs#remove) for mutating arrays
- * [_.random](http://lodash.com/docs#random) supports returning floating-point numbers
- * [_.runInContext](http://lodash.com/docs#runInContext) for easier mocking
- * [_.sortBy](http://lodash.com/docs#sortBy) supports sorting by multiple properties
- * [_.support](http://lodash.com/docs#support) for flagging environment features
- * [_.template](http://lodash.com/docs#template) supports [*“imports”*](http://lodash.com/docs#templateSettings_imports) options & [ES6 template delimiters](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-literals-string-literals)
- * [_.transform](http://lodash.com/docs#transform) as a powerful alternative to [_.reduce](http://lodash.com/docs#reduce) for transforming objects
- * [_.where](http://lodash.com/docs#where) supports deep object comparisons
- * [_.xor](http://lodash.com/docs#xor) as a companion to [_.difference](http://lodash.com/docs#difference), [_.intersection](http://lodash.com/docs#intersection), & [_.union](http://lodash.com/docs#union)
- * [_.zip](http://lodash.com/docs#zip) is capable of unzipping values
- * [_.omit](http://lodash.com/docs#omit), [_.pick](http://lodash.com/docs#pick), &
- [more](http://lodash.com/docs "_.assign, _.clone, _.cloneDeep, _.first, _.initial, _.isEqual, _.last, _.merge, _.rest") accept callbacks
- * [_.contains](http://lodash.com/docs#contains), [_.toArray](http://lodash.com/docs#toArray), &
- [more](http://lodash.com/docs "_.at, _.countBy, _.every, _.filter, _.find, _.forEach, _.forEachRight, _.groupBy, _.invoke, _.map, _.max, _.min, _.pluck, _.reduce, _.reduceRight, _.reject, _.shuffle, _.size, _.some, _.sortBy, _.where") accept strings
- * [_.filter](http://lodash.com/docs#filter), [_.map](http://lodash.com/docs#map), &
- [more](http://lodash.com/docs "_.countBy, _.every, _.find, _.findKey, _.findLast, _.findLastIndex, _.findLastKey, _.first, _.groupBy, _.initial, _.last, _.max, _.min, _.reject, _.rest, _.some, _.sortBy, _.sortedIndex, _.uniq") support *“_.pluck”* & *“_.where”* shorthands
- * [_.findLast](http://lodash.com/docs#findLast), [_.findLastIndex](http://lodash.com/docs#findLastIndex), &
- [more](http://lodash.com/docs "_.findLastKey, _.forEachRight, _.forInRight, _.forOwnRight, _.partialRight") right-associative methods
-
-## Resources
-
- * Podcasts
- - [JavaScript Jabber](http://javascriptjabber.com/079-jsj-lo-dash-with-john-david-dalton/)
-
- * Posts
- - [Say “Hello” to Lo-Dash](http://kitcambridge.be/blog/say-hello-to-lo-dash/)
- - [Custom builds in Lo-Dash 2.0](http://kitcambridge.be/blog/custom-builds-in-lo-dash-2-dot-0/)
-
- * Videos
- - [Introduction](https://vimeo.com/44154599)
- - [Origins](https://vimeo.com/44154600)
- - [Optimizations & builds](https://vimeo.com/44154601)
- - [Native method use](https://vimeo.com/48576012)
- - [Testing](https://vimeo.com/45865290)
- - [CascadiaJS ’12](http://www.youtube.com/watch?v=dpPy4f_SeEk)
-
- A list of other community created podcasts, posts, & videos is available on our [wiki](https://github.com/lodash/lodash/wiki/Resources).
-
-## Support
-
-Tested in Chrome 5~31, Firefox 2~25, IE 6-11, Opera 9.25~17, Safari 3-7, Node.js 0.6.21~0.10.22, Narwhal 0.3.2, PhantomJS 1.9.2, RingoJS 0.9, & Rhino 1.7RC5.
-Automated browser test results [are available](https://saucelabs.com/u/lodash) as well as [Travis CI](https://travis-ci.org/) builds for [lodash](https://travis-ci.org/lodash/lodash/), [lodash-cli](https://travis-ci.org/lodash/lodash-cli/), [lodash-amd](https://travis-ci.org/lodash/lodash-amd/), [lodash-node](https://travis-ci.org/lodash/lodash-node/), & [grunt-lodash](https://travis-ci.org/lodash/grunt-lodash).
-
-Special thanks to [Sauce Labs](https://saucelabs.com/) for providing automated browser testing.
-[](https://saucelabs.com/ "Sauce Labs: Selenium Testing & More")
-
-## Installation & usage
-
-In browsers:
-
-```html
-
-```
-
-Using [`npm`](http://npmjs.org/):
-
-```bash
-npm i --save lodash
-
-{sudo} npm i -g lodash
-npm ln lodash
-```
-
-In [Node.js](http://nodejs.org/) & [Ringo](http://ringojs.org/):
-
-```js
-var _ = require('lodash');
-// or as Underscore
-var _ = require('lodash/dist/lodash.underscore');
-```
-
-**Notes:**
- * Don’t assign values to [special variable](http://nodejs.org/api/repl.html#repl_repl_features) `_` when in the REPL
- * If Lo-Dash is installed globally, run [`npm ln lodash`](http://blog.nodejs.org/2011/03/23/npm-1-0-global-vs-local-installation/) in your project’s root directory *before* requiring it
-
-In [Rhino](http://www.mozilla.org/rhino/):
-
-```js
-load('lodash.js');
-```
-
-In an AMD loader:
-
-```js
-require({
- 'packages': [
- { 'name': 'lodash', 'location': 'path/to/lodash', 'main': 'lodash' }
- ]
-},
-['lodash'], function(_) {
- console.log(_.VERSION);
-});
-```
-
-## Author
-
-| [](https://twitter.com/jdalton "Follow @jdalton on Twitter") |
-|---|
-| [John-David Dalton](http://allyoucanleet.com/) |
-
-## Contributors
-
-| [](https://twitter.com/blainebublitz "Follow @BlaineBublitz on Twitter") | [](https://twitter.com/kitcambridge "Follow @kitcambridge on Twitter") | [](https://twitter.com/mathias "Follow @mathias on Twitter") |
-|---|---|---|
-| [Blaine Bublitz](http://www.iceddev.com/) | [Kit Cambridge](http://kitcambridge.be/) | [Mathias Bynens](http://mathiasbynens.be/) |
-
-[](https://bitdeli.com/free "Bitdeli Badge")
diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/lodash/dist/lodash.compat.js b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/lodash/dist/lodash.compat.js
deleted file mode 100644
index 23798ba8..00000000
--- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/lodash/dist/lodash.compat.js
+++ /dev/null
@@ -1,7157 +0,0 @@
-/**
- * @license
- * Lo-Dash 2.4.1 (Custom Build)
- * Build: `lodash -o ./dist/lodash.compat.js`
- * Copyright 2012-2013 The Dojo Foundation
- * Based on Underscore.js 1.5.2
- * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
- * Available under MIT license
- */
-;(function() {
-
- /** Used as a safe reference for `undefined` in pre ES5 environments */
- var undefined;
-
- /** Used to pool arrays and objects used internally */
- var arrayPool = [],
- objectPool = [];
-
- /** Used to generate unique IDs */
- var idCounter = 0;
-
- /** Used internally to indicate various things */
- var indicatorObject = {};
-
- /** Used to prefix keys to avoid issues with `__proto__` and properties on `Object.prototype` */
- var keyPrefix = +new Date + '';
-
- /** Used as the size when optimizations are enabled for large arrays */
- var largeArraySize = 75;
-
- /** Used as the max size of the `arrayPool` and `objectPool` */
- var maxPoolSize = 40;
-
- /** Used to detect and test whitespace */
- var whitespace = (
- // whitespace
- ' \t\x0B\f\xA0\ufeff' +
-
- // line terminators
- '\n\r\u2028\u2029' +
-
- // unicode category "Zs" space separators
- '\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000'
- );
-
- /** Used to match empty string literals in compiled template source */
- var reEmptyStringLeading = /\b__p \+= '';/g,
- reEmptyStringMiddle = /\b(__p \+=) '' \+/g,
- reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g;
-
- /**
- * Used to match ES6 template delimiters
- * http://people.mozilla.org/~jorendorff/es6-draft.html#sec-literals-string-literals
- */
- var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g;
-
- /** Used to match regexp flags from their coerced string values */
- var reFlags = /\w*$/;
-
- /** Used to detected named functions */
- var reFuncName = /^\s*function[ \n\r\t]+\w/;
-
- /** Used to match "interpolate" template delimiters */
- var reInterpolate = /<%=([\s\S]+?)%>/g;
-
- /** Used to match leading whitespace and zeros to be removed */
- var reLeadingSpacesAndZeros = RegExp('^[' + whitespace + ']*0+(?=.$)');
-
- /** Used to ensure capturing order of template delimiters */
- var reNoMatch = /($^)/;
-
- /** Used to detect functions containing a `this` reference */
- var reThis = /\bthis\b/;
-
- /** Used to match unescaped characters in compiled string literals */
- var reUnescapedString = /['\n\r\t\u2028\u2029\\]/g;
-
- /** Used to assign default `context` object properties */
- var contextProps = [
- 'Array', 'Boolean', 'Date', 'Error', 'Function', 'Math', 'Number', 'Object',
- 'RegExp', 'String', '_', 'attachEvent', 'clearTimeout', 'isFinite', 'isNaN',
- 'parseInt', 'setTimeout'
- ];
-
- /** Used to fix the JScript [[DontEnum]] bug */
- var shadowedProps = [
- 'constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable',
- 'toLocaleString', 'toString', 'valueOf'
- ];
-
- /** Used to make template sourceURLs easier to identify */
- var templateCounter = 0;
-
- /** `Object#toString` result shortcuts */
- var argsClass = '[object Arguments]',
- arrayClass = '[object Array]',
- boolClass = '[object Boolean]',
- dateClass = '[object Date]',
- errorClass = '[object Error]',
- funcClass = '[object Function]',
- numberClass = '[object Number]',
- objectClass = '[object Object]',
- regexpClass = '[object RegExp]',
- stringClass = '[object String]';
-
- /** Used to identify object classifications that `_.clone` supports */
- var cloneableClasses = {};
- cloneableClasses[funcClass] = false;
- cloneableClasses[argsClass] = cloneableClasses[arrayClass] =
- cloneableClasses[boolClass] = cloneableClasses[dateClass] =
- cloneableClasses[numberClass] = cloneableClasses[objectClass] =
- cloneableClasses[regexpClass] = cloneableClasses[stringClass] = true;
-
- /** Used as an internal `_.debounce` options object */
- var debounceOptions = {
- 'leading': false,
- 'maxWait': 0,
- 'trailing': false
- };
-
- /** Used as the property descriptor for `__bindData__` */
- var descriptor = {
- 'configurable': false,
- 'enumerable': false,
- 'value': null,
- 'writable': false
- };
-
- /** Used as the data object for `iteratorTemplate` */
- var iteratorData = {
- 'args': '',
- 'array': null,
- 'bottom': '',
- 'firstArg': '',
- 'init': '',
- 'keys': null,
- 'loop': '',
- 'shadowedProps': null,
- 'support': null,
- 'top': '',
- 'useHas': false
- };
-
- /** Used to determine if values are of the language type Object */
- var objectTypes = {
- 'boolean': false,
- 'function': true,
- 'object': true,
- 'number': false,
- 'string': false,
- 'undefined': false
- };
-
- /** Used to escape characters for inclusion in compiled string literals */
- var stringEscapes = {
- '\\': '\\',
- "'": "'",
- '\n': 'n',
- '\r': 'r',
- '\t': 't',
- '\u2028': 'u2028',
- '\u2029': 'u2029'
- };
-
- /** Used as a reference to the global object */
- var root = (objectTypes[typeof window] && window) || this;
-
- /** Detect free variable `exports` */
- var freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports;
-
- /** Detect free variable `module` */
- var freeModule = objectTypes[typeof module] && module && !module.nodeType && module;
-
- /** Detect the popular CommonJS extension `module.exports` */
- var moduleExports = freeModule && freeModule.exports === freeExports && freeExports;
-
- /** Detect free variable `global` from Node.js or Browserified code and use it as `root` */
- var freeGlobal = objectTypes[typeof global] && global;
- if (freeGlobal && (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal)) {
- root = freeGlobal;
- }
-
- /*--------------------------------------------------------------------------*/
-
- /**
- * The base implementation of `_.indexOf` without support for binary searches
- * or `fromIndex` constraints.
- *
- * @private
- * @param {Array} array The array to search.
- * @param {*} value The value to search for.
- * @param {number} [fromIndex=0] The index to search from.
- * @returns {number} Returns the index of the matched value or `-1`.
- */
- function baseIndexOf(array, value, fromIndex) {
- var index = (fromIndex || 0) - 1,
- length = array ? array.length : 0;
-
- while (++index < length) {
- if (array[index] === value) {
- return index;
- }
- }
- return -1;
- }
-
- /**
- * An implementation of `_.contains` for cache objects that mimics the return
- * signature of `_.indexOf` by returning `0` if the value is found, else `-1`.
- *
- * @private
- * @param {Object} cache The cache object to inspect.
- * @param {*} value The value to search for.
- * @returns {number} Returns `0` if `value` is found, else `-1`.
- */
- function cacheIndexOf(cache, value) {
- var type = typeof value;
- cache = cache.cache;
-
- if (type == 'boolean' || value == null) {
- return cache[value] ? 0 : -1;
- }
- if (type != 'number' && type != 'string') {
- type = 'object';
- }
- var key = type == 'number' ? value : keyPrefix + value;
- cache = (cache = cache[type]) && cache[key];
-
- return type == 'object'
- ? (cache && baseIndexOf(cache, value) > -1 ? 0 : -1)
- : (cache ? 0 : -1);
- }
-
- /**
- * Adds a given value to the corresponding cache object.
- *
- * @private
- * @param {*} value The value to add to the cache.
- */
- function cachePush(value) {
- var cache = this.cache,
- type = typeof value;
-
- if (type == 'boolean' || value == null) {
- cache[value] = true;
- } else {
- if (type != 'number' && type != 'string') {
- type = 'object';
- }
- var key = type == 'number' ? value : keyPrefix + value,
- typeCache = cache[type] || (cache[type] = {});
-
- if (type == 'object') {
- (typeCache[key] || (typeCache[key] = [])).push(value);
- } else {
- typeCache[key] = true;
- }
- }
- }
-
- /**
- * Used by `_.max` and `_.min` as the default callback when a given
- * collection is a string value.
- *
- * @private
- * @param {string} value The character to inspect.
- * @returns {number} Returns the code unit of given character.
- */
- function charAtCallback(value) {
- return value.charCodeAt(0);
- }
-
- /**
- * Used by `sortBy` to compare transformed `collection` elements, stable sorting
- * them in ascending order.
- *
- * @private
- * @param {Object} a The object to compare to `b`.
- * @param {Object} b The object to compare to `a`.
- * @returns {number} Returns the sort order indicator of `1` or `-1`.
- */
- function compareAscending(a, b) {
- var ac = a.criteria,
- bc = b.criteria,
- index = -1,
- length = ac.length;
-
- while (++index < length) {
- var value = ac[index],
- other = bc[index];
-
- if (value !== other) {
- if (value > other || typeof value == 'undefined') {
- return 1;
- }
- if (value < other || typeof other == 'undefined') {
- return -1;
- }
- }
- }
- // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications
- // that causes it, under certain circumstances, to return the same value for
- // `a` and `b`. See https://github.com/jashkenas/underscore/pull/1247
- //
- // This also ensures a stable sort in V8 and other engines.
- // See http://code.google.com/p/v8/issues/detail?id=90
- return a.index - b.index;
- }
-
- /**
- * Creates a cache object to optimize linear searches of large arrays.
- *
- * @private
- * @param {Array} [array=[]] The array to search.
- * @returns {null|Object} Returns the cache object or `null` if caching should not be used.
- */
- function createCache(array) {
- var index = -1,
- length = array.length,
- first = array[0],
- mid = array[(length / 2) | 0],
- last = array[length - 1];
-
- if (first && typeof first == 'object' &&
- mid && typeof mid == 'object' && last && typeof last == 'object') {
- return false;
- }
- var cache = getObject();
- cache['false'] = cache['null'] = cache['true'] = cache['undefined'] = false;
-
- var result = getObject();
- result.array = array;
- result.cache = cache;
- result.push = cachePush;
-
- while (++index < length) {
- result.push(array[index]);
- }
- return result;
- }
-
- /**
- * Used by `template` to escape characters for inclusion in compiled
- * string literals.
- *
- * @private
- * @param {string} match The matched character to escape.
- * @returns {string} Returns the escaped character.
- */
- function escapeStringChar(match) {
- return '\\' + stringEscapes[match];
- }
-
- /**
- * Gets an array from the array pool or creates a new one if the pool is empty.
- *
- * @private
- * @returns {Array} The array from the pool.
- */
- function getArray() {
- return arrayPool.pop() || [];
- }
-
- /**
- * Gets an object from the object pool or creates a new one if the pool is empty.
- *
- * @private
- * @returns {Object} The object from the pool.
- */
- function getObject() {
- return objectPool.pop() || {
- 'array': null,
- 'cache': null,
- 'criteria': null,
- 'false': false,
- 'index': 0,
- 'null': false,
- 'number': null,
- 'object': null,
- 'push': null,
- 'string': null,
- 'true': false,
- 'undefined': false,
- 'value': null
- };
- }
-
- /**
- * Checks if `value` is a DOM node in IE < 9.
- *
- * @private
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if the `value` is a DOM node, else `false`.
- */
- function isNode(value) {
- // IE < 9 presents DOM nodes as `Object` objects except they have `toString`
- // methods that are `typeof` "string" and still can coerce nodes to strings
- return typeof value.toString != 'function' && typeof (value + '') == 'string';
- }
-
- /**
- * Releases the given array back to the array pool.
- *
- * @private
- * @param {Array} [array] The array to release.
- */
- function releaseArray(array) {
- array.length = 0;
- if (arrayPool.length < maxPoolSize) {
- arrayPool.push(array);
- }
- }
-
- /**
- * Releases the given object back to the object pool.
- *
- * @private
- * @param {Object} [object] The object to release.
- */
- function releaseObject(object) {
- var cache = object.cache;
- if (cache) {
- releaseObject(cache);
- }
- object.array = object.cache = object.criteria = object.object = object.number = object.string = object.value = null;
- if (objectPool.length < maxPoolSize) {
- objectPool.push(object);
- }
- }
-
- /**
- * Slices the `collection` from the `start` index up to, but not including,
- * the `end` index.
- *
- * Note: This function is used instead of `Array#slice` to support node lists
- * in IE < 9 and to ensure dense arrays are returned.
- *
- * @private
- * @param {Array|Object|string} collection The collection to slice.
- * @param {number} start The start index.
- * @param {number} end The end index.
- * @returns {Array} Returns the new array.
- */
- function slice(array, start, end) {
- start || (start = 0);
- if (typeof end == 'undefined') {
- end = array ? array.length : 0;
- }
- var index = -1,
- length = end - start || 0,
- result = Array(length < 0 ? 0 : length);
-
- while (++index < length) {
- result[index] = array[start + index];
- }
- return result;
- }
-
- /*--------------------------------------------------------------------------*/
-
- /**
- * Create a new `lodash` function using the given context object.
- *
- * @static
- * @memberOf _
- * @category Utilities
- * @param {Object} [context=root] The context object.
- * @returns {Function} Returns the `lodash` function.
- */
- function runInContext(context) {
- // Avoid issues with some ES3 environments that attempt to use values, named
- // after built-in constructors like `Object`, for the creation of literals.
- // ES5 clears this up by stating that literals must use built-in constructors.
- // See http://es5.github.io/#x11.1.5.
- context = context ? _.defaults(root.Object(), context, _.pick(root, contextProps)) : root;
-
- /** Native constructor references */
- var Array = context.Array,
- Boolean = context.Boolean,
- Date = context.Date,
- Error = context.Error,
- Function = context.Function,
- Math = context.Math,
- Number = context.Number,
- Object = context.Object,
- RegExp = context.RegExp,
- String = context.String,
- TypeError = context.TypeError;
-
- /**
- * Used for `Array` method references.
- *
- * Normally `Array.prototype` would suffice, however, using an array literal
- * avoids issues in Narwhal.
- */
- var arrayRef = [];
-
- /** Used for native method references */
- var errorProto = Error.prototype,
- objectProto = Object.prototype,
- stringProto = String.prototype;
-
- /** Used to restore the original `_` reference in `noConflict` */
- var oldDash = context._;
-
- /** Used to resolve the internal [[Class]] of values */
- var toString = objectProto.toString;
-
- /** Used to detect if a method is native */
- var reNative = RegExp('^' +
- String(toString)
- .replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
- .replace(/toString| for [^\]]+/g, '.*?') + '$'
- );
-
- /** Native method shortcuts */
- var ceil = Math.ceil,
- clearTimeout = context.clearTimeout,
- floor = Math.floor,
- fnToString = Function.prototype.toString,
- getPrototypeOf = isNative(getPrototypeOf = Object.getPrototypeOf) && getPrototypeOf,
- hasOwnProperty = objectProto.hasOwnProperty,
- push = arrayRef.push,
- propertyIsEnumerable = objectProto.propertyIsEnumerable,
- setTimeout = context.setTimeout,
- splice = arrayRef.splice,
- unshift = arrayRef.unshift;
-
- /** Used to set meta data on functions */
- var defineProperty = (function() {
- // IE 8 only accepts DOM elements
- try {
- var o = {},
- func = isNative(func = Object.defineProperty) && func,
- result = func(o, o, o) && func;
- } catch(e) { }
- return result;
- }());
-
- /* Native method shortcuts for methods with the same name as other `lodash` methods */
- var nativeCreate = isNative(nativeCreate = Object.create) && nativeCreate,
- nativeIsArray = isNative(nativeIsArray = Array.isArray) && nativeIsArray,
- nativeIsFinite = context.isFinite,
- nativeIsNaN = context.isNaN,
- nativeKeys = isNative(nativeKeys = Object.keys) && nativeKeys,
- nativeMax = Math.max,
- nativeMin = Math.min,
- nativeParseInt = context.parseInt,
- nativeRandom = Math.random;
-
- /** Used to lookup a built-in constructor by [[Class]] */
- var ctorByClass = {};
- ctorByClass[arrayClass] = Array;
- ctorByClass[boolClass] = Boolean;
- ctorByClass[dateClass] = Date;
- ctorByClass[funcClass] = Function;
- ctorByClass[objectClass] = Object;
- ctorByClass[numberClass] = Number;
- ctorByClass[regexpClass] = RegExp;
- ctorByClass[stringClass] = String;
-
- /** Used to avoid iterating non-enumerable properties in IE < 9 */
- var nonEnumProps = {};
- nonEnumProps[arrayClass] = nonEnumProps[dateClass] = nonEnumProps[numberClass] = { 'constructor': true, 'toLocaleString': true, 'toString': true, 'valueOf': true };
- nonEnumProps[boolClass] = nonEnumProps[stringClass] = { 'constructor': true, 'toString': true, 'valueOf': true };
- nonEnumProps[errorClass] = nonEnumProps[funcClass] = nonEnumProps[regexpClass] = { 'constructor': true, 'toString': true };
- nonEnumProps[objectClass] = { 'constructor': true };
-
- (function() {
- var length = shadowedProps.length;
- while (length--) {
- var key = shadowedProps[length];
- for (var className in nonEnumProps) {
- if (hasOwnProperty.call(nonEnumProps, className) && !hasOwnProperty.call(nonEnumProps[className], key)) {
- nonEnumProps[className][key] = false;
- }
- }
- }
- }());
-
- /*--------------------------------------------------------------------------*/
-
- /**
- * Creates a `lodash` object which wraps the given value to enable intuitive
- * method chaining.
- *
- * In addition to Lo-Dash methods, wrappers also have the following `Array` methods:
- * `concat`, `join`, `pop`, `push`, `reverse`, `shift`, `slice`, `sort`, `splice`,
- * and `unshift`
- *
- * Chaining is supported in custom builds as long as the `value` method is
- * implicitly or explicitly included in the build.
- *
- * The chainable wrapper functions are:
- * `after`, `assign`, `bind`, `bindAll`, `bindKey`, `chain`, `compact`,
- * `compose`, `concat`, `countBy`, `create`, `createCallback`, `curry`,
- * `debounce`, `defaults`, `defer`, `delay`, `difference`, `filter`, `flatten`,
- * `forEach`, `forEachRight`, `forIn`, `forInRight`, `forOwn`, `forOwnRight`,
- * `functions`, `groupBy`, `indexBy`, `initial`, `intersection`, `invert`,
- * `invoke`, `keys`, `map`, `max`, `memoize`, `merge`, `min`, `object`, `omit`,
- * `once`, `pairs`, `partial`, `partialRight`, `pick`, `pluck`, `pull`, `push`,
- * `range`, `reject`, `remove`, `rest`, `reverse`, `shuffle`, `slice`, `sort`,
- * `sortBy`, `splice`, `tap`, `throttle`, `times`, `toArray`, `transform`,
- * `union`, `uniq`, `unshift`, `unzip`, `values`, `where`, `without`, `wrap`,
- * and `zip`
- *
- * The non-chainable wrapper functions are:
- * `clone`, `cloneDeep`, `contains`, `escape`, `every`, `find`, `findIndex`,
- * `findKey`, `findLast`, `findLastIndex`, `findLastKey`, `has`, `identity`,
- * `indexOf`, `isArguments`, `isArray`, `isBoolean`, `isDate`, `isElement`,
- * `isEmpty`, `isEqual`, `isFinite`, `isFunction`, `isNaN`, `isNull`, `isNumber`,
- * `isObject`, `isPlainObject`, `isRegExp`, `isString`, `isUndefined`, `join`,
- * `lastIndexOf`, `mixin`, `noConflict`, `parseInt`, `pop`, `random`, `reduce`,
- * `reduceRight`, `result`, `shift`, `size`, `some`, `sortedIndex`, `runInContext`,
- * `template`, `unescape`, `uniqueId`, and `value`
- *
- * The wrapper functions `first` and `last` return wrapped values when `n` is
- * provided, otherwise they return unwrapped values.
- *
- * Explicit chaining can be enabled by using the `_.chain` method.
- *
- * @name _
- * @constructor
- * @category Chaining
- * @param {*} value The value to wrap in a `lodash` instance.
- * @returns {Object} Returns a `lodash` instance.
- * @example
- *
- * var wrapped = _([1, 2, 3]);
- *
- * // returns an unwrapped value
- * wrapped.reduce(function(sum, num) {
- * return sum + num;
- * });
- * // => 6
- *
- * // returns a wrapped value
- * var squares = wrapped.map(function(num) {
- * return num * num;
- * });
- *
- * _.isArray(squares);
- * // => false
- *
- * _.isArray(squares.value());
- * // => true
- */
- function lodash(value) {
- // don't wrap if already wrapped, even if wrapped by a different `lodash` constructor
- return (value && typeof value == 'object' && !isArray(value) && hasOwnProperty.call(value, '__wrapped__'))
- ? value
- : new lodashWrapper(value);
- }
-
- /**
- * A fast path for creating `lodash` wrapper objects.
- *
- * @private
- * @param {*} value The value to wrap in a `lodash` instance.
- * @param {boolean} chainAll A flag to enable chaining for all methods
- * @returns {Object} Returns a `lodash` instance.
- */
- function lodashWrapper(value, chainAll) {
- this.__chain__ = !!chainAll;
- this.__wrapped__ = value;
- }
- // ensure `new lodashWrapper` is an instance of `lodash`
- lodashWrapper.prototype = lodash.prototype;
-
- /**
- * An object used to flag environments features.
- *
- * @static
- * @memberOf _
- * @type Object
- */
- var support = lodash.support = {};
-
- (function() {
- var ctor = function() { this.x = 1; },
- object = { '0': 1, 'length': 1 },
- props = [];
-
- ctor.prototype = { 'valueOf': 1, 'y': 1 };
- for (var key in new ctor) { props.push(key); }
- for (key in arguments) { }
-
- /**
- * Detect if an `arguments` object's [[Class]] is resolvable (all but Firefox < 4, IE < 9).
- *
- * @memberOf _.support
- * @type boolean
- */
- support.argsClass = toString.call(arguments) == argsClass;
-
- /**
- * Detect if `arguments` objects are `Object` objects (all but Narwhal and Opera < 10.5).
- *
- * @memberOf _.support
- * @type boolean
- */
- support.argsObject = arguments.constructor == Object && !(arguments instanceof Array);
-
- /**
- * Detect if `name` or `message` properties of `Error.prototype` are
- * enumerable by default. (IE < 9, Safari < 5.1)
- *
- * @memberOf _.support
- * @type boolean
- */
- support.enumErrorProps = propertyIsEnumerable.call(errorProto, 'message') || propertyIsEnumerable.call(errorProto, 'name');
-
- /**
- * Detect if `prototype` properties are enumerable by default.
- *
- * Firefox < 3.6, Opera > 9.50 - Opera < 11.60, and Safari < 5.1
- * (if the prototype or a property on the prototype has been set)
- * incorrectly sets a function's `prototype` property [[Enumerable]]
- * value to `true`.
- *
- * @memberOf _.support
- * @type boolean
- */
- support.enumPrototypes = propertyIsEnumerable.call(ctor, 'prototype');
-
- /**
- * Detect if functions can be decompiled by `Function#toString`
- * (all but PS3 and older Opera mobile browsers & avoided in Windows 8 apps).
- *
- * @memberOf _.support
- * @type boolean
- */
- support.funcDecomp = !isNative(context.WinRTError) && reThis.test(runInContext);
-
- /**
- * Detect if `Function#name` is supported (all but IE).
- *
- * @memberOf _.support
- * @type boolean
- */
- support.funcNames = typeof Function.name == 'string';
-
- /**
- * Detect if `arguments` object indexes are non-enumerable
- * (Firefox < 4, IE < 9, PhantomJS, Safari < 5.1).
- *
- * @memberOf _.support
- * @type boolean
- */
- support.nonEnumArgs = key != 0;
-
- /**
- * Detect if properties shadowing those on `Object.prototype` are non-enumerable.
- *
- * In IE < 9 an objects own properties, shadowing non-enumerable ones, are
- * made non-enumerable as well (a.k.a the JScript [[DontEnum]] bug).
- *
- * @memberOf _.support
- * @type boolean
- */
- support.nonEnumShadows = !/valueOf/.test(props);
-
- /**
- * Detect if own properties are iterated after inherited properties (all but IE < 9).
- *
- * @memberOf _.support
- * @type boolean
- */
- support.ownLast = props[0] != 'x';
-
- /**
- * Detect if `Array#shift` and `Array#splice` augment array-like objects correctly.
- *
- * Firefox < 10, IE compatibility mode, and IE < 9 have buggy Array `shift()`
- * and `splice()` functions that fail to remove the last element, `value[0]`,
- * of array-like objects even though the `length` property is set to `0`.
- * The `shift()` method is buggy in IE 8 compatibility mode, while `splice()`
- * is buggy regardless of mode in IE < 9 and buggy in compatibility mode in IE 9.
- *
- * @memberOf _.support
- * @type boolean
- */
- support.spliceObjects = (arrayRef.splice.call(object, 0, 1), !object[0]);
-
- /**
- * Detect lack of support for accessing string characters by index.
- *
- * IE < 8 can't access characters by index and IE 8 can only access
- * characters by index on string literals.
- *
- * @memberOf _.support
- * @type boolean
- */
- support.unindexedChars = ('x'[0] + Object('x')[0]) != 'xx';
-
- /**
- * Detect if a DOM node's [[Class]] is resolvable (all but IE < 9)
- * and that the JS engine errors when attempting to coerce an object to
- * a string without a `toString` function.
- *
- * @memberOf _.support
- * @type boolean
- */
- try {
- support.nodeClass = !(toString.call(document) == objectClass && !({ 'toString': 0 } + ''));
- } catch(e) {
- support.nodeClass = true;
- }
- }(1));
-
- /**
- * By default, the template delimiters used by Lo-Dash are similar to those in
- * embedded Ruby (ERB). Change the following template settings to use alternative
- * delimiters.
- *
- * @static
- * @memberOf _
- * @type Object
- */
- lodash.templateSettings = {
-
- /**
- * Used to detect `data` property values to be HTML-escaped.
- *
- * @memberOf _.templateSettings
- * @type RegExp
- */
- 'escape': /<%-([\s\S]+?)%>/g,
-
- /**
- * Used to detect code to be evaluated.
- *
- * @memberOf _.templateSettings
- * @type RegExp
- */
- 'evaluate': /<%([\s\S]+?)%>/g,
-
- /**
- * Used to detect `data` property values to inject.
- *
- * @memberOf _.templateSettings
- * @type RegExp
- */
- 'interpolate': reInterpolate,
-
- /**
- * Used to reference the data object in the template text.
- *
- * @memberOf _.templateSettings
- * @type string
- */
- 'variable': '',
-
- /**
- * Used to import variables into the compiled template.
- *
- * @memberOf _.templateSettings
- * @type Object
- */
- 'imports': {
-
- /**
- * A reference to the `lodash` function.
- *
- * @memberOf _.templateSettings.imports
- * @type Function
- */
- '_': lodash
- }
- };
-
- /*--------------------------------------------------------------------------*/
-
- /**
- * The template used to create iterator functions.
- *
- * @private
- * @param {Object} data The data object used to populate the text.
- * @returns {string} Returns the interpolated text.
- */
- var iteratorTemplate = function(obj) {
-
- var __p = 'var index, iterable = ' +
- (obj.firstArg) +
- ', result = ' +
- (obj.init) +
- ';\nif (!iterable) return result;\n' +
- (obj.top) +
- ';';
- if (obj.array) {
- __p += '\nvar length = iterable.length; index = -1;\nif (' +
- (obj.array) +
- ') { ';
- if (support.unindexedChars) {
- __p += '\n if (isString(iterable)) {\n iterable = iterable.split(\'\')\n } ';
- }
- __p += '\n while (++index < length) {\n ' +
- (obj.loop) +
- ';\n }\n}\nelse { ';
- } else if (support.nonEnumArgs) {
- __p += '\n var length = iterable.length; index = -1;\n if (length && isArguments(iterable)) {\n while (++index < length) {\n index += \'\';\n ' +
- (obj.loop) +
- ';\n }\n } else { ';
- }
-
- if (support.enumPrototypes) {
- __p += '\n var skipProto = typeof iterable == \'function\';\n ';
- }
-
- if (support.enumErrorProps) {
- __p += '\n var skipErrorProps = iterable === errorProto || iterable instanceof Error;\n ';
- }
-
- var conditions = []; if (support.enumPrototypes) { conditions.push('!(skipProto && index == "prototype")'); } if (support.enumErrorProps) { conditions.push('!(skipErrorProps && (index == "message" || index == "name"))'); }
-
- if (obj.useHas && obj.keys) {
- __p += '\n var ownIndex = -1,\n ownProps = objectTypes[typeof iterable] && keys(iterable),\n length = ownProps ? ownProps.length : 0;\n\n while (++ownIndex < length) {\n index = ownProps[ownIndex];\n';
- if (conditions.length) {
- __p += ' if (' +
- (conditions.join(' && ')) +
- ') {\n ';
- }
- __p +=
- (obj.loop) +
- '; ';
- if (conditions.length) {
- __p += '\n }';
- }
- __p += '\n } ';
- } else {
- __p += '\n for (index in iterable) {\n';
- if (obj.useHas) { conditions.push("hasOwnProperty.call(iterable, index)"); } if (conditions.length) {
- __p += ' if (' +
- (conditions.join(' && ')) +
- ') {\n ';
- }
- __p +=
- (obj.loop) +
- '; ';
- if (conditions.length) {
- __p += '\n }';
- }
- __p += '\n } ';
- if (support.nonEnumShadows) {
- __p += '\n\n if (iterable !== objectProto) {\n var ctor = iterable.constructor,\n isProto = iterable === (ctor && ctor.prototype),\n className = iterable === stringProto ? stringClass : iterable === errorProto ? errorClass : toString.call(iterable),\n nonEnum = nonEnumProps[className];\n ';
- for (k = 0; k < 7; k++) {
- __p += '\n index = \'' +
- (obj.shadowedProps[k]) +
- '\';\n if ((!(isProto && nonEnum[index]) && hasOwnProperty.call(iterable, index))';
- if (!obj.useHas) {
- __p += ' || (!nonEnum[index] && iterable[index] !== objectProto[index])';
- }
- __p += ') {\n ' +
- (obj.loop) +
- ';\n } ';
- }
- __p += '\n } ';
- }
-
- }
-
- if (obj.array || support.nonEnumArgs) {
- __p += '\n}';
- }
- __p +=
- (obj.bottom) +
- ';\nreturn result';
-
- return __p
- };
-
- /*--------------------------------------------------------------------------*/
-
- /**
- * The base implementation of `_.bind` that creates the bound function and
- * sets its meta data.
- *
- * @private
- * @param {Array} bindData The bind data array.
- * @returns {Function} Returns the new bound function.
- */
- function baseBind(bindData) {
- var func = bindData[0],
- partialArgs = bindData[2],
- thisArg = bindData[4];
-
- function bound() {
- // `Function#bind` spec
- // http://es5.github.io/#x15.3.4.5
- if (partialArgs) {
- // avoid `arguments` object deoptimizations by using `slice` instead
- // of `Array.prototype.slice.call` and not assigning `arguments` to a
- // variable as a ternary expression
- var args = slice(partialArgs);
- push.apply(args, arguments);
- }
- // mimic the constructor's `return` behavior
- // http://es5.github.io/#x13.2.2
- if (this instanceof bound) {
- // ensure `new bound` is an instance of `func`
- var thisBinding = baseCreate(func.prototype),
- result = func.apply(thisBinding, args || arguments);
- return isObject(result) ? result : thisBinding;
- }
- return func.apply(thisArg, args || arguments);
- }
- setBindData(bound, bindData);
- return bound;
- }
-
- /**
- * The base implementation of `_.clone` without argument juggling or support
- * for `thisArg` binding.
- *
- * @private
- * @param {*} value The value to clone.
- * @param {boolean} [isDeep=false] Specify a deep clone.
- * @param {Function} [callback] The function to customize cloning values.
- * @param {Array} [stackA=[]] Tracks traversed source objects.
- * @param {Array} [stackB=[]] Associates clones with source counterparts.
- * @returns {*} Returns the cloned value.
- */
- function baseClone(value, isDeep, callback, stackA, stackB) {
- if (callback) {
- var result = callback(value);
- if (typeof result != 'undefined') {
- return result;
- }
- }
- // inspect [[Class]]
- var isObj = isObject(value);
- if (isObj) {
- var className = toString.call(value);
- if (!cloneableClasses[className] || (!support.nodeClass && isNode(value))) {
- return value;
- }
- var ctor = ctorByClass[className];
- switch (className) {
- case boolClass:
- case dateClass:
- return new ctor(+value);
-
- case numberClass:
- case stringClass:
- return new ctor(value);
-
- case regexpClass:
- result = ctor(value.source, reFlags.exec(value));
- result.lastIndex = value.lastIndex;
- return result;
- }
- } else {
- return value;
- }
- var isArr = isArray(value);
- if (isDeep) {
- // check for circular references and return corresponding clone
- var initedStack = !stackA;
- stackA || (stackA = getArray());
- stackB || (stackB = getArray());
-
- var length = stackA.length;
- while (length--) {
- if (stackA[length] == value) {
- return stackB[length];
- }
- }
- result = isArr ? ctor(value.length) : {};
- }
- else {
- result = isArr ? slice(value) : assign({}, value);
- }
- // add array properties assigned by `RegExp#exec`
- if (isArr) {
- if (hasOwnProperty.call(value, 'index')) {
- result.index = value.index;
- }
- if (hasOwnProperty.call(value, 'input')) {
- result.input = value.input;
- }
- }
- // exit for shallow clone
- if (!isDeep) {
- return result;
- }
- // add the source value to the stack of traversed objects
- // and associate it with its clone
- stackA.push(value);
- stackB.push(result);
-
- // recursively populate clone (susceptible to call stack limits)
- (isArr ? baseEach : forOwn)(value, function(objValue, key) {
- result[key] = baseClone(objValue, isDeep, callback, stackA, stackB);
- });
-
- if (initedStack) {
- releaseArray(stackA);
- releaseArray(stackB);
- }
- return result;
- }
-
- /**
- * The base implementation of `_.create` without support for assigning
- * properties to the created object.
- *
- * @private
- * @param {Object} prototype The object to inherit from.
- * @returns {Object} Returns the new object.
- */
- function baseCreate(prototype, properties) {
- return isObject(prototype) ? nativeCreate(prototype) : {};
- }
- // fallback for browsers without `Object.create`
- if (!nativeCreate) {
- baseCreate = (function() {
- function Object() {}
- return function(prototype) {
- if (isObject(prototype)) {
- Object.prototype = prototype;
- var result = new Object;
- Object.prototype = null;
- }
- return result || context.Object();
- };
- }());
- }
-
- /**
- * The base implementation of `_.createCallback` without support for creating
- * "_.pluck" or "_.where" style callbacks.
- *
- * @private
- * @param {*} [func=identity] The value to convert to a callback.
- * @param {*} [thisArg] The `this` binding of the created callback.
- * @param {number} [argCount] The number of arguments the callback accepts.
- * @returns {Function} Returns a callback function.
- */
- function baseCreateCallback(func, thisArg, argCount) {
- if (typeof func != 'function') {
- return identity;
- }
- // exit early for no `thisArg` or already bound by `Function#bind`
- if (typeof thisArg == 'undefined' || !('prototype' in func)) {
- return func;
- }
- var bindData = func.__bindData__;
- if (typeof bindData == 'undefined') {
- if (support.funcNames) {
- bindData = !func.name;
- }
- bindData = bindData || !support.funcDecomp;
- if (!bindData) {
- var source = fnToString.call(func);
- if (!support.funcNames) {
- bindData = !reFuncName.test(source);
- }
- if (!bindData) {
- // checks if `func` references the `this` keyword and stores the result
- bindData = reThis.test(source);
- setBindData(func, bindData);
- }
- }
- }
- // exit early if there are no `this` references or `func` is bound
- if (bindData === false || (bindData !== true && bindData[1] & 1)) {
- return func;
- }
- switch (argCount) {
- case 1: return function(value) {
- return func.call(thisArg, value);
- };
- case 2: return function(a, b) {
- return func.call(thisArg, a, b);
- };
- case 3: return function(value, index, collection) {
- return func.call(thisArg, value, index, collection);
- };
- case 4: return function(accumulator, value, index, collection) {
- return func.call(thisArg, accumulator, value, index, collection);
- };
- }
- return bind(func, thisArg);
- }
-
- /**
- * The base implementation of `createWrapper` that creates the wrapper and
- * sets its meta data.
- *
- * @private
- * @param {Array} bindData The bind data array.
- * @returns {Function} Returns the new function.
- */
- function baseCreateWrapper(bindData) {
- var func = bindData[0],
- bitmask = bindData[1],
- partialArgs = bindData[2],
- partialRightArgs = bindData[3],
- thisArg = bindData[4],
- arity = bindData[5];
-
- var isBind = bitmask & 1,
- isBindKey = bitmask & 2,
- isCurry = bitmask & 4,
- isCurryBound = bitmask & 8,
- key = func;
-
- function bound() {
- var thisBinding = isBind ? thisArg : this;
- if (partialArgs) {
- var args = slice(partialArgs);
- push.apply(args, arguments);
- }
- if (partialRightArgs || isCurry) {
- args || (args = slice(arguments));
- if (partialRightArgs) {
- push.apply(args, partialRightArgs);
- }
- if (isCurry && args.length < arity) {
- bitmask |= 16 & ~32;
- return baseCreateWrapper([func, (isCurryBound ? bitmask : bitmask & ~3), args, null, thisArg, arity]);
- }
- }
- args || (args = arguments);
- if (isBindKey) {
- func = thisBinding[key];
- }
- if (this instanceof bound) {
- thisBinding = baseCreate(func.prototype);
- var result = func.apply(thisBinding, args);
- return isObject(result) ? result : thisBinding;
- }
- return func.apply(thisBinding, args);
- }
- setBindData(bound, bindData);
- return bound;
- }
-
- /**
- * The base implementation of `_.difference` that accepts a single array
- * of values to exclude.
- *
- * @private
- * @param {Array} array The array to process.
- * @param {Array} [values] The array of values to exclude.
- * @returns {Array} Returns a new array of filtered values.
- */
- function baseDifference(array, values) {
- var index = -1,
- indexOf = getIndexOf(),
- length = array ? array.length : 0,
- isLarge = length >= largeArraySize && indexOf === baseIndexOf,
- result = [];
-
- if (isLarge) {
- var cache = createCache(values);
- if (cache) {
- indexOf = cacheIndexOf;
- values = cache;
- } else {
- isLarge = false;
- }
- }
- while (++index < length) {
- var value = array[index];
- if (indexOf(values, value) < 0) {
- result.push(value);
- }
- }
- if (isLarge) {
- releaseObject(values);
- }
- return result;
- }
-
- /**
- * The base implementation of `_.flatten` without support for callback
- * shorthands or `thisArg` binding.
- *
- * @private
- * @param {Array} array The array to flatten.
- * @param {boolean} [isShallow=false] A flag to restrict flattening to a single level.
- * @param {boolean} [isStrict=false] A flag to restrict flattening to arrays and `arguments` objects.
- * @param {number} [fromIndex=0] The index to start from.
- * @returns {Array} Returns a new flattened array.
- */
- function baseFlatten(array, isShallow, isStrict, fromIndex) {
- var index = (fromIndex || 0) - 1,
- length = array ? array.length : 0,
- result = [];
-
- while (++index < length) {
- var value = array[index];
-
- if (value && typeof value == 'object' && typeof value.length == 'number'
- && (isArray(value) || isArguments(value))) {
- // recursively flatten arrays (susceptible to call stack limits)
- if (!isShallow) {
- value = baseFlatten(value, isShallow, isStrict);
- }
- var valIndex = -1,
- valLength = value.length,
- resIndex = result.length;
-
- result.length += valLength;
- while (++valIndex < valLength) {
- result[resIndex++] = value[valIndex];
- }
- } else if (!isStrict) {
- result.push(value);
- }
- }
- return result;
- }
-
- /**
- * The base implementation of `_.isEqual`, without support for `thisArg` binding,
- * that allows partial "_.where" style comparisons.
- *
- * @private
- * @param {*} a The value to compare.
- * @param {*} b The other value to compare.
- * @param {Function} [callback] The function to customize comparing values.
- * @param {Function} [isWhere=false] A flag to indicate performing partial comparisons.
- * @param {Array} [stackA=[]] Tracks traversed `a` objects.
- * @param {Array} [stackB=[]] Tracks traversed `b` objects.
- * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
- */
- function baseIsEqual(a, b, callback, isWhere, stackA, stackB) {
- // used to indicate that when comparing objects, `a` has at least the properties of `b`
- if (callback) {
- var result = callback(a, b);
- if (typeof result != 'undefined') {
- return !!result;
- }
- }
- // exit early for identical values
- if (a === b) {
- // treat `+0` vs. `-0` as not equal
- return a !== 0 || (1 / a == 1 / b);
- }
- var type = typeof a,
- otherType = typeof b;
-
- // exit early for unlike primitive values
- if (a === a &&
- !(a && objectTypes[type]) &&
- !(b && objectTypes[otherType])) {
- return false;
- }
- // exit early for `null` and `undefined` avoiding ES3's Function#call behavior
- // http://es5.github.io/#x15.3.4.4
- if (a == null || b == null) {
- return a === b;
- }
- // compare [[Class]] names
- var className = toString.call(a),
- otherClass = toString.call(b);
-
- if (className == argsClass) {
- className = objectClass;
- }
- if (otherClass == argsClass) {
- otherClass = objectClass;
- }
- if (className != otherClass) {
- return false;
- }
- switch (className) {
- case boolClass:
- case dateClass:
- // coerce dates and booleans to numbers, dates to milliseconds and booleans
- // to `1` or `0` treating invalid dates coerced to `NaN` as not equal
- return +a == +b;
-
- case numberClass:
- // treat `NaN` vs. `NaN` as equal
- return (a != +a)
- ? b != +b
- // but treat `+0` vs. `-0` as not equal
- : (a == 0 ? (1 / a == 1 / b) : a == +b);
-
- case regexpClass:
- case stringClass:
- // coerce regexes to strings (http://es5.github.io/#x15.10.6.4)
- // treat string primitives and their corresponding object instances as equal
- return a == String(b);
- }
- var isArr = className == arrayClass;
- if (!isArr) {
- // unwrap any `lodash` wrapped values
- var aWrapped = hasOwnProperty.call(a, '__wrapped__'),
- bWrapped = hasOwnProperty.call(b, '__wrapped__');
-
- if (aWrapped || bWrapped) {
- return baseIsEqual(aWrapped ? a.__wrapped__ : a, bWrapped ? b.__wrapped__ : b, callback, isWhere, stackA, stackB);
- }
- // exit for functions and DOM nodes
- if (className != objectClass || (!support.nodeClass && (isNode(a) || isNode(b)))) {
- return false;
- }
- // in older versions of Opera, `arguments` objects have `Array` constructors
- var ctorA = !support.argsObject && isArguments(a) ? Object : a.constructor,
- ctorB = !support.argsObject && isArguments(b) ? Object : b.constructor;
-
- // non `Object` object instances with different constructors are not equal
- if (ctorA != ctorB &&
- !(isFunction(ctorA) && ctorA instanceof ctorA && isFunction(ctorB) && ctorB instanceof ctorB) &&
- ('constructor' in a && 'constructor' in b)
- ) {
- return false;
- }
- }
- // assume cyclic structures are equal
- // the algorithm for detecting cyclic structures is adapted from ES 5.1
- // section 15.12.3, abstract operation `JO` (http://es5.github.io/#x15.12.3)
- var initedStack = !stackA;
- stackA || (stackA = getArray());
- stackB || (stackB = getArray());
-
- var length = stackA.length;
- while (length--) {
- if (stackA[length] == a) {
- return stackB[length] == b;
- }
- }
- var size = 0;
- result = true;
-
- // add `a` and `b` to the stack of traversed objects
- stackA.push(a);
- stackB.push(b);
-
- // recursively compare objects and arrays (susceptible to call stack limits)
- if (isArr) {
- // compare lengths to determine if a deep comparison is necessary
- length = a.length;
- size = b.length;
- result = size == length;
-
- if (result || isWhere) {
- // deep compare the contents, ignoring non-numeric properties
- while (size--) {
- var index = length,
- value = b[size];
-
- if (isWhere) {
- while (index--) {
- if ((result = baseIsEqual(a[index], value, callback, isWhere, stackA, stackB))) {
- break;
- }
- }
- } else if (!(result = baseIsEqual(a[size], value, callback, isWhere, stackA, stackB))) {
- break;
- }
- }
- }
- }
- else {
- // deep compare objects using `forIn`, instead of `forOwn`, to avoid `Object.keys`
- // which, in this case, is more costly
- forIn(b, function(value, key, b) {
- if (hasOwnProperty.call(b, key)) {
- // count the number of properties.
- size++;
- // deep compare each property value.
- return (result = hasOwnProperty.call(a, key) && baseIsEqual(a[key], value, callback, isWhere, stackA, stackB));
- }
- });
-
- if (result && !isWhere) {
- // ensure both objects have the same number of properties
- forIn(a, function(value, key, a) {
- if (hasOwnProperty.call(a, key)) {
- // `size` will be `-1` if `a` has more properties than `b`
- return (result = --size > -1);
- }
- });
- }
- }
- stackA.pop();
- stackB.pop();
-
- if (initedStack) {
- releaseArray(stackA);
- releaseArray(stackB);
- }
- return result;
- }
-
- /**
- * The base implementation of `_.merge` without argument juggling or support
- * for `thisArg` binding.
- *
- * @private
- * @param {Object} object The destination object.
- * @param {Object} source The source object.
- * @param {Function} [callback] The function to customize merging properties.
- * @param {Array} [stackA=[]] Tracks traversed source objects.
- * @param {Array} [stackB=[]] Associates values with source counterparts.
- */
- function baseMerge(object, source, callback, stackA, stackB) {
- (isArray(source) ? forEach : forOwn)(source, function(source, key) {
- var found,
- isArr,
- result = source,
- value = object[key];
-
- if (source && ((isArr = isArray(source)) || isPlainObject(source))) {
- // avoid merging previously merged cyclic sources
- var stackLength = stackA.length;
- while (stackLength--) {
- if ((found = stackA[stackLength] == source)) {
- value = stackB[stackLength];
- break;
- }
- }
- if (!found) {
- var isShallow;
- if (callback) {
- result = callback(value, source);
- if ((isShallow = typeof result != 'undefined')) {
- value = result;
- }
- }
- if (!isShallow) {
- value = isArr
- ? (isArray(value) ? value : [])
- : (isPlainObject(value) ? value : {});
- }
- // add `source` and associated `value` to the stack of traversed objects
- stackA.push(source);
- stackB.push(value);
-
- // recursively merge objects and arrays (susceptible to call stack limits)
- if (!isShallow) {
- baseMerge(value, source, callback, stackA, stackB);
- }
- }
- }
- else {
- if (callback) {
- result = callback(value, source);
- if (typeof result == 'undefined') {
- result = source;
- }
- }
- if (typeof result != 'undefined') {
- value = result;
- }
- }
- object[key] = value;
- });
- }
-
- /**
- * The base implementation of `_.random` without argument juggling or support
- * for returning floating-point numbers.
- *
- * @private
- * @param {number} min The minimum possible value.
- * @param {number} max The maximum possible value.
- * @returns {number} Returns a random number.
- */
- function baseRandom(min, max) {
- return min + floor(nativeRandom() * (max - min + 1));
- }
-
- /**
- * The base implementation of `_.uniq` without support for callback shorthands
- * or `thisArg` binding.
- *
- * @private
- * @param {Array} array The array to process.
- * @param {boolean} [isSorted=false] A flag to indicate that `array` is sorted.
- * @param {Function} [callback] The function called per iteration.
- * @returns {Array} Returns a duplicate-value-free array.
- */
- function baseUniq(array, isSorted, callback) {
- var index = -1,
- indexOf = getIndexOf(),
- length = array ? array.length : 0,
- result = [];
-
- var isLarge = !isSorted && length >= largeArraySize && indexOf === baseIndexOf,
- seen = (callback || isLarge) ? getArray() : result;
-
- if (isLarge) {
- var cache = createCache(seen);
- indexOf = cacheIndexOf;
- seen = cache;
- }
- while (++index < length) {
- var value = array[index],
- computed = callback ? callback(value, index, array) : value;
-
- if (isSorted
- ? !index || seen[seen.length - 1] !== computed
- : indexOf(seen, computed) < 0
- ) {
- if (callback || isLarge) {
- seen.push(computed);
- }
- result.push(value);
- }
- }
- if (isLarge) {
- releaseArray(seen.array);
- releaseObject(seen);
- } else if (callback) {
- releaseArray(seen);
- }
- return result;
- }
-
- /**
- * Creates a function that aggregates a collection, creating an object composed
- * of keys generated from the results of running each element of the collection
- * through a callback. The given `setter` function sets the keys and values
- * of the composed object.
- *
- * @private
- * @param {Function} setter The setter function.
- * @returns {Function} Returns the new aggregator function.
- */
- function createAggregator(setter) {
- return function(collection, callback, thisArg) {
- var result = {};
- callback = lodash.createCallback(callback, thisArg, 3);
-
- if (isArray(collection)) {
- var index = -1,
- length = collection.length;
-
- while (++index < length) {
- var value = collection[index];
- setter(result, value, callback(value, index, collection), collection);
- }
- } else {
- baseEach(collection, function(value, key, collection) {
- setter(result, value, callback(value, key, collection), collection);
- });
- }
- return result;
- };
- }
-
- /**
- * Creates a function that, when called, either curries or invokes `func`
- * with an optional `this` binding and partially applied arguments.
- *
- * @private
- * @param {Function|string} func The function or method name to reference.
- * @param {number} bitmask The bitmask of method flags to compose.
- * The bitmask may be composed of the following flags:
- * 1 - `_.bind`
- * 2 - `_.bindKey`
- * 4 - `_.curry`
- * 8 - `_.curry` (bound)
- * 16 - `_.partial`
- * 32 - `_.partialRight`
- * @param {Array} [partialArgs] An array of arguments to prepend to those
- * provided to the new function.
- * @param {Array} [partialRightArgs] An array of arguments to append to those
- * provided to the new function.
- * @param {*} [thisArg] The `this` binding of `func`.
- * @param {number} [arity] The arity of `func`.
- * @returns {Function} Returns the new function.
- */
- function createWrapper(func, bitmask, partialArgs, partialRightArgs, thisArg, arity) {
- var isBind = bitmask & 1,
- isBindKey = bitmask & 2,
- isCurry = bitmask & 4,
- isCurryBound = bitmask & 8,
- isPartial = bitmask & 16,
- isPartialRight = bitmask & 32;
-
- if (!isBindKey && !isFunction(func)) {
- throw new TypeError;
- }
- if (isPartial && !partialArgs.length) {
- bitmask &= ~16;
- isPartial = partialArgs = false;
- }
- if (isPartialRight && !partialRightArgs.length) {
- bitmask &= ~32;
- isPartialRight = partialRightArgs = false;
- }
- var bindData = func && func.__bindData__;
- if (bindData && bindData !== true) {
- // clone `bindData`
- bindData = slice(bindData);
- if (bindData[2]) {
- bindData[2] = slice(bindData[2]);
- }
- if (bindData[3]) {
- bindData[3] = slice(bindData[3]);
- }
- // set `thisBinding` is not previously bound
- if (isBind && !(bindData[1] & 1)) {
- bindData[4] = thisArg;
- }
- // set if previously bound but not currently (subsequent curried functions)
- if (!isBind && bindData[1] & 1) {
- bitmask |= 8;
- }
- // set curried arity if not yet set
- if (isCurry && !(bindData[1] & 4)) {
- bindData[5] = arity;
- }
- // append partial left arguments
- if (isPartial) {
- push.apply(bindData[2] || (bindData[2] = []), partialArgs);
- }
- // append partial right arguments
- if (isPartialRight) {
- unshift.apply(bindData[3] || (bindData[3] = []), partialRightArgs);
- }
- // merge flags
- bindData[1] |= bitmask;
- return createWrapper.apply(null, bindData);
- }
- // fast path for `_.bind`
- var creater = (bitmask == 1 || bitmask === 17) ? baseBind : baseCreateWrapper;
- return creater([func, bitmask, partialArgs, partialRightArgs, thisArg, arity]);
- }
-
- /**
- * Creates compiled iteration functions.
- *
- * @private
- * @param {...Object} [options] The compile options object(s).
- * @param {string} [options.array] Code to determine if the iterable is an array or array-like.
- * @param {boolean} [options.useHas] Specify using `hasOwnProperty` checks in the object loop.
- * @param {Function} [options.keys] A reference to `_.keys` for use in own property iteration.
- * @param {string} [options.args] A comma separated string of iteration function arguments.
- * @param {string} [options.top] Code to execute before the iteration branches.
- * @param {string} [options.loop] Code to execute in the object loop.
- * @param {string} [options.bottom] Code to execute after the iteration branches.
- * @returns {Function} Returns the compiled function.
- */
- function createIterator() {
- // data properties
- iteratorData.shadowedProps = shadowedProps;
-
- // iterator options
- iteratorData.array = iteratorData.bottom = iteratorData.loop = iteratorData.top = '';
- iteratorData.init = 'iterable';
- iteratorData.useHas = true;
-
- // merge options into a template data object
- for (var object, index = 0; object = arguments[index]; index++) {
- for (var key in object) {
- iteratorData[key] = object[key];
- }
- }
- var args = iteratorData.args;
- iteratorData.firstArg = /^[^,]+/.exec(args)[0];
-
- // create the function factory
- var factory = Function(
- 'baseCreateCallback, errorClass, errorProto, hasOwnProperty, ' +
- 'indicatorObject, isArguments, isArray, isString, keys, objectProto, ' +
- 'objectTypes, nonEnumProps, stringClass, stringProto, toString',
- 'return function(' + args + ') {\n' + iteratorTemplate(iteratorData) + '\n}'
- );
-
- // return the compiled function
- return factory(
- baseCreateCallback, errorClass, errorProto, hasOwnProperty,
- indicatorObject, isArguments, isArray, isString, iteratorData.keys, objectProto,
- objectTypes, nonEnumProps, stringClass, stringProto, toString
- );
- }
-
- /**
- * Used by `escape` to convert characters to HTML entities.
- *
- * @private
- * @param {string} match The matched character to escape.
- * @returns {string} Returns the escaped character.
- */
- function escapeHtmlChar(match) {
- return htmlEscapes[match];
- }
-
- /**
- * Gets the appropriate "indexOf" function. If the `_.indexOf` method is
- * customized, this method returns the custom method, otherwise it returns
- * the `baseIndexOf` function.
- *
- * @private
- * @returns {Function} Returns the "indexOf" function.
- */
- function getIndexOf() {
- var result = (result = lodash.indexOf) === indexOf ? baseIndexOf : result;
- return result;
- }
-
- /**
- * Checks if `value` is a native function.
- *
- * @private
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if the `value` is a native function, else `false`.
- */
- function isNative(value) {
- return typeof value == 'function' && reNative.test(value);
- }
-
- /**
- * Sets `this` binding data on a given function.
- *
- * @private
- * @param {Function} func The function to set data on.
- * @param {Array} value The data array to set.
- */
- var setBindData = !defineProperty ? noop : function(func, value) {
- descriptor.value = value;
- defineProperty(func, '__bindData__', descriptor);
- };
-
- /**
- * A fallback implementation of `isPlainObject` which checks if a given value
- * is an object created by the `Object` constructor, assuming objects created
- * by the `Object` constructor have no inherited enumerable properties and that
- * there are no `Object.prototype` extensions.
- *
- * @private
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
- */
- function shimIsPlainObject(value) {
- var ctor,
- result;
-
- // avoid non Object objects, `arguments` objects, and DOM elements
- if (!(value && toString.call(value) == objectClass) ||
- (ctor = value.constructor, isFunction(ctor) && !(ctor instanceof ctor)) ||
- (!support.argsClass && isArguments(value)) ||
- (!support.nodeClass && isNode(value))) {
- return false;
- }
- // IE < 9 iterates inherited properties before own properties. If the first
- // iterated property is an object's own property then there are no inherited
- // enumerable properties.
- if (support.ownLast) {
- forIn(value, function(value, key, object) {
- result = hasOwnProperty.call(object, key);
- return false;
- });
- return result !== false;
- }
- // In most environments an object's own properties are iterated before
- // its inherited properties. If the last iterated property is an object's
- // own property then there are no inherited enumerable properties.
- forIn(value, function(value, key) {
- result = key;
- });
- return typeof result == 'undefined' || hasOwnProperty.call(value, result);
- }
-
- /**
- * Used by `unescape` to convert HTML entities to characters.
- *
- * @private
- * @param {string} match The matched character to unescape.
- * @returns {string} Returns the unescaped character.
- */
- function unescapeHtmlChar(match) {
- return htmlUnescapes[match];
- }
-
- /*--------------------------------------------------------------------------*/
-
- /**
- * Checks if `value` is an `arguments` object.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if the `value` is an `arguments` object, else `false`.
- * @example
- *
- * (function() { return _.isArguments(arguments); })(1, 2, 3);
- * // => true
- *
- * _.isArguments([1, 2, 3]);
- * // => false
- */
- function isArguments(value) {
- return value && typeof value == 'object' && typeof value.length == 'number' &&
- toString.call(value) == argsClass || false;
- }
- // fallback for browsers that can't detect `arguments` objects by [[Class]]
- if (!support.argsClass) {
- isArguments = function(value) {
- return value && typeof value == 'object' && typeof value.length == 'number' &&
- hasOwnProperty.call(value, 'callee') && !propertyIsEnumerable.call(value, 'callee') || false;
- };
- }
-
- /**
- * Checks if `value` is an array.
- *
- * @static
- * @memberOf _
- * @type Function
- * @category Objects
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if the `value` is an array, else `false`.
- * @example
- *
- * (function() { return _.isArray(arguments); })();
- * // => false
- *
- * _.isArray([1, 2, 3]);
- * // => true
- */
- var isArray = nativeIsArray || function(value) {
- return value && typeof value == 'object' && typeof value.length == 'number' &&
- toString.call(value) == arrayClass || false;
- };
-
- /**
- * A fallback implementation of `Object.keys` which produces an array of the
- * given object's own enumerable property names.
- *
- * @private
- * @type Function
- * @param {Object} object The object to inspect.
- * @returns {Array} Returns an array of property names.
- */
- var shimKeys = createIterator({
- 'args': 'object',
- 'init': '[]',
- 'top': 'if (!(objectTypes[typeof object])) return result',
- 'loop': 'result.push(index)'
- });
-
- /**
- * Creates an array composed of the own enumerable property names of an object.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {Object} object The object to inspect.
- * @returns {Array} Returns an array of property names.
- * @example
- *
- * _.keys({ 'one': 1, 'two': 2, 'three': 3 });
- * // => ['one', 'two', 'three'] (property order is not guaranteed across environments)
- */
- var keys = !nativeKeys ? shimKeys : function(object) {
- if (!isObject(object)) {
- return [];
- }
- if ((support.enumPrototypes && typeof object == 'function') ||
- (support.nonEnumArgs && object.length && isArguments(object))) {
- return shimKeys(object);
- }
- return nativeKeys(object);
- };
-
- /** Reusable iterator options shared by `each`, `forIn`, and `forOwn` */
- var eachIteratorOptions = {
- 'args': 'collection, callback, thisArg',
- 'top': "callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3)",
- 'array': "typeof length == 'number'",
- 'keys': keys,
- 'loop': 'if (callback(iterable[index], index, collection) === false) return result'
- };
-
- /** Reusable iterator options for `assign` and `defaults` */
- var defaultsIteratorOptions = {
- 'args': 'object, source, guard',
- 'top':
- 'var args = arguments,\n' +
- ' argsIndex = 0,\n' +
- " argsLength = typeof guard == 'number' ? 2 : args.length;\n" +
- 'while (++argsIndex < argsLength) {\n' +
- ' iterable = args[argsIndex];\n' +
- ' if (iterable && objectTypes[typeof iterable]) {',
- 'keys': keys,
- 'loop': "if (typeof result[index] == 'undefined') result[index] = iterable[index]",
- 'bottom': ' }\n}'
- };
-
- /** Reusable iterator options for `forIn` and `forOwn` */
- var forOwnIteratorOptions = {
- 'top': 'if (!objectTypes[typeof iterable]) return result;\n' + eachIteratorOptions.top,
- 'array': false
- };
-
- /**
- * Used to convert characters to HTML entities:
- *
- * Though the `>` character is escaped for symmetry, characters like `>` and `/`
- * don't require escaping in HTML and have no special meaning unless they're part
- * of a tag or an unquoted attribute value.
- * http://mathiasbynens.be/notes/ambiguous-ampersands (under "semi-related fun fact")
- */
- var htmlEscapes = {
- '&': '&',
- '<': '<',
- '>': '>',
- '"': '"',
- "'": '''
- };
-
- /** Used to convert HTML entities to characters */
- var htmlUnescapes = invert(htmlEscapes);
-
- /** Used to match HTML entities and HTML characters */
- var reEscapedHtml = RegExp('(' + keys(htmlUnescapes).join('|') + ')', 'g'),
- reUnescapedHtml = RegExp('[' + keys(htmlEscapes).join('') + ']', 'g');
-
- /**
- * A function compiled to iterate `arguments` objects, arrays, objects, and
- * strings consistenly across environments, executing the callback for each
- * element in the collection. The callback is bound to `thisArg` and invoked
- * with three arguments; (value, index|key, collection). Callbacks may exit
- * iteration early by explicitly returning `false`.
- *
- * @private
- * @type Function
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function} [callback=identity] The function called per iteration.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Array|Object|string} Returns `collection`.
- */
- var baseEach = createIterator(eachIteratorOptions);
-
- /*--------------------------------------------------------------------------*/
-
- /**
- * Assigns own enumerable properties of source object(s) to the destination
- * object. Subsequent sources will overwrite property assignments of previous
- * sources. If a callback is provided it will be executed to produce the
- * assigned values. The callback is bound to `thisArg` and invoked with two
- * arguments; (objectValue, sourceValue).
- *
- * @static
- * @memberOf _
- * @type Function
- * @alias extend
- * @category Objects
- * @param {Object} object The destination object.
- * @param {...Object} [source] The source objects.
- * @param {Function} [callback] The function to customize assigning values.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Object} Returns the destination object.
- * @example
- *
- * _.assign({ 'name': 'fred' }, { 'employer': 'slate' });
- * // => { 'name': 'fred', 'employer': 'slate' }
- *
- * var defaults = _.partialRight(_.assign, function(a, b) {
- * return typeof a == 'undefined' ? b : a;
- * });
- *
- * var object = { 'name': 'barney' };
- * defaults(object, { 'name': 'fred', 'employer': 'slate' });
- * // => { 'name': 'barney', 'employer': 'slate' }
- */
- var assign = createIterator(defaultsIteratorOptions, {
- 'top':
- defaultsIteratorOptions.top.replace(';',
- ';\n' +
- "if (argsLength > 3 && typeof args[argsLength - 2] == 'function') {\n" +
- ' var callback = baseCreateCallback(args[--argsLength - 1], args[argsLength--], 2);\n' +
- "} else if (argsLength > 2 && typeof args[argsLength - 1] == 'function') {\n" +
- ' callback = args[--argsLength];\n' +
- '}'
- ),
- 'loop': 'result[index] = callback ? callback(result[index], iterable[index]) : iterable[index]'
- });
-
- /**
- * Creates a clone of `value`. If `isDeep` is `true` nested objects will also
- * be cloned, otherwise they will be assigned by reference. If a callback
- * is provided it will be executed to produce the cloned values. If the
- * callback returns `undefined` cloning will be handled by the method instead.
- * The callback is bound to `thisArg` and invoked with one argument; (value).
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {*} value The value to clone.
- * @param {boolean} [isDeep=false] Specify a deep clone.
- * @param {Function} [callback] The function to customize cloning values.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {*} Returns the cloned value.
- * @example
- *
- * var characters = [
- * { 'name': 'barney', 'age': 36 },
- * { 'name': 'fred', 'age': 40 }
- * ];
- *
- * var shallow = _.clone(characters);
- * shallow[0] === characters[0];
- * // => true
- *
- * var deep = _.clone(characters, true);
- * deep[0] === characters[0];
- * // => false
- *
- * _.mixin({
- * 'clone': _.partialRight(_.clone, function(value) {
- * return _.isElement(value) ? value.cloneNode(false) : undefined;
- * })
- * });
- *
- * var clone = _.clone(document.body);
- * clone.childNodes.length;
- * // => 0
- */
- function clone(value, isDeep, callback, thisArg) {
- // allows working with "Collections" methods without using their `index`
- // and `collection` arguments for `isDeep` and `callback`
- if (typeof isDeep != 'boolean' && isDeep != null) {
- thisArg = callback;
- callback = isDeep;
- isDeep = false;
- }
- return baseClone(value, isDeep, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 1));
- }
-
- /**
- * Creates a deep clone of `value`. If a callback is provided it will be
- * executed to produce the cloned values. If the callback returns `undefined`
- * cloning will be handled by the method instead. The callback is bound to
- * `thisArg` and invoked with one argument; (value).
- *
- * Note: This method is loosely based on the structured clone algorithm. Functions
- * and DOM nodes are **not** cloned. The enumerable properties of `arguments` objects and
- * objects created by constructors other than `Object` are cloned to plain `Object` objects.
- * See http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {*} value The value to deep clone.
- * @param {Function} [callback] The function to customize cloning values.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {*} Returns the deep cloned value.
- * @example
- *
- * var characters = [
- * { 'name': 'barney', 'age': 36 },
- * { 'name': 'fred', 'age': 40 }
- * ];
- *
- * var deep = _.cloneDeep(characters);
- * deep[0] === characters[0];
- * // => false
- *
- * var view = {
- * 'label': 'docs',
- * 'node': element
- * };
- *
- * var clone = _.cloneDeep(view, function(value) {
- * return _.isElement(value) ? value.cloneNode(true) : undefined;
- * });
- *
- * clone.node == view.node;
- * // => false
- */
- function cloneDeep(value, callback, thisArg) {
- return baseClone(value, true, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 1));
- }
-
- /**
- * Creates an object that inherits from the given `prototype` object. If a
- * `properties` object is provided its own enumerable properties are assigned
- * to the created object.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {Object} prototype The object to inherit from.
- * @param {Object} [properties] The properties to assign to the object.
- * @returns {Object} Returns the new object.
- * @example
- *
- * function Shape() {
- * this.x = 0;
- * this.y = 0;
- * }
- *
- * function Circle() {
- * Shape.call(this);
- * }
- *
- * Circle.prototype = _.create(Shape.prototype, { 'constructor': Circle });
- *
- * var circle = new Circle;
- * circle instanceof Circle;
- * // => true
- *
- * circle instanceof Shape;
- * // => true
- */
- function create(prototype, properties) {
- var result = baseCreate(prototype);
- return properties ? assign(result, properties) : result;
- }
-
- /**
- * Assigns own enumerable properties of source object(s) to the destination
- * object for all destination properties that resolve to `undefined`. Once a
- * property is set, additional defaults of the same property will be ignored.
- *
- * @static
- * @memberOf _
- * @type Function
- * @category Objects
- * @param {Object} object The destination object.
- * @param {...Object} [source] The source objects.
- * @param- {Object} [guard] Allows working with `_.reduce` without using its
- * `key` and `object` arguments as sources.
- * @returns {Object} Returns the destination object.
- * @example
- *
- * var object = { 'name': 'barney' };
- * _.defaults(object, { 'name': 'fred', 'employer': 'slate' });
- * // => { 'name': 'barney', 'employer': 'slate' }
- */
- var defaults = createIterator(defaultsIteratorOptions);
-
- /**
- * This method is like `_.findIndex` except that it returns the key of the
- * first element that passes the callback check, instead of the element itself.
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {Object} object The object to search.
- * @param {Function|Object|string} [callback=identity] The function called per
- * iteration. If a property name or object is provided it will be used to
- * create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {string|undefined} Returns the key of the found element, else `undefined`.
- * @example
- *
- * var characters = {
- * 'barney': { 'age': 36, 'blocked': false },
- * 'fred': { 'age': 40, 'blocked': true },
- * 'pebbles': { 'age': 1, 'blocked': false }
- * };
- *
- * _.findKey(characters, function(chr) {
- * return chr.age < 40;
- * });
- * // => 'barney' (property order is not guaranteed across environments)
- *
- * // using "_.where" callback shorthand
- * _.findKey(characters, { 'age': 1 });
- * // => 'pebbles'
- *
- * // using "_.pluck" callback shorthand
- * _.findKey(characters, 'blocked');
- * // => 'fred'
- */
- function findKey(object, callback, thisArg) {
- var result;
- callback = lodash.createCallback(callback, thisArg, 3);
- forOwn(object, function(value, key, object) {
- if (callback(value, key, object)) {
- result = key;
- return false;
- }
- });
- return result;
- }
-
- /**
- * This method is like `_.findKey` except that it iterates over elements
- * of a `collection` in the opposite order.
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {Object} object The object to search.
- * @param {Function|Object|string} [callback=identity] The function called per
- * iteration. If a property name or object is provided it will be used to
- * create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {string|undefined} Returns the key of the found element, else `undefined`.
- * @example
- *
- * var characters = {
- * 'barney': { 'age': 36, 'blocked': true },
- * 'fred': { 'age': 40, 'blocked': false },
- * 'pebbles': { 'age': 1, 'blocked': true }
- * };
- *
- * _.findLastKey(characters, function(chr) {
- * return chr.age < 40;
- * });
- * // => returns `pebbles`, assuming `_.findKey` returns `barney`
- *
- * // using "_.where" callback shorthand
- * _.findLastKey(characters, { 'age': 40 });
- * // => 'fred'
- *
- * // using "_.pluck" callback shorthand
- * _.findLastKey(characters, 'blocked');
- * // => 'pebbles'
- */
- function findLastKey(object, callback, thisArg) {
- var result;
- callback = lodash.createCallback(callback, thisArg, 3);
- forOwnRight(object, function(value, key, object) {
- if (callback(value, key, object)) {
- result = key;
- return false;
- }
- });
- return result;
- }
-
- /**
- * Iterates over own and inherited enumerable properties of an object,
- * executing the callback for each property. The callback is bound to `thisArg`
- * and invoked with three arguments; (value, key, object). Callbacks may exit
- * iteration early by explicitly returning `false`.
- *
- * @static
- * @memberOf _
- * @type Function
- * @category Objects
- * @param {Object} object The object to iterate over.
- * @param {Function} [callback=identity] The function called per iteration.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Object} Returns `object`.
- * @example
- *
- * function Shape() {
- * this.x = 0;
- * this.y = 0;
- * }
- *
- * Shape.prototype.move = function(x, y) {
- * this.x += x;
- * this.y += y;
- * };
- *
- * _.forIn(new Shape, function(value, key) {
- * console.log(key);
- * });
- * // => logs 'x', 'y', and 'move' (property order is not guaranteed across environments)
- */
- var forIn = createIterator(eachIteratorOptions, forOwnIteratorOptions, {
- 'useHas': false
- });
-
- /**
- * This method is like `_.forIn` except that it iterates over elements
- * of a `collection` in the opposite order.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {Object} object The object to iterate over.
- * @param {Function} [callback=identity] The function called per iteration.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Object} Returns `object`.
- * @example
- *
- * function Shape() {
- * this.x = 0;
- * this.y = 0;
- * }
- *
- * Shape.prototype.move = function(x, y) {
- * this.x += x;
- * this.y += y;
- * };
- *
- * _.forInRight(new Shape, function(value, key) {
- * console.log(key);
- * });
- * // => logs 'move', 'y', and 'x' assuming `_.forIn ` logs 'x', 'y', and 'move'
- */
- function forInRight(object, callback, thisArg) {
- var pairs = [];
-
- forIn(object, function(value, key) {
- pairs.push(key, value);
- });
-
- var length = pairs.length;
- callback = baseCreateCallback(callback, thisArg, 3);
- while (length--) {
- if (callback(pairs[length--], pairs[length], object) === false) {
- break;
- }
- }
- return object;
- }
-
- /**
- * Iterates over own enumerable properties of an object, executing the callback
- * for each property. The callback is bound to `thisArg` and invoked with three
- * arguments; (value, key, object). Callbacks may exit iteration early by
- * explicitly returning `false`.
- *
- * @static
- * @memberOf _
- * @type Function
- * @category Objects
- * @param {Object} object The object to iterate over.
- * @param {Function} [callback=identity] The function called per iteration.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Object} Returns `object`.
- * @example
- *
- * _.forOwn({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) {
- * console.log(key);
- * });
- * // => logs '0', '1', and 'length' (property order is not guaranteed across environments)
- */
- var forOwn = createIterator(eachIteratorOptions, forOwnIteratorOptions);
-
- /**
- * This method is like `_.forOwn` except that it iterates over elements
- * of a `collection` in the opposite order.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {Object} object The object to iterate over.
- * @param {Function} [callback=identity] The function called per iteration.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Object} Returns `object`.
- * @example
- *
- * _.forOwnRight({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) {
- * console.log(key);
- * });
- * // => logs 'length', '1', and '0' assuming `_.forOwn` logs '0', '1', and 'length'
- */
- function forOwnRight(object, callback, thisArg) {
- var props = keys(object),
- length = props.length;
-
- callback = baseCreateCallback(callback, thisArg, 3);
- while (length--) {
- var key = props[length];
- if (callback(object[key], key, object) === false) {
- break;
- }
- }
- return object;
- }
-
- /**
- * Creates a sorted array of property names of all enumerable properties,
- * own and inherited, of `object` that have function values.
- *
- * @static
- * @memberOf _
- * @alias methods
- * @category Objects
- * @param {Object} object The object to inspect.
- * @returns {Array} Returns an array of property names that have function values.
- * @example
- *
- * _.functions(_);
- * // => ['all', 'any', 'bind', 'bindAll', 'clone', 'compact', 'compose', ...]
- */
- function functions(object) {
- var result = [];
- forIn(object, function(value, key) {
- if (isFunction(value)) {
- result.push(key);
- }
- });
- return result.sort();
- }
-
- /**
- * Checks if the specified property name exists as a direct property of `object`,
- * instead of an inherited property.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {Object} object The object to inspect.
- * @param {string} key The name of the property to check.
- * @returns {boolean} Returns `true` if key is a direct property, else `false`.
- * @example
- *
- * _.has({ 'a': 1, 'b': 2, 'c': 3 }, 'b');
- * // => true
- */
- function has(object, key) {
- return object ? hasOwnProperty.call(object, key) : false;
- }
-
- /**
- * Creates an object composed of the inverted keys and values of the given object.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {Object} object The object to invert.
- * @returns {Object} Returns the created inverted object.
- * @example
- *
- * _.invert({ 'first': 'fred', 'second': 'barney' });
- * // => { 'fred': 'first', 'barney': 'second' }
- */
- function invert(object) {
- var index = -1,
- props = keys(object),
- length = props.length,
- result = {};
-
- while (++index < length) {
- var key = props[index];
- result[object[key]] = key;
- }
- return result;
- }
-
- /**
- * Checks if `value` is a boolean value.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if the `value` is a boolean value, else `false`.
- * @example
- *
- * _.isBoolean(null);
- * // => false
- */
- function isBoolean(value) {
- return value === true || value === false ||
- value && typeof value == 'object' && toString.call(value) == boolClass || false;
- }
-
- /**
- * Checks if `value` is a date.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if the `value` is a date, else `false`.
- * @example
- *
- * _.isDate(new Date);
- * // => true
- */
- function isDate(value) {
- return value && typeof value == 'object' && toString.call(value) == dateClass || false;
- }
-
- /**
- * Checks if `value` is a DOM element.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if the `value` is a DOM element, else `false`.
- * @example
- *
- * _.isElement(document.body);
- * // => true
- */
- function isElement(value) {
- return value && value.nodeType === 1 || false;
- }
-
- /**
- * Checks if `value` is empty. Arrays, strings, or `arguments` objects with a
- * length of `0` and objects with no own enumerable properties are considered
- * "empty".
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {Array|Object|string} value The value to inspect.
- * @returns {boolean} Returns `true` if the `value` is empty, else `false`.
- * @example
- *
- * _.isEmpty([1, 2, 3]);
- * // => false
- *
- * _.isEmpty({});
- * // => true
- *
- * _.isEmpty('');
- * // => true
- */
- function isEmpty(value) {
- var result = true;
- if (!value) {
- return result;
- }
- var className = toString.call(value),
- length = value.length;
-
- if ((className == arrayClass || className == stringClass ||
- (support.argsClass ? className == argsClass : isArguments(value))) ||
- (className == objectClass && typeof length == 'number' && isFunction(value.splice))) {
- return !length;
- }
- forOwn(value, function() {
- return (result = false);
- });
- return result;
- }
-
- /**
- * Performs a deep comparison between two values to determine if they are
- * equivalent to each other. If a callback is provided it will be executed
- * to compare values. If the callback returns `undefined` comparisons will
- * be handled by the method instead. The callback is bound to `thisArg` and
- * invoked with two arguments; (a, b).
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {*} a The value to compare.
- * @param {*} b The other value to compare.
- * @param {Function} [callback] The function to customize comparing values.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
- * @example
- *
- * var object = { 'name': 'fred' };
- * var copy = { 'name': 'fred' };
- *
- * object == copy;
- * // => false
- *
- * _.isEqual(object, copy);
- * // => true
- *
- * var words = ['hello', 'goodbye'];
- * var otherWords = ['hi', 'goodbye'];
- *
- * _.isEqual(words, otherWords, function(a, b) {
- * var reGreet = /^(?:hello|hi)$/i,
- * aGreet = _.isString(a) && reGreet.test(a),
- * bGreet = _.isString(b) && reGreet.test(b);
- *
- * return (aGreet || bGreet) ? (aGreet == bGreet) : undefined;
- * });
- * // => true
- */
- function isEqual(a, b, callback, thisArg) {
- return baseIsEqual(a, b, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 2));
- }
-
- /**
- * Checks if `value` is, or can be coerced to, a finite number.
- *
- * Note: This is not the same as native `isFinite` which will return true for
- * booleans and empty strings. See http://es5.github.io/#x15.1.2.5.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if the `value` is finite, else `false`.
- * @example
- *
- * _.isFinite(-101);
- * // => true
- *
- * _.isFinite('10');
- * // => true
- *
- * _.isFinite(true);
- * // => false
- *
- * _.isFinite('');
- * // => false
- *
- * _.isFinite(Infinity);
- * // => false
- */
- function isFinite(value) {
- return nativeIsFinite(value) && !nativeIsNaN(parseFloat(value));
- }
-
- /**
- * Checks if `value` is a function.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if the `value` is a function, else `false`.
- * @example
- *
- * _.isFunction(_);
- * // => true
- */
- function isFunction(value) {
- return typeof value == 'function';
- }
- // fallback for older versions of Chrome and Safari
- if (isFunction(/x/)) {
- isFunction = function(value) {
- return typeof value == 'function' && toString.call(value) == funcClass;
- };
- }
-
- /**
- * Checks if `value` is the language type of Object.
- * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if the `value` is an object, else `false`.
- * @example
- *
- * _.isObject({});
- * // => true
- *
- * _.isObject([1, 2, 3]);
- * // => true
- *
- * _.isObject(1);
- * // => false
- */
- function isObject(value) {
- // check if the value is the ECMAScript language type of Object
- // http://es5.github.io/#x8
- // and avoid a V8 bug
- // http://code.google.com/p/v8/issues/detail?id=2291
- return !!(value && objectTypes[typeof value]);
- }
-
- /**
- * Checks if `value` is `NaN`.
- *
- * Note: This is not the same as native `isNaN` which will return `true` for
- * `undefined` and other non-numeric values. See http://es5.github.io/#x15.1.2.4.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if the `value` is `NaN`, else `false`.
- * @example
- *
- * _.isNaN(NaN);
- * // => true
- *
- * _.isNaN(new Number(NaN));
- * // => true
- *
- * isNaN(undefined);
- * // => true
- *
- * _.isNaN(undefined);
- * // => false
- */
- function isNaN(value) {
- // `NaN` as a primitive is the only value that is not equal to itself
- // (perform the [[Class]] check first to avoid errors with some host objects in IE)
- return isNumber(value) && value != +value;
- }
-
- /**
- * Checks if `value` is `null`.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if the `value` is `null`, else `false`.
- * @example
- *
- * _.isNull(null);
- * // => true
- *
- * _.isNull(undefined);
- * // => false
- */
- function isNull(value) {
- return value === null;
- }
-
- /**
- * Checks if `value` is a number.
- *
- * Note: `NaN` is considered a number. See http://es5.github.io/#x8.5.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if the `value` is a number, else `false`.
- * @example
- *
- * _.isNumber(8.4 * 5);
- * // => true
- */
- function isNumber(value) {
- return typeof value == 'number' ||
- value && typeof value == 'object' && toString.call(value) == numberClass || false;
- }
-
- /**
- * Checks if `value` is an object created by the `Object` constructor.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
- * @example
- *
- * function Shape() {
- * this.x = 0;
- * this.y = 0;
- * }
- *
- * _.isPlainObject(new Shape);
- * // => false
- *
- * _.isPlainObject([1, 2, 3]);
- * // => false
- *
- * _.isPlainObject({ 'x': 0, 'y': 0 });
- * // => true
- */
- var isPlainObject = !getPrototypeOf ? shimIsPlainObject : function(value) {
- if (!(value && toString.call(value) == objectClass) || (!support.argsClass && isArguments(value))) {
- return false;
- }
- var valueOf = value.valueOf,
- objProto = isNative(valueOf) && (objProto = getPrototypeOf(valueOf)) && getPrototypeOf(objProto);
-
- return objProto
- ? (value == objProto || getPrototypeOf(value) == objProto)
- : shimIsPlainObject(value);
- };
-
- /**
- * Checks if `value` is a regular expression.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if the `value` is a regular expression, else `false`.
- * @example
- *
- * _.isRegExp(/fred/);
- * // => true
- */
- function isRegExp(value) {
- return value && objectTypes[typeof value] && toString.call(value) == regexpClass || false;
- }
-
- /**
- * Checks if `value` is a string.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if the `value` is a string, else `false`.
- * @example
- *
- * _.isString('fred');
- * // => true
- */
- function isString(value) {
- return typeof value == 'string' ||
- value && typeof value == 'object' && toString.call(value) == stringClass || false;
- }
-
- /**
- * Checks if `value` is `undefined`.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if the `value` is `undefined`, else `false`.
- * @example
- *
- * _.isUndefined(void 0);
- * // => true
- */
- function isUndefined(value) {
- return typeof value == 'undefined';
- }
-
- /**
- * Creates an object with the same keys as `object` and values generated by
- * running each own enumerable property of `object` through the callback.
- * The callback is bound to `thisArg` and invoked with three arguments;
- * (value, key, object).
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {Object} object The object to iterate over.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Array} Returns a new object with values of the results of each `callback` execution.
- * @example
- *
- * _.mapValues({ 'a': 1, 'b': 2, 'c': 3} , function(num) { return num * 3; });
- * // => { 'a': 3, 'b': 6, 'c': 9 }
- *
- * var characters = {
- * 'fred': { 'name': 'fred', 'age': 40 },
- * 'pebbles': { 'name': 'pebbles', 'age': 1 }
- * };
- *
- * // using "_.pluck" callback shorthand
- * _.mapValues(characters, 'age');
- * // => { 'fred': 40, 'pebbles': 1 }
- */
- function mapValues(object, callback, thisArg) {
- var result = {};
- callback = lodash.createCallback(callback, thisArg, 3);
-
- forOwn(object, function(value, key, object) {
- result[key] = callback(value, key, object);
- });
- return result;
- }
-
- /**
- * Recursively merges own enumerable properties of the source object(s), that
- * don't resolve to `undefined` into the destination object. Subsequent sources
- * will overwrite property assignments of previous sources. If a callback is
- * provided it will be executed to produce the merged values of the destination
- * and source properties. If the callback returns `undefined` merging will
- * be handled by the method instead. The callback is bound to `thisArg` and
- * invoked with two arguments; (objectValue, sourceValue).
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {Object} object The destination object.
- * @param {...Object} [source] The source objects.
- * @param {Function} [callback] The function to customize merging properties.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Object} Returns the destination object.
- * @example
- *
- * var names = {
- * 'characters': [
- * { 'name': 'barney' },
- * { 'name': 'fred' }
- * ]
- * };
- *
- * var ages = {
- * 'characters': [
- * { 'age': 36 },
- * { 'age': 40 }
- * ]
- * };
- *
- * _.merge(names, ages);
- * // => { 'characters': [{ 'name': 'barney', 'age': 36 }, { 'name': 'fred', 'age': 40 }] }
- *
- * var food = {
- * 'fruits': ['apple'],
- * 'vegetables': ['beet']
- * };
- *
- * var otherFood = {
- * 'fruits': ['banana'],
- * 'vegetables': ['carrot']
- * };
- *
- * _.merge(food, otherFood, function(a, b) {
- * return _.isArray(a) ? a.concat(b) : undefined;
- * });
- * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot] }
- */
- function merge(object) {
- var args = arguments,
- length = 2;
-
- if (!isObject(object)) {
- return object;
- }
- // allows working with `_.reduce` and `_.reduceRight` without using
- // their `index` and `collection` arguments
- if (typeof args[2] != 'number') {
- length = args.length;
- }
- if (length > 3 && typeof args[length - 2] == 'function') {
- var callback = baseCreateCallback(args[--length - 1], args[length--], 2);
- } else if (length > 2 && typeof args[length - 1] == 'function') {
- callback = args[--length];
- }
- var sources = slice(arguments, 1, length),
- index = -1,
- stackA = getArray(),
- stackB = getArray();
-
- while (++index < length) {
- baseMerge(object, sources[index], callback, stackA, stackB);
- }
- releaseArray(stackA);
- releaseArray(stackB);
- return object;
- }
-
- /**
- * Creates a shallow clone of `object` excluding the specified properties.
- * Property names may be specified as individual arguments or as arrays of
- * property names. If a callback is provided it will be executed for each
- * property of `object` omitting the properties the callback returns truey
- * for. The callback is bound to `thisArg` and invoked with three arguments;
- * (value, key, object).
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {Object} object The source object.
- * @param {Function|...string|string[]} [callback] The properties to omit or the
- * function called per iteration.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Object} Returns an object without the omitted properties.
- * @example
- *
- * _.omit({ 'name': 'fred', 'age': 40 }, 'age');
- * // => { 'name': 'fred' }
- *
- * _.omit({ 'name': 'fred', 'age': 40 }, function(value) {
- * return typeof value == 'number';
- * });
- * // => { 'name': 'fred' }
- */
- function omit(object, callback, thisArg) {
- var result = {};
- if (typeof callback != 'function') {
- var props = [];
- forIn(object, function(value, key) {
- props.push(key);
- });
- props = baseDifference(props, baseFlatten(arguments, true, false, 1));
-
- var index = -1,
- length = props.length;
-
- while (++index < length) {
- var key = props[index];
- result[key] = object[key];
- }
- } else {
- callback = lodash.createCallback(callback, thisArg, 3);
- forIn(object, function(value, key, object) {
- if (!callback(value, key, object)) {
- result[key] = value;
- }
- });
- }
- return result;
- }
-
- /**
- * Creates a two dimensional array of an object's key-value pairs,
- * i.e. `[[key1, value1], [key2, value2]]`.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {Object} object The object to inspect.
- * @returns {Array} Returns new array of key-value pairs.
- * @example
- *
- * _.pairs({ 'barney': 36, 'fred': 40 });
- * // => [['barney', 36], ['fred', 40]] (property order is not guaranteed across environments)
- */
- function pairs(object) {
- var index = -1,
- props = keys(object),
- length = props.length,
- result = Array(length);
-
- while (++index < length) {
- var key = props[index];
- result[index] = [key, object[key]];
- }
- return result;
- }
-
- /**
- * Creates a shallow clone of `object` composed of the specified properties.
- * Property names may be specified as individual arguments or as arrays of
- * property names. If a callback is provided it will be executed for each
- * property of `object` picking the properties the callback returns truey
- * for. The callback is bound to `thisArg` and invoked with three arguments;
- * (value, key, object).
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {Object} object The source object.
- * @param {Function|...string|string[]} [callback] The function called per
- * iteration or property names to pick, specified as individual property
- * names or arrays of property names.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Object} Returns an object composed of the picked properties.
- * @example
- *
- * _.pick({ 'name': 'fred', '_userid': 'fred1' }, 'name');
- * // => { 'name': 'fred' }
- *
- * _.pick({ 'name': 'fred', '_userid': 'fred1' }, function(value, key) {
- * return key.charAt(0) != '_';
- * });
- * // => { 'name': 'fred' }
- */
- function pick(object, callback, thisArg) {
- var result = {};
- if (typeof callback != 'function') {
- var index = -1,
- props = baseFlatten(arguments, true, false, 1),
- length = isObject(object) ? props.length : 0;
-
- while (++index < length) {
- var key = props[index];
- if (key in object) {
- result[key] = object[key];
- }
- }
- } else {
- callback = lodash.createCallback(callback, thisArg, 3);
- forIn(object, function(value, key, object) {
- if (callback(value, key, object)) {
- result[key] = value;
- }
- });
- }
- return result;
- }
-
- /**
- * An alternative to `_.reduce` this method transforms `object` to a new
- * `accumulator` object which is the result of running each of its own
- * enumerable properties through a callback, with each callback execution
- * potentially mutating the `accumulator` object. The callback is bound to
- * `thisArg` and invoked with four arguments; (accumulator, value, key, object).
- * Callbacks may exit iteration early by explicitly returning `false`.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {Array|Object} object The object to iterate over.
- * @param {Function} [callback=identity] The function called per iteration.
- * @param {*} [accumulator] The custom accumulator value.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {*} Returns the accumulated value.
- * @example
- *
- * var squares = _.transform([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], function(result, num) {
- * num *= num;
- * if (num % 2) {
- * return result.push(num) < 3;
- * }
- * });
- * // => [1, 9, 25]
- *
- * var mapped = _.transform({ 'a': 1, 'b': 2, 'c': 3 }, function(result, num, key) {
- * result[key] = num * 3;
- * });
- * // => { 'a': 3, 'b': 6, 'c': 9 }
- */
- function transform(object, callback, accumulator, thisArg) {
- var isArr = isArray(object);
- if (accumulator == null) {
- if (isArr) {
- accumulator = [];
- } else {
- var ctor = object && object.constructor,
- proto = ctor && ctor.prototype;
-
- accumulator = baseCreate(proto);
- }
- }
- if (callback) {
- callback = lodash.createCallback(callback, thisArg, 4);
- (isArr ? baseEach : forOwn)(object, function(value, index, object) {
- return callback(accumulator, value, index, object);
- });
- }
- return accumulator;
- }
-
- /**
- * Creates an array composed of the own enumerable property values of `object`.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {Object} object The object to inspect.
- * @returns {Array} Returns an array of property values.
- * @example
- *
- * _.values({ 'one': 1, 'two': 2, 'three': 3 });
- * // => [1, 2, 3] (property order is not guaranteed across environments)
- */
- function values(object) {
- var index = -1,
- props = keys(object),
- length = props.length,
- result = Array(length);
-
- while (++index < length) {
- result[index] = object[props[index]];
- }
- return result;
- }
-
- /*--------------------------------------------------------------------------*/
-
- /**
- * Creates an array of elements from the specified indexes, or keys, of the
- * `collection`. Indexes may be specified as individual arguments or as arrays
- * of indexes.
- *
- * @static
- * @memberOf _
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {...(number|number[]|string|string[])} [index] The indexes of `collection`
- * to retrieve, specified as individual indexes or arrays of indexes.
- * @returns {Array} Returns a new array of elements corresponding to the
- * provided indexes.
- * @example
- *
- * _.at(['a', 'b', 'c', 'd', 'e'], [0, 2, 4]);
- * // => ['a', 'c', 'e']
- *
- * _.at(['fred', 'barney', 'pebbles'], 0, 2);
- * // => ['fred', 'pebbles']
- */
- function at(collection) {
- var args = arguments,
- index = -1,
- props = baseFlatten(args, true, false, 1),
- length = (args[2] && args[2][args[1]] === collection) ? 1 : props.length,
- result = Array(length);
-
- if (support.unindexedChars && isString(collection)) {
- collection = collection.split('');
- }
- while(++index < length) {
- result[index] = collection[props[index]];
- }
- return result;
- }
-
- /**
- * Checks if a given value is present in a collection using strict equality
- * for comparisons, i.e. `===`. If `fromIndex` is negative, it is used as the
- * offset from the end of the collection.
- *
- * @static
- * @memberOf _
- * @alias include
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {*} target The value to check for.
- * @param {number} [fromIndex=0] The index to search from.
- * @returns {boolean} Returns `true` if the `target` element is found, else `false`.
- * @example
- *
- * _.contains([1, 2, 3], 1);
- * // => true
- *
- * _.contains([1, 2, 3], 1, 2);
- * // => false
- *
- * _.contains({ 'name': 'fred', 'age': 40 }, 'fred');
- * // => true
- *
- * _.contains('pebbles', 'eb');
- * // => true
- */
- function contains(collection, target, fromIndex) {
- var index = -1,
- indexOf = getIndexOf(),
- length = collection ? collection.length : 0,
- result = false;
-
- fromIndex = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex) || 0;
- if (isArray(collection)) {
- result = indexOf(collection, target, fromIndex) > -1;
- } else if (typeof length == 'number') {
- result = (isString(collection) ? collection.indexOf(target, fromIndex) : indexOf(collection, target, fromIndex)) > -1;
- } else {
- baseEach(collection, function(value) {
- if (++index >= fromIndex) {
- return !(result = value === target);
- }
- });
- }
- return result;
- }
-
- /**
- * Creates an object composed of keys generated from the results of running
- * each element of `collection` through the callback. The corresponding value
- * of each key is the number of times the key was returned by the callback.
- * The callback is bound to `thisArg` and invoked with three arguments;
- * (value, index|key, collection).
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Object} Returns the composed aggregate object.
- * @example
- *
- * _.countBy([4.3, 6.1, 6.4], function(num) { return Math.floor(num); });
- * // => { '4': 1, '6': 2 }
- *
- * _.countBy([4.3, 6.1, 6.4], function(num) { return this.floor(num); }, Math);
- * // => { '4': 1, '6': 2 }
- *
- * _.countBy(['one', 'two', 'three'], 'length');
- * // => { '3': 2, '5': 1 }
- */
- var countBy = createAggregator(function(result, value, key) {
- (hasOwnProperty.call(result, key) ? result[key]++ : result[key] = 1);
- });
-
- /**
- * Checks if the given callback returns truey value for **all** elements of
- * a collection. The callback is bound to `thisArg` and invoked with three
- * arguments; (value, index|key, collection).
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @alias all
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {boolean} Returns `true` if all elements passed the callback check,
- * else `false`.
- * @example
- *
- * _.every([true, 1, null, 'yes']);
- * // => false
- *
- * var characters = [
- * { 'name': 'barney', 'age': 36 },
- * { 'name': 'fred', 'age': 40 }
- * ];
- *
- * // using "_.pluck" callback shorthand
- * _.every(characters, 'age');
- * // => true
- *
- * // using "_.where" callback shorthand
- * _.every(characters, { 'age': 36 });
- * // => false
- */
- function every(collection, callback, thisArg) {
- var result = true;
- callback = lodash.createCallback(callback, thisArg, 3);
-
- if (isArray(collection)) {
- var index = -1,
- length = collection.length;
-
- while (++index < length) {
- if (!(result = !!callback(collection[index], index, collection))) {
- break;
- }
- }
- } else {
- baseEach(collection, function(value, index, collection) {
- return (result = !!callback(value, index, collection));
- });
- }
- return result;
- }
-
- /**
- * Iterates over elements of a collection, returning an array of all elements
- * the callback returns truey for. The callback is bound to `thisArg` and
- * invoked with three arguments; (value, index|key, collection).
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @alias select
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Array} Returns a new array of elements that passed the callback check.
- * @example
- *
- * var evens = _.filter([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; });
- * // => [2, 4, 6]
- *
- * var characters = [
- * { 'name': 'barney', 'age': 36, 'blocked': false },
- * { 'name': 'fred', 'age': 40, 'blocked': true }
- * ];
- *
- * // using "_.pluck" callback shorthand
- * _.filter(characters, 'blocked');
- * // => [{ 'name': 'fred', 'age': 40, 'blocked': true }]
- *
- * // using "_.where" callback shorthand
- * _.filter(characters, { 'age': 36 });
- * // => [{ 'name': 'barney', 'age': 36, 'blocked': false }]
- */
- function filter(collection, callback, thisArg) {
- var result = [];
- callback = lodash.createCallback(callback, thisArg, 3);
-
- if (isArray(collection)) {
- var index = -1,
- length = collection.length;
-
- while (++index < length) {
- var value = collection[index];
- if (callback(value, index, collection)) {
- result.push(value);
- }
- }
- } else {
- baseEach(collection, function(value, index, collection) {
- if (callback(value, index, collection)) {
- result.push(value);
- }
- });
- }
- return result;
- }
-
- /**
- * Iterates over elements of a collection, returning the first element that
- * the callback returns truey for. The callback is bound to `thisArg` and
- * invoked with three arguments; (value, index|key, collection).
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @alias detect, findWhere
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {*} Returns the found element, else `undefined`.
- * @example
- *
- * var characters = [
- * { 'name': 'barney', 'age': 36, 'blocked': false },
- * { 'name': 'fred', 'age': 40, 'blocked': true },
- * { 'name': 'pebbles', 'age': 1, 'blocked': false }
- * ];
- *
- * _.find(characters, function(chr) {
- * return chr.age < 40;
- * });
- * // => { 'name': 'barney', 'age': 36, 'blocked': false }
- *
- * // using "_.where" callback shorthand
- * _.find(characters, { 'age': 1 });
- * // => { 'name': 'pebbles', 'age': 1, 'blocked': false }
- *
- * // using "_.pluck" callback shorthand
- * _.find(characters, 'blocked');
- * // => { 'name': 'fred', 'age': 40, 'blocked': true }
- */
- function find(collection, callback, thisArg) {
- callback = lodash.createCallback(callback, thisArg, 3);
-
- if (isArray(collection)) {
- var index = -1,
- length = collection.length;
-
- while (++index < length) {
- var value = collection[index];
- if (callback(value, index, collection)) {
- return value;
- }
- }
- } else {
- var result;
- baseEach(collection, function(value, index, collection) {
- if (callback(value, index, collection)) {
- result = value;
- return false;
- }
- });
- return result;
- }
- }
-
- /**
- * This method is like `_.find` except that it iterates over elements
- * of a `collection` from right to left.
- *
- * @static
- * @memberOf _
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {*} Returns the found element, else `undefined`.
- * @example
- *
- * _.findLast([1, 2, 3, 4], function(num) {
- * return num % 2 == 1;
- * });
- * // => 3
- */
- function findLast(collection, callback, thisArg) {
- var result;
- callback = lodash.createCallback(callback, thisArg, 3);
- forEachRight(collection, function(value, index, collection) {
- if (callback(value, index, collection)) {
- result = value;
- return false;
- }
- });
- return result;
- }
-
- /**
- * Iterates over elements of a collection, executing the callback for each
- * element. The callback is bound to `thisArg` and invoked with three arguments;
- * (value, index|key, collection). Callbacks may exit iteration early by
- * explicitly returning `false`.
- *
- * Note: As with other "Collections" methods, objects with a `length` property
- * are iterated like arrays. To avoid this behavior `_.forIn` or `_.forOwn`
- * may be used for object iteration.
- *
- * @static
- * @memberOf _
- * @alias each
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function} [callback=identity] The function called per iteration.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Array|Object|string} Returns `collection`.
- * @example
- *
- * _([1, 2, 3]).forEach(function(num) { console.log(num); }).join(',');
- * // => logs each number and returns '1,2,3'
- *
- * _.forEach({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { console.log(num); });
- * // => logs each number and returns the object (property order is not guaranteed across environments)
- */
- function forEach(collection, callback, thisArg) {
- if (callback && typeof thisArg == 'undefined' && isArray(collection)) {
- var index = -1,
- length = collection.length;
-
- while (++index < length) {
- if (callback(collection[index], index, collection) === false) {
- break;
- }
- }
- } else {
- baseEach(collection, callback, thisArg);
- }
- return collection;
- }
-
- /**
- * This method is like `_.forEach` except that it iterates over elements
- * of a `collection` from right to left.
- *
- * @static
- * @memberOf _
- * @alias eachRight
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function} [callback=identity] The function called per iteration.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Array|Object|string} Returns `collection`.
- * @example
- *
- * _([1, 2, 3]).forEachRight(function(num) { console.log(num); }).join(',');
- * // => logs each number from right to left and returns '3,2,1'
- */
- function forEachRight(collection, callback, thisArg) {
- var iterable = collection,
- length = collection ? collection.length : 0;
-
- callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3);
- if (isArray(collection)) {
- while (length--) {
- if (callback(collection[length], length, collection) === false) {
- break;
- }
- }
- } else {
- if (typeof length != 'number') {
- var props = keys(collection);
- length = props.length;
- } else if (support.unindexedChars && isString(collection)) {
- iterable = collection.split('');
- }
- baseEach(collection, function(value, key, collection) {
- key = props ? props[--length] : --length;
- return callback(iterable[key], key, collection);
- });
- }
- return collection;
- }
-
- /**
- * Creates an object composed of keys generated from the results of running
- * each element of a collection through the callback. The corresponding value
- * of each key is an array of the elements responsible for generating the key.
- * The callback is bound to `thisArg` and invoked with three arguments;
- * (value, index|key, collection).
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`
- *
- * @static
- * @memberOf _
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Object} Returns the composed aggregate object.
- * @example
- *
- * _.groupBy([4.2, 6.1, 6.4], function(num) { return Math.floor(num); });
- * // => { '4': [4.2], '6': [6.1, 6.4] }
- *
- * _.groupBy([4.2, 6.1, 6.4], function(num) { return this.floor(num); }, Math);
- * // => { '4': [4.2], '6': [6.1, 6.4] }
- *
- * // using "_.pluck" callback shorthand
- * _.groupBy(['one', 'two', 'three'], 'length');
- * // => { '3': ['one', 'two'], '5': ['three'] }
- */
- var groupBy = createAggregator(function(result, value, key) {
- (hasOwnProperty.call(result, key) ? result[key] : result[key] = []).push(value);
- });
-
- /**
- * Creates an object composed of keys generated from the results of running
- * each element of the collection through the given callback. The corresponding
- * value of each key is the last element responsible for generating the key.
- * The callback is bound to `thisArg` and invoked with three arguments;
- * (value, index|key, collection).
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Object} Returns the composed aggregate object.
- * @example
- *
- * var keys = [
- * { 'dir': 'left', 'code': 97 },
- * { 'dir': 'right', 'code': 100 }
- * ];
- *
- * _.indexBy(keys, 'dir');
- * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } }
- *
- * _.indexBy(keys, function(key) { return String.fromCharCode(key.code); });
- * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
- *
- * _.indexBy(characters, function(key) { this.fromCharCode(key.code); }, String);
- * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
- */
- var indexBy = createAggregator(function(result, value, key) {
- result[key] = value;
- });
-
- /**
- * Invokes the method named by `methodName` on each element in the `collection`
- * returning an array of the results of each invoked method. Additional arguments
- * will be provided to each invoked method. If `methodName` is a function it
- * will be invoked for, and `this` bound to, each element in the `collection`.
- *
- * @static
- * @memberOf _
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|string} methodName The name of the method to invoke or
- * the function invoked per iteration.
- * @param {...*} [arg] Arguments to invoke the method with.
- * @returns {Array} Returns a new array of the results of each invoked method.
- * @example
- *
- * _.invoke([[5, 1, 7], [3, 2, 1]], 'sort');
- * // => [[1, 5, 7], [1, 2, 3]]
- *
- * _.invoke([123, 456], String.prototype.split, '');
- * // => [['1', '2', '3'], ['4', '5', '6']]
- */
- function invoke(collection, methodName) {
- var args = slice(arguments, 2),
- index = -1,
- isFunc = typeof methodName == 'function',
- length = collection ? collection.length : 0,
- result = Array(typeof length == 'number' ? length : 0);
-
- forEach(collection, function(value) {
- result[++index] = (isFunc ? methodName : value[methodName]).apply(value, args);
- });
- return result;
- }
-
- /**
- * Creates an array of values by running each element in the collection
- * through the callback. The callback is bound to `thisArg` and invoked with
- * three arguments; (value, index|key, collection).
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @alias collect
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Array} Returns a new array of the results of each `callback` execution.
- * @example
- *
- * _.map([1, 2, 3], function(num) { return num * 3; });
- * // => [3, 6, 9]
- *
- * _.map({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { return num * 3; });
- * // => [3, 6, 9] (property order is not guaranteed across environments)
- *
- * var characters = [
- * { 'name': 'barney', 'age': 36 },
- * { 'name': 'fred', 'age': 40 }
- * ];
- *
- * // using "_.pluck" callback shorthand
- * _.map(characters, 'name');
- * // => ['barney', 'fred']
- */
- function map(collection, callback, thisArg) {
- var index = -1,
- length = collection ? collection.length : 0,
- result = Array(typeof length == 'number' ? length : 0);
-
- callback = lodash.createCallback(callback, thisArg, 3);
- if (isArray(collection)) {
- while (++index < length) {
- result[index] = callback(collection[index], index, collection);
- }
- } else {
- baseEach(collection, function(value, key, collection) {
- result[++index] = callback(value, key, collection);
- });
- }
- return result;
- }
-
- /**
- * Retrieves the maximum value of a collection. If the collection is empty or
- * falsey `-Infinity` is returned. If a callback is provided it will be executed
- * for each value in the collection to generate the criterion by which the value
- * is ranked. The callback is bound to `thisArg` and invoked with three
- * arguments; (value, index, collection).
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {*} Returns the maximum value.
- * @example
- *
- * _.max([4, 2, 8, 6]);
- * // => 8
- *
- * var characters = [
- * { 'name': 'barney', 'age': 36 },
- * { 'name': 'fred', 'age': 40 }
- * ];
- *
- * _.max(characters, function(chr) { return chr.age; });
- * // => { 'name': 'fred', 'age': 40 };
- *
- * // using "_.pluck" callback shorthand
- * _.max(characters, 'age');
- * // => { 'name': 'fred', 'age': 40 };
- */
- function max(collection, callback, thisArg) {
- var computed = -Infinity,
- result = computed;
-
- // allows working with functions like `_.map` without using
- // their `index` argument as a callback
- if (typeof callback != 'function' && thisArg && thisArg[callback] === collection) {
- callback = null;
- }
- if (callback == null && isArray(collection)) {
- var index = -1,
- length = collection.length;
-
- while (++index < length) {
- var value = collection[index];
- if (value > result) {
- result = value;
- }
- }
- } else {
- callback = (callback == null && isString(collection))
- ? charAtCallback
- : lodash.createCallback(callback, thisArg, 3);
-
- baseEach(collection, function(value, index, collection) {
- var current = callback(value, index, collection);
- if (current > computed) {
- computed = current;
- result = value;
- }
- });
- }
- return result;
- }
-
- /**
- * Retrieves the minimum value of a collection. If the collection is empty or
- * falsey `Infinity` is returned. If a callback is provided it will be executed
- * for each value in the collection to generate the criterion by which the value
- * is ranked. The callback is bound to `thisArg` and invoked with three
- * arguments; (value, index, collection).
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {*} Returns the minimum value.
- * @example
- *
- * _.min([4, 2, 8, 6]);
- * // => 2
- *
- * var characters = [
- * { 'name': 'barney', 'age': 36 },
- * { 'name': 'fred', 'age': 40 }
- * ];
- *
- * _.min(characters, function(chr) { return chr.age; });
- * // => { 'name': 'barney', 'age': 36 };
- *
- * // using "_.pluck" callback shorthand
- * _.min(characters, 'age');
- * // => { 'name': 'barney', 'age': 36 };
- */
- function min(collection, callback, thisArg) {
- var computed = Infinity,
- result = computed;
-
- // allows working with functions like `_.map` without using
- // their `index` argument as a callback
- if (typeof callback != 'function' && thisArg && thisArg[callback] === collection) {
- callback = null;
- }
- if (callback == null && isArray(collection)) {
- var index = -1,
- length = collection.length;
-
- while (++index < length) {
- var value = collection[index];
- if (value < result) {
- result = value;
- }
- }
- } else {
- callback = (callback == null && isString(collection))
- ? charAtCallback
- : lodash.createCallback(callback, thisArg, 3);
-
- baseEach(collection, function(value, index, collection) {
- var current = callback(value, index, collection);
- if (current < computed) {
- computed = current;
- result = value;
- }
- });
- }
- return result;
- }
-
- /**
- * Retrieves the value of a specified property from all elements in the collection.
- *
- * @static
- * @memberOf _
- * @type Function
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {string} property The name of the property to pluck.
- * @returns {Array} Returns a new array of property values.
- * @example
- *
- * var characters = [
- * { 'name': 'barney', 'age': 36 },
- * { 'name': 'fred', 'age': 40 }
- * ];
- *
- * _.pluck(characters, 'name');
- * // => ['barney', 'fred']
- */
- var pluck = map;
-
- /**
- * Reduces a collection to a value which is the accumulated result of running
- * each element in the collection through the callback, where each successive
- * callback execution consumes the return value of the previous execution. If
- * `accumulator` is not provided the first element of the collection will be
- * used as the initial `accumulator` value. The callback is bound to `thisArg`
- * and invoked with four arguments; (accumulator, value, index|key, collection).
- *
- * @static
- * @memberOf _
- * @alias foldl, inject
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function} [callback=identity] The function called per iteration.
- * @param {*} [accumulator] Initial value of the accumulator.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {*} Returns the accumulated value.
- * @example
- *
- * var sum = _.reduce([1, 2, 3], function(sum, num) {
- * return sum + num;
- * });
- * // => 6
- *
- * var mapped = _.reduce({ 'a': 1, 'b': 2, 'c': 3 }, function(result, num, key) {
- * result[key] = num * 3;
- * return result;
- * }, {});
- * // => { 'a': 3, 'b': 6, 'c': 9 }
- */
- function reduce(collection, callback, accumulator, thisArg) {
- var noaccum = arguments.length < 3;
- callback = lodash.createCallback(callback, thisArg, 4);
-
- if (isArray(collection)) {
- var index = -1,
- length = collection.length;
-
- if (noaccum) {
- accumulator = collection[++index];
- }
- while (++index < length) {
- accumulator = callback(accumulator, collection[index], index, collection);
- }
- } else {
- baseEach(collection, function(value, index, collection) {
- accumulator = noaccum
- ? (noaccum = false, value)
- : callback(accumulator, value, index, collection)
- });
- }
- return accumulator;
- }
-
- /**
- * This method is like `_.reduce` except that it iterates over elements
- * of a `collection` from right to left.
- *
- * @static
- * @memberOf _
- * @alias foldr
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function} [callback=identity] The function called per iteration.
- * @param {*} [accumulator] Initial value of the accumulator.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {*} Returns the accumulated value.
- * @example
- *
- * var list = [[0, 1], [2, 3], [4, 5]];
- * var flat = _.reduceRight(list, function(a, b) { return a.concat(b); }, []);
- * // => [4, 5, 2, 3, 0, 1]
- */
- function reduceRight(collection, callback, accumulator, thisArg) {
- var noaccum = arguments.length < 3;
- callback = lodash.createCallback(callback, thisArg, 4);
- forEachRight(collection, function(value, index, collection) {
- accumulator = noaccum
- ? (noaccum = false, value)
- : callback(accumulator, value, index, collection);
- });
- return accumulator;
- }
-
- /**
- * The opposite of `_.filter` this method returns the elements of a
- * collection that the callback does **not** return truey for.
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Array} Returns a new array of elements that failed the callback check.
- * @example
- *
- * var odds = _.reject([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; });
- * // => [1, 3, 5]
- *
- * var characters = [
- * { 'name': 'barney', 'age': 36, 'blocked': false },
- * { 'name': 'fred', 'age': 40, 'blocked': true }
- * ];
- *
- * // using "_.pluck" callback shorthand
- * _.reject(characters, 'blocked');
- * // => [{ 'name': 'barney', 'age': 36, 'blocked': false }]
- *
- * // using "_.where" callback shorthand
- * _.reject(characters, { 'age': 36 });
- * // => [{ 'name': 'fred', 'age': 40, 'blocked': true }]
- */
- function reject(collection, callback, thisArg) {
- callback = lodash.createCallback(callback, thisArg, 3);
- return filter(collection, function(value, index, collection) {
- return !callback(value, index, collection);
- });
- }
-
- /**
- * Retrieves a random element or `n` random elements from a collection.
- *
- * @static
- * @memberOf _
- * @category Collections
- * @param {Array|Object|string} collection The collection to sample.
- * @param {number} [n] The number of elements to sample.
- * @param- {Object} [guard] Allows working with functions like `_.map`
- * without using their `index` arguments as `n`.
- * @returns {Array} Returns the random sample(s) of `collection`.
- * @example
- *
- * _.sample([1, 2, 3, 4]);
- * // => 2
- *
- * _.sample([1, 2, 3, 4], 2);
- * // => [3, 1]
- */
- function sample(collection, n, guard) {
- if (collection && typeof collection.length != 'number') {
- collection = values(collection);
- } else if (support.unindexedChars && isString(collection)) {
- collection = collection.split('');
- }
- if (n == null || guard) {
- return collection ? collection[baseRandom(0, collection.length - 1)] : undefined;
- }
- var result = shuffle(collection);
- result.length = nativeMin(nativeMax(0, n), result.length);
- return result;
- }
-
- /**
- * Creates an array of shuffled values, using a version of the Fisher-Yates
- * shuffle. See http://en.wikipedia.org/wiki/Fisher-Yates_shuffle.
- *
- * @static
- * @memberOf _
- * @category Collections
- * @param {Array|Object|string} collection The collection to shuffle.
- * @returns {Array} Returns a new shuffled collection.
- * @example
- *
- * _.shuffle([1, 2, 3, 4, 5, 6]);
- * // => [4, 1, 6, 3, 5, 2]
- */
- function shuffle(collection) {
- var index = -1,
- length = collection ? collection.length : 0,
- result = Array(typeof length == 'number' ? length : 0);
-
- forEach(collection, function(value) {
- var rand = baseRandom(0, ++index);
- result[index] = result[rand];
- result[rand] = value;
- });
- return result;
- }
-
- /**
- * Gets the size of the `collection` by returning `collection.length` for arrays
- * and array-like objects or the number of own enumerable properties for objects.
- *
- * @static
- * @memberOf _
- * @category Collections
- * @param {Array|Object|string} collection The collection to inspect.
- * @returns {number} Returns `collection.length` or number of own enumerable properties.
- * @example
- *
- * _.size([1, 2]);
- * // => 2
- *
- * _.size({ 'one': 1, 'two': 2, 'three': 3 });
- * // => 3
- *
- * _.size('pebbles');
- * // => 7
- */
- function size(collection) {
- var length = collection ? collection.length : 0;
- return typeof length == 'number' ? length : keys(collection).length;
- }
-
- /**
- * Checks if the callback returns a truey value for **any** element of a
- * collection. The function returns as soon as it finds a passing value and
- * does not iterate over the entire collection. The callback is bound to
- * `thisArg` and invoked with three arguments; (value, index|key, collection).
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @alias any
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {boolean} Returns `true` if any element passed the callback check,
- * else `false`.
- * @example
- *
- * _.some([null, 0, 'yes', false], Boolean);
- * // => true
- *
- * var characters = [
- * { 'name': 'barney', 'age': 36, 'blocked': false },
- * { 'name': 'fred', 'age': 40, 'blocked': true }
- * ];
- *
- * // using "_.pluck" callback shorthand
- * _.some(characters, 'blocked');
- * // => true
- *
- * // using "_.where" callback shorthand
- * _.some(characters, { 'age': 1 });
- * // => false
- */
- function some(collection, callback, thisArg) {
- var result;
- callback = lodash.createCallback(callback, thisArg, 3);
-
- if (isArray(collection)) {
- var index = -1,
- length = collection.length;
-
- while (++index < length) {
- if ((result = callback(collection[index], index, collection))) {
- break;
- }
- }
- } else {
- baseEach(collection, function(value, index, collection) {
- return !(result = callback(value, index, collection));
- });
- }
- return !!result;
- }
-
- /**
- * Creates an array of elements, sorted in ascending order by the results of
- * running each element in a collection through the callback. This method
- * performs a stable sort, that is, it will preserve the original sort order
- * of equal elements. The callback is bound to `thisArg` and invoked with
- * three arguments; (value, index|key, collection).
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an array of property names is provided for `callback` the collection
- * will be sorted by each property value.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Array|Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Array} Returns a new array of sorted elements.
- * @example
- *
- * _.sortBy([1, 2, 3], function(num) { return Math.sin(num); });
- * // => [3, 1, 2]
- *
- * _.sortBy([1, 2, 3], function(num) { return this.sin(num); }, Math);
- * // => [3, 1, 2]
- *
- * var characters = [
- * { 'name': 'barney', 'age': 36 },
- * { 'name': 'fred', 'age': 40 },
- * { 'name': 'barney', 'age': 26 },
- * { 'name': 'fred', 'age': 30 }
- * ];
- *
- * // using "_.pluck" callback shorthand
- * _.map(_.sortBy(characters, 'age'), _.values);
- * // => [['barney', 26], ['fred', 30], ['barney', 36], ['fred', 40]]
- *
- * // sorting by multiple properties
- * _.map(_.sortBy(characters, ['name', 'age']), _.values);
- * // = > [['barney', 26], ['barney', 36], ['fred', 30], ['fred', 40]]
- */
- function sortBy(collection, callback, thisArg) {
- var index = -1,
- isArr = isArray(callback),
- length = collection ? collection.length : 0,
- result = Array(typeof length == 'number' ? length : 0);
-
- if (!isArr) {
- callback = lodash.createCallback(callback, thisArg, 3);
- }
- forEach(collection, function(value, key, collection) {
- var object = result[++index] = getObject();
- if (isArr) {
- object.criteria = map(callback, function(key) { return value[key]; });
- } else {
- (object.criteria = getArray())[0] = callback(value, key, collection);
- }
- object.index = index;
- object.value = value;
- });
-
- length = result.length;
- result.sort(compareAscending);
- while (length--) {
- var object = result[length];
- result[length] = object.value;
- if (!isArr) {
- releaseArray(object.criteria);
- }
- releaseObject(object);
- }
- return result;
- }
-
- /**
- * Converts the `collection` to an array.
- *
- * @static
- * @memberOf _
- * @category Collections
- * @param {Array|Object|string} collection The collection to convert.
- * @returns {Array} Returns the new converted array.
- * @example
- *
- * (function() { return _.toArray(arguments).slice(1); })(1, 2, 3, 4);
- * // => [2, 3, 4]
- */
- function toArray(collection) {
- if (collection && typeof collection.length == 'number') {
- return (support.unindexedChars && isString(collection))
- ? collection.split('')
- : slice(collection);
- }
- return values(collection);
- }
-
- /**
- * Performs a deep comparison of each element in a `collection` to the given
- * `properties` object, returning an array of all elements that have equivalent
- * property values.
- *
- * @static
- * @memberOf _
- * @type Function
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Object} props The object of property values to filter by.
- * @returns {Array} Returns a new array of elements that have the given properties.
- * @example
- *
- * var characters = [
- * { 'name': 'barney', 'age': 36, 'pets': ['hoppy'] },
- * { 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] }
- * ];
- *
- * _.where(characters, { 'age': 36 });
- * // => [{ 'name': 'barney', 'age': 36, 'pets': ['hoppy'] }]
- *
- * _.where(characters, { 'pets': ['dino'] });
- * // => [{ 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] }]
- */
- var where = filter;
-
- /*--------------------------------------------------------------------------*/
-
- /**
- * Creates an array with all falsey values removed. The values `false`, `null`,
- * `0`, `""`, `undefined`, and `NaN` are all falsey.
- *
- * @static
- * @memberOf _
- * @category Arrays
- * @param {Array} array The array to compact.
- * @returns {Array} Returns a new array of filtered values.
- * @example
- *
- * _.compact([0, 1, false, 2, '', 3]);
- * // => [1, 2, 3]
- */
- function compact(array) {
- var index = -1,
- length = array ? array.length : 0,
- result = [];
-
- while (++index < length) {
- var value = array[index];
- if (value) {
- result.push(value);
- }
- }
- return result;
- }
-
- /**
- * Creates an array excluding all values of the provided arrays using strict
- * equality for comparisons, i.e. `===`.
- *
- * @static
- * @memberOf _
- * @category Arrays
- * @param {Array} array The array to process.
- * @param {...Array} [values] The arrays of values to exclude.
- * @returns {Array} Returns a new array of filtered values.
- * @example
- *
- * _.difference([1, 2, 3, 4, 5], [5, 2, 10]);
- * // => [1, 3, 4]
- */
- function difference(array) {
- return baseDifference(array, baseFlatten(arguments, true, true, 1));
- }
-
- /**
- * This method is like `_.find` except that it returns the index of the first
- * element that passes the callback check, instead of the element itself.
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @category Arrays
- * @param {Array} array The array to search.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {number} Returns the index of the found element, else `-1`.
- * @example
- *
- * var characters = [
- * { 'name': 'barney', 'age': 36, 'blocked': false },
- * { 'name': 'fred', 'age': 40, 'blocked': true },
- * { 'name': 'pebbles', 'age': 1, 'blocked': false }
- * ];
- *
- * _.findIndex(characters, function(chr) {
- * return chr.age < 20;
- * });
- * // => 2
- *
- * // using "_.where" callback shorthand
- * _.findIndex(characters, { 'age': 36 });
- * // => 0
- *
- * // using "_.pluck" callback shorthand
- * _.findIndex(characters, 'blocked');
- * // => 1
- */
- function findIndex(array, callback, thisArg) {
- var index = -1,
- length = array ? array.length : 0;
-
- callback = lodash.createCallback(callback, thisArg, 3);
- while (++index < length) {
- if (callback(array[index], index, array)) {
- return index;
- }
- }
- return -1;
- }
-
- /**
- * This method is like `_.findIndex` except that it iterates over elements
- * of a `collection` from right to left.
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @category Arrays
- * @param {Array} array The array to search.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {number} Returns the index of the found element, else `-1`.
- * @example
- *
- * var characters = [
- * { 'name': 'barney', 'age': 36, 'blocked': true },
- * { 'name': 'fred', 'age': 40, 'blocked': false },
- * { 'name': 'pebbles', 'age': 1, 'blocked': true }
- * ];
- *
- * _.findLastIndex(characters, function(chr) {
- * return chr.age > 30;
- * });
- * // => 1
- *
- * // using "_.where" callback shorthand
- * _.findLastIndex(characters, { 'age': 36 });
- * // => 0
- *
- * // using "_.pluck" callback shorthand
- * _.findLastIndex(characters, 'blocked');
- * // => 2
- */
- function findLastIndex(array, callback, thisArg) {
- var length = array ? array.length : 0;
- callback = lodash.createCallback(callback, thisArg, 3);
- while (length--) {
- if (callback(array[length], length, array)) {
- return length;
- }
- }
- return -1;
- }
-
- /**
- * Gets the first element or first `n` elements of an array. If a callback
- * is provided elements at the beginning of the array are returned as long
- * as the callback returns truey. The callback is bound to `thisArg` and
- * invoked with three arguments; (value, index, array).
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @alias head, take
- * @category Arrays
- * @param {Array} array The array to query.
- * @param {Function|Object|number|string} [callback] The function called
- * per element or the number of elements to return. If a property name or
- * object is provided it will be used to create a "_.pluck" or "_.where"
- * style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {*} Returns the first element(s) of `array`.
- * @example
- *
- * _.first([1, 2, 3]);
- * // => 1
- *
- * _.first([1, 2, 3], 2);
- * // => [1, 2]
- *
- * _.first([1, 2, 3], function(num) {
- * return num < 3;
- * });
- * // => [1, 2]
- *
- * var characters = [
- * { 'name': 'barney', 'blocked': true, 'employer': 'slate' },
- * { 'name': 'fred', 'blocked': false, 'employer': 'slate' },
- * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' }
- * ];
- *
- * // using "_.pluck" callback shorthand
- * _.first(characters, 'blocked');
- * // => [{ 'name': 'barney', 'blocked': true, 'employer': 'slate' }]
- *
- * // using "_.where" callback shorthand
- * _.pluck(_.first(characters, { 'employer': 'slate' }), 'name');
- * // => ['barney', 'fred']
- */
- function first(array, callback, thisArg) {
- var n = 0,
- length = array ? array.length : 0;
-
- if (typeof callback != 'number' && callback != null) {
- var index = -1;
- callback = lodash.createCallback(callback, thisArg, 3);
- while (++index < length && callback(array[index], index, array)) {
- n++;
- }
- } else {
- n = callback;
- if (n == null || thisArg) {
- return array ? array[0] : undefined;
- }
- }
- return slice(array, 0, nativeMin(nativeMax(0, n), length));
- }
-
- /**
- * Flattens a nested array (the nesting can be to any depth). If `isShallow`
- * is truey, the array will only be flattened a single level. If a callback
- * is provided each element of the array is passed through the callback before
- * flattening. The callback is bound to `thisArg` and invoked with three
- * arguments; (value, index, array).
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @category Arrays
- * @param {Array} array The array to flatten.
- * @param {boolean} [isShallow=false] A flag to restrict flattening to a single level.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Array} Returns a new flattened array.
- * @example
- *
- * _.flatten([1, [2], [3, [[4]]]]);
- * // => [1, 2, 3, 4];
- *
- * _.flatten([1, [2], [3, [[4]]]], true);
- * // => [1, 2, 3, [[4]]];
- *
- * var characters = [
- * { 'name': 'barney', 'age': 30, 'pets': ['hoppy'] },
- * { 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] }
- * ];
- *
- * // using "_.pluck" callback shorthand
- * _.flatten(characters, 'pets');
- * // => ['hoppy', 'baby puss', 'dino']
- */
- function flatten(array, isShallow, callback, thisArg) {
- // juggle arguments
- if (typeof isShallow != 'boolean' && isShallow != null) {
- thisArg = callback;
- callback = (typeof isShallow != 'function' && thisArg && thisArg[isShallow] === array) ? null : isShallow;
- isShallow = false;
- }
- if (callback != null) {
- array = map(array, callback, thisArg);
- }
- return baseFlatten(array, isShallow);
- }
-
- /**
- * Gets the index at which the first occurrence of `value` is found using
- * strict equality for comparisons, i.e. `===`. If the array is already sorted
- * providing `true` for `fromIndex` will run a faster binary search.
- *
- * @static
- * @memberOf _
- * @category Arrays
- * @param {Array} array The array to search.
- * @param {*} value The value to search for.
- * @param {boolean|number} [fromIndex=0] The index to search from or `true`
- * to perform a binary search on a sorted array.
- * @returns {number} Returns the index of the matched value or `-1`.
- * @example
- *
- * _.indexOf([1, 2, 3, 1, 2, 3], 2);
- * // => 1
- *
- * _.indexOf([1, 2, 3, 1, 2, 3], 2, 3);
- * // => 4
- *
- * _.indexOf([1, 1, 2, 2, 3, 3], 2, true);
- * // => 2
- */
- function indexOf(array, value, fromIndex) {
- if (typeof fromIndex == 'number') {
- var length = array ? array.length : 0;
- fromIndex = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex || 0);
- } else if (fromIndex) {
- var index = sortedIndex(array, value);
- return array[index] === value ? index : -1;
- }
- return baseIndexOf(array, value, fromIndex);
- }
-
- /**
- * Gets all but the last element or last `n` elements of an array. If a
- * callback is provided elements at the end of the array are excluded from
- * the result as long as the callback returns truey. The callback is bound
- * to `thisArg` and invoked with three arguments; (value, index, array).
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @category Arrays
- * @param {Array} array The array to query.
- * @param {Function|Object|number|string} [callback=1] The function called
- * per element or the number of elements to exclude. If a property name or
- * object is provided it will be used to create a "_.pluck" or "_.where"
- * style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Array} Returns a slice of `array`.
- * @example
- *
- * _.initial([1, 2, 3]);
- * // => [1, 2]
- *
- * _.initial([1, 2, 3], 2);
- * // => [1]
- *
- * _.initial([1, 2, 3], function(num) {
- * return num > 1;
- * });
- * // => [1]
- *
- * var characters = [
- * { 'name': 'barney', 'blocked': false, 'employer': 'slate' },
- * { 'name': 'fred', 'blocked': true, 'employer': 'slate' },
- * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' }
- * ];
- *
- * // using "_.pluck" callback shorthand
- * _.initial(characters, 'blocked');
- * // => [{ 'name': 'barney', 'blocked': false, 'employer': 'slate' }]
- *
- * // using "_.where" callback shorthand
- * _.pluck(_.initial(characters, { 'employer': 'na' }), 'name');
- * // => ['barney', 'fred']
- */
- function initial(array, callback, thisArg) {
- var n = 0,
- length = array ? array.length : 0;
-
- if (typeof callback != 'number' && callback != null) {
- var index = length;
- callback = lodash.createCallback(callback, thisArg, 3);
- while (index-- && callback(array[index], index, array)) {
- n++;
- }
- } else {
- n = (callback == null || thisArg) ? 1 : callback || n;
- }
- return slice(array, 0, nativeMin(nativeMax(0, length - n), length));
- }
-
- /**
- * Creates an array of unique values present in all provided arrays using
- * strict equality for comparisons, i.e. `===`.
- *
- * @static
- * @memberOf _
- * @category Arrays
- * @param {...Array} [array] The arrays to inspect.
- * @returns {Array} Returns an array of shared values.
- * @example
- *
- * _.intersection([1, 2, 3], [5, 2, 1, 4], [2, 1]);
- * // => [1, 2]
- */
- function intersection() {
- var args = [],
- argsIndex = -1,
- argsLength = arguments.length,
- caches = getArray(),
- indexOf = getIndexOf(),
- trustIndexOf = indexOf === baseIndexOf,
- seen = getArray();
-
- while (++argsIndex < argsLength) {
- var value = arguments[argsIndex];
- if (isArray(value) || isArguments(value)) {
- args.push(value);
- caches.push(trustIndexOf && value.length >= largeArraySize &&
- createCache(argsIndex ? args[argsIndex] : seen));
- }
- }
- var array = args[0],
- index = -1,
- length = array ? array.length : 0,
- result = [];
-
- outer:
- while (++index < length) {
- var cache = caches[0];
- value = array[index];
-
- if ((cache ? cacheIndexOf(cache, value) : indexOf(seen, value)) < 0) {
- argsIndex = argsLength;
- (cache || seen).push(value);
- while (--argsIndex) {
- cache = caches[argsIndex];
- if ((cache ? cacheIndexOf(cache, value) : indexOf(args[argsIndex], value)) < 0) {
- continue outer;
- }
- }
- result.push(value);
- }
- }
- while (argsLength--) {
- cache = caches[argsLength];
- if (cache) {
- releaseObject(cache);
- }
- }
- releaseArray(caches);
- releaseArray(seen);
- return result;
- }
-
- /**
- * Gets the last element or last `n` elements of an array. If a callback is
- * provided elements at the end of the array are returned as long as the
- * callback returns truey. The callback is bound to `thisArg` and invoked
- * with three arguments; (value, index, array).
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @category Arrays
- * @param {Array} array The array to query.
- * @param {Function|Object|number|string} [callback] The function called
- * per element or the number of elements to return. If a property name or
- * object is provided it will be used to create a "_.pluck" or "_.where"
- * style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {*} Returns the last element(s) of `array`.
- * @example
- *
- * _.last([1, 2, 3]);
- * // => 3
- *
- * _.last([1, 2, 3], 2);
- * // => [2, 3]
- *
- * _.last([1, 2, 3], function(num) {
- * return num > 1;
- * });
- * // => [2, 3]
- *
- * var characters = [
- * { 'name': 'barney', 'blocked': false, 'employer': 'slate' },
- * { 'name': 'fred', 'blocked': true, 'employer': 'slate' },
- * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' }
- * ];
- *
- * // using "_.pluck" callback shorthand
- * _.pluck(_.last(characters, 'blocked'), 'name');
- * // => ['fred', 'pebbles']
- *
- * // using "_.where" callback shorthand
- * _.last(characters, { 'employer': 'na' });
- * // => [{ 'name': 'pebbles', 'blocked': true, 'employer': 'na' }]
- */
- function last(array, callback, thisArg) {
- var n = 0,
- length = array ? array.length : 0;
-
- if (typeof callback != 'number' && callback != null) {
- var index = length;
- callback = lodash.createCallback(callback, thisArg, 3);
- while (index-- && callback(array[index], index, array)) {
- n++;
- }
- } else {
- n = callback;
- if (n == null || thisArg) {
- return array ? array[length - 1] : undefined;
- }
- }
- return slice(array, nativeMax(0, length - n));
- }
-
- /**
- * Gets the index at which the last occurrence of `value` is found using strict
- * equality for comparisons, i.e. `===`. If `fromIndex` is negative, it is used
- * as the offset from the end of the collection.
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @category Arrays
- * @param {Array} array The array to search.
- * @param {*} value The value to search for.
- * @param {number} [fromIndex=array.length-1] The index to search from.
- * @returns {number} Returns the index of the matched value or `-1`.
- * @example
- *
- * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2);
- * // => 4
- *
- * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2, 3);
- * // => 1
- */
- function lastIndexOf(array, value, fromIndex) {
- var index = array ? array.length : 0;
- if (typeof fromIndex == 'number') {
- index = (fromIndex < 0 ? nativeMax(0, index + fromIndex) : nativeMin(fromIndex, index - 1)) + 1;
- }
- while (index--) {
- if (array[index] === value) {
- return index;
- }
- }
- return -1;
- }
-
- /**
- * Removes all provided values from the given array using strict equality for
- * comparisons, i.e. `===`.
- *
- * @static
- * @memberOf _
- * @category Arrays
- * @param {Array} array The array to modify.
- * @param {...*} [value] The values to remove.
- * @returns {Array} Returns `array`.
- * @example
- *
- * var array = [1, 2, 3, 1, 2, 3];
- * _.pull(array, 2, 3);
- * console.log(array);
- * // => [1, 1]
- */
- function pull(array) {
- var args = arguments,
- argsIndex = 0,
- argsLength = args.length,
- length = array ? array.length : 0;
-
- while (++argsIndex < argsLength) {
- var index = -1,
- value = args[argsIndex];
- while (++index < length) {
- if (array[index] === value) {
- splice.call(array, index--, 1);
- length--;
- }
- }
- }
- return array;
- }
-
- /**
- * Creates an array of numbers (positive and/or negative) progressing from
- * `start` up to but not including `end`. If `start` is less than `stop` a
- * zero-length range is created unless a negative `step` is specified.
- *
- * @static
- * @memberOf _
- * @category Arrays
- * @param {number} [start=0] The start of the range.
- * @param {number} end The end of the range.
- * @param {number} [step=1] The value to increment or decrement by.
- * @returns {Array} Returns a new range array.
- * @example
- *
- * _.range(4);
- * // => [0, 1, 2, 3]
- *
- * _.range(1, 5);
- * // => [1, 2, 3, 4]
- *
- * _.range(0, 20, 5);
- * // => [0, 5, 10, 15]
- *
- * _.range(0, -4, -1);
- * // => [0, -1, -2, -3]
- *
- * _.range(1, 4, 0);
- * // => [1, 1, 1]
- *
- * _.range(0);
- * // => []
- */
- function range(start, end, step) {
- start = +start || 0;
- step = typeof step == 'number' ? step : (+step || 1);
-
- if (end == null) {
- end = start;
- start = 0;
- }
- // use `Array(length)` so engines like Chakra and V8 avoid slower modes
- // http://youtu.be/XAqIpGU8ZZk#t=17m25s
- var index = -1,
- length = nativeMax(0, ceil((end - start) / (step || 1))),
- result = Array(length);
-
- while (++index < length) {
- result[index] = start;
- start += step;
- }
- return result;
- }
-
- /**
- * Removes all elements from an array that the callback returns truey for
- * and returns an array of removed elements. The callback is bound to `thisArg`
- * and invoked with three arguments; (value, index, array).
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @category Arrays
- * @param {Array} array The array to modify.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Array} Returns a new array of removed elements.
- * @example
- *
- * var array = [1, 2, 3, 4, 5, 6];
- * var evens = _.remove(array, function(num) { return num % 2 == 0; });
- *
- * console.log(array);
- * // => [1, 3, 5]
- *
- * console.log(evens);
- * // => [2, 4, 6]
- */
- function remove(array, callback, thisArg) {
- var index = -1,
- length = array ? array.length : 0,
- result = [];
-
- callback = lodash.createCallback(callback, thisArg, 3);
- while (++index < length) {
- var value = array[index];
- if (callback(value, index, array)) {
- result.push(value);
- splice.call(array, index--, 1);
- length--;
- }
- }
- return result;
- }
-
- /**
- * The opposite of `_.initial` this method gets all but the first element or
- * first `n` elements of an array. If a callback function is provided elements
- * at the beginning of the array are excluded from the result as long as the
- * callback returns truey. The callback is bound to `thisArg` and invoked
- * with three arguments; (value, index, array).
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @alias drop, tail
- * @category Arrays
- * @param {Array} array The array to query.
- * @param {Function|Object|number|string} [callback=1] The function called
- * per element or the number of elements to exclude. If a property name or
- * object is provided it will be used to create a "_.pluck" or "_.where"
- * style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Array} Returns a slice of `array`.
- * @example
- *
- * _.rest([1, 2, 3]);
- * // => [2, 3]
- *
- * _.rest([1, 2, 3], 2);
- * // => [3]
- *
- * _.rest([1, 2, 3], function(num) {
- * return num < 3;
- * });
- * // => [3]
- *
- * var characters = [
- * { 'name': 'barney', 'blocked': true, 'employer': 'slate' },
- * { 'name': 'fred', 'blocked': false, 'employer': 'slate' },
- * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' }
- * ];
- *
- * // using "_.pluck" callback shorthand
- * _.pluck(_.rest(characters, 'blocked'), 'name');
- * // => ['fred', 'pebbles']
- *
- * // using "_.where" callback shorthand
- * _.rest(characters, { 'employer': 'slate' });
- * // => [{ 'name': 'pebbles', 'blocked': true, 'employer': 'na' }]
- */
- function rest(array, callback, thisArg) {
- if (typeof callback != 'number' && callback != null) {
- var n = 0,
- index = -1,
- length = array ? array.length : 0;
-
- callback = lodash.createCallback(callback, thisArg, 3);
- while (++index < length && callback(array[index], index, array)) {
- n++;
- }
- } else {
- n = (callback == null || thisArg) ? 1 : nativeMax(0, callback);
- }
- return slice(array, n);
- }
-
- /**
- * Uses a binary search to determine the smallest index at which a value
- * should be inserted into a given sorted array in order to maintain the sort
- * order of the array. If a callback is provided it will be executed for
- * `value` and each element of `array` to compute their sort ranking. The
- * callback is bound to `thisArg` and invoked with one argument; (value).
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @category Arrays
- * @param {Array} array The array to inspect.
- * @param {*} value The value to evaluate.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {number} Returns the index at which `value` should be inserted
- * into `array`.
- * @example
- *
- * _.sortedIndex([20, 30, 50], 40);
- * // => 2
- *
- * // using "_.pluck" callback shorthand
- * _.sortedIndex([{ 'x': 20 }, { 'x': 30 }, { 'x': 50 }], { 'x': 40 }, 'x');
- * // => 2
- *
- * var dict = {
- * 'wordToNumber': { 'twenty': 20, 'thirty': 30, 'fourty': 40, 'fifty': 50 }
- * };
- *
- * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) {
- * return dict.wordToNumber[word];
- * });
- * // => 2
- *
- * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) {
- * return this.wordToNumber[word];
- * }, dict);
- * // => 2
- */
- function sortedIndex(array, value, callback, thisArg) {
- var low = 0,
- high = array ? array.length : low;
-
- // explicitly reference `identity` for better inlining in Firefox
- callback = callback ? lodash.createCallback(callback, thisArg, 1) : identity;
- value = callback(value);
-
- while (low < high) {
- var mid = (low + high) >>> 1;
- (callback(array[mid]) < value)
- ? low = mid + 1
- : high = mid;
- }
- return low;
- }
-
- /**
- * Creates an array of unique values, in order, of the provided arrays using
- * strict equality for comparisons, i.e. `===`.
- *
- * @static
- * @memberOf _
- * @category Arrays
- * @param {...Array} [array] The arrays to inspect.
- * @returns {Array} Returns an array of combined values.
- * @example
- *
- * _.union([1, 2, 3], [5, 2, 1, 4], [2, 1]);
- * // => [1, 2, 3, 5, 4]
- */
- function union() {
- return baseUniq(baseFlatten(arguments, true, true));
- }
-
- /**
- * Creates a duplicate-value-free version of an array using strict equality
- * for comparisons, i.e. `===`. If the array is sorted, providing
- * `true` for `isSorted` will use a faster algorithm. If a callback is provided
- * each element of `array` is passed through the callback before uniqueness
- * is computed. The callback is bound to `thisArg` and invoked with three
- * arguments; (value, index, array).
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @alias unique
- * @category Arrays
- * @param {Array} array The array to process.
- * @param {boolean} [isSorted=false] A flag to indicate that `array` is sorted.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Array} Returns a duplicate-value-free array.
- * @example
- *
- * _.uniq([1, 2, 1, 3, 1]);
- * // => [1, 2, 3]
- *
- * _.uniq([1, 1, 2, 2, 3], true);
- * // => [1, 2, 3]
- *
- * _.uniq(['A', 'b', 'C', 'a', 'B', 'c'], function(letter) { return letter.toLowerCase(); });
- * // => ['A', 'b', 'C']
- *
- * _.uniq([1, 2.5, 3, 1.5, 2, 3.5], function(num) { return this.floor(num); }, Math);
- * // => [1, 2.5, 3]
- *
- * // using "_.pluck" callback shorthand
- * _.uniq([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');
- * // => [{ 'x': 1 }, { 'x': 2 }]
- */
- function uniq(array, isSorted, callback, thisArg) {
- // juggle arguments
- if (typeof isSorted != 'boolean' && isSorted != null) {
- thisArg = callback;
- callback = (typeof isSorted != 'function' && thisArg && thisArg[isSorted] === array) ? null : isSorted;
- isSorted = false;
- }
- if (callback != null) {
- callback = lodash.createCallback(callback, thisArg, 3);
- }
- return baseUniq(array, isSorted, callback);
- }
-
- /**
- * Creates an array excluding all provided values using strict equality for
- * comparisons, i.e. `===`.
- *
- * @static
- * @memberOf _
- * @category Arrays
- * @param {Array} array The array to filter.
- * @param {...*} [value] The values to exclude.
- * @returns {Array} Returns a new array of filtered values.
- * @example
- *
- * _.without([1, 2, 1, 0, 3, 1, 4], 0, 1);
- * // => [2, 3, 4]
- */
- function without(array) {
- return baseDifference(array, slice(arguments, 1));
- }
-
- /**
- * Creates an array that is the symmetric difference of the provided arrays.
- * See http://en.wikipedia.org/wiki/Symmetric_difference.
- *
- * @static
- * @memberOf _
- * @category Arrays
- * @param {...Array} [array] The arrays to inspect.
- * @returns {Array} Returns an array of values.
- * @example
- *
- * _.xor([1, 2, 3], [5, 2, 1, 4]);
- * // => [3, 5, 4]
- *
- * _.xor([1, 2, 5], [2, 3, 5], [3, 4, 5]);
- * // => [1, 4, 5]
- */
- function xor() {
- var index = -1,
- length = arguments.length;
-
- while (++index < length) {
- var array = arguments[index];
- if (isArray(array) || isArguments(array)) {
- var result = result
- ? baseUniq(baseDifference(result, array).concat(baseDifference(array, result)))
- : array;
- }
- }
- return result || [];
- }
-
- /**
- * Creates an array of grouped elements, the first of which contains the first
- * elements of the given arrays, the second of which contains the second
- * elements of the given arrays, and so on.
- *
- * @static
- * @memberOf _
- * @alias unzip
- * @category Arrays
- * @param {...Array} [array] Arrays to process.
- * @returns {Array} Returns a new array of grouped elements.
- * @example
- *
- * _.zip(['fred', 'barney'], [30, 40], [true, false]);
- * // => [['fred', 30, true], ['barney', 40, false]]
- */
- function zip() {
- var array = arguments.length > 1 ? arguments : arguments[0],
- index = -1,
- length = array ? max(pluck(array, 'length')) : 0,
- result = Array(length < 0 ? 0 : length);
-
- while (++index < length) {
- result[index] = pluck(array, index);
- }
- return result;
- }
-
- /**
- * Creates an object composed from arrays of `keys` and `values`. Provide
- * either a single two dimensional array, i.e. `[[key1, value1], [key2, value2]]`
- * or two arrays, one of `keys` and one of corresponding `values`.
- *
- * @static
- * @memberOf _
- * @alias object
- * @category Arrays
- * @param {Array} keys The array of keys.
- * @param {Array} [values=[]] The array of values.
- * @returns {Object} Returns an object composed of the given keys and
- * corresponding values.
- * @example
- *
- * _.zipObject(['fred', 'barney'], [30, 40]);
- * // => { 'fred': 30, 'barney': 40 }
- */
- function zipObject(keys, values) {
- var index = -1,
- length = keys ? keys.length : 0,
- result = {};
-
- if (!values && length && !isArray(keys[0])) {
- values = [];
- }
- while (++index < length) {
- var key = keys[index];
- if (values) {
- result[key] = values[index];
- } else if (key) {
- result[key[0]] = key[1];
- }
- }
- return result;
- }
-
- /*--------------------------------------------------------------------------*/
-
- /**
- * Creates a function that executes `func`, with the `this` binding and
- * arguments of the created function, only after being called `n` times.
- *
- * @static
- * @memberOf _
- * @category Functions
- * @param {number} n The number of times the function must be called before
- * `func` is executed.
- * @param {Function} func The function to restrict.
- * @returns {Function} Returns the new restricted function.
- * @example
- *
- * var saves = ['profile', 'settings'];
- *
- * var done = _.after(saves.length, function() {
- * console.log('Done saving!');
- * });
- *
- * _.forEach(saves, function(type) {
- * asyncSave({ 'type': type, 'complete': done });
- * });
- * // => logs 'Done saving!', after all saves have completed
- */
- function after(n, func) {
- if (!isFunction(func)) {
- throw new TypeError;
- }
- return function() {
- if (--n < 1) {
- return func.apply(this, arguments);
- }
- };
- }
-
- /**
- * Creates a function that, when called, invokes `func` with the `this`
- * binding of `thisArg` and prepends any additional `bind` arguments to those
- * provided to the bound function.
- *
- * @static
- * @memberOf _
- * @category Functions
- * @param {Function} func The function to bind.
- * @param {*} [thisArg] The `this` binding of `func`.
- * @param {...*} [arg] Arguments to be partially applied.
- * @returns {Function} Returns the new bound function.
- * @example
- *
- * var func = function(greeting) {
- * return greeting + ' ' + this.name;
- * };
- *
- * func = _.bind(func, { 'name': 'fred' }, 'hi');
- * func();
- * // => 'hi fred'
- */
- function bind(func, thisArg) {
- return arguments.length > 2
- ? createWrapper(func, 17, slice(arguments, 2), null, thisArg)
- : createWrapper(func, 1, null, null, thisArg);
- }
-
- /**
- * Binds methods of an object to the object itself, overwriting the existing
- * method. Method names may be specified as individual arguments or as arrays
- * of method names. If no method names are provided all the function properties
- * of `object` will be bound.
- *
- * @static
- * @memberOf _
- * @category Functions
- * @param {Object} object The object to bind and assign the bound methods to.
- * @param {...string} [methodName] The object method names to
- * bind, specified as individual method names or arrays of method names.
- * @returns {Object} Returns `object`.
- * @example
- *
- * var view = {
- * 'label': 'docs',
- * 'onClick': function() { console.log('clicked ' + this.label); }
- * };
- *
- * _.bindAll(view);
- * jQuery('#docs').on('click', view.onClick);
- * // => logs 'clicked docs', when the button is clicked
- */
- function bindAll(object) {
- var funcs = arguments.length > 1 ? baseFlatten(arguments, true, false, 1) : functions(object),
- index = -1,
- length = funcs.length;
-
- while (++index < length) {
- var key = funcs[index];
- object[key] = createWrapper(object[key], 1, null, null, object);
- }
- return object;
- }
-
- /**
- * Creates a function that, when called, invokes the method at `object[key]`
- * and prepends any additional `bindKey` arguments to those provided to the bound
- * function. This method differs from `_.bind` by allowing bound functions to
- * reference methods that will be redefined or don't yet exist.
- * See http://michaux.ca/articles/lazy-function-definition-pattern.
- *
- * @static
- * @memberOf _
- * @category Functions
- * @param {Object} object The object the method belongs to.
- * @param {string} key The key of the method.
- * @param {...*} [arg] Arguments to be partially applied.
- * @returns {Function} Returns the new bound function.
- * @example
- *
- * var object = {
- * 'name': 'fred',
- * 'greet': function(greeting) {
- * return greeting + ' ' + this.name;
- * }
- * };
- *
- * var func = _.bindKey(object, 'greet', 'hi');
- * func();
- * // => 'hi fred'
- *
- * object.greet = function(greeting) {
- * return greeting + 'ya ' + this.name + '!';
- * };
- *
- * func();
- * // => 'hiya fred!'
- */
- function bindKey(object, key) {
- return arguments.length > 2
- ? createWrapper(key, 19, slice(arguments, 2), null, object)
- : createWrapper(key, 3, null, null, object);
- }
-
- /**
- * Creates a function that is the composition of the provided functions,
- * where each function consumes the return value of the function that follows.
- * For example, composing the functions `f()`, `g()`, and `h()` produces `f(g(h()))`.
- * Each function is executed with the `this` binding of the composed function.
- *
- * @static
- * @memberOf _
- * @category Functions
- * @param {...Function} [func] Functions to compose.
- * @returns {Function} Returns the new composed function.
- * @example
- *
- * var realNameMap = {
- * 'pebbles': 'penelope'
- * };
- *
- * var format = function(name) {
- * name = realNameMap[name.toLowerCase()] || name;
- * return name.charAt(0).toUpperCase() + name.slice(1).toLowerCase();
- * };
- *
- * var greet = function(formatted) {
- * return 'Hiya ' + formatted + '!';
- * };
- *
- * var welcome = _.compose(greet, format);
- * welcome('pebbles');
- * // => 'Hiya Penelope!'
- */
- function compose() {
- var funcs = arguments,
- length = funcs.length;
-
- while (length--) {
- if (!isFunction(funcs[length])) {
- throw new TypeError;
- }
- }
- return function() {
- var args = arguments,
- length = funcs.length;
-
- while (length--) {
- args = [funcs[length].apply(this, args)];
- }
- return args[0];
- };
- }
-
- /**
- * Creates a function which accepts one or more arguments of `func` that when
- * invoked either executes `func` returning its result, if all `func` arguments
- * have been provided, or returns a function that accepts one or more of the
- * remaining `func` arguments, and so on. The arity of `func` can be specified
- * if `func.length` is not sufficient.
- *
- * @static
- * @memberOf _
- * @category Functions
- * @param {Function} func The function to curry.
- * @param {number} [arity=func.length] The arity of `func`.
- * @returns {Function} Returns the new curried function.
- * @example
- *
- * var curried = _.curry(function(a, b, c) {
- * console.log(a + b + c);
- * });
- *
- * curried(1)(2)(3);
- * // => 6
- *
- * curried(1, 2)(3);
- * // => 6
- *
- * curried(1, 2, 3);
- * // => 6
- */
- function curry(func, arity) {
- arity = typeof arity == 'number' ? arity : (+arity || func.length);
- return createWrapper(func, 4, null, null, null, arity);
- }
-
- /**
- * Creates a function that will delay the execution of `func` until after
- * `wait` milliseconds have elapsed since the last time it was invoked.
- * Provide an options object to indicate that `func` should be invoked on
- * the leading and/or trailing edge of the `wait` timeout. Subsequent calls
- * to the debounced function will return the result of the last `func` call.
- *
- * Note: If `leading` and `trailing` options are `true` `func` will be called
- * on the trailing edge of the timeout only if the the debounced function is
- * invoked more than once during the `wait` timeout.
- *
- * @static
- * @memberOf _
- * @category Functions
- * @param {Function} func The function to debounce.
- * @param {number} wait The number of milliseconds to delay.
- * @param {Object} [options] The options object.
- * @param {boolean} [options.leading=false] Specify execution on the leading edge of the timeout.
- * @param {number} [options.maxWait] The maximum time `func` is allowed to be delayed before it's called.
- * @param {boolean} [options.trailing=true] Specify execution on the trailing edge of the timeout.
- * @returns {Function} Returns the new debounced function.
- * @example
- *
- * // avoid costly calculations while the window size is in flux
- * var lazyLayout = _.debounce(calculateLayout, 150);
- * jQuery(window).on('resize', lazyLayout);
- *
- * // execute `sendMail` when the click event is fired, debouncing subsequent calls
- * jQuery('#postbox').on('click', _.debounce(sendMail, 300, {
- * 'leading': true,
- * 'trailing': false
- * });
- *
- * // ensure `batchLog` is executed once after 1 second of debounced calls
- * var source = new EventSource('/stream');
- * source.addEventListener('message', _.debounce(batchLog, 250, {
- * 'maxWait': 1000
- * }, false);
- */
- function debounce(func, wait, options) {
- var args,
- maxTimeoutId,
- result,
- stamp,
- thisArg,
- timeoutId,
- trailingCall,
- lastCalled = 0,
- maxWait = false,
- trailing = true;
-
- if (!isFunction(func)) {
- throw new TypeError;
- }
- wait = nativeMax(0, wait) || 0;
- if (options === true) {
- var leading = true;
- trailing = false;
- } else if (isObject(options)) {
- leading = options.leading;
- maxWait = 'maxWait' in options && (nativeMax(wait, options.maxWait) || 0);
- trailing = 'trailing' in options ? options.trailing : trailing;
- }
- var delayed = function() {
- var remaining = wait - (now() - stamp);
- if (remaining <= 0) {
- if (maxTimeoutId) {
- clearTimeout(maxTimeoutId);
- }
- var isCalled = trailingCall;
- maxTimeoutId = timeoutId = trailingCall = undefined;
- if (isCalled) {
- lastCalled = now();
- result = func.apply(thisArg, args);
- if (!timeoutId && !maxTimeoutId) {
- args = thisArg = null;
- }
- }
- } else {
- timeoutId = setTimeout(delayed, remaining);
- }
- };
-
- var maxDelayed = function() {
- if (timeoutId) {
- clearTimeout(timeoutId);
- }
- maxTimeoutId = timeoutId = trailingCall = undefined;
- if (trailing || (maxWait !== wait)) {
- lastCalled = now();
- result = func.apply(thisArg, args);
- if (!timeoutId && !maxTimeoutId) {
- args = thisArg = null;
- }
- }
- };
-
- return function() {
- args = arguments;
- stamp = now();
- thisArg = this;
- trailingCall = trailing && (timeoutId || !leading);
-
- if (maxWait === false) {
- var leadingCall = leading && !timeoutId;
- } else {
- if (!maxTimeoutId && !leading) {
- lastCalled = stamp;
- }
- var remaining = maxWait - (stamp - lastCalled),
- isCalled = remaining <= 0;
-
- if (isCalled) {
- if (maxTimeoutId) {
- maxTimeoutId = clearTimeout(maxTimeoutId);
- }
- lastCalled = stamp;
- result = func.apply(thisArg, args);
- }
- else if (!maxTimeoutId) {
- maxTimeoutId = setTimeout(maxDelayed, remaining);
- }
- }
- if (isCalled && timeoutId) {
- timeoutId = clearTimeout(timeoutId);
- }
- else if (!timeoutId && wait !== maxWait) {
- timeoutId = setTimeout(delayed, wait);
- }
- if (leadingCall) {
- isCalled = true;
- result = func.apply(thisArg, args);
- }
- if (isCalled && !timeoutId && !maxTimeoutId) {
- args = thisArg = null;
- }
- return result;
- };
- }
-
- /**
- * Defers executing the `func` function until the current call stack has cleared.
- * Additional arguments will be provided to `func` when it is invoked.
- *
- * @static
- * @memberOf _
- * @category Functions
- * @param {Function} func The function to defer.
- * @param {...*} [arg] Arguments to invoke the function with.
- * @returns {number} Returns the timer id.
- * @example
- *
- * _.defer(function(text) { console.log(text); }, 'deferred');
- * // logs 'deferred' after one or more milliseconds
- */
- function defer(func) {
- if (!isFunction(func)) {
- throw new TypeError;
- }
- var args = slice(arguments, 1);
- return setTimeout(function() { func.apply(undefined, args); }, 1);
- }
-
- /**
- * Executes the `func` function after `wait` milliseconds. Additional arguments
- * will be provided to `func` when it is invoked.
- *
- * @static
- * @memberOf _
- * @category Functions
- * @param {Function} func The function to delay.
- * @param {number} wait The number of milliseconds to delay execution.
- * @param {...*} [arg] Arguments to invoke the function with.
- * @returns {number} Returns the timer id.
- * @example
- *
- * _.delay(function(text) { console.log(text); }, 1000, 'later');
- * // => logs 'later' after one second
- */
- function delay(func, wait) {
- if (!isFunction(func)) {
- throw new TypeError;
- }
- var args = slice(arguments, 2);
- return setTimeout(function() { func.apply(undefined, args); }, wait);
- }
-
- /**
- * Creates a function that memoizes the result of `func`. If `resolver` is
- * provided it will be used to determine the cache key for storing the result
- * based on the arguments provided to the memoized function. By default, the
- * first argument provided to the memoized function is used as the cache key.
- * The `func` is executed with the `this` binding of the memoized function.
- * The result cache is exposed as the `cache` property on the memoized function.
- *
- * @static
- * @memberOf _
- * @category Functions
- * @param {Function} func The function to have its output memoized.
- * @param {Function} [resolver] A function used to resolve the cache key.
- * @returns {Function} Returns the new memoizing function.
- * @example
- *
- * var fibonacci = _.memoize(function(n) {
- * return n < 2 ? n : fibonacci(n - 1) + fibonacci(n - 2);
- * });
- *
- * fibonacci(9)
- * // => 34
- *
- * var data = {
- * 'fred': { 'name': 'fred', 'age': 40 },
- * 'pebbles': { 'name': 'pebbles', 'age': 1 }
- * };
- *
- * // modifying the result cache
- * var get = _.memoize(function(name) { return data[name]; }, _.identity);
- * get('pebbles');
- * // => { 'name': 'pebbles', 'age': 1 }
- *
- * get.cache.pebbles.name = 'penelope';
- * get('pebbles');
- * // => { 'name': 'penelope', 'age': 1 }
- */
- function memoize(func, resolver) {
- if (!isFunction(func)) {
- throw new TypeError;
- }
- var memoized = function() {
- var cache = memoized.cache,
- key = resolver ? resolver.apply(this, arguments) : keyPrefix + arguments[0];
-
- return hasOwnProperty.call(cache, key)
- ? cache[key]
- : (cache[key] = func.apply(this, arguments));
- }
- memoized.cache = {};
- return memoized;
- }
-
- /**
- * Creates a function that is restricted to execute `func` once. Repeat calls to
- * the function will return the value of the first call. The `func` is executed
- * with the `this` binding of the created function.
- *
- * @static
- * @memberOf _
- * @category Functions
- * @param {Function} func The function to restrict.
- * @returns {Function} Returns the new restricted function.
- * @example
- *
- * var initialize = _.once(createApplication);
- * initialize();
- * initialize();
- * // `initialize` executes `createApplication` once
- */
- function once(func) {
- var ran,
- result;
-
- if (!isFunction(func)) {
- throw new TypeError;
- }
- return function() {
- if (ran) {
- return result;
- }
- ran = true;
- result = func.apply(this, arguments);
-
- // clear the `func` variable so the function may be garbage collected
- func = null;
- return result;
- };
- }
-
- /**
- * Creates a function that, when called, invokes `func` with any additional
- * `partial` arguments prepended to those provided to the new function. This
- * method is similar to `_.bind` except it does **not** alter the `this` binding.
- *
- * @static
- * @memberOf _
- * @category Functions
- * @param {Function} func The function to partially apply arguments to.
- * @param {...*} [arg] Arguments to be partially applied.
- * @returns {Function} Returns the new partially applied function.
- * @example
- *
- * var greet = function(greeting, name) { return greeting + ' ' + name; };
- * var hi = _.partial(greet, 'hi');
- * hi('fred');
- * // => 'hi fred'
- */
- function partial(func) {
- return createWrapper(func, 16, slice(arguments, 1));
- }
-
- /**
- * This method is like `_.partial` except that `partial` arguments are
- * appended to those provided to the new function.
- *
- * @static
- * @memberOf _
- * @category Functions
- * @param {Function} func The function to partially apply arguments to.
- * @param {...*} [arg] Arguments to be partially applied.
- * @returns {Function} Returns the new partially applied function.
- * @example
- *
- * var defaultsDeep = _.partialRight(_.merge, _.defaults);
- *
- * var options = {
- * 'variable': 'data',
- * 'imports': { 'jq': $ }
- * };
- *
- * defaultsDeep(options, _.templateSettings);
- *
- * options.variable
- * // => 'data'
- *
- * options.imports
- * // => { '_': _, 'jq': $ }
- */
- function partialRight(func) {
- return createWrapper(func, 32, null, slice(arguments, 1));
- }
-
- /**
- * Creates a function that, when executed, will only call the `func` function
- * at most once per every `wait` milliseconds. Provide an options object to
- * indicate that `func` should be invoked on the leading and/or trailing edge
- * of the `wait` timeout. Subsequent calls to the throttled function will
- * return the result of the last `func` call.
- *
- * Note: If `leading` and `trailing` options are `true` `func` will be called
- * on the trailing edge of the timeout only if the the throttled function is
- * invoked more than once during the `wait` timeout.
- *
- * @static
- * @memberOf _
- * @category Functions
- * @param {Function} func The function to throttle.
- * @param {number} wait The number of milliseconds to throttle executions to.
- * @param {Object} [options] The options object.
- * @param {boolean} [options.leading=true] Specify execution on the leading edge of the timeout.
- * @param {boolean} [options.trailing=true] Specify execution on the trailing edge of the timeout.
- * @returns {Function} Returns the new throttled function.
- * @example
- *
- * // avoid excessively updating the position while scrolling
- * var throttled = _.throttle(updatePosition, 100);
- * jQuery(window).on('scroll', throttled);
- *
- * // execute `renewToken` when the click event is fired, but not more than once every 5 minutes
- * jQuery('.interactive').on('click', _.throttle(renewToken, 300000, {
- * 'trailing': false
- * }));
- */
- function throttle(func, wait, options) {
- var leading = true,
- trailing = true;
-
- if (!isFunction(func)) {
- throw new TypeError;
- }
- if (options === false) {
- leading = false;
- } else if (isObject(options)) {
- leading = 'leading' in options ? options.leading : leading;
- trailing = 'trailing' in options ? options.trailing : trailing;
- }
- debounceOptions.leading = leading;
- debounceOptions.maxWait = wait;
- debounceOptions.trailing = trailing;
-
- return debounce(func, wait, debounceOptions);
- }
-
- /**
- * Creates a function that provides `value` to the wrapper function as its
- * first argument. Additional arguments provided to the function are appended
- * to those provided to the wrapper function. The wrapper is executed with
- * the `this` binding of the created function.
- *
- * @static
- * @memberOf _
- * @category Functions
- * @param {*} value The value to wrap.
- * @param {Function} wrapper The wrapper function.
- * @returns {Function} Returns the new function.
- * @example
- *
- * var p = _.wrap(_.escape, function(func, text) {
- * return '' + func(text) + '
';
- * });
- *
- * p('Fred, Wilma, & Pebbles');
- * // => 'Fred, Wilma, & Pebbles
'
- */
- function wrap(value, wrapper) {
- return createWrapper(wrapper, 16, [value]);
- }
-
- /*--------------------------------------------------------------------------*/
-
- /**
- * Creates a function that returns `value`.
- *
- * @static
- * @memberOf _
- * @category Utilities
- * @param {*} value The value to return from the new function.
- * @returns {Function} Returns the new function.
- * @example
- *
- * var object = { 'name': 'fred' };
- * var getter = _.constant(object);
- * getter() === object;
- * // => true
- */
- function constant(value) {
- return function() {
- return value;
- };
- }
-
- /**
- * Produces a callback bound to an optional `thisArg`. If `func` is a property
- * name the created callback will return the property value for a given element.
- * If `func` is an object the created callback will return `true` for elements
- * that contain the equivalent object properties, otherwise it will return `false`.
- *
- * @static
- * @memberOf _
- * @category Utilities
- * @param {*} [func=identity] The value to convert to a callback.
- * @param {*} [thisArg] The `this` binding of the created callback.
- * @param {number} [argCount] The number of arguments the callback accepts.
- * @returns {Function} Returns a callback function.
- * @example
- *
- * var characters = [
- * { 'name': 'barney', 'age': 36 },
- * { 'name': 'fred', 'age': 40 }
- * ];
- *
- * // wrap to create custom callback shorthands
- * _.createCallback = _.wrap(_.createCallback, function(func, callback, thisArg) {
- * var match = /^(.+?)__([gl]t)(.+)$/.exec(callback);
- * return !match ? func(callback, thisArg) : function(object) {
- * return match[2] == 'gt' ? object[match[1]] > match[3] : object[match[1]] < match[3];
- * };
- * });
- *
- * _.filter(characters, 'age__gt38');
- * // => [{ 'name': 'fred', 'age': 40 }]
- */
- function createCallback(func, thisArg, argCount) {
- var type = typeof func;
- if (func == null || type == 'function') {
- return baseCreateCallback(func, thisArg, argCount);
- }
- // handle "_.pluck" style callback shorthands
- if (type != 'object') {
- return property(func);
- }
- var props = keys(func),
- key = props[0],
- a = func[key];
-
- // handle "_.where" style callback shorthands
- if (props.length == 1 && a === a && !isObject(a)) {
- // fast path the common case of providing an object with a single
- // property containing a primitive value
- return function(object) {
- var b = object[key];
- return a === b && (a !== 0 || (1 / a == 1 / b));
- };
- }
- return function(object) {
- var length = props.length,
- result = false;
-
- while (length--) {
- if (!(result = baseIsEqual(object[props[length]], func[props[length]], null, true))) {
- break;
- }
- }
- return result;
- };
- }
-
- /**
- * Converts the characters `&`, `<`, `>`, `"`, and `'` in `string` to their
- * corresponding HTML entities.
- *
- * @static
- * @memberOf _
- * @category Utilities
- * @param {string} string The string to escape.
- * @returns {string} Returns the escaped string.
- * @example
- *
- * _.escape('Fred, Wilma, & Pebbles');
- * // => 'Fred, Wilma, & Pebbles'
- */
- function escape(string) {
- return string == null ? '' : String(string).replace(reUnescapedHtml, escapeHtmlChar);
- }
-
- /**
- * This method returns the first argument provided to it.
- *
- * @static
- * @memberOf _
- * @category Utilities
- * @param {*} value Any value.
- * @returns {*} Returns `value`.
- * @example
- *
- * var object = { 'name': 'fred' };
- * _.identity(object) === object;
- * // => true
- */
- function identity(value) {
- return value;
- }
-
- /**
- * Adds function properties of a source object to the destination object.
- * If `object` is a function methods will be added to its prototype as well.
- *
- * @static
- * @memberOf _
- * @category Utilities
- * @param {Function|Object} [object=lodash] object The destination object.
- * @param {Object} source The object of functions to add.
- * @param {Object} [options] The options object.
- * @param {boolean} [options.chain=true] Specify whether the functions added are chainable.
- * @example
- *
- * function capitalize(string) {
- * return string.charAt(0).toUpperCase() + string.slice(1).toLowerCase();
- * }
- *
- * _.mixin({ 'capitalize': capitalize });
- * _.capitalize('fred');
- * // => 'Fred'
- *
- * _('fred').capitalize().value();
- * // => 'Fred'
- *
- * _.mixin({ 'capitalize': capitalize }, { 'chain': false });
- * _('fred').capitalize();
- * // => 'Fred'
- */
- function mixin(object, source, options) {
- var chain = true,
- methodNames = source && functions(source);
-
- if (!source || (!options && !methodNames.length)) {
- if (options == null) {
- options = source;
- }
- ctor = lodashWrapper;
- source = object;
- object = lodash;
- methodNames = functions(source);
- }
- if (options === false) {
- chain = false;
- } else if (isObject(options) && 'chain' in options) {
- chain = options.chain;
- }
- var ctor = object,
- isFunc = isFunction(ctor);
-
- forEach(methodNames, function(methodName) {
- var func = object[methodName] = source[methodName];
- if (isFunc) {
- ctor.prototype[methodName] = function() {
- var chainAll = this.__chain__,
- value = this.__wrapped__,
- args = [value];
-
- push.apply(args, arguments);
- var result = func.apply(object, args);
- if (chain || chainAll) {
- if (value === result && isObject(result)) {
- return this;
- }
- result = new ctor(result);
- result.__chain__ = chainAll;
- }
- return result;
- };
- }
- });
- }
-
- /**
- * Reverts the '_' variable to its previous value and returns a reference to
- * the `lodash` function.
- *
- * @static
- * @memberOf _
- * @category Utilities
- * @returns {Function} Returns the `lodash` function.
- * @example
- *
- * var lodash = _.noConflict();
- */
- function noConflict() {
- context._ = oldDash;
- return this;
- }
-
- /**
- * A no-operation function.
- *
- * @static
- * @memberOf _
- * @category Utilities
- * @example
- *
- * var object = { 'name': 'fred' };
- * _.noop(object) === undefined;
- * // => true
- */
- function noop() {
- // no operation performed
- }
-
- /**
- * Gets the number of milliseconds that have elapsed since the Unix epoch
- * (1 January 1970 00:00:00 UTC).
- *
- * @static
- * @memberOf _
- * @category Utilities
- * @example
- *
- * var stamp = _.now();
- * _.defer(function() { console.log(_.now() - stamp); });
- * // => logs the number of milliseconds it took for the deferred function to be called
- */
- var now = isNative(now = Date.now) && now || function() {
- return new Date().getTime();
- };
-
- /**
- * Converts the given value into an integer of the specified radix.
- * If `radix` is `undefined` or `0` a `radix` of `10` is used unless the
- * `value` is a hexadecimal, in which case a `radix` of `16` is used.
- *
- * Note: This method avoids differences in native ES3 and ES5 `parseInt`
- * implementations. See http://es5.github.io/#E.
- *
- * @static
- * @memberOf _
- * @category Utilities
- * @param {string} value The value to parse.
- * @param {number} [radix] The radix used to interpret the value to parse.
- * @returns {number} Returns the new integer value.
- * @example
- *
- * _.parseInt('08');
- * // => 8
- */
- var parseInt = nativeParseInt(whitespace + '08') == 8 ? nativeParseInt : function(value, radix) {
- // Firefox < 21 and Opera < 15 follow the ES3 specified implementation of `parseInt`
- return nativeParseInt(isString(value) ? value.replace(reLeadingSpacesAndZeros, '') : value, radix || 0);
- };
-
- /**
- * Creates a "_.pluck" style function, which returns the `key` value of a
- * given object.
- *
- * @static
- * @memberOf _
- * @category Utilities
- * @param {string} key The name of the property to retrieve.
- * @returns {Function} Returns the new function.
- * @example
- *
- * var characters = [
- * { 'name': 'fred', 'age': 40 },
- * { 'name': 'barney', 'age': 36 }
- * ];
- *
- * var getName = _.property('name');
- *
- * _.map(characters, getName);
- * // => ['barney', 'fred']
- *
- * _.sortBy(characters, getName);
- * // => [{ 'name': 'barney', 'age': 36 }, { 'name': 'fred', 'age': 40 }]
- */
- function property(key) {
- return function(object) {
- return object[key];
- };
- }
-
- /**
- * Produces a random number between `min` and `max` (inclusive). If only one
- * argument is provided a number between `0` and the given number will be
- * returned. If `floating` is truey or either `min` or `max` are floats a
- * floating-point number will be returned instead of an integer.
- *
- * @static
- * @memberOf _
- * @category Utilities
- * @param {number} [min=0] The minimum possible value.
- * @param {number} [max=1] The maximum possible value.
- * @param {boolean} [floating=false] Specify returning a floating-point number.
- * @returns {number} Returns a random number.
- * @example
- *
- * _.random(0, 5);
- * // => an integer between 0 and 5
- *
- * _.random(5);
- * // => also an integer between 0 and 5
- *
- * _.random(5, true);
- * // => a floating-point number between 0 and 5
- *
- * _.random(1.2, 5.2);
- * // => a floating-point number between 1.2 and 5.2
- */
- function random(min, max, floating) {
- var noMin = min == null,
- noMax = max == null;
-
- if (floating == null) {
- if (typeof min == 'boolean' && noMax) {
- floating = min;
- min = 1;
- }
- else if (!noMax && typeof max == 'boolean') {
- floating = max;
- noMax = true;
- }
- }
- if (noMin && noMax) {
- max = 1;
- }
- min = +min || 0;
- if (noMax) {
- max = min;
- min = 0;
- } else {
- max = +max || 0;
- }
- if (floating || min % 1 || max % 1) {
- var rand = nativeRandom();
- return nativeMin(min + (rand * (max - min + parseFloat('1e-' + ((rand +'').length - 1)))), max);
- }
- return baseRandom(min, max);
- }
-
- /**
- * Resolves the value of property `key` on `object`. If `key` is a function
- * it will be invoked with the `this` binding of `object` and its result returned,
- * else the property value is returned. If `object` is falsey then `undefined`
- * is returned.
- *
- * @static
- * @memberOf _
- * @category Utilities
- * @param {Object} object The object to inspect.
- * @param {string} key The name of the property to resolve.
- * @returns {*} Returns the resolved value.
- * @example
- *
- * var object = {
- * 'cheese': 'crumpets',
- * 'stuff': function() {
- * return 'nonsense';
- * }
- * };
- *
- * _.result(object, 'cheese');
- * // => 'crumpets'
- *
- * _.result(object, 'stuff');
- * // => 'nonsense'
- */
- function result(object, key) {
- if (object) {
- var value = object[key];
- return isFunction(value) ? object[key]() : value;
- }
- }
-
- /**
- * A micro-templating method that handles arbitrary delimiters, preserves
- * whitespace, and correctly escapes quotes within interpolated code.
- *
- * Note: In the development build, `_.template` utilizes sourceURLs for easier
- * debugging. See http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl
- *
- * For more information on precompiling templates see:
- * http://lodash.com/custom-builds
- *
- * For more information on Chrome extension sandboxes see:
- * http://developer.chrome.com/stable/extensions/sandboxingEval.html
- *
- * @static
- * @memberOf _
- * @category Utilities
- * @param {string} text The template text.
- * @param {Object} data The data object used to populate the text.
- * @param {Object} [options] The options object.
- * @param {RegExp} [options.escape] The "escape" delimiter.
- * @param {RegExp} [options.evaluate] The "evaluate" delimiter.
- * @param {Object} [options.imports] An object to import into the template as local variables.
- * @param {RegExp} [options.interpolate] The "interpolate" delimiter.
- * @param {string} [sourceURL] The sourceURL of the template's compiled source.
- * @param {string} [variable] The data object variable name.
- * @returns {Function|string} Returns a compiled function when no `data` object
- * is given, else it returns the interpolated text.
- * @example
- *
- * // using the "interpolate" delimiter to create a compiled template
- * var compiled = _.template('hello <%= name %>');
- * compiled({ 'name': 'fred' });
- * // => 'hello fred'
- *
- * // using the "escape" delimiter to escape HTML in data property values
- * _.template('<%- value %>', { 'value': '
-
-
-
-## Documentation
-
-### Collections
-
-* [forEach](#forEach)
-* [map](#map)
-* [filter](#filter)
-* [reject](#reject)
-* [reduce](#reduce)
-* [detect](#detect)
-* [sortBy](#sortBy)
-* [some](#some)
-* [every](#every)
-* [concat](#concat)
-
-### Control Flow
-
-* [series](#series)
-* [parallel](#parallel)
-* [whilst](#whilst)
-* [until](#until)
-* [waterfall](#waterfall)
-* [queue](#queue)
-* [auto](#auto)
-* [iterator](#iterator)
-* [apply](#apply)
-* [nextTick](#nextTick)
-
-### Utils
-
-* [memoize](#memoize)
-* [unmemoize](#unmemoize)
-* [log](#log)
-* [dir](#dir)
-* [noConflict](#noConflict)
-
-
-## Collections
-
-
-### forEach(arr, iterator, callback)
-
-Applies an iterator function to each item in an array, in parallel.
-The iterator is called with an item from the list and a callback for when it
-has finished. If the iterator passes an error to this callback, the main
-callback for the forEach function is immediately called with the error.
-
-Note, that since this function applies the iterator to each item in parallel
-there is no guarantee that the iterator functions will complete in order.
-
-__Arguments__
-
-* arr - An array to iterate over.
-* iterator(item, callback) - A function to apply to each item in the array.
- The iterator is passed a callback which must be called once it has completed.
-* callback(err) - A callback which is called after all the iterator functions
- have finished, or an error has occurred.
-
-__Example__
-
- // assuming openFiles is an array of file names and saveFile is a function
- // to save the modified contents of that file:
-
- async.forEach(openFiles, saveFile, function(err){
- // if any of the saves produced an error, err would equal that error
- });
-
----------------------------------------
-
-
-### forEachSeries(arr, iterator, callback)
-
-The same as forEach only the iterator is applied to each item in the array in
-series. The next iterator is only called once the current one has completed
-processing. This means the iterator functions will complete in order.
-
-
----------------------------------------
-
-
-### forEachLimit(arr, limit, iterator, callback)
-
-The same as forEach only the iterator is applied to batches of items in the
-array, in series. The next batch of iterators is only called once the current
-one has completed processing.
-
-__Arguments__
-
-* arr - An array to iterate over.
-* limit - How many items should be in each batch.
-* iterator(item, callback) - A function to apply to each item in the array.
- The iterator is passed a callback which must be called once it has completed.
-* callback(err) - A callback which is called after all the iterator functions
- have finished, or an error has occurred.
-
-__Example__
-
- // Assume documents is an array of JSON objects and requestApi is a
- // function that interacts with a rate-limited REST api.
-
- async.forEachLimit(documents, 20, requestApi, function(err){
- // if any of the saves produced an error, err would equal that error
- });
----------------------------------------
-
-
-### map(arr, iterator, callback)
-
-Produces a new array of values by mapping each value in the given array through
-the iterator function. The iterator is called with an item from the array and a
-callback for when it has finished processing. The callback takes 2 arguments,
-an error and the transformed item from the array. If the iterator passes an
-error to this callback, the main callback for the map function is immediately
-called with the error.
-
-Note, that since this function applies the iterator to each item in parallel
-there is no guarantee that the iterator functions will complete in order, however
-the results array will be in the same order as the original array.
-
-__Arguments__
-
-* arr - An array to iterate over.
-* iterator(item, callback) - A function to apply to each item in the array.
- The iterator is passed a callback which must be called once it has completed
- with an error (which can be null) and a transformed item.
-* callback(err, results) - A callback which is called after all the iterator
- functions have finished, or an error has occurred. Results is an array of the
- transformed items from the original array.
-
-__Example__
-
- async.map(['file1','file2','file3'], fs.stat, function(err, results){
- // results is now an array of stats for each file
- });
-
----------------------------------------
-
-
-### mapSeries(arr, iterator, callback)
-
-The same as map only the iterator is applied to each item in the array in
-series. The next iterator is only called once the current one has completed
-processing. The results array will be in the same order as the original.
-
-
----------------------------------------
-
-
-### filter(arr, iterator, callback)
-
-__Alias:__ select
-
-Returns a new array of all the values which pass an async truth test.
-_The callback for each iterator call only accepts a single argument of true or
-false, it does not accept an error argument first!_ This is in-line with the
-way node libraries work with truth tests like path.exists. This operation is
-performed in parallel, but the results array will be in the same order as the
-original.
-
-__Arguments__
-
-* arr - An array to iterate over.
-* iterator(item, callback) - A truth test to apply to each item in the array.
- The iterator is passed a callback which must be called once it has completed.
-* callback(results) - A callback which is called after all the iterator
- functions have finished.
-
-__Example__
-
- async.filter(['file1','file2','file3'], path.exists, function(results){
- // results now equals an array of the existing files
- });
-
----------------------------------------
-
-
-### filterSeries(arr, iterator, callback)
-
-__alias:__ selectSeries
-
-The same as filter only the iterator is applied to each item in the array in
-series. The next iterator is only called once the current one has completed
-processing. The results array will be in the same order as the original.
-
----------------------------------------
-
-
-### reject(arr, iterator, callback)
-
-The opposite of filter. Removes values that pass an async truth test.
-
----------------------------------------
-
-
-### rejectSeries(arr, iterator, callback)
-
-The same as filter, only the iterator is applied to each item in the array
-in series.
-
-
----------------------------------------
-
-
-### reduce(arr, memo, iterator, callback)
-
-__aliases:__ inject, foldl
-
-Reduces a list of values into a single value using an async iterator to return
-each successive step. Memo is the initial state of the reduction. This
-function only operates in series. For performance reasons, it may make sense to
-split a call to this function into a parallel map, then use the normal
-Array.prototype.reduce on the results. This function is for situations where
-each step in the reduction needs to be async, if you can get the data before
-reducing it then its probably a good idea to do so.
-
-__Arguments__
-
-* arr - An array to iterate over.
-* memo - The initial state of the reduction.
-* iterator(memo, item, callback) - A function applied to each item in the
- array to produce the next step in the reduction. The iterator is passed a
- callback which accepts an optional error as its first argument, and the state
- of the reduction as the second. If an error is passed to the callback, the
- reduction is stopped and the main callback is immediately called with the
- error.
-* callback(err, result) - A callback which is called after all the iterator
- functions have finished. Result is the reduced value.
-
-__Example__
-
- async.reduce([1,2,3], 0, function(memo, item, callback){
- // pointless async:
- process.nextTick(function(){
- callback(null, memo + item)
- });
- }, function(err, result){
- // result is now equal to the last value of memo, which is 6
- });
-
----------------------------------------
-
-
-### reduceRight(arr, memo, iterator, callback)
-
-__Alias:__ foldr
-
-Same as reduce, only operates on the items in the array in reverse order.
-
-
----------------------------------------
-
-
-### detect(arr, iterator, callback)
-
-Returns the first value in a list that passes an async truth test. The
-iterator is applied in parallel, meaning the first iterator to return true will
-fire the detect callback with that result. That means the result might not be
-the first item in the original array (in terms of order) that passes the test.
-
-If order within the original array is important then look at detectSeries.
-
-__Arguments__
-
-* arr - An array to iterate over.
-* iterator(item, callback) - A truth test to apply to each item in the array.
- The iterator is passed a callback which must be called once it has completed.
-* callback(result) - A callback which is called as soon as any iterator returns
- true, or after all the iterator functions have finished. Result will be
- the first item in the array that passes the truth test (iterator) or the
- value undefined if none passed.
-
-__Example__
-
- async.detect(['file1','file2','file3'], path.exists, function(result){
- // result now equals the first file in the list that exists
- });
-
----------------------------------------
-
-
-### detectSeries(arr, iterator, callback)
-
-The same as detect, only the iterator is applied to each item in the array
-in series. This means the result is always the first in the original array (in
-terms of array order) that passes the truth test.
-
-
----------------------------------------
-
-
-### sortBy(arr, iterator, callback)
-
-Sorts a list by the results of running each value through an async iterator.
-
-__Arguments__
-
-* arr - An array to iterate over.
-* iterator(item, callback) - A function to apply to each item in the array.
- The iterator is passed a callback which must be called once it has completed
- with an error (which can be null) and a value to use as the sort criteria.
-* callback(err, results) - A callback which is called after all the iterator
- functions have finished, or an error has occurred. Results is the items from
- the original array sorted by the values returned by the iterator calls.
-
-__Example__
-
- async.sortBy(['file1','file2','file3'], function(file, callback){
- fs.stat(file, function(err, stats){
- callback(err, stats.mtime);
- });
- }, function(err, results){
- // results is now the original array of files sorted by
- // modified date
- });
-
-
----------------------------------------
-
-
-### some(arr, iterator, callback)
-
-__Alias:__ any
-
-Returns true if at least one element in the array satisfies an async test.
-_The callback for each iterator call only accepts a single argument of true or
-false, it does not accept an error argument first!_ This is in-line with the
-way node libraries work with truth tests like path.exists. Once any iterator
-call returns true, the main callback is immediately called.
-
-__Arguments__
-
-* arr - An array to iterate over.
-* iterator(item, callback) - A truth test to apply to each item in the array.
- The iterator is passed a callback which must be called once it has completed.
-* callback(result) - A callback which is called as soon as any iterator returns
- true, or after all the iterator functions have finished. Result will be
- either true or false depending on the values of the async tests.
-
-__Example__
-
- async.some(['file1','file2','file3'], path.exists, function(result){
- // if result is true then at least one of the files exists
- });
-
----------------------------------------
-
-
-### every(arr, iterator, callback)
-
-__Alias:__ all
-
-Returns true if every element in the array satisfies an async test.
-_The callback for each iterator call only accepts a single argument of true or
-false, it does not accept an error argument first!_ This is in-line with the
-way node libraries work with truth tests like path.exists.
-
-__Arguments__
-
-* arr - An array to iterate over.
-* iterator(item, callback) - A truth test to apply to each item in the array.
- The iterator is passed a callback which must be called once it has completed.
-* callback(result) - A callback which is called after all the iterator
- functions have finished. Result will be either true or false depending on
- the values of the async tests.
-
-__Example__
-
- async.every(['file1','file2','file3'], path.exists, function(result){
- // if result is true then every file exists
- });
-
----------------------------------------
-
-
-### concat(arr, iterator, callback)
-
-Applies an iterator to each item in a list, concatenating the results. Returns the
-concatenated list. The iterators are called in parallel, and the results are
-concatenated as they return. There is no guarantee that the results array will
-be returned in the original order of the arguments passed to the iterator function.
-
-__Arguments__
-
-* arr - An array to iterate over
-* iterator(item, callback) - A function to apply to each item in the array.
- The iterator is passed a callback which must be called once it has completed
- with an error (which can be null) and an array of results.
-* callback(err, results) - A callback which is called after all the iterator
- functions have finished, or an error has occurred. Results is an array containing
- the concatenated results of the iterator function.
-
-__Example__
-
- async.concat(['dir1','dir2','dir3'], fs.readdir, function(err, files){
- // files is now a list of filenames that exist in the 3 directories
- });
-
----------------------------------------
-
-
-### concatSeries(arr, iterator, callback)
-
-Same as async.concat, but executes in series instead of parallel.
-
-
-## Control Flow
-
-
-### series(tasks, [callback])
-
-Run an array of functions in series, each one running once the previous
-function has completed. If any functions in the series pass an error to its
-callback, no more functions are run and the callback for the series is
-immediately called with the value of the error. Once the tasks have completed,
-the results are passed to the final callback as an array.
-
-It is also possible to use an object instead of an array. Each property will be
-run as a function and the results will be passed to the final callback as an object
-instead of an array. This can be a more readable way of handling results from
-async.series.
-
-
-__Arguments__
-
-* tasks - An array or object containing functions to run, each function is passed
- a callback it must call on completion.
-* callback(err, results) - An optional callback to run once all the functions
- have completed. This function gets an array of all the arguments passed to
- the callbacks used in the array.
-
-__Example__
-
- async.series([
- function(callback){
- // do some stuff ...
- callback(null, 'one');
- },
- function(callback){
- // do some more stuff ...
- callback(null, 'two');
- },
- ],
- // optional callback
- function(err, results){
- // results is now equal to ['one', 'two']
- });
-
-
- // an example using an object instead of an array
- async.series({
- one: function(callback){
- setTimeout(function(){
- callback(null, 1);
- }, 200);
- },
- two: function(callback){
- setTimeout(function(){
- callback(null, 2);
- }, 100);
- },
- },
- function(err, results) {
- // results is now equal to: {one: 1, two: 2}
- });
-
-
----------------------------------------
-
-
-### parallel(tasks, [callback])
-
-Run an array of functions in parallel, without waiting until the previous
-function has completed. If any of the functions pass an error to its
-callback, the main callback is immediately called with the value of the error.
-Once the tasks have completed, the results are passed to the final callback as an
-array.
-
-It is also possible to use an object instead of an array. Each property will be
-run as a function and the results will be passed to the final callback as an object
-instead of an array. This can be a more readable way of handling results from
-async.parallel.
-
-
-__Arguments__
-
-* tasks - An array or object containing functions to run, each function is passed a
- callback it must call on completion.
-* callback(err, results) - An optional callback to run once all the functions
- have completed. This function gets an array of all the arguments passed to
- the callbacks used in the array.
-
-__Example__
-
- async.parallel([
- function(callback){
- setTimeout(function(){
- callback(null, 'one');
- }, 200);
- },
- function(callback){
- setTimeout(function(){
- callback(null, 'two');
- }, 100);
- },
- ],
- // optional callback
- function(err, results){
- // the results array will equal ['one','two'] even though
- // the second function had a shorter timeout.
- });
-
-
- // an example using an object instead of an array
- async.parallel({
- one: function(callback){
- setTimeout(function(){
- callback(null, 1);
- }, 200);
- },
- two: function(callback){
- setTimeout(function(){
- callback(null, 2);
- }, 100);
- },
- },
- function(err, results) {
- // results is now equals to: {one: 1, two: 2}
- });
-
-
----------------------------------------
-
-
-### whilst(test, fn, callback)
-
-Repeatedly call fn, while test returns true. Calls the callback when stopped,
-or an error occurs.
-
-__Arguments__
-
-* test() - synchronous truth test to perform before each execution of fn.
-* fn(callback) - A function to call each time the test passes. The function is
- passed a callback which must be called once it has completed with an optional
- error as the first argument.
-* callback(err) - A callback which is called after the test fails and repeated
- execution of fn has stopped.
-
-__Example__
-
- var count = 0;
-
- async.whilst(
- function () { return count < 5; },
- function (callback) {
- count++;
- setTimeout(callback, 1000);
- },
- function (err) {
- // 5 seconds have passed
- }
- );
-
-
----------------------------------------
-
-
-### until(test, fn, callback)
-
-Repeatedly call fn, until test returns true. Calls the callback when stopped,
-or an error occurs.
-
-The inverse of async.whilst.
-
-
----------------------------------------
-
-
-### waterfall(tasks, [callback])
-
-Runs an array of functions in series, each passing their results to the next in
-the array. However, if any of the functions pass an error to the callback, the
-next function is not executed and the main callback is immediately called with
-the error.
-
-__Arguments__
-
-* tasks - An array of functions to run, each function is passed a callback it
- must call on completion.
-* callback(err, [results]) - An optional callback to run once all the functions
- have completed. This will be passed the results of the last task's callback.
-
-
-
-__Example__
-
- async.waterfall([
- function(callback){
- callback(null, 'one', 'two');
- },
- function(arg1, arg2, callback){
- callback(null, 'three');
- },
- function(arg1, callback){
- // arg1 now equals 'three'
- callback(null, 'done');
- }
- ], function (err, result) {
- // result now equals 'done'
- });
-
-
----------------------------------------
-
-
-### queue(worker, concurrency)
-
-Creates a queue object with the specified concurrency. Tasks added to the
-queue will be processed in parallel (up to the concurrency limit). If all
-workers are in progress, the task is queued until one is available. Once
-a worker has completed a task, the task's callback is called.
-
-__Arguments__
-
-* worker(task, callback) - An asynchronous function for processing a queued
- task.
-* concurrency - An integer for determining how many worker functions should be
- run in parallel.
-
-__Queue objects__
-
-The queue object returned by this function has the following properties and
-methods:
-
-* length() - a function returning the number of items waiting to be processed.
-* concurrency - an integer for determining how many worker functions should be
- run in parallel. This property can be changed after a queue is created to
- alter the concurrency on-the-fly.
-* push(task, [callback]) - add a new task to the queue, the callback is called
- once the worker has finished processing the task.
- instead of a single task, an array of tasks can be submitted. the respective callback is used for every task in the list.
-* saturated - a callback that is called when the queue length hits the concurrency and further tasks will be queued
-* empty - a callback that is called when the last item from the queue is given to a worker
-* drain - a callback that is called when the last item from the queue has returned from the worker
-
-__Example__
-
- // create a queue object with concurrency 2
-
- var q = async.queue(function (task, callback) {
- console.log('hello ' + task.name);
- callback();
- }, 2);
-
-
- // assign a callback
- q.drain = function() {
- console.log('all items have been processed');
- }
-
- // add some items to the queue
-
- q.push({name: 'foo'}, function (err) {
- console.log('finished processing foo');
- });
- q.push({name: 'bar'}, function (err) {
- console.log('finished processing bar');
- });
-
- // add some items to the queue (batch-wise)
-
- q.push([{name: 'baz'},{name: 'bay'},{name: 'bax'}], function (err) {
- console.log('finished processing bar');
- });
-
-
----------------------------------------
-
-
-### auto(tasks, [callback])
-
-Determines the best order for running functions based on their requirements.
-Each function can optionally depend on other functions being completed first,
-and each function is run as soon as its requirements are satisfied. If any of
-the functions pass an error to their callback, that function will not complete
-(so any other functions depending on it will not run) and the main callback
-will be called immediately with the error. Functions also receive an object
-containing the results of functions which have completed so far.
-
-__Arguments__
-
-* tasks - An object literal containing named functions or an array of
- requirements, with the function itself the last item in the array. The key
- used for each function or array is used when specifying requirements. The
- syntax is easier to understand by looking at the example.
-* callback(err, results) - An optional callback which is called when all the
- tasks have been completed. The callback will receive an error as an argument
- if any tasks pass an error to their callback. If all tasks complete
- successfully, it will receive an object containing their results.
-
-__Example__
-
- async.auto({
- get_data: function(callback){
- // async code to get some data
- },
- make_folder: function(callback){
- // async code to create a directory to store a file in
- // this is run at the same time as getting the data
- },
- write_file: ['get_data', 'make_folder', function(callback){
- // once there is some data and the directory exists,
- // write the data to a file in the directory
- callback(null, filename);
- }],
- email_link: ['write_file', function(callback, results){
- // once the file is written let's email a link to it...
- // results.write_file contains the filename returned by write_file.
- }]
- });
-
-This is a fairly trivial example, but to do this using the basic parallel and
-series functions would look like this:
-
- async.parallel([
- function(callback){
- // async code to get some data
- },
- function(callback){
- // async code to create a directory to store a file in
- // this is run at the same time as getting the data
- }
- ],
- function(results){
- async.series([
- function(callback){
- // once there is some data and the directory exists,
- // write the data to a file in the directory
- },
- email_link: function(callback){
- // once the file is written let's email a link to it...
- }
- ]);
- });
-
-For a complicated series of async tasks using the auto function makes adding
-new tasks much easier and makes the code more readable.
-
-
----------------------------------------
-
-
-### iterator(tasks)
-
-Creates an iterator function which calls the next function in the array,
-returning a continuation to call the next one after that. Its also possible to
-'peek' the next iterator by doing iterator.next().
-
-This function is used internally by the async module but can be useful when
-you want to manually control the flow of functions in series.
-
-__Arguments__
-
-* tasks - An array of functions to run, each function is passed a callback it
- must call on completion.
-
-__Example__
-
- var iterator = async.iterator([
- function(){ sys.p('one'); },
- function(){ sys.p('two'); },
- function(){ sys.p('three'); }
- ]);
-
- node> var iterator2 = iterator();
- 'one'
- node> var iterator3 = iterator2();
- 'two'
- node> iterator3();
- 'three'
- node> var nextfn = iterator2.next();
- node> nextfn();
- 'three'
-
-
----------------------------------------
-
-
-### apply(function, arguments..)
-
-Creates a continuation function with some arguments already applied, a useful
-shorthand when combined with other control flow functions. Any arguments
-passed to the returned function are added to the arguments originally passed
-to apply.
-
-__Arguments__
-
-* function - The function you want to eventually apply all arguments to.
-* arguments... - Any number of arguments to automatically apply when the
- continuation is called.
-
-__Example__
-
- // using apply
-
- async.parallel([
- async.apply(fs.writeFile, 'testfile1', 'test1'),
- async.apply(fs.writeFile, 'testfile2', 'test2'),
- ]);
-
-
- // the same process without using apply
-
- async.parallel([
- function(callback){
- fs.writeFile('testfile1', 'test1', callback);
- },
- function(callback){
- fs.writeFile('testfile2', 'test2', callback);
- },
- ]);
-
-It's possible to pass any number of additional arguments when calling the
-continuation:
-
- node> var fn = async.apply(sys.puts, 'one');
- node> fn('two', 'three');
- one
- two
- three
-
----------------------------------------
-
-
-### nextTick(callback)
-
-Calls the callback on a later loop around the event loop. In node.js this just
-calls process.nextTick, in the browser it falls back to setTimeout(callback, 0),
-which means other higher priority events may precede the execution of the callback.
-
-This is used internally for browser-compatibility purposes.
-
-__Arguments__
-
-* callback - The function to call on a later loop around the event loop.
-
-__Example__
-
- var call_order = [];
- async.nextTick(function(){
- call_order.push('two');
- // call_order now equals ['one','two]
- });
- call_order.push('one')
-
-
-## Utils
-
-
-### memoize(fn, [hasher])
-
-Caches the results of an async function. When creating a hash to store function
-results against, the callback is omitted from the hash and an optional hash
-function can be used.
-
-__Arguments__
-
-* fn - the function you to proxy and cache results from.
-* hasher - an optional function for generating a custom hash for storing
- results, it has all the arguments applied to it apart from the callback, and
- must be synchronous.
-
-__Example__
-
- var slow_fn = function (name, callback) {
- // do something
- callback(null, result);
- };
- var fn = async.memoize(slow_fn);
-
- // fn can now be used as if it were slow_fn
- fn('some name', function () {
- // callback
- });
-
-
-### unmemoize(fn)
-
-Undoes a memoized function, reverting it to the original, unmemoized
-form. Comes handy in tests.
-
-__Arguments__
-
-* fn - the memoized function
-
-
-### log(function, arguments)
-
-Logs the result of an async function to the console. Only works in node.js or
-in browsers that support console.log and console.error (such as FF and Chrome).
-If multiple arguments are returned from the async function, console.log is
-called on each argument in order.
-
-__Arguments__
-
-* function - The function you want to eventually apply all arguments to.
-* arguments... - Any number of arguments to apply to the function.
-
-__Example__
-
- var hello = function(name, callback){
- setTimeout(function(){
- callback(null, 'hello ' + name);
- }, 1000);
- };
-
- node> async.log(hello, 'world');
- 'hello world'
-
-
----------------------------------------
-
-
-### dir(function, arguments)
-
-Logs the result of an async function to the console using console.dir to
-display the properties of the resulting object. Only works in node.js or
-in browsers that support console.dir and console.error (such as FF and Chrome).
-If multiple arguments are returned from the async function, console.dir is
-called on each argument in order.
-
-__Arguments__
-
-* function - The function you want to eventually apply all arguments to.
-* arguments... - Any number of arguments to apply to the function.
-
-__Example__
-
- var hello = function(name, callback){
- setTimeout(function(){
- callback(null, {hello: name});
- }, 1000);
- };
-
- node> async.dir(hello, 'world');
- {hello: 'world'}
-
-
----------------------------------------
-
-
-### noConflict()
-
-Changes the value of async back to its original value, returning a reference to the
-async object.
diff --git a/spec/fixture/node_modules/grunt/node_modules/async/index.js b/spec/fixture/node_modules/grunt/node_modules/async/index.js
deleted file mode 100644
index 8e238453..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/async/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-// This file is just added for convenience so this repository can be
-// directly checked out into a project's deps folder
-module.exports = require('./lib/async');
diff --git a/spec/fixture/node_modules/grunt/node_modules/async/lib/async.js b/spec/fixture/node_modules/grunt/node_modules/async/lib/async.js
deleted file mode 100644
index 7cc4f5ea..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/async/lib/async.js
+++ /dev/null
@@ -1,692 +0,0 @@
-/*global setTimeout: false, console: false */
-(function () {
-
- var async = {};
-
- // global on the server, window in the browser
- var root = this,
- previous_async = root.async;
-
- if (typeof module !== 'undefined' && module.exports) {
- module.exports = async;
- }
- else {
- root.async = async;
- }
-
- async.noConflict = function () {
- root.async = previous_async;
- return async;
- };
-
- //// cross-browser compatiblity functions ////
-
- var _forEach = function (arr, iterator) {
- if (arr.forEach) {
- return arr.forEach(iterator);
- }
- for (var i = 0; i < arr.length; i += 1) {
- iterator(arr[i], i, arr);
- }
- };
-
- var _map = function (arr, iterator) {
- if (arr.map) {
- return arr.map(iterator);
- }
- var results = [];
- _forEach(arr, function (x, i, a) {
- results.push(iterator(x, i, a));
- });
- return results;
- };
-
- var _reduce = function (arr, iterator, memo) {
- if (arr.reduce) {
- return arr.reduce(iterator, memo);
- }
- _forEach(arr, function (x, i, a) {
- memo = iterator(memo, x, i, a);
- });
- return memo;
- };
-
- var _keys = function (obj) {
- if (Object.keys) {
- return Object.keys(obj);
- }
- var keys = [];
- for (var k in obj) {
- if (obj.hasOwnProperty(k)) {
- keys.push(k);
- }
- }
- return keys;
- };
-
- //// exported async module functions ////
-
- //// nextTick implementation with browser-compatible fallback ////
- if (typeof process === 'undefined' || !(process.nextTick)) {
- async.nextTick = function (fn) {
- setTimeout(fn, 0);
- };
- }
- else {
- async.nextTick = process.nextTick;
- }
-
- async.forEach = function (arr, iterator, callback) {
- callback = callback || function () {};
- if (!arr.length) {
- return callback();
- }
- var completed = 0;
- _forEach(arr, function (x) {
- iterator(x, function (err) {
- if (err) {
- callback(err);
- callback = function () {};
- }
- else {
- completed += 1;
- if (completed === arr.length) {
- callback(null);
- }
- }
- });
- });
- };
-
- async.forEachSeries = function (arr, iterator, callback) {
- callback = callback || function () {};
- if (!arr.length) {
- return callback();
- }
- var completed = 0;
- var iterate = function () {
- iterator(arr[completed], function (err) {
- if (err) {
- callback(err);
- callback = function () {};
- }
- else {
- completed += 1;
- if (completed === arr.length) {
- callback(null);
- }
- else {
- iterate();
- }
- }
- });
- };
- iterate();
- };
-
- async.forEachLimit = function (arr, limit, iterator, callback) {
- callback = callback || function () {};
- if (!arr.length || limit <= 0) {
- return callback();
- }
- var completed = 0;
- var started = 0;
- var running = 0;
-
- (function replenish () {
- if (completed === arr.length) {
- return callback();
- }
-
- while (running < limit && started < arr.length) {
- started += 1;
- running += 1;
- iterator(arr[started - 1], function (err) {
- if (err) {
- callback(err);
- callback = function () {};
- }
- else {
- completed += 1;
- running -= 1;
- if (completed === arr.length) {
- callback();
- }
- else {
- replenish();
- }
- }
- });
- }
- })();
- };
-
-
- var doParallel = function (fn) {
- return function () {
- var args = Array.prototype.slice.call(arguments);
- return fn.apply(null, [async.forEach].concat(args));
- };
- };
- var doSeries = function (fn) {
- return function () {
- var args = Array.prototype.slice.call(arguments);
- return fn.apply(null, [async.forEachSeries].concat(args));
- };
- };
-
-
- var _asyncMap = function (eachfn, arr, iterator, callback) {
- var results = [];
- arr = _map(arr, function (x, i) {
- return {index: i, value: x};
- });
- eachfn(arr, function (x, callback) {
- iterator(x.value, function (err, v) {
- results[x.index] = v;
- callback(err);
- });
- }, function (err) {
- callback(err, results);
- });
- };
- async.map = doParallel(_asyncMap);
- async.mapSeries = doSeries(_asyncMap);
-
-
- // reduce only has a series version, as doing reduce in parallel won't
- // work in many situations.
- async.reduce = function (arr, memo, iterator, callback) {
- async.forEachSeries(arr, function (x, callback) {
- iterator(memo, x, function (err, v) {
- memo = v;
- callback(err);
- });
- }, function (err) {
- callback(err, memo);
- });
- };
- // inject alias
- async.inject = async.reduce;
- // foldl alias
- async.foldl = async.reduce;
-
- async.reduceRight = function (arr, memo, iterator, callback) {
- var reversed = _map(arr, function (x) {
- return x;
- }).reverse();
- async.reduce(reversed, memo, iterator, callback);
- };
- // foldr alias
- async.foldr = async.reduceRight;
-
- var _filter = function (eachfn, arr, iterator, callback) {
- var results = [];
- arr = _map(arr, function (x, i) {
- return {index: i, value: x};
- });
- eachfn(arr, function (x, callback) {
- iterator(x.value, function (v) {
- if (v) {
- results.push(x);
- }
- callback();
- });
- }, function (err) {
- callback(_map(results.sort(function (a, b) {
- return a.index - b.index;
- }), function (x) {
- return x.value;
- }));
- });
- };
- async.filter = doParallel(_filter);
- async.filterSeries = doSeries(_filter);
- // select alias
- async.select = async.filter;
- async.selectSeries = async.filterSeries;
-
- var _reject = function (eachfn, arr, iterator, callback) {
- var results = [];
- arr = _map(arr, function (x, i) {
- return {index: i, value: x};
- });
- eachfn(arr, function (x, callback) {
- iterator(x.value, function (v) {
- if (!v) {
- results.push(x);
- }
- callback();
- });
- }, function (err) {
- callback(_map(results.sort(function (a, b) {
- return a.index - b.index;
- }), function (x) {
- return x.value;
- }));
- });
- };
- async.reject = doParallel(_reject);
- async.rejectSeries = doSeries(_reject);
-
- var _detect = function (eachfn, arr, iterator, main_callback) {
- eachfn(arr, function (x, callback) {
- iterator(x, function (result) {
- if (result) {
- main_callback(x);
- main_callback = function () {};
- }
- else {
- callback();
- }
- });
- }, function (err) {
- main_callback();
- });
- };
- async.detect = doParallel(_detect);
- async.detectSeries = doSeries(_detect);
-
- async.some = function (arr, iterator, main_callback) {
- async.forEach(arr, function (x, callback) {
- iterator(x, function (v) {
- if (v) {
- main_callback(true);
- main_callback = function () {};
- }
- callback();
- });
- }, function (err) {
- main_callback(false);
- });
- };
- // any alias
- async.any = async.some;
-
- async.every = function (arr, iterator, main_callback) {
- async.forEach(arr, function (x, callback) {
- iterator(x, function (v) {
- if (!v) {
- main_callback(false);
- main_callback = function () {};
- }
- callback();
- });
- }, function (err) {
- main_callback(true);
- });
- };
- // all alias
- async.all = async.every;
-
- async.sortBy = function (arr, iterator, callback) {
- async.map(arr, function (x, callback) {
- iterator(x, function (err, criteria) {
- if (err) {
- callback(err);
- }
- else {
- callback(null, {value: x, criteria: criteria});
- }
- });
- }, function (err, results) {
- if (err) {
- return callback(err);
- }
- else {
- var fn = function (left, right) {
- var a = left.criteria, b = right.criteria;
- return a < b ? -1 : a > b ? 1 : 0;
- };
- callback(null, _map(results.sort(fn), function (x) {
- return x.value;
- }));
- }
- });
- };
-
- async.auto = function (tasks, callback) {
- callback = callback || function () {};
- var keys = _keys(tasks);
- if (!keys.length) {
- return callback(null);
- }
-
- var results = {};
-
- var listeners = [];
- var addListener = function (fn) {
- listeners.unshift(fn);
- };
- var removeListener = function (fn) {
- for (var i = 0; i < listeners.length; i += 1) {
- if (listeners[i] === fn) {
- listeners.splice(i, 1);
- return;
- }
- }
- };
- var taskComplete = function () {
- _forEach(listeners.slice(0), function (fn) {
- fn();
- });
- };
-
- addListener(function () {
- if (_keys(results).length === keys.length) {
- callback(null, results);
- callback = function () {};
- }
- });
-
- _forEach(keys, function (k) {
- var task = (tasks[k] instanceof Function) ? [tasks[k]]: tasks[k];
- var taskCallback = function (err) {
- if (err) {
- callback(err);
- // stop subsequent errors hitting callback multiple times
- callback = function () {};
- }
- else {
- var args = Array.prototype.slice.call(arguments, 1);
- if (args.length <= 1) {
- args = args[0];
- }
- results[k] = args;
- taskComplete();
- }
- };
- var requires = task.slice(0, Math.abs(task.length - 1)) || [];
- var ready = function () {
- return _reduce(requires, function (a, x) {
- return (a && results.hasOwnProperty(x));
- }, true) && !results.hasOwnProperty(k);
- };
- if (ready()) {
- task[task.length - 1](taskCallback, results);
- }
- else {
- var listener = function () {
- if (ready()) {
- removeListener(listener);
- task[task.length - 1](taskCallback, results);
- }
- };
- addListener(listener);
- }
- });
- };
-
- async.waterfall = function (tasks, callback) {
- callback = callback || function () {};
- if (!tasks.length) {
- return callback();
- }
- var wrapIterator = function (iterator) {
- return function (err) {
- if (err) {
- callback(err);
- callback = function () {};
- }
- else {
- var args = Array.prototype.slice.call(arguments, 1);
- var next = iterator.next();
- if (next) {
- args.push(wrapIterator(next));
- }
- else {
- args.push(callback);
- }
- async.nextTick(function () {
- iterator.apply(null, args);
- });
- }
- };
- };
- wrapIterator(async.iterator(tasks))();
- };
-
- async.parallel = function (tasks, callback) {
- callback = callback || function () {};
- if (tasks.constructor === Array) {
- async.map(tasks, function (fn, callback) {
- if (fn) {
- fn(function (err) {
- var args = Array.prototype.slice.call(arguments, 1);
- if (args.length <= 1) {
- args = args[0];
- }
- callback.call(null, err, args);
- });
- }
- }, callback);
- }
- else {
- var results = {};
- async.forEach(_keys(tasks), function (k, callback) {
- tasks[k](function (err) {
- var args = Array.prototype.slice.call(arguments, 1);
- if (args.length <= 1) {
- args = args[0];
- }
- results[k] = args;
- callback(err);
- });
- }, function (err) {
- callback(err, results);
- });
- }
- };
-
- async.series = function (tasks, callback) {
- callback = callback || function () {};
- if (tasks.constructor === Array) {
- async.mapSeries(tasks, function (fn, callback) {
- if (fn) {
- fn(function (err) {
- var args = Array.prototype.slice.call(arguments, 1);
- if (args.length <= 1) {
- args = args[0];
- }
- callback.call(null, err, args);
- });
- }
- }, callback);
- }
- else {
- var results = {};
- async.forEachSeries(_keys(tasks), function (k, callback) {
- tasks[k](function (err) {
- var args = Array.prototype.slice.call(arguments, 1);
- if (args.length <= 1) {
- args = args[0];
- }
- results[k] = args;
- callback(err);
- });
- }, function (err) {
- callback(err, results);
- });
- }
- };
-
- async.iterator = function (tasks) {
- var makeCallback = function (index) {
- var fn = function () {
- if (tasks.length) {
- tasks[index].apply(null, arguments);
- }
- return fn.next();
- };
- fn.next = function () {
- return (index < tasks.length - 1) ? makeCallback(index + 1): null;
- };
- return fn;
- };
- return makeCallback(0);
- };
-
- async.apply = function (fn) {
- var args = Array.prototype.slice.call(arguments, 1);
- return function () {
- return fn.apply(
- null, args.concat(Array.prototype.slice.call(arguments))
- );
- };
- };
-
- var _concat = function (eachfn, arr, fn, callback) {
- var r = [];
- eachfn(arr, function (x, cb) {
- fn(x, function (err, y) {
- r = r.concat(y || []);
- cb(err);
- });
- }, function (err) {
- callback(err, r);
- });
- };
- async.concat = doParallel(_concat);
- async.concatSeries = doSeries(_concat);
-
- async.whilst = function (test, iterator, callback) {
- if (test()) {
- iterator(function (err) {
- if (err) {
- return callback(err);
- }
- async.whilst(test, iterator, callback);
- });
- }
- else {
- callback();
- }
- };
-
- async.until = function (test, iterator, callback) {
- if (!test()) {
- iterator(function (err) {
- if (err) {
- return callback(err);
- }
- async.until(test, iterator, callback);
- });
- }
- else {
- callback();
- }
- };
-
- async.queue = function (worker, concurrency) {
- var workers = 0;
- var q = {
- tasks: [],
- concurrency: concurrency,
- saturated: null,
- empty: null,
- drain: null,
- push: function (data, callback) {
- if(data.constructor !== Array) {
- data = [data];
- }
- _forEach(data, function(task) {
- q.tasks.push({
- data: task,
- callback: typeof callback === 'function' ? callback : null
- });
- if (q.saturated && q.tasks.length == concurrency) {
- q.saturated();
- }
- async.nextTick(q.process);
- });
- },
- process: function () {
- if (workers < q.concurrency && q.tasks.length) {
- var task = q.tasks.shift();
- if(q.empty && q.tasks.length == 0) q.empty();
- workers += 1;
- worker(task.data, function () {
- workers -= 1;
- if (task.callback) {
- task.callback.apply(task, arguments);
- }
- if(q.drain && q.tasks.length + workers == 0) q.drain();
- q.process();
- });
- }
- },
- length: function () {
- return q.tasks.length;
- },
- running: function () {
- return workers;
- }
- };
- return q;
- };
-
- var _console_fn = function (name) {
- return function (fn) {
- var args = Array.prototype.slice.call(arguments, 1);
- fn.apply(null, args.concat([function (err) {
- var args = Array.prototype.slice.call(arguments, 1);
- if (typeof console !== 'undefined') {
- if (err) {
- if (console.error) {
- console.error(err);
- }
- }
- else if (console[name]) {
- _forEach(args, function (x) {
- console[name](x);
- });
- }
- }
- }]));
- };
- };
- async.log = _console_fn('log');
- async.dir = _console_fn('dir');
- /*async.info = _console_fn('info');
- async.warn = _console_fn('warn');
- async.error = _console_fn('error');*/
-
- async.memoize = function (fn, hasher) {
- var memo = {};
- var queues = {};
- hasher = hasher || function (x) {
- return x;
- };
- var memoized = function () {
- var args = Array.prototype.slice.call(arguments);
- var callback = args.pop();
- var key = hasher.apply(null, args);
- if (key in memo) {
- callback.apply(null, memo[key]);
- }
- else if (key in queues) {
- queues[key].push(callback);
- }
- else {
- queues[key] = [callback];
- fn.apply(null, args.concat([function () {
- memo[key] = arguments;
- var q = queues[key];
- delete queues[key];
- for (var i = 0, l = q.length; i < l; i++) {
- q[i].apply(null, arguments);
- }
- }]));
- }
- };
- memoized.unmemoized = fn;
- return memoized;
- };
-
- async.unmemoize = function (fn) {
- return function () {
- return (fn.unmemoized || fn).apply(null, arguments);
- };
- };
-
-}());
diff --git a/spec/fixture/node_modules/grunt/node_modules/async/package.json b/spec/fixture/node_modules/grunt/node_modules/async/package.json
deleted file mode 100644
index 29bf9131..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/async/package.json
+++ /dev/null
@@ -1,58 +0,0 @@
-{
- "name": "async",
- "description": "Higher-order functions and common patterns for asynchronous code",
- "main": "./index",
- "author": {
- "name": "Caolan McMahon"
- },
- "version": "0.1.22",
- "repository": {
- "type": "git",
- "url": "git://github.com/caolan/async.git"
- },
- "bugs": {
- "url": "http://github.com/caolan/async/issues"
- },
- "licenses": [
- {
- "type": "MIT",
- "url": "http://github.com/caolan/async/raw/master/LICENSE"
- }
- ],
- "devDependencies": {
- "nodeunit": ">0.0.0",
- "uglify-js": "1.2.x",
- "nodelint": ">0.0.0"
- },
- "_npmUser": {
- "name": "caolan",
- "email": "caolan@caolanmcmahon.com"
- },
- "_id": "async@0.1.22",
- "dependencies": {},
- "optionalDependencies": {},
- "engines": {
- "node": "*"
- },
- "_engineSupported": true,
- "_npmVersion": "1.1.21",
- "_nodeVersion": "v0.6.18",
- "_defaultsLoaded": true,
- "dist": {
- "shasum": "0fc1aaa088a0e3ef0ebe2d8831bab0dcf8845061",
- "tarball": "http://registry.npmjs.org/async/-/async-0.1.22.tgz"
- },
- "maintainers": [
- {
- "name": "caolan",
- "email": "caolan@caolanmcmahon.com"
- }
- ],
- "directories": {},
- "_shasum": "0fc1aaa088a0e3ef0ebe2d8831bab0dcf8845061",
- "_from": "async@~0.1.22",
- "_resolved": "https://registry.npmjs.org/async/-/async-0.1.22.tgz",
- "readme": "ERROR: No README data found!",
- "homepage": "https://github.com/caolan/async",
- "scripts": {}
-}
diff --git a/spec/fixture/node_modules/grunt/node_modules/coffee-script/.npmignore b/spec/fixture/node_modules/grunt/node_modules/coffee-script/.npmignore
deleted file mode 100644
index 21e430d2..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/coffee-script/.npmignore
+++ /dev/null
@@ -1,11 +0,0 @@
-*.coffee
-*.html
-.DS_Store
-.git*
-Cakefile
-documentation/
-examples/
-extras/coffee-script.js
-raw/
-src/
-test/
diff --git a/spec/fixture/node_modules/grunt/node_modules/coffee-script/CNAME b/spec/fixture/node_modules/grunt/node_modules/coffee-script/CNAME
deleted file mode 100644
index faadabe5..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/coffee-script/CNAME
+++ /dev/null
@@ -1 +0,0 @@
-coffeescript.org
\ No newline at end of file
diff --git a/spec/fixture/node_modules/grunt/node_modules/coffee-script/LICENSE b/spec/fixture/node_modules/grunt/node_modules/coffee-script/LICENSE
deleted file mode 100644
index dbe6b4e3..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/coffee-script/LICENSE
+++ /dev/null
@@ -1,22 +0,0 @@
-Copyright (c) 2009-2012 Jeremy Ashkenas
-
-Permission is hereby granted, free of charge, to any person
-obtaining a copy of this software and associated documentation
-files (the "Software"), to deal in the Software without
-restriction, including without limitation the rights to use,
-copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the
-Software is furnished to do so, subject to the following
-conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-OTHER DEALINGS IN THE SOFTWARE.
\ No newline at end of file
diff --git a/spec/fixture/node_modules/grunt/node_modules/coffee-script/README b/spec/fixture/node_modules/grunt/node_modules/coffee-script/README
deleted file mode 100644
index 69ee6f43..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/coffee-script/README
+++ /dev/null
@@ -1,51 +0,0 @@
-
- {
- } } {
- { { } }
- } }{ {
- { }{ } } _____ __ __
- ( }{ }{ { ) / ____| / _|/ _|
- .- { { } { }} -. | | ___ | |_| |_ ___ ___
- ( ( } { } { } } ) | | / _ \| _| _/ _ \/ _ \
- |`-..________ ..-'| | |___| (_) | | | || __/ __/
- | | \_____\___/|_| |_| \___|\___|
- | ;--.
- | (__ \ _____ _ _
- | | ) ) / ____| (_) | |
- | |/ / | (___ ___ _ __ _ _ __ | |_
- | ( / \___ \ / __| '__| | '_ \| __|
- | |/ ____) | (__| | | | |_) | |_
- | | |_____/ \___|_| |_| .__/ \__|
- `-.._________..-' | |
- |_|
-
-
- CoffeeScript is a little language that compiles into JavaScript.
-
- Install Node.js, and then the CoffeeScript compiler:
- sudo bin/cake install
-
- Or, if you have the Node Package Manager installed:
- npm install -g coffee-script
- (Leave off the -g if you don't wish to install globally.)
-
- Execute a script:
- coffee /path/to/script.coffee
-
- Compile a script:
- coffee -c /path/to/script.coffee
-
- For documentation, usage, and examples, see:
- http://coffeescript.org/
-
- To suggest a feature, report a bug, or general discussion:
- http://github.com/jashkenas/coffee-script/issues/
-
- If you'd like to chat, drop by #coffeescript on Freenode IRC,
- or on webchat.freenode.net.
-
- The source repository:
- git://github.com/jashkenas/coffee-script.git
-
- All contributors are listed here:
- http://github.com/jashkenas/coffee-script/contributors
diff --git a/spec/fixture/node_modules/grunt/node_modules/coffee-script/Rakefile b/spec/fixture/node_modules/grunt/node_modules/coffee-script/Rakefile
deleted file mode 100644
index dfb85dab..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/coffee-script/Rakefile
+++ /dev/null
@@ -1,78 +0,0 @@
-require 'rubygems'
-require 'erb'
-require 'fileutils'
-require 'rake/testtask'
-require 'json'
-
-desc "Build the documentation page"
-task :doc do
- source = 'documentation/index.html.erb'
- child = fork { exec "bin/coffee -bcw -o documentation/js documentation/coffee/*.coffee" }
- at_exit { Process.kill("INT", child) }
- Signal.trap("INT") { exit }
- loop do
- mtime = File.stat(source).mtime
- if !@mtime || mtime > @mtime
- rendered = ERB.new(File.read(source)).result(binding)
- File.open('index.html', 'w+') {|f| f.write(rendered) }
- end
- @mtime = mtime
- sleep 1
- end
-end
-
-desc "Build coffee-script-source gem"
-task :gem do
- require 'rubygems'
- require 'rubygems/package'
-
- gemspec = Gem::Specification.new do |s|
- s.name = 'coffee-script-source'
- s.version = JSON.parse(File.read('package.json'))["version"]
- s.date = Time.now.strftime("%Y-%m-%d")
-
- s.homepage = "http://jashkenas.github.com/coffee-script/"
- s.summary = "The CoffeeScript Compiler"
- s.description = <<-EOS
- CoffeeScript is a little language that compiles into JavaScript.
- Underneath all of those embarrassing braces and semicolons,
- JavaScript has always had a gorgeous object model at its heart.
- CoffeeScript is an attempt to expose the good parts of JavaScript
- in a simple way.
- EOS
-
- s.files = [
- 'lib/coffee_script/coffee-script.js',
- 'lib/coffee_script/source.rb'
- ]
-
- s.authors = ['Jeremy Ashkenas']
- s.email = 'jashkenas@gmail.com'
- s.rubyforge_project = 'coffee-script-source'
- end
-
- file = File.open("coffee-script-source.gem", "w")
- Gem::Package.open(file, 'w') do |pkg|
- pkg.metadata = gemspec.to_yaml
-
- path = "lib/coffee_script/source.rb"
- contents = <<-ERUBY
-module CoffeeScript
- module Source
- def self.bundled_path
- File.expand_path("../coffee-script.js", __FILE__)
- end
- end
-end
- ERUBY
- pkg.add_file_simple(path, 0644, contents.size) do |tar_io|
- tar_io.write(contents)
- end
-
- contents = File.read("extras/coffee-script.js")
- path = "lib/coffee_script/coffee-script.js"
- pkg.add_file_simple(path, 0644, contents.size) do |tar_io|
- tar_io.write(contents)
- end
- end
-end
diff --git a/spec/fixture/node_modules/grunt/node_modules/coffee-script/bin/cake b/spec/fixture/node_modules/grunt/node_modules/coffee-script/bin/cake
deleted file mode 100755
index 5965f4ee..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/coffee-script/bin/cake
+++ /dev/null
@@ -1,7 +0,0 @@
-#!/usr/bin/env node
-
-var path = require('path');
-var fs = require('fs');
-var lib = path.join(path.dirname(fs.realpathSync(__filename)), '../lib');
-
-require(lib + '/coffee-script/cake').run();
diff --git a/spec/fixture/node_modules/grunt/node_modules/coffee-script/bin/coffee b/spec/fixture/node_modules/grunt/node_modules/coffee-script/bin/coffee
deleted file mode 100755
index 3d1d71c8..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/coffee-script/bin/coffee
+++ /dev/null
@@ -1,7 +0,0 @@
-#!/usr/bin/env node
-
-var path = require('path');
-var fs = require('fs');
-var lib = path.join(path.dirname(fs.realpathSync(__filename)), '../lib');
-
-require(lib + '/coffee-script/command').run();
diff --git a/spec/fixture/node_modules/grunt/node_modules/coffee-script/extras/jsl.conf b/spec/fixture/node_modules/grunt/node_modules/coffee-script/extras/jsl.conf
deleted file mode 100644
index 1190da52..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/coffee-script/extras/jsl.conf
+++ /dev/null
@@ -1,44 +0,0 @@
-# JavaScriptLint configuration file for CoffeeScript.
-
-+no_return_value # function {0} does not always return a value
-+duplicate_formal # duplicate formal argument {0}
--equal_as_assign # test for equality (==) mistyped as assignment (=)?{0}
-+var_hides_arg # variable {0} hides argument
-+redeclared_var # redeclaration of {0} {1}
--anon_no_return_value # anonymous function does not always return a value
-+missing_semicolon # missing semicolon
-+meaningless_block # meaningless block; curly braces have no impact
--comma_separated_stmts # multiple statements separated by commas (use semicolons?)
-+unreachable_code # unreachable code
-+missing_break # missing break statement
--missing_break_for_last_case # missing break statement for last case in switch
--comparison_type_conv # comparisons against null, 0, true, false, or an empty string allowing implicit type conversion (use === or !==)
--inc_dec_within_stmt # increment (++) and decrement (--) operators used as part of greater statement
--useless_void # use of the void type may be unnecessary (void is always undefined)
-+multiple_plus_minus # unknown order of operations for successive plus (e.g. x+++y) or minus (e.g. x---y) signs
-+use_of_label # use of label
--block_without_braces # block statement without curly braces
-+leading_decimal_point # leading decimal point may indicate a number or an object member
-+trailing_decimal_point # trailing decimal point may indicate a number or an object member
-+octal_number # leading zeros make an octal number
-+nested_comment # nested comment
-+misplaced_regex # regular expressions should be preceded by a left parenthesis, assignment, colon, or comma
-+ambiguous_newline # unexpected end of line; it is ambiguous whether these lines are part of the same statement
-+empty_statement # empty statement or extra semicolon
--missing_option_explicit # the "option explicit" control comment is missing
-+partial_option_explicit # the "option explicit" control comment, if used, must be in the first script tag
-+dup_option_explicit # duplicate "option explicit" control comment
-+useless_assign # useless assignment
-+ambiguous_nested_stmt # block statements containing block statements should use curly braces to resolve ambiguity
-+ambiguous_else_stmt # the else statement could be matched with one of multiple if statements (use curly braces to indicate intent)
--missing_default_case # missing default case in switch statement
-+duplicate_case_in_switch # duplicate case in switch statements
-+default_not_at_end # the default case is not at the end of the switch statement
-+legacy_cc_not_understood # couldn't understand control comment using /*@keyword@*/ syntax
-+jsl_cc_not_understood # couldn't understand control comment using /*jsl:keyword*/ syntax
-+useless_comparison # useless comparison; comparing identical expressions
-+with_statement # with statement hides undeclared variables; use temporary variable instead
-+trailing_comma_in_array # extra comma is not recommended in array initializers
-+assign_to_function_call # assignment to a function call
-+parseint_missing_radix # parseInt missing radix parameter
-+lambda_assign_requires_semicolon
diff --git a/spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/browser.js b/spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/browser.js
deleted file mode 100644
index 825cbf31..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/browser.js
+++ /dev/null
@@ -1,92 +0,0 @@
-// Generated by CoffeeScript 1.3.3
-(function() {
- var CoffeeScript, runScripts;
-
- CoffeeScript = require('./coffee-script');
-
- CoffeeScript.require = require;
-
- CoffeeScript["eval"] = function(code, options) {
- var _ref;
- if (options == null) {
- options = {};
- }
- if ((_ref = options.bare) == null) {
- options.bare = true;
- }
- return eval(CoffeeScript.compile(code, options));
- };
-
- CoffeeScript.run = function(code, options) {
- if (options == null) {
- options = {};
- }
- options.bare = true;
- return Function(CoffeeScript.compile(code, options))();
- };
-
- if (typeof window === "undefined" || window === null) {
- return;
- }
-
- CoffeeScript.load = function(url, callback) {
- var xhr;
- xhr = new (window.ActiveXObject || XMLHttpRequest)('Microsoft.XMLHTTP');
- xhr.open('GET', url, true);
- if ('overrideMimeType' in xhr) {
- xhr.overrideMimeType('text/plain');
- }
- xhr.onreadystatechange = function() {
- var _ref;
- if (xhr.readyState === 4) {
- if ((_ref = xhr.status) === 0 || _ref === 200) {
- CoffeeScript.run(xhr.responseText);
- } else {
- throw new Error("Could not load " + url);
- }
- if (callback) {
- return callback();
- }
- }
- };
- return xhr.send(null);
- };
-
- runScripts = function() {
- var coffees, execute, index, length, s, scripts;
- scripts = document.getElementsByTagName('script');
- coffees = (function() {
- var _i, _len, _results;
- _results = [];
- for (_i = 0, _len = scripts.length; _i < _len; _i++) {
- s = scripts[_i];
- if (s.type === 'text/coffeescript') {
- _results.push(s);
- }
- }
- return _results;
- })();
- index = 0;
- length = coffees.length;
- (execute = function() {
- var script;
- script = coffees[index++];
- if ((script != null ? script.type : void 0) === 'text/coffeescript') {
- if (script.src) {
- return CoffeeScript.load(script.src, execute);
- } else {
- CoffeeScript.run(script.innerHTML);
- return execute();
- }
- }
- })();
- return null;
- };
-
- if (window.addEventListener) {
- addEventListener('DOMContentLoaded', runScripts, false);
- } else {
- attachEvent('onload', runScripts);
- }
-
-}).call(this);
diff --git a/spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/cake.js b/spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/cake.js
deleted file mode 100644
index 1523418f..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/cake.js
+++ /dev/null
@@ -1,111 +0,0 @@
-// Generated by CoffeeScript 1.3.3
-(function() {
- var CoffeeScript, cakefileDirectory, fatalError, fs, helpers, missingTask, oparse, options, optparse, path, printTasks, switches, tasks;
-
- fs = require('fs');
-
- path = require('path');
-
- helpers = require('./helpers');
-
- optparse = require('./optparse');
-
- CoffeeScript = require('./coffee-script');
-
- tasks = {};
-
- options = {};
-
- switches = [];
-
- oparse = null;
-
- helpers.extend(global, {
- task: function(name, description, action) {
- var _ref;
- if (!action) {
- _ref = [description, action], action = _ref[0], description = _ref[1];
- }
- return tasks[name] = {
- name: name,
- description: description,
- action: action
- };
- },
- option: function(letter, flag, description) {
- return switches.push([letter, flag, description]);
- },
- invoke: function(name) {
- if (!tasks[name]) {
- missingTask(name);
- }
- return tasks[name].action(options);
- }
- });
-
- exports.run = function() {
- var arg, args, _i, _len, _ref, _results;
- global.__originalDirname = fs.realpathSync('.');
- process.chdir(cakefileDirectory(__originalDirname));
- args = process.argv.slice(2);
- CoffeeScript.run(fs.readFileSync('Cakefile').toString(), {
- filename: 'Cakefile'
- });
- oparse = new optparse.OptionParser(switches);
- if (!args.length) {
- return printTasks();
- }
- try {
- options = oparse.parse(args);
- } catch (e) {
- return fatalError("" + e);
- }
- _ref = options["arguments"];
- _results = [];
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
- arg = _ref[_i];
- _results.push(invoke(arg));
- }
- return _results;
- };
-
- printTasks = function() {
- var cakefilePath, desc, name, relative, spaces, task;
- relative = path.relative || path.resolve;
- cakefilePath = path.join(relative(__originalDirname, process.cwd()), 'Cakefile');
- console.log("" + cakefilePath + " defines the following tasks:\n");
- for (name in tasks) {
- task = tasks[name];
- spaces = 20 - name.length;
- spaces = spaces > 0 ? Array(spaces + 1).join(' ') : '';
- desc = task.description ? "# " + task.description : '';
- console.log("cake " + name + spaces + " " + desc);
- }
- if (switches.length) {
- return console.log(oparse.help());
- }
- };
-
- fatalError = function(message) {
- console.error(message + '\n');
- console.log('To see a list of all tasks/options, run "cake"');
- return process.exit(1);
- };
-
- missingTask = function(task) {
- return fatalError("No such task: " + task);
- };
-
- cakefileDirectory = function(dir) {
- var parent;
- if (path.existsSync(path.join(dir, 'Cakefile'))) {
- return dir;
- }
- parent = path.normalize(path.join(dir, '..'));
- if (parent !== dir) {
- return cakefileDirectory(parent);
- }
- throw new Error("Cakefile not found in " + (process.cwd()));
- };
-
-}).call(this);
diff --git a/spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/coffee-script.js b/spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/coffee-script.js
deleted file mode 100644
index c43fa497..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/coffee-script.js
+++ /dev/null
@@ -1,167 +0,0 @@
-// Generated by CoffeeScript 1.3.3
-(function() {
- var Lexer, RESERVED, compile, fs, lexer, parser, path, vm, _ref,
- __hasProp = {}.hasOwnProperty;
-
- fs = require('fs');
-
- path = require('path');
-
- _ref = require('./lexer'), Lexer = _ref.Lexer, RESERVED = _ref.RESERVED;
-
- parser = require('./parser').parser;
-
- vm = require('vm');
-
- if (require.extensions) {
- require.extensions['.coffee'] = function(module, filename) {
- var content;
- content = compile(fs.readFileSync(filename, 'utf8'), {
- filename: filename
- });
- return module._compile(content, filename);
- };
- } else if (require.registerExtension) {
- require.registerExtension('.coffee', function(content) {
- return compile(content);
- });
- }
-
- exports.VERSION = '1.3.3';
-
- exports.RESERVED = RESERVED;
-
- exports.helpers = require('./helpers');
-
- exports.compile = compile = function(code, options) {
- var header, js, merge;
- if (options == null) {
- options = {};
- }
- merge = exports.helpers.merge;
- try {
- js = (parser.parse(lexer.tokenize(code))).compile(options);
- if (!options.header) {
- return js;
- }
- } catch (err) {
- if (options.filename) {
- err.message = "In " + options.filename + ", " + err.message;
- }
- throw err;
- }
- header = "Generated by CoffeeScript " + this.VERSION;
- return "// " + header + "\n" + js;
- };
-
- exports.tokens = function(code, options) {
- return lexer.tokenize(code, options);
- };
-
- exports.nodes = function(source, options) {
- if (typeof source === 'string') {
- return parser.parse(lexer.tokenize(source, options));
- } else {
- return parser.parse(source);
- }
- };
-
- exports.run = function(code, options) {
- var mainModule;
- if (options == null) {
- options = {};
- }
- mainModule = require.main;
- mainModule.filename = process.argv[1] = options.filename ? fs.realpathSync(options.filename) : '.';
- mainModule.moduleCache && (mainModule.moduleCache = {});
- mainModule.paths = require('module')._nodeModulePaths(path.dirname(fs.realpathSync(options.filename)));
- if (path.extname(mainModule.filename) !== '.coffee' || require.extensions) {
- return mainModule._compile(compile(code, options), mainModule.filename);
- } else {
- return mainModule._compile(code, mainModule.filename);
- }
- };
-
- exports["eval"] = function(code, options) {
- var Module, Script, js, k, o, r, sandbox, v, _i, _len, _module, _ref1, _ref2, _require;
- if (options == null) {
- options = {};
- }
- if (!(code = code.trim())) {
- return;
- }
- Script = vm.Script;
- if (Script) {
- if (options.sandbox != null) {
- if (options.sandbox instanceof Script.createContext().constructor) {
- sandbox = options.sandbox;
- } else {
- sandbox = Script.createContext();
- _ref1 = options.sandbox;
- for (k in _ref1) {
- if (!__hasProp.call(_ref1, k)) continue;
- v = _ref1[k];
- sandbox[k] = v;
- }
- }
- sandbox.global = sandbox.root = sandbox.GLOBAL = sandbox;
- } else {
- sandbox = global;
- }
- sandbox.__filename = options.filename || 'eval';
- sandbox.__dirname = path.dirname(sandbox.__filename);
- if (!(sandbox !== global || sandbox.module || sandbox.require)) {
- Module = require('module');
- sandbox.module = _module = new Module(options.modulename || 'eval');
- sandbox.require = _require = function(path) {
- return Module._load(path, _module, true);
- };
- _module.filename = sandbox.__filename;
- _ref2 = Object.getOwnPropertyNames(require);
- for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
- r = _ref2[_i];
- if (r !== 'paths') {
- _require[r] = require[r];
- }
- }
- _require.paths = _module.paths = Module._nodeModulePaths(process.cwd());
- _require.resolve = function(request) {
- return Module._resolveFilename(request, _module);
- };
- }
- }
- o = {};
- for (k in options) {
- if (!__hasProp.call(options, k)) continue;
- v = options[k];
- o[k] = v;
- }
- o.bare = true;
- js = compile(code, o);
- if (sandbox === global) {
- return vm.runInThisContext(js);
- } else {
- return vm.runInContext(js, sandbox);
- }
- };
-
- lexer = new Lexer;
-
- parser.lexer = {
- lex: function() {
- var tag, _ref1;
- _ref1 = this.tokens[this.pos++] || [''], tag = _ref1[0], this.yytext = _ref1[1], this.yylineno = _ref1[2];
- return tag;
- },
- setInput: function(tokens) {
- this.tokens = tokens;
- return this.pos = 0;
- },
- upcomingInput: function() {
- return "";
- }
- };
-
- parser.yy = require('./nodes');
-
-}).call(this);
diff --git a/spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/command.js b/spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/command.js
deleted file mode 100644
index e02da9fe..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/command.js
+++ /dev/null
@@ -1,500 +0,0 @@
-// Generated by CoffeeScript 1.3.3
-(function() {
- var BANNER, CoffeeScript, EventEmitter, SWITCHES, compileJoin, compileOptions, compilePath, compileScript, compileStdio, exec, forkNode, fs, helpers, hidden, joinTimeout, lint, loadRequires, notSources, optionParser, optparse, opts, outputPath, parseOptions, path, printLine, printTokens, printWarn, removeSource, sourceCode, sources, spawn, timeLog, unwatchDir, usage, version, wait, watch, watchDir, watchers, writeJs, _ref;
-
- fs = require('fs');
-
- path = require('path');
-
- helpers = require('./helpers');
-
- optparse = require('./optparse');
-
- CoffeeScript = require('./coffee-script');
-
- _ref = require('child_process'), spawn = _ref.spawn, exec = _ref.exec;
-
- EventEmitter = require('events').EventEmitter;
-
- helpers.extend(CoffeeScript, new EventEmitter);
-
- printLine = function(line) {
- return process.stdout.write(line + '\n');
- };
-
- printWarn = function(line) {
- return process.stderr.write(line + '\n');
- };
-
- hidden = function(file) {
- return /^\.|~$/.test(file);
- };
-
- BANNER = 'Usage: coffee [options] path/to/script.coffee -- [args]\n\nIf called without options, `coffee` will run your script.';
-
- SWITCHES = [['-b', '--bare', 'compile without a top-level function wrapper'], ['-c', '--compile', 'compile to JavaScript and save as .js files'], ['-e', '--eval', 'pass a string from the command line as input'], ['-h', '--help', 'display this help message'], ['-i', '--interactive', 'run an interactive CoffeeScript REPL'], ['-j', '--join [FILE]', 'concatenate the source CoffeeScript before compiling'], ['-l', '--lint', 'pipe the compiled JavaScript through JavaScript Lint'], ['-n', '--nodes', 'print out the parse tree that the parser produces'], ['--nodejs [ARGS]', 'pass options directly to the "node" binary'], ['-o', '--output [DIR]', 'set the output directory for compiled JavaScript'], ['-p', '--print', 'print out the compiled JavaScript'], ['-r', '--require [FILE*]', 'require a library before executing your script'], ['-s', '--stdio', 'listen for and compile scripts over stdio'], ['-t', '--tokens', 'print out the tokens that the lexer/rewriter produce'], ['-v', '--version', 'display the version number'], ['-w', '--watch', 'watch scripts for changes and rerun commands']];
-
- opts = {};
-
- sources = [];
-
- sourceCode = [];
-
- notSources = {};
-
- watchers = {};
-
- optionParser = null;
-
- exports.run = function() {
- var literals, source, _i, _len, _results;
- parseOptions();
- if (opts.nodejs) {
- return forkNode();
- }
- if (opts.help) {
- return usage();
- }
- if (opts.version) {
- return version();
- }
- if (opts.require) {
- loadRequires();
- }
- if (opts.interactive) {
- return require('./repl');
- }
- if (opts.watch && !fs.watch) {
- return printWarn("The --watch feature depends on Node v0.6.0+. You are running " + process.version + ".");
- }
- if (opts.stdio) {
- return compileStdio();
- }
- if (opts["eval"]) {
- return compileScript(null, sources[0]);
- }
- if (!sources.length) {
- return require('./repl');
- }
- literals = opts.run ? sources.splice(1) : [];
- process.argv = process.argv.slice(0, 2).concat(literals);
- process.argv[0] = 'coffee';
- process.execPath = require.main.filename;
- _results = [];
- for (_i = 0, _len = sources.length; _i < _len; _i++) {
- source = sources[_i];
- _results.push(compilePath(source, true, path.normalize(source)));
- }
- return _results;
- };
-
- compilePath = function(source, topLevel, base) {
- return fs.stat(source, function(err, stats) {
- if (err && err.code !== 'ENOENT') {
- throw err;
- }
- if ((err != null ? err.code : void 0) === 'ENOENT') {
- if (topLevel && source.slice(-7) !== '.coffee') {
- source = sources[sources.indexOf(source)] = "" + source + ".coffee";
- return compilePath(source, topLevel, base);
- }
- if (topLevel) {
- console.error("File not found: " + source);
- process.exit(1);
- }
- return;
- }
- if (stats.isDirectory()) {
- if (opts.watch) {
- watchDir(source, base);
- }
- return fs.readdir(source, function(err, files) {
- var file, index, _ref1, _ref2;
- if (err && err.code !== 'ENOENT') {
- throw err;
- }
- if ((err != null ? err.code : void 0) === 'ENOENT') {
- return;
- }
- index = sources.indexOf(source);
- files = files.filter(function(file) {
- return !hidden(file);
- });
- [].splice.apply(sources, [index, index - index + 1].concat(_ref1 = (function() {
- var _i, _len, _results;
- _results = [];
- for (_i = 0, _len = files.length; _i < _len; _i++) {
- file = files[_i];
- _results.push(path.join(source, file));
- }
- return _results;
- })())), _ref1;
- [].splice.apply(sourceCode, [index, index - index + 1].concat(_ref2 = files.map(function() {
- return null;
- }))), _ref2;
- return files.forEach(function(file) {
- return compilePath(path.join(source, file), false, base);
- });
- });
- } else if (topLevel || path.extname(source) === '.coffee') {
- if (opts.watch) {
- watch(source, base);
- }
- return fs.readFile(source, function(err, code) {
- if (err && err.code !== 'ENOENT') {
- throw err;
- }
- if ((err != null ? err.code : void 0) === 'ENOENT') {
- return;
- }
- return compileScript(source, code.toString(), base);
- });
- } else {
- notSources[source] = true;
- return removeSource(source, base);
- }
- });
- };
-
- compileScript = function(file, input, base) {
- var o, options, t, task;
- o = opts;
- options = compileOptions(file);
- try {
- t = task = {
- file: file,
- input: input,
- options: options
- };
- CoffeeScript.emit('compile', task);
- if (o.tokens) {
- return printTokens(CoffeeScript.tokens(t.input));
- } else if (o.nodes) {
- return printLine(CoffeeScript.nodes(t.input).toString().trim());
- } else if (o.run) {
- return CoffeeScript.run(t.input, t.options);
- } else if (o.join && t.file !== o.join) {
- sourceCode[sources.indexOf(t.file)] = t.input;
- return compileJoin();
- } else {
- t.output = CoffeeScript.compile(t.input, t.options);
- CoffeeScript.emit('success', task);
- if (o.print) {
- return printLine(t.output.trim());
- } else if (o.compile) {
- return writeJs(t.file, t.output, base);
- } else if (o.lint) {
- return lint(t.file, t.output);
- }
- }
- } catch (err) {
- CoffeeScript.emit('failure', err, task);
- if (CoffeeScript.listeners('failure').length) {
- return;
- }
- if (o.watch) {
- return printLine(err.message + '\x07');
- }
- printWarn(err instanceof Error && err.stack || ("ERROR: " + err));
- return process.exit(1);
- }
- };
-
- compileStdio = function() {
- var code, stdin;
- code = '';
- stdin = process.openStdin();
- stdin.on('data', function(buffer) {
- if (buffer) {
- return code += buffer.toString();
- }
- });
- return stdin.on('end', function() {
- return compileScript(null, code);
- });
- };
-
- joinTimeout = null;
-
- compileJoin = function() {
- if (!opts.join) {
- return;
- }
- if (!sourceCode.some(function(code) {
- return code === null;
- })) {
- clearTimeout(joinTimeout);
- return joinTimeout = wait(100, function() {
- return compileScript(opts.join, sourceCode.join('\n'), opts.join);
- });
- }
- };
-
- loadRequires = function() {
- var realFilename, req, _i, _len, _ref1;
- realFilename = module.filename;
- module.filename = '.';
- _ref1 = opts.require;
- for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
- req = _ref1[_i];
- require(req);
- }
- return module.filename = realFilename;
- };
-
- watch = function(source, base) {
- var compile, compileTimeout, prevStats, rewatch, watchErr, watcher;
- prevStats = null;
- compileTimeout = null;
- watchErr = function(e) {
- if (e.code === 'ENOENT') {
- if (sources.indexOf(source) === -1) {
- return;
- }
- try {
- rewatch();
- return compile();
- } catch (e) {
- removeSource(source, base, true);
- return compileJoin();
- }
- } else {
- throw e;
- }
- };
- compile = function() {
- clearTimeout(compileTimeout);
- return compileTimeout = wait(25, function() {
- return fs.stat(source, function(err, stats) {
- if (err) {
- return watchErr(err);
- }
- if (prevStats && stats.size === prevStats.size && stats.mtime.getTime() === prevStats.mtime.getTime()) {
- return rewatch();
- }
- prevStats = stats;
- return fs.readFile(source, function(err, code) {
- if (err) {
- return watchErr(err);
- }
- compileScript(source, code.toString(), base);
- return rewatch();
- });
- });
- });
- };
- try {
- watcher = fs.watch(source, compile);
- } catch (e) {
- watchErr(e);
- }
- return rewatch = function() {
- if (watcher != null) {
- watcher.close();
- }
- return watcher = fs.watch(source, compile);
- };
- };
-
- watchDir = function(source, base) {
- var readdirTimeout, watcher;
- readdirTimeout = null;
- try {
- return watcher = fs.watch(source, function() {
- clearTimeout(readdirTimeout);
- return readdirTimeout = wait(25, function() {
- return fs.readdir(source, function(err, files) {
- var file, _i, _len, _results;
- if (err) {
- if (err.code !== 'ENOENT') {
- throw err;
- }
- watcher.close();
- return unwatchDir(source, base);
- }
- _results = [];
- for (_i = 0, _len = files.length; _i < _len; _i++) {
- file = files[_i];
- if (!(!hidden(file) && !notSources[file])) {
- continue;
- }
- file = path.join(source, file);
- if (sources.some(function(s) {
- return s.indexOf(file) >= 0;
- })) {
- continue;
- }
- sources.push(file);
- sourceCode.push(null);
- _results.push(compilePath(file, false, base));
- }
- return _results;
- });
- });
- });
- } catch (e) {
- if (e.code !== 'ENOENT') {
- throw e;
- }
- }
- };
-
- unwatchDir = function(source, base) {
- var file, prevSources, toRemove, _i, _len;
- prevSources = sources.slice(0);
- toRemove = (function() {
- var _i, _len, _results;
- _results = [];
- for (_i = 0, _len = sources.length; _i < _len; _i++) {
- file = sources[_i];
- if (file.indexOf(source) >= 0) {
- _results.push(file);
- }
- }
- return _results;
- })();
- for (_i = 0, _len = toRemove.length; _i < _len; _i++) {
- file = toRemove[_i];
- removeSource(file, base, true);
- }
- if (!sources.some(function(s, i) {
- return prevSources[i] !== s;
- })) {
- return;
- }
- return compileJoin();
- };
-
- removeSource = function(source, base, removeJs) {
- var index, jsPath;
- index = sources.indexOf(source);
- sources.splice(index, 1);
- sourceCode.splice(index, 1);
- if (removeJs && !opts.join) {
- jsPath = outputPath(source, base);
- return path.exists(jsPath, function(exists) {
- if (exists) {
- return fs.unlink(jsPath, function(err) {
- if (err && err.code !== 'ENOENT') {
- throw err;
- }
- return timeLog("removed " + source);
- });
- }
- });
- }
- };
-
- outputPath = function(source, base) {
- var baseDir, dir, filename, srcDir;
- filename = path.basename(source, path.extname(source)) + '.js';
- srcDir = path.dirname(source);
- baseDir = base === '.' ? srcDir : srcDir.substring(base.length);
- dir = opts.output ? path.join(opts.output, baseDir) : srcDir;
- return path.join(dir, filename);
- };
-
- writeJs = function(source, js, base) {
- var compile, jsDir, jsPath;
- jsPath = outputPath(source, base);
- jsDir = path.dirname(jsPath);
- compile = function() {
- if (js.length <= 0) {
- js = ' ';
- }
- return fs.writeFile(jsPath, js, function(err) {
- if (err) {
- return printLine(err.message);
- } else if (opts.compile && opts.watch) {
- return timeLog("compiled " + source);
- }
- });
- };
- return path.exists(jsDir, function(exists) {
- if (exists) {
- return compile();
- } else {
- return exec("mkdir -p " + jsDir, compile);
- }
- });
- };
-
- wait = function(milliseconds, func) {
- return setTimeout(func, milliseconds);
- };
-
- timeLog = function(message) {
- return console.log("" + ((new Date).toLocaleTimeString()) + " - " + message);
- };
-
- lint = function(file, js) {
- var conf, jsl, printIt;
- printIt = function(buffer) {
- return printLine(file + ':\t' + buffer.toString().trim());
- };
- conf = __dirname + '/../../extras/jsl.conf';
- jsl = spawn('jsl', ['-nologo', '-stdin', '-conf', conf]);
- jsl.stdout.on('data', printIt);
- jsl.stderr.on('data', printIt);
- jsl.stdin.write(js);
- return jsl.stdin.end();
- };
-
- printTokens = function(tokens) {
- var strings, tag, token, value;
- strings = (function() {
- var _i, _len, _ref1, _results;
- _results = [];
- for (_i = 0, _len = tokens.length; _i < _len; _i++) {
- token = tokens[_i];
- _ref1 = [token[0], token[1].toString().replace(/\n/, '\\n')], tag = _ref1[0], value = _ref1[1];
- _results.push("[" + tag + " " + value + "]");
- }
- return _results;
- })();
- return printLine(strings.join(' '));
- };
-
- parseOptions = function() {
- var i, o, source, _i, _len;
- optionParser = new optparse.OptionParser(SWITCHES, BANNER);
- o = opts = optionParser.parse(process.argv.slice(2));
- o.compile || (o.compile = !!o.output);
- o.run = !(o.compile || o.print || o.lint);
- o.print = !!(o.print || (o["eval"] || o.stdio && o.compile));
- sources = o["arguments"];
- for (i = _i = 0, _len = sources.length; _i < _len; i = ++_i) {
- source = sources[i];
- sourceCode[i] = null;
- }
- };
-
- compileOptions = function(filename) {
- return {
- filename: filename,
- bare: opts.bare,
- header: opts.compile
- };
- };
-
- forkNode = function() {
- var args, nodeArgs;
- nodeArgs = opts.nodejs.split(/\s+/);
- args = process.argv.slice(1);
- args.splice(args.indexOf('--nodejs'), 2);
- return spawn(process.execPath, nodeArgs.concat(args), {
- cwd: process.cwd(),
- env: process.env,
- customFds: [0, 1, 2]
- });
- };
-
- usage = function() {
- return printLine((new optparse.OptionParser(SWITCHES, BANNER)).help());
- };
-
- version = function() {
- return printLine("CoffeeScript version " + CoffeeScript.VERSION);
- };
-
-}).call(this);
diff --git a/spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/grammar.js b/spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/grammar.js
deleted file mode 100644
index 56621388..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/grammar.js
+++ /dev/null
@@ -1,606 +0,0 @@
-// Generated by CoffeeScript 1.3.3
-(function() {
- var Parser, alt, alternatives, grammar, name, o, operators, token, tokens, unwrap;
-
- Parser = require('jison').Parser;
-
- unwrap = /^function\s*\(\)\s*\{\s*return\s*([\s\S]*);\s*\}/;
-
- o = function(patternString, action, options) {
- var match;
- patternString = patternString.replace(/\s{2,}/g, ' ');
- if (!action) {
- return [patternString, '$$ = $1;', options];
- }
- action = (match = unwrap.exec(action)) ? match[1] : "(" + action + "())";
- action = action.replace(/\bnew /g, '$&yy.');
- action = action.replace(/\b(?:Block\.wrap|extend)\b/g, 'yy.$&');
- return [patternString, "$$ = " + action + ";", options];
- };
-
- grammar = {
- Root: [
- o('', function() {
- return new Block;
- }), o('Body'), o('Block TERMINATOR')
- ],
- Body: [
- o('Line', function() {
- return Block.wrap([$1]);
- }), o('Body TERMINATOR Line', function() {
- return $1.push($3);
- }), o('Body TERMINATOR')
- ],
- Line: [o('Expression'), o('Statement')],
- Statement: [
- o('Return'), o('Comment'), o('STATEMENT', function() {
- return new Literal($1);
- })
- ],
- Expression: [o('Value'), o('Invocation'), o('Code'), o('Operation'), o('Assign'), o('If'), o('Try'), o('While'), o('For'), o('Switch'), o('Class'), o('Throw')],
- Block: [
- o('INDENT OUTDENT', function() {
- return new Block;
- }), o('INDENT Body OUTDENT', function() {
- return $2;
- })
- ],
- Identifier: [
- o('IDENTIFIER', function() {
- return new Literal($1);
- })
- ],
- AlphaNumeric: [
- o('NUMBER', function() {
- return new Literal($1);
- }), o('STRING', function() {
- return new Literal($1);
- })
- ],
- Literal: [
- o('AlphaNumeric'), o('JS', function() {
- return new Literal($1);
- }), o('REGEX', function() {
- return new Literal($1);
- }), o('DEBUGGER', function() {
- return new Literal($1);
- }), o('UNDEFINED', function() {
- return new Undefined;
- }), o('NULL', function() {
- return new Null;
- }), o('BOOL', function() {
- return new Bool($1);
- })
- ],
- Assign: [
- o('Assignable = Expression', function() {
- return new Assign($1, $3);
- }), o('Assignable = TERMINATOR Expression', function() {
- return new Assign($1, $4);
- }), o('Assignable = INDENT Expression OUTDENT', function() {
- return new Assign($1, $4);
- })
- ],
- AssignObj: [
- o('ObjAssignable', function() {
- return new Value($1);
- }), o('ObjAssignable : Expression', function() {
- return new Assign(new Value($1), $3, 'object');
- }), o('ObjAssignable :\
- INDENT Expression OUTDENT', function() {
- return new Assign(new Value($1), $4, 'object');
- }), o('Comment')
- ],
- ObjAssignable: [o('Identifier'), o('AlphaNumeric'), o('ThisProperty')],
- Return: [
- o('RETURN Expression', function() {
- return new Return($2);
- }), o('RETURN', function() {
- return new Return;
- })
- ],
- Comment: [
- o('HERECOMMENT', function() {
- return new Comment($1);
- })
- ],
- Code: [
- o('PARAM_START ParamList PARAM_END FuncGlyph Block', function() {
- return new Code($2, $5, $4);
- }), o('FuncGlyph Block', function() {
- return new Code([], $2, $1);
- })
- ],
- FuncGlyph: [
- o('->', function() {
- return 'func';
- }), o('=>', function() {
- return 'boundfunc';
- })
- ],
- OptComma: [o(''), o(',')],
- ParamList: [
- o('', function() {
- return [];
- }), o('Param', function() {
- return [$1];
- }), o('ParamList , Param', function() {
- return $1.concat($3);
- }), o('ParamList OptComma TERMINATOR Param', function() {
- return $1.concat($4);
- }), o('ParamList OptComma INDENT ParamList OptComma OUTDENT', function() {
- return $1.concat($4);
- })
- ],
- Param: [
- o('ParamVar', function() {
- return new Param($1);
- }), o('ParamVar ...', function() {
- return new Param($1, null, true);
- }), o('ParamVar = Expression', function() {
- return new Param($1, $3);
- })
- ],
- ParamVar: [o('Identifier'), o('ThisProperty'), o('Array'), o('Object')],
- Splat: [
- o('Expression ...', function() {
- return new Splat($1);
- })
- ],
- SimpleAssignable: [
- o('Identifier', function() {
- return new Value($1);
- }), o('Value Accessor', function() {
- return $1.add($2);
- }), o('Invocation Accessor', function() {
- return new Value($1, [].concat($2));
- }), o('ThisProperty')
- ],
- Assignable: [
- o('SimpleAssignable'), o('Array', function() {
- return new Value($1);
- }), o('Object', function() {
- return new Value($1);
- })
- ],
- Value: [
- o('Assignable'), o('Literal', function() {
- return new Value($1);
- }), o('Parenthetical', function() {
- return new Value($1);
- }), o('Range', function() {
- return new Value($1);
- }), o('This')
- ],
- Accessor: [
- o('. Identifier', function() {
- return new Access($2);
- }), o('?. Identifier', function() {
- return new Access($2, 'soak');
- }), o(':: Identifier', function() {
- return [new Access(new Literal('prototype')), new Access($2)];
- }), o('::', function() {
- return new Access(new Literal('prototype'));
- }), o('Index')
- ],
- Index: [
- o('INDEX_START IndexValue INDEX_END', function() {
- return $2;
- }), o('INDEX_SOAK Index', function() {
- return extend($2, {
- soak: true
- });
- })
- ],
- IndexValue: [
- o('Expression', function() {
- return new Index($1);
- }), o('Slice', function() {
- return new Slice($1);
- })
- ],
- Object: [
- o('{ AssignList OptComma }', function() {
- return new Obj($2, $1.generated);
- })
- ],
- AssignList: [
- o('', function() {
- return [];
- }), o('AssignObj', function() {
- return [$1];
- }), o('AssignList , AssignObj', function() {
- return $1.concat($3);
- }), o('AssignList OptComma TERMINATOR AssignObj', function() {
- return $1.concat($4);
- }), o('AssignList OptComma INDENT AssignList OptComma OUTDENT', function() {
- return $1.concat($4);
- })
- ],
- Class: [
- o('CLASS', function() {
- return new Class;
- }), o('CLASS Block', function() {
- return new Class(null, null, $2);
- }), o('CLASS EXTENDS Expression', function() {
- return new Class(null, $3);
- }), o('CLASS EXTENDS Expression Block', function() {
- return new Class(null, $3, $4);
- }), o('CLASS SimpleAssignable', function() {
- return new Class($2);
- }), o('CLASS SimpleAssignable Block', function() {
- return new Class($2, null, $3);
- }), o('CLASS SimpleAssignable EXTENDS Expression', function() {
- return new Class($2, $4);
- }), o('CLASS SimpleAssignable EXTENDS Expression Block', function() {
- return new Class($2, $4, $5);
- })
- ],
- Invocation: [
- o('Value OptFuncExist Arguments', function() {
- return new Call($1, $3, $2);
- }), o('Invocation OptFuncExist Arguments', function() {
- return new Call($1, $3, $2);
- }), o('SUPER', function() {
- return new Call('super', [new Splat(new Literal('arguments'))]);
- }), o('SUPER Arguments', function() {
- return new Call('super', $2);
- })
- ],
- OptFuncExist: [
- o('', function() {
- return false;
- }), o('FUNC_EXIST', function() {
- return true;
- })
- ],
- Arguments: [
- o('CALL_START CALL_END', function() {
- return [];
- }), o('CALL_START ArgList OptComma CALL_END', function() {
- return $2;
- })
- ],
- This: [
- o('THIS', function() {
- return new Value(new Literal('this'));
- }), o('@', function() {
- return new Value(new Literal('this'));
- })
- ],
- ThisProperty: [
- o('@ Identifier', function() {
- return new Value(new Literal('this'), [new Access($2)], 'this');
- })
- ],
- Array: [
- o('[ ]', function() {
- return new Arr([]);
- }), o('[ ArgList OptComma ]', function() {
- return new Arr($2);
- })
- ],
- RangeDots: [
- o('..', function() {
- return 'inclusive';
- }), o('...', function() {
- return 'exclusive';
- })
- ],
- Range: [
- o('[ Expression RangeDots Expression ]', function() {
- return new Range($2, $4, $3);
- })
- ],
- Slice: [
- o('Expression RangeDots Expression', function() {
- return new Range($1, $3, $2);
- }), o('Expression RangeDots', function() {
- return new Range($1, null, $2);
- }), o('RangeDots Expression', function() {
- return new Range(null, $2, $1);
- }), o('RangeDots', function() {
- return new Range(null, null, $1);
- })
- ],
- ArgList: [
- o('Arg', function() {
- return [$1];
- }), o('ArgList , Arg', function() {
- return $1.concat($3);
- }), o('ArgList OptComma TERMINATOR Arg', function() {
- return $1.concat($4);
- }), o('INDENT ArgList OptComma OUTDENT', function() {
- return $2;
- }), o('ArgList OptComma INDENT ArgList OptComma OUTDENT', function() {
- return $1.concat($4);
- })
- ],
- Arg: [o('Expression'), o('Splat')],
- SimpleArgs: [
- o('Expression'), o('SimpleArgs , Expression', function() {
- return [].concat($1, $3);
- })
- ],
- Try: [
- o('TRY Block', function() {
- return new Try($2);
- }), o('TRY Block Catch', function() {
- return new Try($2, $3[0], $3[1]);
- }), o('TRY Block FINALLY Block', function() {
- return new Try($2, null, null, $4);
- }), o('TRY Block Catch FINALLY Block', function() {
- return new Try($2, $3[0], $3[1], $5);
- })
- ],
- Catch: [
- o('CATCH Identifier Block', function() {
- return [$2, $3];
- })
- ],
- Throw: [
- o('THROW Expression', function() {
- return new Throw($2);
- })
- ],
- Parenthetical: [
- o('( Body )', function() {
- return new Parens($2);
- }), o('( INDENT Body OUTDENT )', function() {
- return new Parens($3);
- })
- ],
- WhileSource: [
- o('WHILE Expression', function() {
- return new While($2);
- }), o('WHILE Expression WHEN Expression', function() {
- return new While($2, {
- guard: $4
- });
- }), o('UNTIL Expression', function() {
- return new While($2, {
- invert: true
- });
- }), o('UNTIL Expression WHEN Expression', function() {
- return new While($2, {
- invert: true,
- guard: $4
- });
- })
- ],
- While: [
- o('WhileSource Block', function() {
- return $1.addBody($2);
- }), o('Statement WhileSource', function() {
- return $2.addBody(Block.wrap([$1]));
- }), o('Expression WhileSource', function() {
- return $2.addBody(Block.wrap([$1]));
- }), o('Loop', function() {
- return $1;
- })
- ],
- Loop: [
- o('LOOP Block', function() {
- return new While(new Literal('true')).addBody($2);
- }), o('LOOP Expression', function() {
- return new While(new Literal('true')).addBody(Block.wrap([$2]));
- })
- ],
- For: [
- o('Statement ForBody', function() {
- return new For($1, $2);
- }), o('Expression ForBody', function() {
- return new For($1, $2);
- }), o('ForBody Block', function() {
- return new For($2, $1);
- })
- ],
- ForBody: [
- o('FOR Range', function() {
- return {
- source: new Value($2)
- };
- }), o('ForStart ForSource', function() {
- $2.own = $1.own;
- $2.name = $1[0];
- $2.index = $1[1];
- return $2;
- })
- ],
- ForStart: [
- o('FOR ForVariables', function() {
- return $2;
- }), o('FOR OWN ForVariables', function() {
- $3.own = true;
- return $3;
- })
- ],
- ForValue: [
- o('Identifier'), o('ThisProperty'), o('Array', function() {
- return new Value($1);
- }), o('Object', function() {
- return new Value($1);
- })
- ],
- ForVariables: [
- o('ForValue', function() {
- return [$1];
- }), o('ForValue , ForValue', function() {
- return [$1, $3];
- })
- ],
- ForSource: [
- o('FORIN Expression', function() {
- return {
- source: $2
- };
- }), o('FOROF Expression', function() {
- return {
- source: $2,
- object: true
- };
- }), o('FORIN Expression WHEN Expression', function() {
- return {
- source: $2,
- guard: $4
- };
- }), o('FOROF Expression WHEN Expression', function() {
- return {
- source: $2,
- guard: $4,
- object: true
- };
- }), o('FORIN Expression BY Expression', function() {
- return {
- source: $2,
- step: $4
- };
- }), o('FORIN Expression WHEN Expression BY Expression', function() {
- return {
- source: $2,
- guard: $4,
- step: $6
- };
- }), o('FORIN Expression BY Expression WHEN Expression', function() {
- return {
- source: $2,
- step: $4,
- guard: $6
- };
- })
- ],
- Switch: [
- o('SWITCH Expression INDENT Whens OUTDENT', function() {
- return new Switch($2, $4);
- }), o('SWITCH Expression INDENT Whens ELSE Block OUTDENT', function() {
- return new Switch($2, $4, $6);
- }), o('SWITCH INDENT Whens OUTDENT', function() {
- return new Switch(null, $3);
- }), o('SWITCH INDENT Whens ELSE Block OUTDENT', function() {
- return new Switch(null, $3, $5);
- })
- ],
- Whens: [
- o('When'), o('Whens When', function() {
- return $1.concat($2);
- })
- ],
- When: [
- o('LEADING_WHEN SimpleArgs Block', function() {
- return [[$2, $3]];
- }), o('LEADING_WHEN SimpleArgs Block TERMINATOR', function() {
- return [[$2, $3]];
- })
- ],
- IfBlock: [
- o('IF Expression Block', function() {
- return new If($2, $3, {
- type: $1
- });
- }), o('IfBlock ELSE IF Expression Block', function() {
- return $1.addElse(new If($4, $5, {
- type: $3
- }));
- })
- ],
- If: [
- o('IfBlock'), o('IfBlock ELSE Block', function() {
- return $1.addElse($3);
- }), o('Statement POST_IF Expression', function() {
- return new If($3, Block.wrap([$1]), {
- type: $2,
- statement: true
- });
- }), o('Expression POST_IF Expression', function() {
- return new If($3, Block.wrap([$1]), {
- type: $2,
- statement: true
- });
- })
- ],
- Operation: [
- o('UNARY Expression', function() {
- return new Op($1, $2);
- }), o('- Expression', (function() {
- return new Op('-', $2);
- }), {
- prec: 'UNARY'
- }), o('+ Expression', (function() {
- return new Op('+', $2);
- }), {
- prec: 'UNARY'
- }), o('-- SimpleAssignable', function() {
- return new Op('--', $2);
- }), o('++ SimpleAssignable', function() {
- return new Op('++', $2);
- }), o('SimpleAssignable --', function() {
- return new Op('--', $1, null, true);
- }), o('SimpleAssignable ++', function() {
- return new Op('++', $1, null, true);
- }), o('Expression ?', function() {
- return new Existence($1);
- }), o('Expression + Expression', function() {
- return new Op('+', $1, $3);
- }), o('Expression - Expression', function() {
- return new Op('-', $1, $3);
- }), o('Expression MATH Expression', function() {
- return new Op($2, $1, $3);
- }), o('Expression SHIFT Expression', function() {
- return new Op($2, $1, $3);
- }), o('Expression COMPARE Expression', function() {
- return new Op($2, $1, $3);
- }), o('Expression LOGIC Expression', function() {
- return new Op($2, $1, $3);
- }), o('Expression RELATION Expression', function() {
- if ($2.charAt(0) === '!') {
- return new Op($2.slice(1), $1, $3).invert();
- } else {
- return new Op($2, $1, $3);
- }
- }), o('SimpleAssignable COMPOUND_ASSIGN\
- Expression', function() {
- return new Assign($1, $3, $2);
- }), o('SimpleAssignable COMPOUND_ASSIGN\
- INDENT Expression OUTDENT', function() {
- return new Assign($1, $4, $2);
- }), o('SimpleAssignable EXTENDS Expression', function() {
- return new Extends($1, $3);
- })
- ]
- };
-
- operators = [['left', '.', '?.', '::'], ['left', 'CALL_START', 'CALL_END'], ['nonassoc', '++', '--'], ['left', '?'], ['right', 'UNARY'], ['left', 'MATH'], ['left', '+', '-'], ['left', 'SHIFT'], ['left', 'RELATION'], ['left', 'COMPARE'], ['left', 'LOGIC'], ['nonassoc', 'INDENT', 'OUTDENT'], ['right', '=', ':', 'COMPOUND_ASSIGN', 'RETURN', 'THROW', 'EXTENDS'], ['right', 'FORIN', 'FOROF', 'BY', 'WHEN'], ['right', 'IF', 'ELSE', 'FOR', 'WHILE', 'UNTIL', 'LOOP', 'SUPER', 'CLASS'], ['right', 'POST_IF']];
-
- tokens = [];
-
- for (name in grammar) {
- alternatives = grammar[name];
- grammar[name] = (function() {
- var _i, _j, _len, _len1, _ref, _results;
- _results = [];
- for (_i = 0, _len = alternatives.length; _i < _len; _i++) {
- alt = alternatives[_i];
- _ref = alt[0].split(' ');
- for (_j = 0, _len1 = _ref.length; _j < _len1; _j++) {
- token = _ref[_j];
- if (!grammar[token]) {
- tokens.push(token);
- }
- }
- if (name === 'Root') {
- alt[1] = "return " + alt[1];
- }
- _results.push(alt);
- }
- return _results;
- })();
- }
-
- exports.parser = new Parser({
- tokens: tokens.join(' '),
- bnf: grammar,
- operators: operators.reverse(),
- startSymbol: 'Root'
- });
-
-}).call(this);
diff --git a/spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/helpers.js b/spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/helpers.js
deleted file mode 100644
index b0a997b8..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/helpers.js
+++ /dev/null
@@ -1,77 +0,0 @@
-// Generated by CoffeeScript 1.3.3
-(function() {
- var extend, flatten;
-
- exports.starts = function(string, literal, start) {
- return literal === string.substr(start, literal.length);
- };
-
- exports.ends = function(string, literal, back) {
- var len;
- len = literal.length;
- return literal === string.substr(string.length - len - (back || 0), len);
- };
-
- exports.compact = function(array) {
- var item, _i, _len, _results;
- _results = [];
- for (_i = 0, _len = array.length; _i < _len; _i++) {
- item = array[_i];
- if (item) {
- _results.push(item);
- }
- }
- return _results;
- };
-
- exports.count = function(string, substr) {
- var num, pos;
- num = pos = 0;
- if (!substr.length) {
- return 1 / 0;
- }
- while (pos = 1 + string.indexOf(substr, pos)) {
- num++;
- }
- return num;
- };
-
- exports.merge = function(options, overrides) {
- return extend(extend({}, options), overrides);
- };
-
- extend = exports.extend = function(object, properties) {
- var key, val;
- for (key in properties) {
- val = properties[key];
- object[key] = val;
- }
- return object;
- };
-
- exports.flatten = flatten = function(array) {
- var element, flattened, _i, _len;
- flattened = [];
- for (_i = 0, _len = array.length; _i < _len; _i++) {
- element = array[_i];
- if (element instanceof Array) {
- flattened = flattened.concat(flatten(element));
- } else {
- flattened.push(element);
- }
- }
- return flattened;
- };
-
- exports.del = function(obj, key) {
- var val;
- val = obj[key];
- delete obj[key];
- return val;
- };
-
- exports.last = function(array, back) {
- return array[array.length - (back || 0) - 1];
- };
-
-}).call(this);
diff --git a/spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/index.js b/spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/index.js
deleted file mode 100644
index d344c41a..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/index.js
+++ /dev/null
@@ -1,11 +0,0 @@
-// Generated by CoffeeScript 1.3.3
-(function() {
- var key, val, _ref;
-
- _ref = require('./coffee-script');
- for (key in _ref) {
- val = _ref[key];
- exports[key] = val;
- }
-
-}).call(this);
diff --git a/spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/lexer.js b/spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/lexer.js
deleted file mode 100644
index f80a4433..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/lexer.js
+++ /dev/null
@@ -1,788 +0,0 @@
-// Generated by CoffeeScript 1.3.3
-(function() {
- var BOOL, CALLABLE, CODE, COFFEE_ALIASES, COFFEE_ALIAS_MAP, COFFEE_KEYWORDS, COMMENT, COMPARE, COMPOUND_ASSIGN, HEREDOC, HEREDOC_ILLEGAL, HEREDOC_INDENT, HEREGEX, HEREGEX_OMIT, IDENTIFIER, INDEXABLE, INVERSES, JSTOKEN, JS_FORBIDDEN, JS_KEYWORDS, LINE_BREAK, LINE_CONTINUER, LOGIC, Lexer, MATH, MULTILINER, MULTI_DENT, NOT_REGEX, NOT_SPACED_REGEX, NUMBER, OPERATOR, REGEX, RELATION, RESERVED, Rewriter, SHIFT, SIMPLESTR, STRICT_PROSCRIBED, TRAILING_SPACES, UNARY, WHITESPACE, compact, count, key, last, starts, _ref, _ref1,
- __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
-
- _ref = require('./rewriter'), Rewriter = _ref.Rewriter, INVERSES = _ref.INVERSES;
-
- _ref1 = require('./helpers'), count = _ref1.count, starts = _ref1.starts, compact = _ref1.compact, last = _ref1.last;
-
- exports.Lexer = Lexer = (function() {
-
- function Lexer() {}
-
- Lexer.prototype.tokenize = function(code, opts) {
- var i, tag;
- if (opts == null) {
- opts = {};
- }
- if (WHITESPACE.test(code)) {
- code = "\n" + code;
- }
- code = code.replace(/\r/g, '').replace(TRAILING_SPACES, '');
- this.code = code;
- this.line = opts.line || 0;
- this.indent = 0;
- this.indebt = 0;
- this.outdebt = 0;
- this.indents = [];
- this.ends = [];
- this.tokens = [];
- i = 0;
- while (this.chunk = code.slice(i)) {
- i += this.identifierToken() || this.commentToken() || this.whitespaceToken() || this.lineToken() || this.heredocToken() || this.stringToken() || this.numberToken() || this.regexToken() || this.jsToken() || this.literalToken();
- }
- this.closeIndentation();
- if (tag = this.ends.pop()) {
- this.error("missing " + tag);
- }
- if (opts.rewrite === false) {
- return this.tokens;
- }
- return (new Rewriter).rewrite(this.tokens);
- };
-
- Lexer.prototype.identifierToken = function() {
- var colon, forcedIdentifier, id, input, match, prev, tag, _ref2, _ref3;
- if (!(match = IDENTIFIER.exec(this.chunk))) {
- return 0;
- }
- input = match[0], id = match[1], colon = match[2];
- if (id === 'own' && this.tag() === 'FOR') {
- this.token('OWN', id);
- return id.length;
- }
- forcedIdentifier = colon || (prev = last(this.tokens)) && (((_ref2 = prev[0]) === '.' || _ref2 === '?.' || _ref2 === '::') || !prev.spaced && prev[0] === '@');
- tag = 'IDENTIFIER';
- if (!forcedIdentifier && (__indexOf.call(JS_KEYWORDS, id) >= 0 || __indexOf.call(COFFEE_KEYWORDS, id) >= 0)) {
- tag = id.toUpperCase();
- if (tag === 'WHEN' && (_ref3 = this.tag(), __indexOf.call(LINE_BREAK, _ref3) >= 0)) {
- tag = 'LEADING_WHEN';
- } else if (tag === 'FOR') {
- this.seenFor = true;
- } else if (tag === 'UNLESS') {
- tag = 'IF';
- } else if (__indexOf.call(UNARY, tag) >= 0) {
- tag = 'UNARY';
- } else if (__indexOf.call(RELATION, tag) >= 0) {
- if (tag !== 'INSTANCEOF' && this.seenFor) {
- tag = 'FOR' + tag;
- this.seenFor = false;
- } else {
- tag = 'RELATION';
- if (this.value() === '!') {
- this.tokens.pop();
- id = '!' + id;
- }
- }
- }
- }
- if (__indexOf.call(JS_FORBIDDEN, id) >= 0) {
- if (forcedIdentifier) {
- tag = 'IDENTIFIER';
- id = new String(id);
- id.reserved = true;
- } else if (__indexOf.call(RESERVED, id) >= 0) {
- this.error("reserved word \"" + id + "\"");
- }
- }
- if (!forcedIdentifier) {
- if (__indexOf.call(COFFEE_ALIASES, id) >= 0) {
- id = COFFEE_ALIAS_MAP[id];
- }
- tag = (function() {
- switch (id) {
- case '!':
- return 'UNARY';
- case '==':
- case '!=':
- return 'COMPARE';
- case '&&':
- case '||':
- return 'LOGIC';
- case 'true':
- case 'false':
- return 'BOOL';
- case 'break':
- case 'continue':
- return 'STATEMENT';
- default:
- return tag;
- }
- })();
- }
- this.token(tag, id);
- if (colon) {
- this.token(':', ':');
- }
- return input.length;
- };
-
- Lexer.prototype.numberToken = function() {
- var binaryLiteral, lexedLength, match, number, octalLiteral;
- if (!(match = NUMBER.exec(this.chunk))) {
- return 0;
- }
- number = match[0];
- if (/^0[BOX]/.test(number)) {
- this.error("radix prefix '" + number + "' must be lowercase");
- } else if (/E/.test(number) && !/^0x/.test(number)) {
- this.error("exponential notation '" + number + "' must be indicated with a lowercase 'e'");
- } else if (/^0\d*[89]/.test(number)) {
- this.error("decimal literal '" + number + "' must not be prefixed with '0'");
- } else if (/^0\d+/.test(number)) {
- this.error("octal literal '" + number + "' must be prefixed with '0o'");
- }
- lexedLength = number.length;
- if (octalLiteral = /^0o([0-7]+)/.exec(number)) {
- number = '0x' + (parseInt(octalLiteral[1], 8)).toString(16);
- }
- if (binaryLiteral = /^0b([01]+)/.exec(number)) {
- number = '0x' + (parseInt(binaryLiteral[1], 2)).toString(16);
- }
- this.token('NUMBER', number);
- return lexedLength;
- };
-
- Lexer.prototype.stringToken = function() {
- var match, octalEsc, string;
- switch (this.chunk.charAt(0)) {
- case "'":
- if (!(match = SIMPLESTR.exec(this.chunk))) {
- return 0;
- }
- this.token('STRING', (string = match[0]).replace(MULTILINER, '\\\n'));
- break;
- case '"':
- if (!(string = this.balancedString(this.chunk, '"'))) {
- return 0;
- }
- if (0 < string.indexOf('#{', 1)) {
- this.interpolateString(string.slice(1, -1));
- } else {
- this.token('STRING', this.escapeLines(string));
- }
- break;
- default:
- return 0;
- }
- if (octalEsc = /^(?:\\.|[^\\])*\\(?:0[0-7]|[1-7])/.test(string)) {
- this.error("octal escape sequences " + string + " are not allowed");
- }
- this.line += count(string, '\n');
- return string.length;
- };
-
- Lexer.prototype.heredocToken = function() {
- var doc, heredoc, match, quote;
- if (!(match = HEREDOC.exec(this.chunk))) {
- return 0;
- }
- heredoc = match[0];
- quote = heredoc.charAt(0);
- doc = this.sanitizeHeredoc(match[2], {
- quote: quote,
- indent: null
- });
- if (quote === '"' && 0 <= doc.indexOf('#{')) {
- this.interpolateString(doc, {
- heredoc: true
- });
- } else {
- this.token('STRING', this.makeString(doc, quote, true));
- }
- this.line += count(heredoc, '\n');
- return heredoc.length;
- };
-
- Lexer.prototype.commentToken = function() {
- var comment, here, match;
- if (!(match = this.chunk.match(COMMENT))) {
- return 0;
- }
- comment = match[0], here = match[1];
- if (here) {
- this.token('HERECOMMENT', this.sanitizeHeredoc(here, {
- herecomment: true,
- indent: Array(this.indent + 1).join(' ')
- }));
- }
- this.line += count(comment, '\n');
- return comment.length;
- };
-
- Lexer.prototype.jsToken = function() {
- var match, script;
- if (!(this.chunk.charAt(0) === '`' && (match = JSTOKEN.exec(this.chunk)))) {
- return 0;
- }
- this.token('JS', (script = match[0]).slice(1, -1));
- return script.length;
- };
-
- Lexer.prototype.regexToken = function() {
- var flags, length, match, prev, regex, _ref2, _ref3;
- if (this.chunk.charAt(0) !== '/') {
- return 0;
- }
- if (match = HEREGEX.exec(this.chunk)) {
- length = this.heregexToken(match);
- this.line += count(match[0], '\n');
- return length;
- }
- prev = last(this.tokens);
- if (prev && (_ref2 = prev[0], __indexOf.call((prev.spaced ? NOT_REGEX : NOT_SPACED_REGEX), _ref2) >= 0)) {
- return 0;
- }
- if (!(match = REGEX.exec(this.chunk))) {
- return 0;
- }
- _ref3 = match, match = _ref3[0], regex = _ref3[1], flags = _ref3[2];
- if (regex.slice(0, 2) === '/*') {
- this.error('regular expressions cannot begin with `*`');
- }
- if (regex === '//') {
- regex = '/(?:)/';
- }
- this.token('REGEX', "" + regex + flags);
- return match.length;
- };
-
- Lexer.prototype.heregexToken = function(match) {
- var body, flags, heregex, re, tag, tokens, value, _i, _len, _ref2, _ref3, _ref4, _ref5;
- heregex = match[0], body = match[1], flags = match[2];
- if (0 > body.indexOf('#{')) {
- re = body.replace(HEREGEX_OMIT, '').replace(/\//g, '\\/');
- if (re.match(/^\*/)) {
- this.error('regular expressions cannot begin with `*`');
- }
- this.token('REGEX', "/" + (re || '(?:)') + "/" + flags);
- return heregex.length;
- }
- this.token('IDENTIFIER', 'RegExp');
- this.tokens.push(['CALL_START', '(']);
- tokens = [];
- _ref2 = this.interpolateString(body, {
- regex: true
- });
- for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
- _ref3 = _ref2[_i], tag = _ref3[0], value = _ref3[1];
- if (tag === 'TOKENS') {
- tokens.push.apply(tokens, value);
- } else {
- if (!(value = value.replace(HEREGEX_OMIT, ''))) {
- continue;
- }
- value = value.replace(/\\/g, '\\\\');
- tokens.push(['STRING', this.makeString(value, '"', true)]);
- }
- tokens.push(['+', '+']);
- }
- tokens.pop();
- if (((_ref4 = tokens[0]) != null ? _ref4[0] : void 0) !== 'STRING') {
- this.tokens.push(['STRING', '""'], ['+', '+']);
- }
- (_ref5 = this.tokens).push.apply(_ref5, tokens);
- if (flags) {
- this.tokens.push([',', ','], ['STRING', '"' + flags + '"']);
- }
- this.token(')', ')');
- return heregex.length;
- };
-
- Lexer.prototype.lineToken = function() {
- var diff, indent, match, noNewlines, prev, size;
- if (!(match = MULTI_DENT.exec(this.chunk))) {
- return 0;
- }
- indent = match[0];
- this.line += count(indent, '\n');
- this.seenFor = false;
- prev = last(this.tokens, 1);
- size = indent.length - 1 - indent.lastIndexOf('\n');
- noNewlines = this.unfinished();
- if (size - this.indebt === this.indent) {
- if (noNewlines) {
- this.suppressNewlines();
- } else {
- this.newlineToken();
- }
- return indent.length;
- }
- if (size > this.indent) {
- if (noNewlines) {
- this.indebt = size - this.indent;
- this.suppressNewlines();
- return indent.length;
- }
- diff = size - this.indent + this.outdebt;
- this.token('INDENT', diff);
- this.indents.push(diff);
- this.ends.push('OUTDENT');
- this.outdebt = this.indebt = 0;
- } else {
- this.indebt = 0;
- this.outdentToken(this.indent - size, noNewlines);
- }
- this.indent = size;
- return indent.length;
- };
-
- Lexer.prototype.outdentToken = function(moveOut, noNewlines) {
- var dent, len;
- while (moveOut > 0) {
- len = this.indents.length - 1;
- if (this.indents[len] === void 0) {
- moveOut = 0;
- } else if (this.indents[len] === this.outdebt) {
- moveOut -= this.outdebt;
- this.outdebt = 0;
- } else if (this.indents[len] < this.outdebt) {
- this.outdebt -= this.indents[len];
- moveOut -= this.indents[len];
- } else {
- dent = this.indents.pop() - this.outdebt;
- moveOut -= dent;
- this.outdebt = 0;
- this.pair('OUTDENT');
- this.token('OUTDENT', dent);
- }
- }
- if (dent) {
- this.outdebt -= moveOut;
- }
- while (this.value() === ';') {
- this.tokens.pop();
- }
- if (!(this.tag() === 'TERMINATOR' || noNewlines)) {
- this.token('TERMINATOR', '\n');
- }
- return this;
- };
-
- Lexer.prototype.whitespaceToken = function() {
- var match, nline, prev;
- if (!((match = WHITESPACE.exec(this.chunk)) || (nline = this.chunk.charAt(0) === '\n'))) {
- return 0;
- }
- prev = last(this.tokens);
- if (prev) {
- prev[match ? 'spaced' : 'newLine'] = true;
- }
- if (match) {
- return match[0].length;
- } else {
- return 0;
- }
- };
-
- Lexer.prototype.newlineToken = function() {
- while (this.value() === ';') {
- this.tokens.pop();
- }
- if (this.tag() !== 'TERMINATOR') {
- this.token('TERMINATOR', '\n');
- }
- return this;
- };
-
- Lexer.prototype.suppressNewlines = function() {
- if (this.value() === '\\') {
- this.tokens.pop();
- }
- return this;
- };
-
- Lexer.prototype.literalToken = function() {
- var match, prev, tag, value, _ref2, _ref3, _ref4, _ref5;
- if (match = OPERATOR.exec(this.chunk)) {
- value = match[0];
- if (CODE.test(value)) {
- this.tagParameters();
- }
- } else {
- value = this.chunk.charAt(0);
- }
- tag = value;
- prev = last(this.tokens);
- if (value === '=' && prev) {
- if (!prev[1].reserved && (_ref2 = prev[1], __indexOf.call(JS_FORBIDDEN, _ref2) >= 0)) {
- this.error("reserved word \"" + (this.value()) + "\" can't be assigned");
- }
- if ((_ref3 = prev[1]) === '||' || _ref3 === '&&') {
- prev[0] = 'COMPOUND_ASSIGN';
- prev[1] += '=';
- return value.length;
- }
- }
- if (value === ';') {
- this.seenFor = false;
- tag = 'TERMINATOR';
- } else if (__indexOf.call(MATH, value) >= 0) {
- tag = 'MATH';
- } else if (__indexOf.call(COMPARE, value) >= 0) {
- tag = 'COMPARE';
- } else if (__indexOf.call(COMPOUND_ASSIGN, value) >= 0) {
- tag = 'COMPOUND_ASSIGN';
- } else if (__indexOf.call(UNARY, value) >= 0) {
- tag = 'UNARY';
- } else if (__indexOf.call(SHIFT, value) >= 0) {
- tag = 'SHIFT';
- } else if (__indexOf.call(LOGIC, value) >= 0 || value === '?' && (prev != null ? prev.spaced : void 0)) {
- tag = 'LOGIC';
- } else if (prev && !prev.spaced) {
- if (value === '(' && (_ref4 = prev[0], __indexOf.call(CALLABLE, _ref4) >= 0)) {
- if (prev[0] === '?') {
- prev[0] = 'FUNC_EXIST';
- }
- tag = 'CALL_START';
- } else if (value === '[' && (_ref5 = prev[0], __indexOf.call(INDEXABLE, _ref5) >= 0)) {
- tag = 'INDEX_START';
- switch (prev[0]) {
- case '?':
- prev[0] = 'INDEX_SOAK';
- }
- }
- }
- switch (value) {
- case '(':
- case '{':
- case '[':
- this.ends.push(INVERSES[value]);
- break;
- case ')':
- case '}':
- case ']':
- this.pair(value);
- }
- this.token(tag, value);
- return value.length;
- };
-
- Lexer.prototype.sanitizeHeredoc = function(doc, options) {
- var attempt, herecomment, indent, match, _ref2;
- indent = options.indent, herecomment = options.herecomment;
- if (herecomment) {
- if (HEREDOC_ILLEGAL.test(doc)) {
- this.error("block comment cannot contain \"*/\", starting");
- }
- if (doc.indexOf('\n') <= 0) {
- return doc;
- }
- } else {
- while (match = HEREDOC_INDENT.exec(doc)) {
- attempt = match[1];
- if (indent === null || (0 < (_ref2 = attempt.length) && _ref2 < indent.length)) {
- indent = attempt;
- }
- }
- }
- if (indent) {
- doc = doc.replace(RegExp("\\n" + indent, "g"), '\n');
- }
- if (!herecomment) {
- doc = doc.replace(/^\n/, '');
- }
- return doc;
- };
-
- Lexer.prototype.tagParameters = function() {
- var i, stack, tok, tokens;
- if (this.tag() !== ')') {
- return this;
- }
- stack = [];
- tokens = this.tokens;
- i = tokens.length;
- tokens[--i][0] = 'PARAM_END';
- while (tok = tokens[--i]) {
- switch (tok[0]) {
- case ')':
- stack.push(tok);
- break;
- case '(':
- case 'CALL_START':
- if (stack.length) {
- stack.pop();
- } else if (tok[0] === '(') {
- tok[0] = 'PARAM_START';
- return this;
- } else {
- return this;
- }
- }
- }
- return this;
- };
-
- Lexer.prototype.closeIndentation = function() {
- return this.outdentToken(this.indent);
- };
-
- Lexer.prototype.balancedString = function(str, end) {
- var continueCount, i, letter, match, prev, stack, _i, _ref2;
- continueCount = 0;
- stack = [end];
- for (i = _i = 1, _ref2 = str.length; 1 <= _ref2 ? _i < _ref2 : _i > _ref2; i = 1 <= _ref2 ? ++_i : --_i) {
- if (continueCount) {
- --continueCount;
- continue;
- }
- switch (letter = str.charAt(i)) {
- case '\\':
- ++continueCount;
- continue;
- case end:
- stack.pop();
- if (!stack.length) {
- return str.slice(0, i + 1 || 9e9);
- }
- end = stack[stack.length - 1];
- continue;
- }
- if (end === '}' && (letter === '"' || letter === "'")) {
- stack.push(end = letter);
- } else if (end === '}' && letter === '/' && (match = HEREGEX.exec(str.slice(i)) || REGEX.exec(str.slice(i)))) {
- continueCount += match[0].length - 1;
- } else if (end === '}' && letter === '{') {
- stack.push(end = '}');
- } else if (end === '"' && prev === '#' && letter === '{') {
- stack.push(end = '}');
- }
- prev = letter;
- }
- return this.error("missing " + (stack.pop()) + ", starting");
- };
-
- Lexer.prototype.interpolateString = function(str, options) {
- var expr, heredoc, i, inner, interpolated, len, letter, nested, pi, regex, tag, tokens, value, _i, _len, _ref2, _ref3, _ref4;
- if (options == null) {
- options = {};
- }
- heredoc = options.heredoc, regex = options.regex;
- tokens = [];
- pi = 0;
- i = -1;
- while (letter = str.charAt(i += 1)) {
- if (letter === '\\') {
- i += 1;
- continue;
- }
- if (!(letter === '#' && str.charAt(i + 1) === '{' && (expr = this.balancedString(str.slice(i + 1), '}')))) {
- continue;
- }
- if (pi < i) {
- tokens.push(['NEOSTRING', str.slice(pi, i)]);
- }
- inner = expr.slice(1, -1);
- if (inner.length) {
- nested = new Lexer().tokenize(inner, {
- line: this.line,
- rewrite: false
- });
- nested.pop();
- if (((_ref2 = nested[0]) != null ? _ref2[0] : void 0) === 'TERMINATOR') {
- nested.shift();
- }
- if (len = nested.length) {
- if (len > 1) {
- nested.unshift(['(', '(', this.line]);
- nested.push([')', ')', this.line]);
- }
- tokens.push(['TOKENS', nested]);
- }
- }
- i += expr.length;
- pi = i + 1;
- }
- if ((i > pi && pi < str.length)) {
- tokens.push(['NEOSTRING', str.slice(pi)]);
- }
- if (regex) {
- return tokens;
- }
- if (!tokens.length) {
- return this.token('STRING', '""');
- }
- if (tokens[0][0] !== 'NEOSTRING') {
- tokens.unshift(['', '']);
- }
- if (interpolated = tokens.length > 1) {
- this.token('(', '(');
- }
- for (i = _i = 0, _len = tokens.length; _i < _len; i = ++_i) {
- _ref3 = tokens[i], tag = _ref3[0], value = _ref3[1];
- if (i) {
- this.token('+', '+');
- }
- if (tag === 'TOKENS') {
- (_ref4 = this.tokens).push.apply(_ref4, value);
- } else {
- this.token('STRING', this.makeString(value, '"', heredoc));
- }
- }
- if (interpolated) {
- this.token(')', ')');
- }
- return tokens;
- };
-
- Lexer.prototype.pair = function(tag) {
- var size, wanted;
- if (tag !== (wanted = last(this.ends))) {
- if ('OUTDENT' !== wanted) {
- this.error("unmatched " + tag);
- }
- this.indent -= size = last(this.indents);
- this.outdentToken(size, true);
- return this.pair(tag);
- }
- return this.ends.pop();
- };
-
- Lexer.prototype.token = function(tag, value) {
- return this.tokens.push([tag, value, this.line]);
- };
-
- Lexer.prototype.tag = function(index, tag) {
- var tok;
- return (tok = last(this.tokens, index)) && (tag ? tok[0] = tag : tok[0]);
- };
-
- Lexer.prototype.value = function(index, val) {
- var tok;
- return (tok = last(this.tokens, index)) && (val ? tok[1] = val : tok[1]);
- };
-
- Lexer.prototype.unfinished = function() {
- var _ref2;
- return LINE_CONTINUER.test(this.chunk) || ((_ref2 = this.tag()) === '\\' || _ref2 === '.' || _ref2 === '?.' || _ref2 === 'UNARY' || _ref2 === 'MATH' || _ref2 === '+' || _ref2 === '-' || _ref2 === 'SHIFT' || _ref2 === 'RELATION' || _ref2 === 'COMPARE' || _ref2 === 'LOGIC' || _ref2 === 'THROW' || _ref2 === 'EXTENDS');
- };
-
- Lexer.prototype.escapeLines = function(str, heredoc) {
- return str.replace(MULTILINER, heredoc ? '\\n' : '');
- };
-
- Lexer.prototype.makeString = function(body, quote, heredoc) {
- if (!body) {
- return quote + quote;
- }
- body = body.replace(/\\([\s\S])/g, function(match, contents) {
- if (contents === '\n' || contents === quote) {
- return contents;
- } else {
- return match;
- }
- });
- body = body.replace(RegExp("" + quote, "g"), '\\$&');
- return quote + this.escapeLines(body, heredoc) + quote;
- };
-
- Lexer.prototype.error = function(message) {
- throw SyntaxError("" + message + " on line " + (this.line + 1));
- };
-
- return Lexer;
-
- })();
-
- JS_KEYWORDS = ['true', 'false', 'null', 'this', 'new', 'delete', 'typeof', 'in', 'instanceof', 'return', 'throw', 'break', 'continue', 'debugger', 'if', 'else', 'switch', 'for', 'while', 'do', 'try', 'catch', 'finally', 'class', 'extends', 'super'];
-
- COFFEE_KEYWORDS = ['undefined', 'then', 'unless', 'until', 'loop', 'of', 'by', 'when'];
-
- COFFEE_ALIAS_MAP = {
- and: '&&',
- or: '||',
- is: '==',
- isnt: '!=',
- not: '!',
- yes: 'true',
- no: 'false',
- on: 'true',
- off: 'false'
- };
-
- COFFEE_ALIASES = (function() {
- var _results;
- _results = [];
- for (key in COFFEE_ALIAS_MAP) {
- _results.push(key);
- }
- return _results;
- })();
-
- COFFEE_KEYWORDS = COFFEE_KEYWORDS.concat(COFFEE_ALIASES);
-
- RESERVED = ['case', 'default', 'function', 'var', 'void', 'with', 'const', 'let', 'enum', 'export', 'import', 'native', '__hasProp', '__extends', '__slice', '__bind', '__indexOf', 'implements', 'interface', 'let', 'package', 'private', 'protected', 'public', 'static', 'yield'];
-
- STRICT_PROSCRIBED = ['arguments', 'eval'];
-
- JS_FORBIDDEN = JS_KEYWORDS.concat(RESERVED).concat(STRICT_PROSCRIBED);
-
- exports.RESERVED = RESERVED.concat(JS_KEYWORDS).concat(COFFEE_KEYWORDS).concat(STRICT_PROSCRIBED);
-
- exports.STRICT_PROSCRIBED = STRICT_PROSCRIBED;
-
- IDENTIFIER = /^([$A-Za-z_\x7f-\uffff][$\w\x7f-\uffff]*)([^\n\S]*:(?!:))?/;
-
- NUMBER = /^0b[01]+|^0o[0-7]+|^0x[\da-f]+|^\d*\.?\d+(?:e[+-]?\d+)?/i;
-
- HEREDOC = /^("""|''')([\s\S]*?)(?:\n[^\n\S]*)?\1/;
-
- OPERATOR = /^(?:[-=]>|[-+*\/%<>&|^!?=]=|>>>=?|([-+:])\1|([&|<>])\2=?|\?\.|\.{2,3})/;
-
- WHITESPACE = /^[^\n\S]+/;
-
- COMMENT = /^###([^#][\s\S]*?)(?:###[^\n\S]*|(?:###)?$)|^(?:\s*#(?!##[^#]).*)+/;
-
- CODE = /^[-=]>/;
-
- MULTI_DENT = /^(?:\n[^\n\S]*)+/;
-
- SIMPLESTR = /^'[^\\']*(?:\\.[^\\']*)*'/;
-
- JSTOKEN = /^`[^\\`]*(?:\\.[^\\`]*)*`/;
-
- REGEX = /^(\/(?![\s=])[^[\/\n\\]*(?:(?:\\[\s\S]|\[[^\]\n\\]*(?:\\[\s\S][^\]\n\\]*)*])[^[\/\n\\]*)*\/)([imgy]{0,4})(?!\w)/;
-
- HEREGEX = /^\/{3}([\s\S]+?)\/{3}([imgy]{0,4})(?!\w)/;
-
- HEREGEX_OMIT = /\s+(?:#.*)?/g;
-
- MULTILINER = /\n/g;
-
- HEREDOC_INDENT = /\n+([^\n\S]*)/g;
-
- HEREDOC_ILLEGAL = /\*\//;
-
- LINE_CONTINUER = /^\s*(?:,|\??\.(?![.\d])|::)/;
-
- TRAILING_SPACES = /\s+$/;
-
- COMPOUND_ASSIGN = ['-=', '+=', '/=', '*=', '%=', '||=', '&&=', '?=', '<<=', '>>=', '>>>=', '&=', '^=', '|='];
-
- UNARY = ['!', '~', 'NEW', 'TYPEOF', 'DELETE', 'DO'];
-
- LOGIC = ['&&', '||', '&', '|', '^'];
-
- SHIFT = ['<<', '>>', '>>>'];
-
- COMPARE = ['==', '!=', '<', '>', '<=', '>='];
-
- MATH = ['*', '/', '%'];
-
- RELATION = ['IN', 'OF', 'INSTANCEOF'];
-
- BOOL = ['TRUE', 'FALSE'];
-
- NOT_REGEX = ['NUMBER', 'REGEX', 'BOOL', 'NULL', 'UNDEFINED', '++', '--', ']'];
-
- NOT_SPACED_REGEX = NOT_REGEX.concat(')', '}', 'THIS', 'IDENTIFIER', 'STRING');
-
- CALLABLE = ['IDENTIFIER', 'STRING', 'REGEX', ')', ']', '}', '?', '::', '@', 'THIS', 'SUPER'];
-
- INDEXABLE = CALLABLE.concat('NUMBER', 'BOOL', 'NULL', 'UNDEFINED');
-
- LINE_BREAK = ['INDENT', 'OUTDENT', 'TERMINATOR'];
-
-}).call(this);
diff --git a/spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/nodes.js b/spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/nodes.js
deleted file mode 100644
index 799b68eb..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/nodes.js
+++ /dev/null
@@ -1,2986 +0,0 @@
-// Generated by CoffeeScript 1.3.3
-(function() {
- var Access, Arr, Assign, Base, Block, Call, Class, Closure, Code, Comment, Existence, Extends, For, IDENTIFIER, IDENTIFIER_STR, IS_STRING, If, In, Index, LEVEL_ACCESS, LEVEL_COND, LEVEL_LIST, LEVEL_OP, LEVEL_PAREN, LEVEL_TOP, Literal, METHOD_DEF, NEGATE, NO, Obj, Op, Param, Parens, RESERVED, Range, Return, SIMPLENUM, STRICT_PROSCRIBED, Scope, Slice, Splat, Switch, TAB, THIS, Throw, Try, UTILITIES, Value, While, YES, compact, del, ends, extend, flatten, last, merge, multident, starts, unfoldSoak, utility, _ref, _ref1,
- __hasProp = {}.hasOwnProperty,
- __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
- __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
-
- Scope = require('./scope').Scope;
-
- _ref = require('./lexer'), RESERVED = _ref.RESERVED, STRICT_PROSCRIBED = _ref.STRICT_PROSCRIBED;
-
- _ref1 = require('./helpers'), compact = _ref1.compact, flatten = _ref1.flatten, extend = _ref1.extend, merge = _ref1.merge, del = _ref1.del, starts = _ref1.starts, ends = _ref1.ends, last = _ref1.last;
-
- exports.extend = extend;
-
- YES = function() {
- return true;
- };
-
- NO = function() {
- return false;
- };
-
- THIS = function() {
- return this;
- };
-
- NEGATE = function() {
- this.negated = !this.negated;
- return this;
- };
-
- exports.Base = Base = (function() {
-
- function Base() {}
-
- Base.prototype.compile = function(o, lvl) {
- var node;
- o = extend({}, o);
- if (lvl) {
- o.level = lvl;
- }
- node = this.unfoldSoak(o) || this;
- node.tab = o.indent;
- if (o.level === LEVEL_TOP || !node.isStatement(o)) {
- return node.compileNode(o);
- } else {
- return node.compileClosure(o);
- }
- };
-
- Base.prototype.compileClosure = function(o) {
- if (this.jumps()) {
- throw SyntaxError('cannot use a pure statement in an expression.');
- }
- o.sharedScope = true;
- return Closure.wrap(this).compileNode(o);
- };
-
- Base.prototype.cache = function(o, level, reused) {
- var ref, sub;
- if (!this.isComplex()) {
- ref = level ? this.compile(o, level) : this;
- return [ref, ref];
- } else {
- ref = new Literal(reused || o.scope.freeVariable('ref'));
- sub = new Assign(ref, this);
- if (level) {
- return [sub.compile(o, level), ref.value];
- } else {
- return [sub, ref];
- }
- }
- };
-
- Base.prototype.compileLoopReference = function(o, name) {
- var src, tmp;
- src = tmp = this.compile(o, LEVEL_LIST);
- if (!((-Infinity < +src && +src < Infinity) || IDENTIFIER.test(src) && o.scope.check(src, true))) {
- src = "" + (tmp = o.scope.freeVariable(name)) + " = " + src;
- }
- return [src, tmp];
- };
-
- Base.prototype.makeReturn = function(res) {
- var me;
- me = this.unwrapAll();
- if (res) {
- return new Call(new Literal("" + res + ".push"), [me]);
- } else {
- return new Return(me);
- }
- };
-
- Base.prototype.contains = function(pred) {
- var contains;
- contains = false;
- this.traverseChildren(false, function(node) {
- if (pred(node)) {
- contains = true;
- return false;
- }
- });
- return contains;
- };
-
- Base.prototype.containsType = function(type) {
- return this instanceof type || this.contains(function(node) {
- return node instanceof type;
- });
- };
-
- Base.prototype.lastNonComment = function(list) {
- var i;
- i = list.length;
- while (i--) {
- if (!(list[i] instanceof Comment)) {
- return list[i];
- }
- }
- return null;
- };
-
- Base.prototype.toString = function(idt, name) {
- var tree;
- if (idt == null) {
- idt = '';
- }
- if (name == null) {
- name = this.constructor.name;
- }
- tree = '\n' + idt + name;
- if (this.soak) {
- tree += '?';
- }
- this.eachChild(function(node) {
- return tree += node.toString(idt + TAB);
- });
- return tree;
- };
-
- Base.prototype.eachChild = function(func) {
- var attr, child, _i, _j, _len, _len1, _ref2, _ref3;
- if (!this.children) {
- return this;
- }
- _ref2 = this.children;
- for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
- attr = _ref2[_i];
- if (this[attr]) {
- _ref3 = flatten([this[attr]]);
- for (_j = 0, _len1 = _ref3.length; _j < _len1; _j++) {
- child = _ref3[_j];
- if (func(child) === false) {
- return this;
- }
- }
- }
- }
- return this;
- };
-
- Base.prototype.traverseChildren = function(crossScope, func) {
- return this.eachChild(function(child) {
- if (func(child) === false) {
- return false;
- }
- return child.traverseChildren(crossScope, func);
- });
- };
-
- Base.prototype.invert = function() {
- return new Op('!', this);
- };
-
- Base.prototype.unwrapAll = function() {
- var node;
- node = this;
- while (node !== (node = node.unwrap())) {
- continue;
- }
- return node;
- };
-
- Base.prototype.children = [];
-
- Base.prototype.isStatement = NO;
-
- Base.prototype.jumps = NO;
-
- Base.prototype.isComplex = YES;
-
- Base.prototype.isChainable = NO;
-
- Base.prototype.isAssignable = NO;
-
- Base.prototype.unwrap = THIS;
-
- Base.prototype.unfoldSoak = NO;
-
- Base.prototype.assigns = NO;
-
- return Base;
-
- })();
-
- exports.Block = Block = (function(_super) {
-
- __extends(Block, _super);
-
- function Block(nodes) {
- this.expressions = compact(flatten(nodes || []));
- }
-
- Block.prototype.children = ['expressions'];
-
- Block.prototype.push = function(node) {
- this.expressions.push(node);
- return this;
- };
-
- Block.prototype.pop = function() {
- return this.expressions.pop();
- };
-
- Block.prototype.unshift = function(node) {
- this.expressions.unshift(node);
- return this;
- };
-
- Block.prototype.unwrap = function() {
- if (this.expressions.length === 1) {
- return this.expressions[0];
- } else {
- return this;
- }
- };
-
- Block.prototype.isEmpty = function() {
- return !this.expressions.length;
- };
-
- Block.prototype.isStatement = function(o) {
- var exp, _i, _len, _ref2;
- _ref2 = this.expressions;
- for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
- exp = _ref2[_i];
- if (exp.isStatement(o)) {
- return true;
- }
- }
- return false;
- };
-
- Block.prototype.jumps = function(o) {
- var exp, _i, _len, _ref2;
- _ref2 = this.expressions;
- for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
- exp = _ref2[_i];
- if (exp.jumps(o)) {
- return exp;
- }
- }
- };
-
- Block.prototype.makeReturn = function(res) {
- var expr, len;
- len = this.expressions.length;
- while (len--) {
- expr = this.expressions[len];
- if (!(expr instanceof Comment)) {
- this.expressions[len] = expr.makeReturn(res);
- if (expr instanceof Return && !expr.expression) {
- this.expressions.splice(len, 1);
- }
- break;
- }
- }
- return this;
- };
-
- Block.prototype.compile = function(o, level) {
- if (o == null) {
- o = {};
- }
- if (o.scope) {
- return Block.__super__.compile.call(this, o, level);
- } else {
- return this.compileRoot(o);
- }
- };
-
- Block.prototype.compileNode = function(o) {
- var code, codes, node, top, _i, _len, _ref2;
- this.tab = o.indent;
- top = o.level === LEVEL_TOP;
- codes = [];
- _ref2 = this.expressions;
- for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
- node = _ref2[_i];
- node = node.unwrapAll();
- node = node.unfoldSoak(o) || node;
- if (node instanceof Block) {
- codes.push(node.compileNode(o));
- } else if (top) {
- node.front = true;
- code = node.compile(o);
- if (!node.isStatement(o)) {
- code = "" + this.tab + code + ";";
- if (node instanceof Literal) {
- code = "" + code + "\n";
- }
- }
- codes.push(code);
- } else {
- codes.push(node.compile(o, LEVEL_LIST));
- }
- }
- if (top) {
- if (this.spaced) {
- return "\n" + (codes.join('\n\n')) + "\n";
- } else {
- return codes.join('\n');
- }
- }
- code = codes.join(', ') || 'void 0';
- if (codes.length > 1 && o.level >= LEVEL_LIST) {
- return "(" + code + ")";
- } else {
- return code;
- }
- };
-
- Block.prototype.compileRoot = function(o) {
- var code, exp, i, prelude, preludeExps, rest;
- o.indent = o.bare ? '' : TAB;
- o.scope = new Scope(null, this, null);
- o.level = LEVEL_TOP;
- this.spaced = true;
- prelude = "";
- if (!o.bare) {
- preludeExps = (function() {
- var _i, _len, _ref2, _results;
- _ref2 = this.expressions;
- _results = [];
- for (i = _i = 0, _len = _ref2.length; _i < _len; i = ++_i) {
- exp = _ref2[i];
- if (!(exp.unwrap() instanceof Comment)) {
- break;
- }
- _results.push(exp);
- }
- return _results;
- }).call(this);
- rest = this.expressions.slice(preludeExps.length);
- this.expressions = preludeExps;
- if (preludeExps.length) {
- prelude = "" + (this.compileNode(merge(o, {
- indent: ''
- }))) + "\n";
- }
- this.expressions = rest;
- }
- code = this.compileWithDeclarations(o);
- if (o.bare) {
- return code;
- }
- return "" + prelude + "(function() {\n" + code + "\n}).call(this);\n";
- };
-
- Block.prototype.compileWithDeclarations = function(o) {
- var assigns, code, declars, exp, i, post, rest, scope, spaced, _i, _len, _ref2, _ref3, _ref4;
- code = post = '';
- _ref2 = this.expressions;
- for (i = _i = 0, _len = _ref2.length; _i < _len; i = ++_i) {
- exp = _ref2[i];
- exp = exp.unwrap();
- if (!(exp instanceof Comment || exp instanceof Literal)) {
- break;
- }
- }
- o = merge(o, {
- level: LEVEL_TOP
- });
- if (i) {
- rest = this.expressions.splice(i, 9e9);
- _ref3 = [this.spaced, false], spaced = _ref3[0], this.spaced = _ref3[1];
- _ref4 = [this.compileNode(o), spaced], code = _ref4[0], this.spaced = _ref4[1];
- this.expressions = rest;
- }
- post = this.compileNode(o);
- scope = o.scope;
- if (scope.expressions === this) {
- declars = o.scope.hasDeclarations();
- assigns = scope.hasAssignments;
- if (declars || assigns) {
- if (i) {
- code += '\n';
- }
- code += "" + this.tab + "var ";
- if (declars) {
- code += scope.declaredVariables().join(', ');
- }
- if (assigns) {
- if (declars) {
- code += ",\n" + (this.tab + TAB);
- }
- code += scope.assignedVariables().join(",\n" + (this.tab + TAB));
- }
- code += ';\n';
- }
- }
- return code + post;
- };
-
- Block.wrap = function(nodes) {
- if (nodes.length === 1 && nodes[0] instanceof Block) {
- return nodes[0];
- }
- return new Block(nodes);
- };
-
- return Block;
-
- })(Base);
-
- exports.Literal = Literal = (function(_super) {
-
- __extends(Literal, _super);
-
- function Literal(value) {
- this.value = value;
- }
-
- Literal.prototype.makeReturn = function() {
- if (this.isStatement()) {
- return this;
- } else {
- return Literal.__super__.makeReturn.apply(this, arguments);
- }
- };
-
- Literal.prototype.isAssignable = function() {
- return IDENTIFIER.test(this.value);
- };
-
- Literal.prototype.isStatement = function() {
- var _ref2;
- return (_ref2 = this.value) === 'break' || _ref2 === 'continue' || _ref2 === 'debugger';
- };
-
- Literal.prototype.isComplex = NO;
-
- Literal.prototype.assigns = function(name) {
- return name === this.value;
- };
-
- Literal.prototype.jumps = function(o) {
- if (this.value === 'break' && !((o != null ? o.loop : void 0) || (o != null ? o.block : void 0))) {
- return this;
- }
- if (this.value === 'continue' && !(o != null ? o.loop : void 0)) {
- return this;
- }
- };
-
- Literal.prototype.compileNode = function(o) {
- var code, _ref2;
- code = this.value === 'this' ? ((_ref2 = o.scope.method) != null ? _ref2.bound : void 0) ? o.scope.method.context : this.value : this.value.reserved ? "\"" + this.value + "\"" : this.value;
- if (this.isStatement()) {
- return "" + this.tab + code + ";";
- } else {
- return code;
- }
- };
-
- Literal.prototype.toString = function() {
- return ' "' + this.value + '"';
- };
-
- return Literal;
-
- })(Base);
-
- exports.Undefined = (function(_super) {
-
- __extends(Undefined, _super);
-
- function Undefined() {
- return Undefined.__super__.constructor.apply(this, arguments);
- }
-
- Undefined.prototype.isAssignable = NO;
-
- Undefined.prototype.isComplex = NO;
-
- Undefined.prototype.compileNode = function(o) {
- if (o.level >= LEVEL_ACCESS) {
- return '(void 0)';
- } else {
- return 'void 0';
- }
- };
-
- return Undefined;
-
- })(Base);
-
- exports.Null = (function(_super) {
-
- __extends(Null, _super);
-
- function Null() {
- return Null.__super__.constructor.apply(this, arguments);
- }
-
- Null.prototype.isAssignable = NO;
-
- Null.prototype.isComplex = NO;
-
- Null.prototype.compileNode = function() {
- return "null";
- };
-
- return Null;
-
- })(Base);
-
- exports.Bool = (function(_super) {
-
- __extends(Bool, _super);
-
- Bool.prototype.isAssignable = NO;
-
- Bool.prototype.isComplex = NO;
-
- Bool.prototype.compileNode = function() {
- return this.val;
- };
-
- function Bool(val) {
- this.val = val;
- }
-
- return Bool;
-
- })(Base);
-
- exports.Return = Return = (function(_super) {
-
- __extends(Return, _super);
-
- function Return(expr) {
- if (expr && !expr.unwrap().isUndefined) {
- this.expression = expr;
- }
- }
-
- Return.prototype.children = ['expression'];
-
- Return.prototype.isStatement = YES;
-
- Return.prototype.makeReturn = THIS;
-
- Return.prototype.jumps = THIS;
-
- Return.prototype.compile = function(o, level) {
- var expr, _ref2;
- expr = (_ref2 = this.expression) != null ? _ref2.makeReturn() : void 0;
- if (expr && !(expr instanceof Return)) {
- return expr.compile(o, level);
- } else {
- return Return.__super__.compile.call(this, o, level);
- }
- };
-
- Return.prototype.compileNode = function(o) {
- return this.tab + ("return" + [this.expression ? " " + (this.expression.compile(o, LEVEL_PAREN)) : void 0] + ";");
- };
-
- return Return;
-
- })(Base);
-
- exports.Value = Value = (function(_super) {
-
- __extends(Value, _super);
-
- function Value(base, props, tag) {
- if (!props && base instanceof Value) {
- return base;
- }
- this.base = base;
- this.properties = props || [];
- if (tag) {
- this[tag] = true;
- }
- return this;
- }
-
- Value.prototype.children = ['base', 'properties'];
-
- Value.prototype.add = function(props) {
- this.properties = this.properties.concat(props);
- return this;
- };
-
- Value.prototype.hasProperties = function() {
- return !!this.properties.length;
- };
-
- Value.prototype.isArray = function() {
- return !this.properties.length && this.base instanceof Arr;
- };
-
- Value.prototype.isComplex = function() {
- return this.hasProperties() || this.base.isComplex();
- };
-
- Value.prototype.isAssignable = function() {
- return this.hasProperties() || this.base.isAssignable();
- };
-
- Value.prototype.isSimpleNumber = function() {
- return this.base instanceof Literal && SIMPLENUM.test(this.base.value);
- };
-
- Value.prototype.isString = function() {
- return this.base instanceof Literal && IS_STRING.test(this.base.value);
- };
-
- Value.prototype.isAtomic = function() {
- var node, _i, _len, _ref2;
- _ref2 = this.properties.concat(this.base);
- for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
- node = _ref2[_i];
- if (node.soak || node instanceof Call) {
- return false;
- }
- }
- return true;
- };
-
- Value.prototype.isStatement = function(o) {
- return !this.properties.length && this.base.isStatement(o);
- };
-
- Value.prototype.assigns = function(name) {
- return !this.properties.length && this.base.assigns(name);
- };
-
- Value.prototype.jumps = function(o) {
- return !this.properties.length && this.base.jumps(o);
- };
-
- Value.prototype.isObject = function(onlyGenerated) {
- if (this.properties.length) {
- return false;
- }
- return (this.base instanceof Obj) && (!onlyGenerated || this.base.generated);
- };
-
- Value.prototype.isSplice = function() {
- return last(this.properties) instanceof Slice;
- };
-
- Value.prototype.unwrap = function() {
- if (this.properties.length) {
- return this;
- } else {
- return this.base;
- }
- };
-
- Value.prototype.cacheReference = function(o) {
- var base, bref, name, nref;
- name = last(this.properties);
- if (this.properties.length < 2 && !this.base.isComplex() && !(name != null ? name.isComplex() : void 0)) {
- return [this, this];
- }
- base = new Value(this.base, this.properties.slice(0, -1));
- if (base.isComplex()) {
- bref = new Literal(o.scope.freeVariable('base'));
- base = new Value(new Parens(new Assign(bref, base)));
- }
- if (!name) {
- return [base, bref];
- }
- if (name.isComplex()) {
- nref = new Literal(o.scope.freeVariable('name'));
- name = new Index(new Assign(nref, name.index));
- nref = new Index(nref);
- }
- return [base.add(name), new Value(bref || base.base, [nref || name])];
- };
-
- Value.prototype.compileNode = function(o) {
- var code, prop, props, _i, _len;
- this.base.front = this.front;
- props = this.properties;
- code = this.base.compile(o, props.length ? LEVEL_ACCESS : null);
- if ((this.base instanceof Parens || props.length) && SIMPLENUM.test(code)) {
- code = "" + code + ".";
- }
- for (_i = 0, _len = props.length; _i < _len; _i++) {
- prop = props[_i];
- code += prop.compile(o);
- }
- return code;
- };
-
- Value.prototype.unfoldSoak = function(o) {
- var result,
- _this = this;
- if (this.unfoldedSoak != null) {
- return this.unfoldedSoak;
- }
- result = (function() {
- var fst, i, ifn, prop, ref, snd, _i, _len, _ref2;
- if (ifn = _this.base.unfoldSoak(o)) {
- Array.prototype.push.apply(ifn.body.properties, _this.properties);
- return ifn;
- }
- _ref2 = _this.properties;
- for (i = _i = 0, _len = _ref2.length; _i < _len; i = ++_i) {
- prop = _ref2[i];
- if (!prop.soak) {
- continue;
- }
- prop.soak = false;
- fst = new Value(_this.base, _this.properties.slice(0, i));
- snd = new Value(_this.base, _this.properties.slice(i));
- if (fst.isComplex()) {
- ref = new Literal(o.scope.freeVariable('ref'));
- fst = new Parens(new Assign(ref, fst));
- snd.base = ref;
- }
- return new If(new Existence(fst), snd, {
- soak: true
- });
- }
- return null;
- })();
- return this.unfoldedSoak = result || false;
- };
-
- return Value;
-
- })(Base);
-
- exports.Comment = Comment = (function(_super) {
-
- __extends(Comment, _super);
-
- function Comment(comment) {
- this.comment = comment;
- }
-
- Comment.prototype.isStatement = YES;
-
- Comment.prototype.makeReturn = THIS;
-
- Comment.prototype.compileNode = function(o, level) {
- var code;
- code = '/*' + multident(this.comment, this.tab) + ("\n" + this.tab + "*/\n");
- if ((level || o.level) === LEVEL_TOP) {
- code = o.indent + code;
- }
- return code;
- };
-
- return Comment;
-
- })(Base);
-
- exports.Call = Call = (function(_super) {
-
- __extends(Call, _super);
-
- function Call(variable, args, soak) {
- this.args = args != null ? args : [];
- this.soak = soak;
- this.isNew = false;
- this.isSuper = variable === 'super';
- this.variable = this.isSuper ? null : variable;
- }
-
- Call.prototype.children = ['variable', 'args'];
-
- Call.prototype.newInstance = function() {
- var base, _ref2;
- base = ((_ref2 = this.variable) != null ? _ref2.base : void 0) || this.variable;
- if (base instanceof Call && !base.isNew) {
- base.newInstance();
- } else {
- this.isNew = true;
- }
- return this;
- };
-
- Call.prototype.superReference = function(o) {
- var accesses, method, name;
- method = o.scope.namedMethod();
- if (!method) {
- throw SyntaxError('cannot call super outside of a function.');
- }
- name = method.name;
- if (name == null) {
- throw SyntaxError('cannot call super on an anonymous function.');
- }
- if (method.klass) {
- accesses = [new Access(new Literal('__super__'))];
- if (method["static"]) {
- accesses.push(new Access(new Literal('constructor')));
- }
- accesses.push(new Access(new Literal(name)));
- return (new Value(new Literal(method.klass), accesses)).compile(o);
- } else {
- return "" + name + ".__super__.constructor";
- }
- };
-
- Call.prototype.superThis = function(o) {
- var method;
- method = o.scope.method;
- return (method && !method.klass && method.context) || "this";
- };
-
- Call.prototype.unfoldSoak = function(o) {
- var call, ifn, left, list, rite, _i, _len, _ref2, _ref3;
- if (this.soak) {
- if (this.variable) {
- if (ifn = unfoldSoak(o, this, 'variable')) {
- return ifn;
- }
- _ref2 = new Value(this.variable).cacheReference(o), left = _ref2[0], rite = _ref2[1];
- } else {
- left = new Literal(this.superReference(o));
- rite = new Value(left);
- }
- rite = new Call(rite, this.args);
- rite.isNew = this.isNew;
- left = new Literal("typeof " + (left.compile(o)) + " === \"function\"");
- return new If(left, new Value(rite), {
- soak: true
- });
- }
- call = this;
- list = [];
- while (true) {
- if (call.variable instanceof Call) {
- list.push(call);
- call = call.variable;
- continue;
- }
- if (!(call.variable instanceof Value)) {
- break;
- }
- list.push(call);
- if (!((call = call.variable.base) instanceof Call)) {
- break;
- }
- }
- _ref3 = list.reverse();
- for (_i = 0, _len = _ref3.length; _i < _len; _i++) {
- call = _ref3[_i];
- if (ifn) {
- if (call.variable instanceof Call) {
- call.variable = ifn;
- } else {
- call.variable.base = ifn;
- }
- }
- ifn = unfoldSoak(o, call, 'variable');
- }
- return ifn;
- };
-
- Call.prototype.filterImplicitObjects = function(list) {
- var node, nodes, obj, prop, properties, _i, _j, _len, _len1, _ref2;
- nodes = [];
- for (_i = 0, _len = list.length; _i < _len; _i++) {
- node = list[_i];
- if (!((typeof node.isObject === "function" ? node.isObject() : void 0) && node.base.generated)) {
- nodes.push(node);
- continue;
- }
- obj = null;
- _ref2 = node.base.properties;
- for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) {
- prop = _ref2[_j];
- if (prop instanceof Assign || prop instanceof Comment) {
- if (!obj) {
- nodes.push(obj = new Obj(properties = [], true));
- }
- properties.push(prop);
- } else {
- nodes.push(prop);
- obj = null;
- }
- }
- }
- return nodes;
- };
-
- Call.prototype.compileNode = function(o) {
- var arg, args, code, _ref2;
- if ((_ref2 = this.variable) != null) {
- _ref2.front = this.front;
- }
- if (code = Splat.compileSplattedArray(o, this.args, true)) {
- return this.compileSplat(o, code);
- }
- args = this.filterImplicitObjects(this.args);
- args = ((function() {
- var _i, _len, _results;
- _results = [];
- for (_i = 0, _len = args.length; _i < _len; _i++) {
- arg = args[_i];
- _results.push(arg.compile(o, LEVEL_LIST));
- }
- return _results;
- })()).join(', ');
- if (this.isSuper) {
- return this.superReference(o) + (".call(" + (this.superThis(o)) + (args && ', ' + args) + ")");
- } else {
- return (this.isNew ? 'new ' : '') + this.variable.compile(o, LEVEL_ACCESS) + ("(" + args + ")");
- }
- };
-
- Call.prototype.compileSuper = function(args, o) {
- return "" + (this.superReference(o)) + ".call(" + (this.superThis(o)) + (args.length ? ', ' : '') + args + ")";
- };
-
- Call.prototype.compileSplat = function(o, splatArgs) {
- var base, fun, idt, name, ref;
- if (this.isSuper) {
- return "" + (this.superReference(o)) + ".apply(" + (this.superThis(o)) + ", " + splatArgs + ")";
- }
- if (this.isNew) {
- idt = this.tab + TAB;
- return "(function(func, args, ctor) {\n" + idt + "ctor.prototype = func.prototype;\n" + idt + "var child = new ctor, result = func.apply(child, args), t = typeof result;\n" + idt + "return t == \"object\" || t == \"function\" ? result || child : child;\n" + this.tab + "})(" + (this.variable.compile(o, LEVEL_LIST)) + ", " + splatArgs + ", function(){})";
- }
- base = new Value(this.variable);
- if ((name = base.properties.pop()) && base.isComplex()) {
- ref = o.scope.freeVariable('ref');
- fun = "(" + ref + " = " + (base.compile(o, LEVEL_LIST)) + ")" + (name.compile(o));
- } else {
- fun = base.compile(o, LEVEL_ACCESS);
- if (SIMPLENUM.test(fun)) {
- fun = "(" + fun + ")";
- }
- if (name) {
- ref = fun;
- fun += name.compile(o);
- } else {
- ref = 'null';
- }
- }
- return "" + fun + ".apply(" + ref + ", " + splatArgs + ")";
- };
-
- return Call;
-
- })(Base);
-
- exports.Extends = Extends = (function(_super) {
-
- __extends(Extends, _super);
-
- function Extends(child, parent) {
- this.child = child;
- this.parent = parent;
- }
-
- Extends.prototype.children = ['child', 'parent'];
-
- Extends.prototype.compile = function(o) {
- return new Call(new Value(new Literal(utility('extends'))), [this.child, this.parent]).compile(o);
- };
-
- return Extends;
-
- })(Base);
-
- exports.Access = Access = (function(_super) {
-
- __extends(Access, _super);
-
- function Access(name, tag) {
- this.name = name;
- this.name.asKey = true;
- this.soak = tag === 'soak';
- }
-
- Access.prototype.children = ['name'];
-
- Access.prototype.compile = function(o) {
- var name;
- name = this.name.compile(o);
- if (IDENTIFIER.test(name)) {
- return "." + name;
- } else {
- return "[" + name + "]";
- }
- };
-
- Access.prototype.isComplex = NO;
-
- return Access;
-
- })(Base);
-
- exports.Index = Index = (function(_super) {
-
- __extends(Index, _super);
-
- function Index(index) {
- this.index = index;
- }
-
- Index.prototype.children = ['index'];
-
- Index.prototype.compile = function(o) {
- return "[" + (this.index.compile(o, LEVEL_PAREN)) + "]";
- };
-
- Index.prototype.isComplex = function() {
- return this.index.isComplex();
- };
-
- return Index;
-
- })(Base);
-
- exports.Range = Range = (function(_super) {
-
- __extends(Range, _super);
-
- Range.prototype.children = ['from', 'to'];
-
- function Range(from, to, tag) {
- this.from = from;
- this.to = to;
- this.exclusive = tag === 'exclusive';
- this.equals = this.exclusive ? '' : '=';
- }
-
- Range.prototype.compileVariables = function(o) {
- var step, _ref2, _ref3, _ref4, _ref5;
- o = merge(o, {
- top: true
- });
- _ref2 = this.from.cache(o, LEVEL_LIST), this.fromC = _ref2[0], this.fromVar = _ref2[1];
- _ref3 = this.to.cache(o, LEVEL_LIST), this.toC = _ref3[0], this.toVar = _ref3[1];
- if (step = del(o, 'step')) {
- _ref4 = step.cache(o, LEVEL_LIST), this.step = _ref4[0], this.stepVar = _ref4[1];
- }
- _ref5 = [this.fromVar.match(SIMPLENUM), this.toVar.match(SIMPLENUM)], this.fromNum = _ref5[0], this.toNum = _ref5[1];
- if (this.stepVar) {
- return this.stepNum = this.stepVar.match(SIMPLENUM);
- }
- };
-
- Range.prototype.compileNode = function(o) {
- var cond, condPart, from, gt, idx, idxName, known, lt, namedIndex, stepPart, to, varPart, _ref2, _ref3;
- if (!this.fromVar) {
- this.compileVariables(o);
- }
- if (!o.index) {
- return this.compileArray(o);
- }
- known = this.fromNum && this.toNum;
- idx = del(o, 'index');
- idxName = del(o, 'name');
- namedIndex = idxName && idxName !== idx;
- varPart = "" + idx + " = " + this.fromC;
- if (this.toC !== this.toVar) {
- varPart += ", " + this.toC;
- }
- if (this.step !== this.stepVar) {
- varPart += ", " + this.step;
- }
- _ref2 = ["" + idx + " <" + this.equals, "" + idx + " >" + this.equals], lt = _ref2[0], gt = _ref2[1];
- condPart = this.stepNum ? +this.stepNum > 0 ? "" + lt + " " + this.toVar : "" + gt + " " + this.toVar : known ? ((_ref3 = [+this.fromNum, +this.toNum], from = _ref3[0], to = _ref3[1], _ref3), from <= to ? "" + lt + " " + to : "" + gt + " " + to) : (cond = "" + this.fromVar + " <= " + this.toVar, "" + cond + " ? " + lt + " " + this.toVar + " : " + gt + " " + this.toVar);
- stepPart = this.stepVar ? "" + idx + " += " + this.stepVar : known ? namedIndex ? from <= to ? "++" + idx : "--" + idx : from <= to ? "" + idx + "++" : "" + idx + "--" : namedIndex ? "" + cond + " ? ++" + idx + " : --" + idx : "" + cond + " ? " + idx + "++ : " + idx + "--";
- if (namedIndex) {
- varPart = "" + idxName + " = " + varPart;
- }
- if (namedIndex) {
- stepPart = "" + idxName + " = " + stepPart;
- }
- return "" + varPart + "; " + condPart + "; " + stepPart;
- };
-
- Range.prototype.compileArray = function(o) {
- var args, body, cond, hasArgs, i, idt, post, pre, range, result, vars, _i, _ref2, _ref3, _results;
- if (this.fromNum && this.toNum && Math.abs(this.fromNum - this.toNum) <= 20) {
- range = (function() {
- _results = [];
- for (var _i = _ref2 = +this.fromNum, _ref3 = +this.toNum; _ref2 <= _ref3 ? _i <= _ref3 : _i >= _ref3; _ref2 <= _ref3 ? _i++ : _i--){ _results.push(_i); }
- return _results;
- }).apply(this);
- if (this.exclusive) {
- range.pop();
- }
- return "[" + (range.join(', ')) + "]";
- }
- idt = this.tab + TAB;
- i = o.scope.freeVariable('i');
- result = o.scope.freeVariable('results');
- pre = "\n" + idt + result + " = [];";
- if (this.fromNum && this.toNum) {
- o.index = i;
- body = this.compileNode(o);
- } else {
- vars = ("" + i + " = " + this.fromC) + (this.toC !== this.toVar ? ", " + this.toC : '');
- cond = "" + this.fromVar + " <= " + this.toVar;
- body = "var " + vars + "; " + cond + " ? " + i + " <" + this.equals + " " + this.toVar + " : " + i + " >" + this.equals + " " + this.toVar + "; " + cond + " ? " + i + "++ : " + i + "--";
- }
- post = "{ " + result + ".push(" + i + "); }\n" + idt + "return " + result + ";\n" + o.indent;
- hasArgs = function(node) {
- return node != null ? node.contains(function(n) {
- return n instanceof Literal && n.value === 'arguments' && !n.asKey;
- }) : void 0;
- };
- if (hasArgs(this.from) || hasArgs(this.to)) {
- args = ', arguments';
- }
- return "(function() {" + pre + "\n" + idt + "for (" + body + ")" + post + "}).apply(this" + (args != null ? args : '') + ")";
- };
-
- return Range;
-
- })(Base);
-
- exports.Slice = Slice = (function(_super) {
-
- __extends(Slice, _super);
-
- Slice.prototype.children = ['range'];
-
- function Slice(range) {
- this.range = range;
- Slice.__super__.constructor.call(this);
- }
-
- Slice.prototype.compileNode = function(o) {
- var compiled, from, fromStr, to, toStr, _ref2;
- _ref2 = this.range, to = _ref2.to, from = _ref2.from;
- fromStr = from && from.compile(o, LEVEL_PAREN) || '0';
- compiled = to && to.compile(o, LEVEL_PAREN);
- if (to && !(!this.range.exclusive && +compiled === -1)) {
- toStr = ', ' + (this.range.exclusive ? compiled : SIMPLENUM.test(compiled) ? "" + (+compiled + 1) : (compiled = to.compile(o, LEVEL_ACCESS), "" + compiled + " + 1 || 9e9"));
- }
- return ".slice(" + fromStr + (toStr || '') + ")";
- };
-
- return Slice;
-
- })(Base);
-
- exports.Obj = Obj = (function(_super) {
-
- __extends(Obj, _super);
-
- function Obj(props, generated) {
- this.generated = generated != null ? generated : false;
- this.objects = this.properties = props || [];
- }
-
- Obj.prototype.children = ['properties'];
-
- Obj.prototype.compileNode = function(o) {
- var i, idt, indent, join, lastNoncom, node, obj, prop, propName, propNames, props, _i, _j, _len, _len1, _ref2;
- props = this.properties;
- propNames = [];
- _ref2 = this.properties;
- for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
- prop = _ref2[_i];
- if (prop.isComplex()) {
- prop = prop.variable;
- }
- if (prop != null) {
- propName = prop.unwrapAll().value.toString();
- if (__indexOf.call(propNames, propName) >= 0) {
- throw SyntaxError("multiple object literal properties named \"" + propName + "\"");
- }
- propNames.push(propName);
- }
- }
- if (!props.length) {
- return (this.front ? '({})' : '{}');
- }
- if (this.generated) {
- for (_j = 0, _len1 = props.length; _j < _len1; _j++) {
- node = props[_j];
- if (node instanceof Value) {
- throw new Error('cannot have an implicit value in an implicit object');
- }
- }
- }
- idt = o.indent += TAB;
- lastNoncom = this.lastNonComment(this.properties);
- props = (function() {
- var _k, _len2, _results;
- _results = [];
- for (i = _k = 0, _len2 = props.length; _k < _len2; i = ++_k) {
- prop = props[i];
- join = i === props.length - 1 ? '' : prop === lastNoncom || prop instanceof Comment ? '\n' : ',\n';
- indent = prop instanceof Comment ? '' : idt;
- if (prop instanceof Value && prop["this"]) {
- prop = new Assign(prop.properties[0].name, prop, 'object');
- }
- if (!(prop instanceof Comment)) {
- if (!(prop instanceof Assign)) {
- prop = new Assign(prop, prop, 'object');
- }
- (prop.variable.base || prop.variable).asKey = true;
- }
- _results.push(indent + prop.compile(o, LEVEL_TOP) + join);
- }
- return _results;
- })();
- props = props.join('');
- obj = "{" + (props && '\n' + props + '\n' + this.tab) + "}";
- if (this.front) {
- return "(" + obj + ")";
- } else {
- return obj;
- }
- };
-
- Obj.prototype.assigns = function(name) {
- var prop, _i, _len, _ref2;
- _ref2 = this.properties;
- for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
- prop = _ref2[_i];
- if (prop.assigns(name)) {
- return true;
- }
- }
- return false;
- };
-
- return Obj;
-
- })(Base);
-
- exports.Arr = Arr = (function(_super) {
-
- __extends(Arr, _super);
-
- function Arr(objs) {
- this.objects = objs || [];
- }
-
- Arr.prototype.children = ['objects'];
-
- Arr.prototype.filterImplicitObjects = Call.prototype.filterImplicitObjects;
-
- Arr.prototype.compileNode = function(o) {
- var code, obj, objs;
- if (!this.objects.length) {
- return '[]';
- }
- o.indent += TAB;
- objs = this.filterImplicitObjects(this.objects);
- if (code = Splat.compileSplattedArray(o, objs)) {
- return code;
- }
- code = ((function() {
- var _i, _len, _results;
- _results = [];
- for (_i = 0, _len = objs.length; _i < _len; _i++) {
- obj = objs[_i];
- _results.push(obj.compile(o, LEVEL_LIST));
- }
- return _results;
- })()).join(', ');
- if (code.indexOf('\n') >= 0) {
- return "[\n" + o.indent + code + "\n" + this.tab + "]";
- } else {
- return "[" + code + "]";
- }
- };
-
- Arr.prototype.assigns = function(name) {
- var obj, _i, _len, _ref2;
- _ref2 = this.objects;
- for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
- obj = _ref2[_i];
- if (obj.assigns(name)) {
- return true;
- }
- }
- return false;
- };
-
- return Arr;
-
- })(Base);
-
- exports.Class = Class = (function(_super) {
-
- __extends(Class, _super);
-
- function Class(variable, parent, body) {
- this.variable = variable;
- this.parent = parent;
- this.body = body != null ? body : new Block;
- this.boundFuncs = [];
- this.body.classBody = true;
- }
-
- Class.prototype.children = ['variable', 'parent', 'body'];
-
- Class.prototype.determineName = function() {
- var decl, tail;
- if (!this.variable) {
- return null;
- }
- decl = (tail = last(this.variable.properties)) ? tail instanceof Access && tail.name.value : this.variable.base.value;
- if (__indexOf.call(STRICT_PROSCRIBED, decl) >= 0) {
- throw SyntaxError("variable name may not be " + decl);
- }
- return decl && (decl = IDENTIFIER.test(decl) && decl);
- };
-
- Class.prototype.setContext = function(name) {
- return this.body.traverseChildren(false, function(node) {
- if (node.classBody) {
- return false;
- }
- if (node instanceof Literal && node.value === 'this') {
- return node.value = name;
- } else if (node instanceof Code) {
- node.klass = name;
- if (node.bound) {
- return node.context = name;
- }
- }
- });
- };
-
- Class.prototype.addBoundFunctions = function(o) {
- var bvar, lhs, _i, _len, _ref2, _results;
- if (this.boundFuncs.length) {
- _ref2 = this.boundFuncs;
- _results = [];
- for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
- bvar = _ref2[_i];
- lhs = (new Value(new Literal("this"), [new Access(bvar)])).compile(o);
- _results.push(this.ctor.body.unshift(new Literal("" + lhs + " = " + (utility('bind')) + "(" + lhs + ", this)")));
- }
- return _results;
- }
- };
-
- Class.prototype.addProperties = function(node, name, o) {
- var assign, base, exprs, func, props;
- props = node.base.properties.slice(0);
- exprs = (function() {
- var _results;
- _results = [];
- while (assign = props.shift()) {
- if (assign instanceof Assign) {
- base = assign.variable.base;
- delete assign.context;
- func = assign.value;
- if (base.value === 'constructor') {
- if (this.ctor) {
- throw new Error('cannot define more than one constructor in a class');
- }
- if (func.bound) {
- throw new Error('cannot define a constructor as a bound function');
- }
- if (func instanceof Code) {
- assign = this.ctor = func;
- } else {
- this.externalCtor = o.scope.freeVariable('class');
- assign = new Assign(new Literal(this.externalCtor), func);
- }
- } else {
- if (assign.variable["this"]) {
- func["static"] = true;
- if (func.bound) {
- func.context = name;
- }
- } else {
- assign.variable = new Value(new Literal(name), [new Access(new Literal('prototype')), new Access(base)]);
- if (func instanceof Code && func.bound) {
- this.boundFuncs.push(base);
- func.bound = false;
- }
- }
- }
- }
- _results.push(assign);
- }
- return _results;
- }).call(this);
- return compact(exprs);
- };
-
- Class.prototype.walkBody = function(name, o) {
- var _this = this;
- return this.traverseChildren(false, function(child) {
- var exps, i, node, _i, _len, _ref2;
- if (child instanceof Class) {
- return false;
- }
- if (child instanceof Block) {
- _ref2 = exps = child.expressions;
- for (i = _i = 0, _len = _ref2.length; _i < _len; i = ++_i) {
- node = _ref2[i];
- if (node instanceof Value && node.isObject(true)) {
- exps[i] = _this.addProperties(node, name, o);
- }
- }
- return child.expressions = exps = flatten(exps);
- }
- });
- };
-
- Class.prototype.hoistDirectivePrologue = function() {
- var expressions, index, node;
- index = 0;
- expressions = this.body.expressions;
- while ((node = expressions[index]) && node instanceof Comment || node instanceof Value && node.isString()) {
- ++index;
- }
- return this.directives = expressions.splice(0, index);
- };
-
- Class.prototype.ensureConstructor = function(name) {
- if (!this.ctor) {
- this.ctor = new Code;
- if (this.parent) {
- this.ctor.body.push(new Literal("" + name + ".__super__.constructor.apply(this, arguments)"));
- }
- if (this.externalCtor) {
- this.ctor.body.push(new Literal("" + this.externalCtor + ".apply(this, arguments)"));
- }
- this.ctor.body.makeReturn();
- this.body.expressions.unshift(this.ctor);
- }
- this.ctor.ctor = this.ctor.name = name;
- this.ctor.klass = null;
- return this.ctor.noReturn = true;
- };
-
- Class.prototype.compileNode = function(o) {
- var call, decl, klass, lname, name, params, _ref2;
- decl = this.determineName();
- name = decl || '_Class';
- if (name.reserved) {
- name = "_" + name;
- }
- lname = new Literal(name);
- this.hoistDirectivePrologue();
- this.setContext(name);
- this.walkBody(name, o);
- this.ensureConstructor(name);
- this.body.spaced = true;
- if (!(this.ctor instanceof Code)) {
- this.body.expressions.unshift(this.ctor);
- }
- this.body.expressions.push(lname);
- (_ref2 = this.body.expressions).unshift.apply(_ref2, this.directives);
- this.addBoundFunctions(o);
- call = Closure.wrap(this.body);
- if (this.parent) {
- this.superClass = new Literal(o.scope.freeVariable('super', false));
- this.body.expressions.unshift(new Extends(lname, this.superClass));
- call.args.push(this.parent);
- params = call.variable.params || call.variable.base.params;
- params.push(new Param(this.superClass));
- }
- klass = new Parens(call, true);
- if (this.variable) {
- klass = new Assign(this.variable, klass);
- }
- return klass.compile(o);
- };
-
- return Class;
-
- })(Base);
-
- exports.Assign = Assign = (function(_super) {
-
- __extends(Assign, _super);
-
- function Assign(variable, value, context, options) {
- var forbidden, name, _ref2;
- this.variable = variable;
- this.value = value;
- this.context = context;
- this.param = options && options.param;
- this.subpattern = options && options.subpattern;
- forbidden = (_ref2 = (name = this.variable.unwrapAll().value), __indexOf.call(STRICT_PROSCRIBED, _ref2) >= 0);
- if (forbidden && this.context !== 'object') {
- throw SyntaxError("variable name may not be \"" + name + "\"");
- }
- }
-
- Assign.prototype.children = ['variable', 'value'];
-
- Assign.prototype.isStatement = function(o) {
- return (o != null ? o.level : void 0) === LEVEL_TOP && (this.context != null) && __indexOf.call(this.context, "?") >= 0;
- };
-
- Assign.prototype.assigns = function(name) {
- return this[this.context === 'object' ? 'value' : 'variable'].assigns(name);
- };
-
- Assign.prototype.unfoldSoak = function(o) {
- return unfoldSoak(o, this, 'variable');
- };
-
- Assign.prototype.compileNode = function(o) {
- var isValue, match, name, val, varBase, _ref2, _ref3, _ref4, _ref5;
- if (isValue = this.variable instanceof Value) {
- if (this.variable.isArray() || this.variable.isObject()) {
- return this.compilePatternMatch(o);
- }
- if (this.variable.isSplice()) {
- return this.compileSplice(o);
- }
- if ((_ref2 = this.context) === '||=' || _ref2 === '&&=' || _ref2 === '?=') {
- return this.compileConditional(o);
- }
- }
- name = this.variable.compile(o, LEVEL_LIST);
- if (!this.context) {
- if (!(varBase = this.variable.unwrapAll()).isAssignable()) {
- throw SyntaxError("\"" + (this.variable.compile(o)) + "\" cannot be assigned.");
- }
- if (!(typeof varBase.hasProperties === "function" ? varBase.hasProperties() : void 0)) {
- if (this.param) {
- o.scope.add(name, 'var');
- } else {
- o.scope.find(name);
- }
- }
- }
- if (this.value instanceof Code && (match = METHOD_DEF.exec(name))) {
- if (match[1]) {
- this.value.klass = match[1];
- }
- this.value.name = (_ref3 = (_ref4 = (_ref5 = match[2]) != null ? _ref5 : match[3]) != null ? _ref4 : match[4]) != null ? _ref3 : match[5];
- }
- val = this.value.compile(o, LEVEL_LIST);
- if (this.context === 'object') {
- return "" + name + ": " + val;
- }
- val = name + (" " + (this.context || '=') + " ") + val;
- if (o.level <= LEVEL_LIST) {
- return val;
- } else {
- return "(" + val + ")";
- }
- };
-
- Assign.prototype.compilePatternMatch = function(o) {
- var acc, assigns, code, i, idx, isObject, ivar, name, obj, objects, olen, ref, rest, splat, top, val, value, vvar, _i, _len, _ref2, _ref3, _ref4, _ref5, _ref6, _ref7, _ref8;
- top = o.level === LEVEL_TOP;
- value = this.value;
- objects = this.variable.base.objects;
- if (!(olen = objects.length)) {
- code = value.compile(o);
- if (o.level >= LEVEL_OP) {
- return "(" + code + ")";
- } else {
- return code;
- }
- }
- isObject = this.variable.isObject();
- if (top && olen === 1 && !((obj = objects[0]) instanceof Splat)) {
- if (obj instanceof Assign) {
- _ref2 = obj, (_ref3 = _ref2.variable, idx = _ref3.base), obj = _ref2.value;
- } else {
- if (obj.base instanceof Parens) {
- _ref4 = new Value(obj.unwrapAll()).cacheReference(o), obj = _ref4[0], idx = _ref4[1];
- } else {
- idx = isObject ? obj["this"] ? obj.properties[0].name : obj : new Literal(0);
- }
- }
- acc = IDENTIFIER.test(idx.unwrap().value || 0);
- value = new Value(value);
- value.properties.push(new (acc ? Access : Index)(idx));
- if (_ref5 = obj.unwrap().value, __indexOf.call(RESERVED, _ref5) >= 0) {
- throw new SyntaxError("assignment to a reserved word: " + (obj.compile(o)) + " = " + (value.compile(o)));
- }
- return new Assign(obj, value, null, {
- param: this.param
- }).compile(o, LEVEL_TOP);
- }
- vvar = value.compile(o, LEVEL_LIST);
- assigns = [];
- splat = false;
- if (!IDENTIFIER.test(vvar) || this.variable.assigns(vvar)) {
- assigns.push("" + (ref = o.scope.freeVariable('ref')) + " = " + vvar);
- vvar = ref;
- }
- for (i = _i = 0, _len = objects.length; _i < _len; i = ++_i) {
- obj = objects[i];
- idx = i;
- if (isObject) {
- if (obj instanceof Assign) {
- _ref6 = obj, (_ref7 = _ref6.variable, idx = _ref7.base), obj = _ref6.value;
- } else {
- if (obj.base instanceof Parens) {
- _ref8 = new Value(obj.unwrapAll()).cacheReference(o), obj = _ref8[0], idx = _ref8[1];
- } else {
- idx = obj["this"] ? obj.properties[0].name : obj;
- }
- }
- }
- if (!splat && obj instanceof Splat) {
- name = obj.name.unwrap().value;
- obj = obj.unwrap();
- val = "" + olen + " <= " + vvar + ".length ? " + (utility('slice')) + ".call(" + vvar + ", " + i;
- if (rest = olen - i - 1) {
- ivar = o.scope.freeVariable('i');
- val += ", " + ivar + " = " + vvar + ".length - " + rest + ") : (" + ivar + " = " + i + ", [])";
- } else {
- val += ") : []";
- }
- val = new Literal(val);
- splat = "" + ivar + "++";
- } else {
- name = obj.unwrap().value;
- if (obj instanceof Splat) {
- obj = obj.name.compile(o);
- throw new SyntaxError("multiple splats are disallowed in an assignment: " + obj + "...");
- }
- if (typeof idx === 'number') {
- idx = new Literal(splat || idx);
- acc = false;
- } else {
- acc = isObject && IDENTIFIER.test(idx.unwrap().value || 0);
- }
- val = new Value(new Literal(vvar), [new (acc ? Access : Index)(idx)]);
- }
- if ((name != null) && __indexOf.call(RESERVED, name) >= 0) {
- throw new SyntaxError("assignment to a reserved word: " + (obj.compile(o)) + " = " + (val.compile(o)));
- }
- assigns.push(new Assign(obj, val, null, {
- param: this.param,
- subpattern: true
- }).compile(o, LEVEL_LIST));
- }
- if (!(top || this.subpattern)) {
- assigns.push(vvar);
- }
- code = assigns.join(', ');
- if (o.level < LEVEL_LIST) {
- return code;
- } else {
- return "(" + code + ")";
- }
- };
-
- Assign.prototype.compileConditional = function(o) {
- var left, right, _ref2;
- _ref2 = this.variable.cacheReference(o), left = _ref2[0], right = _ref2[1];
- if (!left.properties.length && left.base instanceof Literal && left.base.value !== "this" && !o.scope.check(left.base.value)) {
- throw new Error("the variable \"" + left.base.value + "\" can't be assigned with " + this.context + " because it has not been defined.");
- }
- if (__indexOf.call(this.context, "?") >= 0) {
- o.isExistentialEquals = true;
- }
- return new Op(this.context.slice(0, -1), left, new Assign(right, this.value, '=')).compile(o);
- };
-
- Assign.prototype.compileSplice = function(o) {
- var code, exclusive, from, fromDecl, fromRef, name, to, valDef, valRef, _ref2, _ref3, _ref4;
- _ref2 = this.variable.properties.pop().range, from = _ref2.from, to = _ref2.to, exclusive = _ref2.exclusive;
- name = this.variable.compile(o);
- _ref3 = (from != null ? from.cache(o, LEVEL_OP) : void 0) || ['0', '0'], fromDecl = _ref3[0], fromRef = _ref3[1];
- if (to) {
- if ((from != null ? from.isSimpleNumber() : void 0) && to.isSimpleNumber()) {
- to = +to.compile(o) - +fromRef;
- if (!exclusive) {
- to += 1;
- }
- } else {
- to = to.compile(o, LEVEL_ACCESS) + ' - ' + fromRef;
- if (!exclusive) {
- to += ' + 1';
- }
- }
- } else {
- to = "9e9";
- }
- _ref4 = this.value.cache(o, LEVEL_LIST), valDef = _ref4[0], valRef = _ref4[1];
- code = "[].splice.apply(" + name + ", [" + fromDecl + ", " + to + "].concat(" + valDef + ")), " + valRef;
- if (o.level > LEVEL_TOP) {
- return "(" + code + ")";
- } else {
- return code;
- }
- };
-
- return Assign;
-
- })(Base);
-
- exports.Code = Code = (function(_super) {
-
- __extends(Code, _super);
-
- function Code(params, body, tag) {
- this.params = params || [];
- this.body = body || new Block;
- this.bound = tag === 'boundfunc';
- if (this.bound) {
- this.context = '_this';
- }
- }
-
- Code.prototype.children = ['params', 'body'];
-
- Code.prototype.isStatement = function() {
- return !!this.ctor;
- };
-
- Code.prototype.jumps = NO;
-
- Code.prototype.compileNode = function(o) {
- var code, exprs, i, idt, lit, name, p, param, params, ref, splats, uniqs, val, wasEmpty, _i, _j, _k, _l, _len, _len1, _len2, _len3, _len4, _len5, _m, _n, _ref2, _ref3, _ref4, _ref5, _ref6, _ref7, _ref8;
- o.scope = new Scope(o.scope, this.body, this);
- o.scope.shared = del(o, 'sharedScope');
- o.indent += TAB;
- delete o.bare;
- delete o.isExistentialEquals;
- params = [];
- exprs = [];
- _ref2 = this.paramNames();
- for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
- name = _ref2[_i];
- if (!o.scope.check(name)) {
- o.scope.parameter(name);
- }
- }
- _ref3 = this.params;
- for (_j = 0, _len1 = _ref3.length; _j < _len1; _j++) {
- param = _ref3[_j];
- if (!param.splat) {
- continue;
- }
- _ref4 = this.params;
- for (_k = 0, _len2 = _ref4.length; _k < _len2; _k++) {
- p = _ref4[_k].name;
- if (p["this"]) {
- p = p.properties[0].name;
- }
- if (p.value) {
- o.scope.add(p.value, 'var', true);
- }
- }
- splats = new Assign(new Value(new Arr((function() {
- var _l, _len3, _ref5, _results;
- _ref5 = this.params;
- _results = [];
- for (_l = 0, _len3 = _ref5.length; _l < _len3; _l++) {
- p = _ref5[_l];
- _results.push(p.asReference(o));
- }
- return _results;
- }).call(this))), new Value(new Literal('arguments')));
- break;
- }
- _ref5 = this.params;
- for (_l = 0, _len3 = _ref5.length; _l < _len3; _l++) {
- param = _ref5[_l];
- if (param.isComplex()) {
- val = ref = param.asReference(o);
- if (param.value) {
- val = new Op('?', ref, param.value);
- }
- exprs.push(new Assign(new Value(param.name), val, '=', {
- param: true
- }));
- } else {
- ref = param;
- if (param.value) {
- lit = new Literal(ref.name.value + ' == null');
- val = new Assign(new Value(param.name), param.value, '=');
- exprs.push(new If(lit, val));
- }
- }
- if (!splats) {
- params.push(ref);
- }
- }
- wasEmpty = this.body.isEmpty();
- if (splats) {
- exprs.unshift(splats);
- }
- if (exprs.length) {
- (_ref6 = this.body.expressions).unshift.apply(_ref6, exprs);
- }
- for (i = _m = 0, _len4 = params.length; _m < _len4; i = ++_m) {
- p = params[i];
- o.scope.parameter(params[i] = p.compile(o));
- }
- uniqs = [];
- _ref7 = this.paramNames();
- for (_n = 0, _len5 = _ref7.length; _n < _len5; _n++) {
- name = _ref7[_n];
- if (__indexOf.call(uniqs, name) >= 0) {
- throw SyntaxError("multiple parameters named '" + name + "'");
- }
- uniqs.push(name);
- }
- if (!(wasEmpty || this.noReturn)) {
- this.body.makeReturn();
- }
- if (this.bound) {
- if ((_ref8 = o.scope.parent.method) != null ? _ref8.bound : void 0) {
- this.bound = this.context = o.scope.parent.method.context;
- } else if (!this["static"]) {
- o.scope.parent.assign('_this', 'this');
- }
- }
- idt = o.indent;
- code = 'function';
- if (this.ctor) {
- code += ' ' + this.name;
- }
- code += '(' + params.join(', ') + ') {';
- if (!this.body.isEmpty()) {
- code += "\n" + (this.body.compileWithDeclarations(o)) + "\n" + this.tab;
- }
- code += '}';
- if (this.ctor) {
- return this.tab + code;
- }
- if (this.front || (o.level >= LEVEL_ACCESS)) {
- return "(" + code + ")";
- } else {
- return code;
- }
- };
-
- Code.prototype.paramNames = function() {
- var names, param, _i, _len, _ref2;
- names = [];
- _ref2 = this.params;
- for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
- param = _ref2[_i];
- names.push.apply(names, param.names());
- }
- return names;
- };
-
- Code.prototype.traverseChildren = function(crossScope, func) {
- if (crossScope) {
- return Code.__super__.traverseChildren.call(this, crossScope, func);
- }
- };
-
- return Code;
-
- })(Base);
-
- exports.Param = Param = (function(_super) {
-
- __extends(Param, _super);
-
- function Param(name, value, splat) {
- var _ref2;
- this.name = name;
- this.value = value;
- this.splat = splat;
- if (_ref2 = (name = this.name.unwrapAll().value), __indexOf.call(STRICT_PROSCRIBED, _ref2) >= 0) {
- throw SyntaxError("parameter name \"" + name + "\" is not allowed");
- }
- }
-
- Param.prototype.children = ['name', 'value'];
-
- Param.prototype.compile = function(o) {
- return this.name.compile(o, LEVEL_LIST);
- };
-
- Param.prototype.asReference = function(o) {
- var node;
- if (this.reference) {
- return this.reference;
- }
- node = this.name;
- if (node["this"]) {
- node = node.properties[0].name;
- if (node.value.reserved) {
- node = new Literal(o.scope.freeVariable(node.value));
- }
- } else if (node.isComplex()) {
- node = new Literal(o.scope.freeVariable('arg'));
- }
- node = new Value(node);
- if (this.splat) {
- node = new Splat(node);
- }
- return this.reference = node;
- };
-
- Param.prototype.isComplex = function() {
- return this.name.isComplex();
- };
-
- Param.prototype.names = function(name) {
- var atParam, names, obj, _i, _len, _ref2;
- if (name == null) {
- name = this.name;
- }
- atParam = function(obj) {
- var value;
- value = obj.properties[0].name.value;
- if (value.reserved) {
- return [];
- } else {
- return [value];
- }
- };
- if (name instanceof Literal) {
- return [name.value];
- }
- if (name instanceof Value) {
- return atParam(name);
- }
- names = [];
- _ref2 = name.objects;
- for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
- obj = _ref2[_i];
- if (obj instanceof Assign) {
- names.push(obj.value.unwrap().value);
- } else if (obj instanceof Splat) {
- names.push(obj.name.unwrap().value);
- } else if (obj instanceof Value) {
- if (obj.isArray() || obj.isObject()) {
- names.push.apply(names, this.names(obj.base));
- } else if (obj["this"]) {
- names.push.apply(names, atParam(obj));
- } else {
- names.push(obj.base.value);
- }
- } else {
- throw SyntaxError("illegal parameter " + (obj.compile()));
- }
- }
- return names;
- };
-
- return Param;
-
- })(Base);
-
- exports.Splat = Splat = (function(_super) {
-
- __extends(Splat, _super);
-
- Splat.prototype.children = ['name'];
-
- Splat.prototype.isAssignable = YES;
-
- function Splat(name) {
- this.name = name.compile ? name : new Literal(name);
- }
-
- Splat.prototype.assigns = function(name) {
- return this.name.assigns(name);
- };
-
- Splat.prototype.compile = function(o) {
- if (this.index != null) {
- return this.compileParam(o);
- } else {
- return this.name.compile(o);
- }
- };
-
- Splat.prototype.unwrap = function() {
- return this.name;
- };
-
- Splat.compileSplattedArray = function(o, list, apply) {
- var args, base, code, i, index, node, _i, _len;
- index = -1;
- while ((node = list[++index]) && !(node instanceof Splat)) {
- continue;
- }
- if (index >= list.length) {
- return '';
- }
- if (list.length === 1) {
- code = list[0].compile(o, LEVEL_LIST);
- if (apply) {
- return code;
- }
- return "" + (utility('slice')) + ".call(" + code + ")";
- }
- args = list.slice(index);
- for (i = _i = 0, _len = args.length; _i < _len; i = ++_i) {
- node = args[i];
- code = node.compile(o, LEVEL_LIST);
- args[i] = node instanceof Splat ? "" + (utility('slice')) + ".call(" + code + ")" : "[" + code + "]";
- }
- if (index === 0) {
- return args[0] + (".concat(" + (args.slice(1).join(', ')) + ")");
- }
- base = (function() {
- var _j, _len1, _ref2, _results;
- _ref2 = list.slice(0, index);
- _results = [];
- for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) {
- node = _ref2[_j];
- _results.push(node.compile(o, LEVEL_LIST));
- }
- return _results;
- })();
- return "[" + (base.join(', ')) + "].concat(" + (args.join(', ')) + ")";
- };
-
- return Splat;
-
- })(Base);
-
- exports.While = While = (function(_super) {
-
- __extends(While, _super);
-
- function While(condition, options) {
- this.condition = (options != null ? options.invert : void 0) ? condition.invert() : condition;
- this.guard = options != null ? options.guard : void 0;
- }
-
- While.prototype.children = ['condition', 'guard', 'body'];
-
- While.prototype.isStatement = YES;
-
- While.prototype.makeReturn = function(res) {
- if (res) {
- return While.__super__.makeReturn.apply(this, arguments);
- } else {
- this.returns = !this.jumps({
- loop: true
- });
- return this;
- }
- };
-
- While.prototype.addBody = function(body) {
- this.body = body;
- return this;
- };
-
- While.prototype.jumps = function() {
- var expressions, node, _i, _len;
- expressions = this.body.expressions;
- if (!expressions.length) {
- return false;
- }
- for (_i = 0, _len = expressions.length; _i < _len; _i++) {
- node = expressions[_i];
- if (node.jumps({
- loop: true
- })) {
- return node;
- }
- }
- return false;
- };
-
- While.prototype.compileNode = function(o) {
- var body, code, rvar, set;
- o.indent += TAB;
- set = '';
- body = this.body;
- if (body.isEmpty()) {
- body = '';
- } else {
- if (this.returns) {
- body.makeReturn(rvar = o.scope.freeVariable('results'));
- set = "" + this.tab + rvar + " = [];\n";
- }
- if (this.guard) {
- if (body.expressions.length > 1) {
- body.expressions.unshift(new If((new Parens(this.guard)).invert(), new Literal("continue")));
- } else {
- if (this.guard) {
- body = Block.wrap([new If(this.guard, body)]);
- }
- }
- }
- body = "\n" + (body.compile(o, LEVEL_TOP)) + "\n" + this.tab;
- }
- code = set + this.tab + ("while (" + (this.condition.compile(o, LEVEL_PAREN)) + ") {" + body + "}");
- if (this.returns) {
- code += "\n" + this.tab + "return " + rvar + ";";
- }
- return code;
- };
-
- return While;
-
- })(Base);
-
- exports.Op = Op = (function(_super) {
- var CONVERSIONS, INVERSIONS;
-
- __extends(Op, _super);
-
- function Op(op, first, second, flip) {
- if (op === 'in') {
- return new In(first, second);
- }
- if (op === 'do') {
- return this.generateDo(first);
- }
- if (op === 'new') {
- if (first instanceof Call && !first["do"] && !first.isNew) {
- return first.newInstance();
- }
- if (first instanceof Code && first.bound || first["do"]) {
- first = new Parens(first);
- }
- }
- this.operator = CONVERSIONS[op] || op;
- this.first = first;
- this.second = second;
- this.flip = !!flip;
- return this;
- }
-
- CONVERSIONS = {
- '==': '===',
- '!=': '!==',
- 'of': 'in'
- };
-
- INVERSIONS = {
- '!==': '===',
- '===': '!=='
- };
-
- Op.prototype.children = ['first', 'second'];
-
- Op.prototype.isSimpleNumber = NO;
-
- Op.prototype.isUnary = function() {
- return !this.second;
- };
-
- Op.prototype.isComplex = function() {
- var _ref2;
- return !(this.isUnary() && ((_ref2 = this.operator) === '+' || _ref2 === '-')) || this.first.isComplex();
- };
-
- Op.prototype.isChainable = function() {
- var _ref2;
- return (_ref2 = this.operator) === '<' || _ref2 === '>' || _ref2 === '>=' || _ref2 === '<=' || _ref2 === '===' || _ref2 === '!==';
- };
-
- Op.prototype.invert = function() {
- var allInvertable, curr, fst, op, _ref2;
- if (this.isChainable() && this.first.isChainable()) {
- allInvertable = true;
- curr = this;
- while (curr && curr.operator) {
- allInvertable && (allInvertable = curr.operator in INVERSIONS);
- curr = curr.first;
- }
- if (!allInvertable) {
- return new Parens(this).invert();
- }
- curr = this;
- while (curr && curr.operator) {
- curr.invert = !curr.invert;
- curr.operator = INVERSIONS[curr.operator];
- curr = curr.first;
- }
- return this;
- } else if (op = INVERSIONS[this.operator]) {
- this.operator = op;
- if (this.first.unwrap() instanceof Op) {
- this.first.invert();
- }
- return this;
- } else if (this.second) {
- return new Parens(this).invert();
- } else if (this.operator === '!' && (fst = this.first.unwrap()) instanceof Op && ((_ref2 = fst.operator) === '!' || _ref2 === 'in' || _ref2 === 'instanceof')) {
- return fst;
- } else {
- return new Op('!', this);
- }
- };
-
- Op.prototype.unfoldSoak = function(o) {
- var _ref2;
- return ((_ref2 = this.operator) === '++' || _ref2 === '--' || _ref2 === 'delete') && unfoldSoak(o, this, 'first');
- };
-
- Op.prototype.generateDo = function(exp) {
- var call, func, param, passedParams, ref, _i, _len, _ref2;
- passedParams = [];
- func = exp instanceof Assign && (ref = exp.value.unwrap()) instanceof Code ? ref : exp;
- _ref2 = func.params || [];
- for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
- param = _ref2[_i];
- if (param.value) {
- passedParams.push(param.value);
- delete param.value;
- } else {
- passedParams.push(param);
- }
- }
- call = new Call(exp, passedParams);
- call["do"] = true;
- return call;
- };
-
- Op.prototype.compileNode = function(o) {
- var code, isChain, _ref2, _ref3;
- isChain = this.isChainable() && this.first.isChainable();
- if (!isChain) {
- this.first.front = this.front;
- }
- if (this.operator === 'delete' && o.scope.check(this.first.unwrapAll().value)) {
- throw SyntaxError('delete operand may not be argument or var');
- }
- if (((_ref2 = this.operator) === '--' || _ref2 === '++') && (_ref3 = this.first.unwrapAll().value, __indexOf.call(STRICT_PROSCRIBED, _ref3) >= 0)) {
- throw SyntaxError('prefix increment/decrement may not have eval or arguments operand');
- }
- if (this.isUnary()) {
- return this.compileUnary(o);
- }
- if (isChain) {
- return this.compileChain(o);
- }
- if (this.operator === '?') {
- return this.compileExistence(o);
- }
- code = this.first.compile(o, LEVEL_OP) + ' ' + this.operator + ' ' + this.second.compile(o, LEVEL_OP);
- if (o.level <= LEVEL_OP) {
- return code;
- } else {
- return "(" + code + ")";
- }
- };
-
- Op.prototype.compileChain = function(o) {
- var code, fst, shared, _ref2;
- _ref2 = this.first.second.cache(o), this.first.second = _ref2[0], shared = _ref2[1];
- fst = this.first.compile(o, LEVEL_OP);
- code = "" + fst + " " + (this.invert ? '&&' : '||') + " " + (shared.compile(o)) + " " + this.operator + " " + (this.second.compile(o, LEVEL_OP));
- return "(" + code + ")";
- };
-
- Op.prototype.compileExistence = function(o) {
- var fst, ref;
- if (this.first.isComplex()) {
- ref = new Literal(o.scope.freeVariable('ref'));
- fst = new Parens(new Assign(ref, this.first));
- } else {
- fst = this.first;
- ref = fst;
- }
- return new If(new Existence(fst), ref, {
- type: 'if'
- }).addElse(this.second).compile(o);
- };
-
- Op.prototype.compileUnary = function(o) {
- var op, parts, plusMinus;
- if (o.level >= LEVEL_ACCESS) {
- return (new Parens(this)).compile(o);
- }
- parts = [op = this.operator];
- plusMinus = op === '+' || op === '-';
- if ((op === 'new' || op === 'typeof' || op === 'delete') || plusMinus && this.first instanceof Op && this.first.operator === op) {
- parts.push(' ');
- }
- if ((plusMinus && this.first instanceof Op) || (op === 'new' && this.first.isStatement(o))) {
- this.first = new Parens(this.first);
- }
- parts.push(this.first.compile(o, LEVEL_OP));
- if (this.flip) {
- parts.reverse();
- }
- return parts.join('');
- };
-
- Op.prototype.toString = function(idt) {
- return Op.__super__.toString.call(this, idt, this.constructor.name + ' ' + this.operator);
- };
-
- return Op;
-
- })(Base);
-
- exports.In = In = (function(_super) {
-
- __extends(In, _super);
-
- function In(object, array) {
- this.object = object;
- this.array = array;
- }
-
- In.prototype.children = ['object', 'array'];
-
- In.prototype.invert = NEGATE;
-
- In.prototype.compileNode = function(o) {
- var hasSplat, obj, _i, _len, _ref2;
- if (this.array instanceof Value && this.array.isArray()) {
- _ref2 = this.array.base.objects;
- for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
- obj = _ref2[_i];
- if (!(obj instanceof Splat)) {
- continue;
- }
- hasSplat = true;
- break;
- }
- if (!hasSplat) {
- return this.compileOrTest(o);
- }
- }
- return this.compileLoopTest(o);
- };
-
- In.prototype.compileOrTest = function(o) {
- var cmp, cnj, i, item, ref, sub, tests, _ref2, _ref3;
- if (this.array.base.objects.length === 0) {
- return "" + (!!this.negated);
- }
- _ref2 = this.object.cache(o, LEVEL_OP), sub = _ref2[0], ref = _ref2[1];
- _ref3 = this.negated ? [' !== ', ' && '] : [' === ', ' || '], cmp = _ref3[0], cnj = _ref3[1];
- tests = (function() {
- var _i, _len, _ref4, _results;
- _ref4 = this.array.base.objects;
- _results = [];
- for (i = _i = 0, _len = _ref4.length; _i < _len; i = ++_i) {
- item = _ref4[i];
- _results.push((i ? ref : sub) + cmp + item.compile(o, LEVEL_ACCESS));
- }
- return _results;
- }).call(this);
- tests = tests.join(cnj);
- if (o.level < LEVEL_OP) {
- return tests;
- } else {
- return "(" + tests + ")";
- }
- };
-
- In.prototype.compileLoopTest = function(o) {
- var code, ref, sub, _ref2;
- _ref2 = this.object.cache(o, LEVEL_LIST), sub = _ref2[0], ref = _ref2[1];
- code = utility('indexOf') + (".call(" + (this.array.compile(o, LEVEL_LIST)) + ", " + ref + ") ") + (this.negated ? '< 0' : '>= 0');
- if (sub === ref) {
- return code;
- }
- code = sub + ', ' + code;
- if (o.level < LEVEL_LIST) {
- return code;
- } else {
- return "(" + code + ")";
- }
- };
-
- In.prototype.toString = function(idt) {
- return In.__super__.toString.call(this, idt, this.constructor.name + (this.negated ? '!' : ''));
- };
-
- return In;
-
- })(Base);
-
- exports.Try = Try = (function(_super) {
-
- __extends(Try, _super);
-
- function Try(attempt, error, recovery, ensure) {
- this.attempt = attempt;
- this.error = error;
- this.recovery = recovery;
- this.ensure = ensure;
- }
-
- Try.prototype.children = ['attempt', 'recovery', 'ensure'];
-
- Try.prototype.isStatement = YES;
-
- Try.prototype.jumps = function(o) {
- var _ref2;
- return this.attempt.jumps(o) || ((_ref2 = this.recovery) != null ? _ref2.jumps(o) : void 0);
- };
-
- Try.prototype.makeReturn = function(res) {
- if (this.attempt) {
- this.attempt = this.attempt.makeReturn(res);
- }
- if (this.recovery) {
- this.recovery = this.recovery.makeReturn(res);
- }
- return this;
- };
-
- Try.prototype.compileNode = function(o) {
- var catchPart, ensurePart, errorPart, tryPart;
- o.indent += TAB;
- errorPart = this.error ? " (" + (this.error.compile(o)) + ") " : ' ';
- tryPart = this.attempt.compile(o, LEVEL_TOP);
- catchPart = (function() {
- var _ref2;
- if (this.recovery) {
- if (_ref2 = this.error.value, __indexOf.call(STRICT_PROSCRIBED, _ref2) >= 0) {
- throw SyntaxError("catch variable may not be \"" + this.error.value + "\"");
- }
- if (!o.scope.check(this.error.value)) {
- o.scope.add(this.error.value, 'param');
- }
- return " catch" + errorPart + "{\n" + (this.recovery.compile(o, LEVEL_TOP)) + "\n" + this.tab + "}";
- } else if (!(this.ensure || this.recovery)) {
- return ' catch (_error) {}';
- }
- }).call(this);
- ensurePart = this.ensure ? " finally {\n" + (this.ensure.compile(o, LEVEL_TOP)) + "\n" + this.tab + "}" : '';
- return "" + this.tab + "try {\n" + tryPart + "\n" + this.tab + "}" + (catchPart || '') + ensurePart;
- };
-
- return Try;
-
- })(Base);
-
- exports.Throw = Throw = (function(_super) {
-
- __extends(Throw, _super);
-
- function Throw(expression) {
- this.expression = expression;
- }
-
- Throw.prototype.children = ['expression'];
-
- Throw.prototype.isStatement = YES;
-
- Throw.prototype.jumps = NO;
-
- Throw.prototype.makeReturn = THIS;
-
- Throw.prototype.compileNode = function(o) {
- return this.tab + ("throw " + (this.expression.compile(o)) + ";");
- };
-
- return Throw;
-
- })(Base);
-
- exports.Existence = Existence = (function(_super) {
-
- __extends(Existence, _super);
-
- function Existence(expression) {
- this.expression = expression;
- }
-
- Existence.prototype.children = ['expression'];
-
- Existence.prototype.invert = NEGATE;
-
- Existence.prototype.compileNode = function(o) {
- var cmp, cnj, code, _ref2;
- this.expression.front = this.front;
- code = this.expression.compile(o, LEVEL_OP);
- if (IDENTIFIER.test(code) && !o.scope.check(code)) {
- _ref2 = this.negated ? ['===', '||'] : ['!==', '&&'], cmp = _ref2[0], cnj = _ref2[1];
- code = "typeof " + code + " " + cmp + " \"undefined\" " + cnj + " " + code + " " + cmp + " null";
- } else {
- code = "" + code + " " + (this.negated ? '==' : '!=') + " null";
- }
- if (o.level <= LEVEL_COND) {
- return code;
- } else {
- return "(" + code + ")";
- }
- };
-
- return Existence;
-
- })(Base);
-
- exports.Parens = Parens = (function(_super) {
-
- __extends(Parens, _super);
-
- function Parens(body) {
- this.body = body;
- }
-
- Parens.prototype.children = ['body'];
-
- Parens.prototype.unwrap = function() {
- return this.body;
- };
-
- Parens.prototype.isComplex = function() {
- return this.body.isComplex();
- };
-
- Parens.prototype.compileNode = function(o) {
- var bare, code, expr;
- expr = this.body.unwrap();
- if (expr instanceof Value && expr.isAtomic()) {
- expr.front = this.front;
- return expr.compile(o);
- }
- code = expr.compile(o, LEVEL_PAREN);
- bare = o.level < LEVEL_OP && (expr instanceof Op || expr instanceof Call || (expr instanceof For && expr.returns));
- if (bare) {
- return code;
- } else {
- return "(" + code + ")";
- }
- };
-
- return Parens;
-
- })(Base);
-
- exports.For = For = (function(_super) {
-
- __extends(For, _super);
-
- function For(body, source) {
- var _ref2;
- this.source = source.source, this.guard = source.guard, this.step = source.step, this.name = source.name, this.index = source.index;
- this.body = Block.wrap([body]);
- this.own = !!source.own;
- this.object = !!source.object;
- if (this.object) {
- _ref2 = [this.index, this.name], this.name = _ref2[0], this.index = _ref2[1];
- }
- if (this.index instanceof Value) {
- throw SyntaxError('index cannot be a pattern matching expression');
- }
- this.range = this.source instanceof Value && this.source.base instanceof Range && !this.source.properties.length;
- this.pattern = this.name instanceof Value;
- if (this.range && this.index) {
- throw SyntaxError('indexes do not apply to range loops');
- }
- if (this.range && this.pattern) {
- throw SyntaxError('cannot pattern match over range loops');
- }
- this.returns = false;
- }
-
- For.prototype.children = ['body', 'source', 'guard', 'step'];
-
- For.prototype.compileNode = function(o) {
- var body, defPart, forPart, forVarPart, guardPart, idt1, index, ivar, kvar, kvarAssign, lastJumps, lvar, name, namePart, ref, resultPart, returnResult, rvar, scope, source, stepPart, stepvar, svar, varPart, _ref2;
- body = Block.wrap([this.body]);
- lastJumps = (_ref2 = last(body.expressions)) != null ? _ref2.jumps() : void 0;
- if (lastJumps && lastJumps instanceof Return) {
- this.returns = false;
- }
- source = this.range ? this.source.base : this.source;
- scope = o.scope;
- name = this.name && this.name.compile(o, LEVEL_LIST);
- index = this.index && this.index.compile(o, LEVEL_LIST);
- if (name && !this.pattern) {
- scope.find(name);
- }
- if (index) {
- scope.find(index);
- }
- if (this.returns) {
- rvar = scope.freeVariable('results');
- }
- ivar = (this.object && index) || scope.freeVariable('i');
- kvar = (this.range && name) || index || ivar;
- kvarAssign = kvar !== ivar ? "" + kvar + " = " : "";
- if (this.step && !this.range) {
- stepvar = scope.freeVariable("step");
- }
- if (this.pattern) {
- name = ivar;
- }
- varPart = '';
- guardPart = '';
- defPart = '';
- idt1 = this.tab + TAB;
- if (this.range) {
- forPart = source.compile(merge(o, {
- index: ivar,
- name: name,
- step: this.step
- }));
- } else {
- svar = this.source.compile(o, LEVEL_LIST);
- if ((name || this.own) && !IDENTIFIER.test(svar)) {
- defPart = "" + this.tab + (ref = scope.freeVariable('ref')) + " = " + svar + ";\n";
- svar = ref;
- }
- if (name && !this.pattern) {
- namePart = "" + name + " = " + svar + "[" + kvar + "]";
- }
- if (!this.object) {
- lvar = scope.freeVariable('len');
- forVarPart = "" + kvarAssign + ivar + " = 0, " + lvar + " = " + svar + ".length";
- if (this.step) {
- forVarPart += ", " + stepvar + " = " + (this.step.compile(o, LEVEL_OP));
- }
- stepPart = "" + kvarAssign + (this.step ? "" + ivar + " += " + stepvar : (kvar !== ivar ? "++" + ivar : "" + ivar + "++"));
- forPart = "" + forVarPart + "; " + ivar + " < " + lvar + "; " + stepPart;
- }
- }
- if (this.returns) {
- resultPart = "" + this.tab + rvar + " = [];\n";
- returnResult = "\n" + this.tab + "return " + rvar + ";";
- body.makeReturn(rvar);
- }
- if (this.guard) {
- if (body.expressions.length > 1) {
- body.expressions.unshift(new If((new Parens(this.guard)).invert(), new Literal("continue")));
- } else {
- if (this.guard) {
- body = Block.wrap([new If(this.guard, body)]);
- }
- }
- }
- if (this.pattern) {
- body.expressions.unshift(new Assign(this.name, new Literal("" + svar + "[" + kvar + "]")));
- }
- defPart += this.pluckDirectCall(o, body);
- if (namePart) {
- varPart = "\n" + idt1 + namePart + ";";
- }
- if (this.object) {
- forPart = "" + kvar + " in " + svar;
- if (this.own) {
- guardPart = "\n" + idt1 + "if (!" + (utility('hasProp')) + ".call(" + svar + ", " + kvar + ")) continue;";
- }
- }
- body = body.compile(merge(o, {
- indent: idt1
- }), LEVEL_TOP);
- if (body) {
- body = '\n' + body + '\n';
- }
- return "" + defPart + (resultPart || '') + this.tab + "for (" + forPart + ") {" + guardPart + varPart + body + this.tab + "}" + (returnResult || '');
- };
-
- For.prototype.pluckDirectCall = function(o, body) {
- var base, defs, expr, fn, idx, ref, val, _i, _len, _ref2, _ref3, _ref4, _ref5, _ref6, _ref7;
- defs = '';
- _ref2 = body.expressions;
- for (idx = _i = 0, _len = _ref2.length; _i < _len; idx = ++_i) {
- expr = _ref2[idx];
- expr = expr.unwrapAll();
- if (!(expr instanceof Call)) {
- continue;
- }
- val = expr.variable.unwrapAll();
- if (!((val instanceof Code) || (val instanceof Value && ((_ref3 = val.base) != null ? _ref3.unwrapAll() : void 0) instanceof Code && val.properties.length === 1 && ((_ref4 = (_ref5 = val.properties[0].name) != null ? _ref5.value : void 0) === 'call' || _ref4 === 'apply')))) {
- continue;
- }
- fn = ((_ref6 = val.base) != null ? _ref6.unwrapAll() : void 0) || val;
- ref = new Literal(o.scope.freeVariable('fn'));
- base = new Value(ref);
- if (val.base) {
- _ref7 = [base, val], val.base = _ref7[0], base = _ref7[1];
- }
- body.expressions[idx] = new Call(base, expr.args);
- defs += this.tab + new Assign(ref, fn).compile(o, LEVEL_TOP) + ';\n';
- }
- return defs;
- };
-
- return For;
-
- })(While);
-
- exports.Switch = Switch = (function(_super) {
-
- __extends(Switch, _super);
-
- function Switch(subject, cases, otherwise) {
- this.subject = subject;
- this.cases = cases;
- this.otherwise = otherwise;
- }
-
- Switch.prototype.children = ['subject', 'cases', 'otherwise'];
-
- Switch.prototype.isStatement = YES;
-
- Switch.prototype.jumps = function(o) {
- var block, conds, _i, _len, _ref2, _ref3, _ref4;
- if (o == null) {
- o = {
- block: true
- };
- }
- _ref2 = this.cases;
- for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
- _ref3 = _ref2[_i], conds = _ref3[0], block = _ref3[1];
- if (block.jumps(o)) {
- return block;
- }
- }
- return (_ref4 = this.otherwise) != null ? _ref4.jumps(o) : void 0;
- };
-
- Switch.prototype.makeReturn = function(res) {
- var pair, _i, _len, _ref2, _ref3;
- _ref2 = this.cases;
- for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
- pair = _ref2[_i];
- pair[1].makeReturn(res);
- }
- if (res) {
- this.otherwise || (this.otherwise = new Block([new Literal('void 0')]));
- }
- if ((_ref3 = this.otherwise) != null) {
- _ref3.makeReturn(res);
- }
- return this;
- };
-
- Switch.prototype.compileNode = function(o) {
- var block, body, code, cond, conditions, expr, i, idt1, idt2, _i, _j, _len, _len1, _ref2, _ref3, _ref4, _ref5;
- idt1 = o.indent + TAB;
- idt2 = o.indent = idt1 + TAB;
- code = this.tab + ("switch (" + (((_ref2 = this.subject) != null ? _ref2.compile(o, LEVEL_PAREN) : void 0) || false) + ") {\n");
- _ref3 = this.cases;
- for (i = _i = 0, _len = _ref3.length; _i < _len; i = ++_i) {
- _ref4 = _ref3[i], conditions = _ref4[0], block = _ref4[1];
- _ref5 = flatten([conditions]);
- for (_j = 0, _len1 = _ref5.length; _j < _len1; _j++) {
- cond = _ref5[_j];
- if (!this.subject) {
- cond = cond.invert();
- }
- code += idt1 + ("case " + (cond.compile(o, LEVEL_PAREN)) + ":\n");
- }
- if (body = block.compile(o, LEVEL_TOP)) {
- code += body + '\n';
- }
- if (i === this.cases.length - 1 && !this.otherwise) {
- break;
- }
- expr = this.lastNonComment(block.expressions);
- if (expr instanceof Return || (expr instanceof Literal && expr.jumps() && expr.value !== 'debugger')) {
- continue;
- }
- code += idt2 + 'break;\n';
- }
- if (this.otherwise && this.otherwise.expressions.length) {
- code += idt1 + ("default:\n" + (this.otherwise.compile(o, LEVEL_TOP)) + "\n");
- }
- return code + this.tab + '}';
- };
-
- return Switch;
-
- })(Base);
-
- exports.If = If = (function(_super) {
-
- __extends(If, _super);
-
- function If(condition, body, options) {
- this.body = body;
- if (options == null) {
- options = {};
- }
- this.condition = options.type === 'unless' ? condition.invert() : condition;
- this.elseBody = null;
- this.isChain = false;
- this.soak = options.soak;
- }
-
- If.prototype.children = ['condition', 'body', 'elseBody'];
-
- If.prototype.bodyNode = function() {
- var _ref2;
- return (_ref2 = this.body) != null ? _ref2.unwrap() : void 0;
- };
-
- If.prototype.elseBodyNode = function() {
- var _ref2;
- return (_ref2 = this.elseBody) != null ? _ref2.unwrap() : void 0;
- };
-
- If.prototype.addElse = function(elseBody) {
- if (this.isChain) {
- this.elseBodyNode().addElse(elseBody);
- } else {
- this.isChain = elseBody instanceof If;
- this.elseBody = this.ensureBlock(elseBody);
- }
- return this;
- };
-
- If.prototype.isStatement = function(o) {
- var _ref2;
- return (o != null ? o.level : void 0) === LEVEL_TOP || this.bodyNode().isStatement(o) || ((_ref2 = this.elseBodyNode()) != null ? _ref2.isStatement(o) : void 0);
- };
-
- If.prototype.jumps = function(o) {
- var _ref2;
- return this.body.jumps(o) || ((_ref2 = this.elseBody) != null ? _ref2.jumps(o) : void 0);
- };
-
- If.prototype.compileNode = function(o) {
- if (this.isStatement(o)) {
- return this.compileStatement(o);
- } else {
- return this.compileExpression(o);
- }
- };
-
- If.prototype.makeReturn = function(res) {
- if (res) {
- this.elseBody || (this.elseBody = new Block([new Literal('void 0')]));
- }
- this.body && (this.body = new Block([this.body.makeReturn(res)]));
- this.elseBody && (this.elseBody = new Block([this.elseBody.makeReturn(res)]));
- return this;
- };
-
- If.prototype.ensureBlock = function(node) {
- if (node instanceof Block) {
- return node;
- } else {
- return new Block([node]);
- }
- };
-
- If.prototype.compileStatement = function(o) {
- var body, child, cond, exeq, ifPart;
- child = del(o, 'chainChild');
- exeq = del(o, 'isExistentialEquals');
- if (exeq) {
- return new If(this.condition.invert(), this.elseBodyNode(), {
- type: 'if'
- }).compile(o);
- }
- cond = this.condition.compile(o, LEVEL_PAREN);
- o.indent += TAB;
- body = this.ensureBlock(this.body);
- ifPart = "if (" + cond + ") {\n" + (body.compile(o)) + "\n" + this.tab + "}";
- if (!child) {
- ifPart = this.tab + ifPart;
- }
- if (!this.elseBody) {
- return ifPart;
- }
- return ifPart + ' else ' + (this.isChain ? (o.indent = this.tab, o.chainChild = true, this.elseBody.unwrap().compile(o, LEVEL_TOP)) : "{\n" + (this.elseBody.compile(o, LEVEL_TOP)) + "\n" + this.tab + "}");
- };
-
- If.prototype.compileExpression = function(o) {
- var alt, body, code, cond;
- cond = this.condition.compile(o, LEVEL_COND);
- body = this.bodyNode().compile(o, LEVEL_LIST);
- alt = this.elseBodyNode() ? this.elseBodyNode().compile(o, LEVEL_LIST) : 'void 0';
- code = "" + cond + " ? " + body + " : " + alt;
- if (o.level >= LEVEL_COND) {
- return "(" + code + ")";
- } else {
- return code;
- }
- };
-
- If.prototype.unfoldSoak = function() {
- return this.soak && this;
- };
-
- return If;
-
- })(Base);
-
- Closure = {
- wrap: function(expressions, statement, noReturn) {
- var args, call, func, mentionsArgs, meth;
- if (expressions.jumps()) {
- return expressions;
- }
- func = new Code([], Block.wrap([expressions]));
- args = [];
- if ((mentionsArgs = expressions.contains(this.literalArgs)) || expressions.contains(this.literalThis)) {
- meth = new Literal(mentionsArgs ? 'apply' : 'call');
- args = [new Literal('this')];
- if (mentionsArgs) {
- args.push(new Literal('arguments'));
- }
- func = new Value(func, [new Access(meth)]);
- }
- func.noReturn = noReturn;
- call = new Call(func, args);
- if (statement) {
- return Block.wrap([call]);
- } else {
- return call;
- }
- },
- literalArgs: function(node) {
- return node instanceof Literal && node.value === 'arguments' && !node.asKey;
- },
- literalThis: function(node) {
- return (node instanceof Literal && node.value === 'this' && !node.asKey) || (node instanceof Code && node.bound) || (node instanceof Call && node.isSuper);
- }
- };
-
- unfoldSoak = function(o, parent, name) {
- var ifn;
- if (!(ifn = parent[name].unfoldSoak(o))) {
- return;
- }
- parent[name] = ifn.body;
- ifn.body = new Value(parent);
- return ifn;
- };
-
- UTILITIES = {
- "extends": function() {
- return "function(child, parent) { for (var key in parent) { if (" + (utility('hasProp')) + ".call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }";
- },
- bind: function() {
- return 'function(fn, me){ return function(){ return fn.apply(me, arguments); }; }';
- },
- indexOf: function() {
- return "[].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }";
- },
- hasProp: function() {
- return '{}.hasOwnProperty';
- },
- slice: function() {
- return '[].slice';
- }
- };
-
- LEVEL_TOP = 1;
-
- LEVEL_PAREN = 2;
-
- LEVEL_LIST = 3;
-
- LEVEL_COND = 4;
-
- LEVEL_OP = 5;
-
- LEVEL_ACCESS = 6;
-
- TAB = ' ';
-
- IDENTIFIER_STR = "[$A-Za-z_\\x7f-\\uffff][$\\w\\x7f-\\uffff]*";
-
- IDENTIFIER = RegExp("^" + IDENTIFIER_STR + "$");
-
- SIMPLENUM = /^[+-]?\d+$/;
-
- METHOD_DEF = RegExp("^(?:(" + IDENTIFIER_STR + ")\\.prototype(?:\\.(" + IDENTIFIER_STR + ")|\\[(\"(?:[^\\\\\"\\r\\n]|\\\\.)*\"|'(?:[^\\\\'\\r\\n]|\\\\.)*')\\]|\\[(0x[\\da-fA-F]+|\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)\\]))|(" + IDENTIFIER_STR + ")$");
-
- IS_STRING = /^['"]/;
-
- utility = function(name) {
- var ref;
- ref = "__" + name;
- Scope.root.assign(ref, UTILITIES[name]());
- return ref;
- };
-
- multident = function(code, tab) {
- code = code.replace(/\n/g, '$&' + tab);
- return code.replace(/\s+$/, '');
- };
-
-}).call(this);
diff --git a/spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/optparse.js b/spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/optparse.js
deleted file mode 100644
index d7fda40a..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/optparse.js
+++ /dev/null
@@ -1,138 +0,0 @@
-// Generated by CoffeeScript 1.3.3
-(function() {
- var LONG_FLAG, MULTI_FLAG, OPTIONAL, OptionParser, SHORT_FLAG, buildRule, buildRules, normalizeArguments;
-
- exports.OptionParser = OptionParser = (function() {
-
- function OptionParser(rules, banner) {
- this.banner = banner;
- this.rules = buildRules(rules);
- }
-
- OptionParser.prototype.parse = function(args) {
- var arg, i, isOption, matchedRule, options, originalArgs, pos, rule, seenNonOptionArg, skippingArgument, value, _i, _j, _len, _len1, _ref;
- options = {
- "arguments": []
- };
- skippingArgument = false;
- originalArgs = args;
- args = normalizeArguments(args);
- for (i = _i = 0, _len = args.length; _i < _len; i = ++_i) {
- arg = args[i];
- if (skippingArgument) {
- skippingArgument = false;
- continue;
- }
- if (arg === '--') {
- pos = originalArgs.indexOf('--');
- options["arguments"] = options["arguments"].concat(originalArgs.slice(pos + 1));
- break;
- }
- isOption = !!(arg.match(LONG_FLAG) || arg.match(SHORT_FLAG));
- seenNonOptionArg = options["arguments"].length > 0;
- if (!seenNonOptionArg) {
- matchedRule = false;
- _ref = this.rules;
- for (_j = 0, _len1 = _ref.length; _j < _len1; _j++) {
- rule = _ref[_j];
- if (rule.shortFlag === arg || rule.longFlag === arg) {
- value = true;
- if (rule.hasArgument) {
- skippingArgument = true;
- value = args[i + 1];
- }
- options[rule.name] = rule.isList ? (options[rule.name] || []).concat(value) : value;
- matchedRule = true;
- break;
- }
- }
- if (isOption && !matchedRule) {
- throw new Error("unrecognized option: " + arg);
- }
- }
- if (seenNonOptionArg || !isOption) {
- options["arguments"].push(arg);
- }
- }
- return options;
- };
-
- OptionParser.prototype.help = function() {
- var letPart, lines, rule, spaces, _i, _len, _ref;
- lines = [];
- if (this.banner) {
- lines.unshift("" + this.banner + "\n");
- }
- _ref = this.rules;
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
- rule = _ref[_i];
- spaces = 15 - rule.longFlag.length;
- spaces = spaces > 0 ? Array(spaces + 1).join(' ') : '';
- letPart = rule.shortFlag ? rule.shortFlag + ', ' : ' ';
- lines.push(' ' + letPart + rule.longFlag + spaces + rule.description);
- }
- return "\n" + (lines.join('\n')) + "\n";
- };
-
- return OptionParser;
-
- })();
-
- LONG_FLAG = /^(--\w[\w\-]*)/;
-
- SHORT_FLAG = /^(-\w)$/;
-
- MULTI_FLAG = /^-(\w{2,})/;
-
- OPTIONAL = /\[(\w+(\*?))\]/;
-
- buildRules = function(rules) {
- var tuple, _i, _len, _results;
- _results = [];
- for (_i = 0, _len = rules.length; _i < _len; _i++) {
- tuple = rules[_i];
- if (tuple.length < 3) {
- tuple.unshift(null);
- }
- _results.push(buildRule.apply(null, tuple));
- }
- return _results;
- };
-
- buildRule = function(shortFlag, longFlag, description, options) {
- var match;
- if (options == null) {
- options = {};
- }
- match = longFlag.match(OPTIONAL);
- longFlag = longFlag.match(LONG_FLAG)[1];
- return {
- name: longFlag.substr(2),
- shortFlag: shortFlag,
- longFlag: longFlag,
- description: description,
- hasArgument: !!(match && match[1]),
- isList: !!(match && match[2])
- };
- };
-
- normalizeArguments = function(args) {
- var arg, l, match, result, _i, _j, _len, _len1, _ref;
- args = args.slice(0);
- result = [];
- for (_i = 0, _len = args.length; _i < _len; _i++) {
- arg = args[_i];
- if (match = arg.match(MULTI_FLAG)) {
- _ref = match[1].split('');
- for (_j = 0, _len1 = _ref.length; _j < _len1; _j++) {
- l = _ref[_j];
- result.push('-' + l);
- }
- } else {
- result.push(arg);
- }
- }
- return result;
- };
-
-}).call(this);
diff --git a/spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/parser.js b/spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/parser.js
deleted file mode 100755
index f0499038..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/parser.js
+++ /dev/null
@@ -1,683 +0,0 @@
-/* Jison generated parser */
-var parser = (function(){
-var parser = {trace: function trace() { },
-yy: {},
-symbols_: {"error":2,"Root":3,"Body":4,"Block":5,"TERMINATOR":6,"Line":7,"Expression":8,"Statement":9,"Return":10,"Comment":11,"STATEMENT":12,"Value":13,"Invocation":14,"Code":15,"Operation":16,"Assign":17,"If":18,"Try":19,"While":20,"For":21,"Switch":22,"Class":23,"Throw":24,"INDENT":25,"OUTDENT":26,"Identifier":27,"IDENTIFIER":28,"AlphaNumeric":29,"NUMBER":30,"STRING":31,"Literal":32,"JS":33,"REGEX":34,"DEBUGGER":35,"UNDEFINED":36,"NULL":37,"BOOL":38,"Assignable":39,"=":40,"AssignObj":41,"ObjAssignable":42,":":43,"ThisProperty":44,"RETURN":45,"HERECOMMENT":46,"PARAM_START":47,"ParamList":48,"PARAM_END":49,"FuncGlyph":50,"->":51,"=>":52,"OptComma":53,",":54,"Param":55,"ParamVar":56,"...":57,"Array":58,"Object":59,"Splat":60,"SimpleAssignable":61,"Accessor":62,"Parenthetical":63,"Range":64,"This":65,".":66,"?.":67,"::":68,"Index":69,"INDEX_START":70,"IndexValue":71,"INDEX_END":72,"INDEX_SOAK":73,"Slice":74,"{":75,"AssignList":76,"}":77,"CLASS":78,"EXTENDS":79,"OptFuncExist":80,"Arguments":81,"SUPER":82,"FUNC_EXIST":83,"CALL_START":84,"CALL_END":85,"ArgList":86,"THIS":87,"@":88,"[":89,"]":90,"RangeDots":91,"..":92,"Arg":93,"SimpleArgs":94,"TRY":95,"Catch":96,"FINALLY":97,"CATCH":98,"THROW":99,"(":100,")":101,"WhileSource":102,"WHILE":103,"WHEN":104,"UNTIL":105,"Loop":106,"LOOP":107,"ForBody":108,"FOR":109,"ForStart":110,"ForSource":111,"ForVariables":112,"OWN":113,"ForValue":114,"FORIN":115,"FOROF":116,"BY":117,"SWITCH":118,"Whens":119,"ELSE":120,"When":121,"LEADING_WHEN":122,"IfBlock":123,"IF":124,"POST_IF":125,"UNARY":126,"-":127,"+":128,"--":129,"++":130,"?":131,"MATH":132,"SHIFT":133,"COMPARE":134,"LOGIC":135,"RELATION":136,"COMPOUND_ASSIGN":137,"$accept":0,"$end":1},
-terminals_: {2:"error",6:"TERMINATOR",12:"STATEMENT",25:"INDENT",26:"OUTDENT",28:"IDENTIFIER",30:"NUMBER",31:"STRING",33:"JS",34:"REGEX",35:"DEBUGGER",36:"UNDEFINED",37:"NULL",38:"BOOL",40:"=",43:":",45:"RETURN",46:"HERECOMMENT",47:"PARAM_START",49:"PARAM_END",51:"->",52:"=>",54:",",57:"...",66:".",67:"?.",68:"::",70:"INDEX_START",72:"INDEX_END",73:"INDEX_SOAK",75:"{",77:"}",78:"CLASS",79:"EXTENDS",82:"SUPER",83:"FUNC_EXIST",84:"CALL_START",85:"CALL_END",87:"THIS",88:"@",89:"[",90:"]",92:"..",95:"TRY",97:"FINALLY",98:"CATCH",99:"THROW",100:"(",101:")",103:"WHILE",104:"WHEN",105:"UNTIL",107:"LOOP",109:"FOR",113:"OWN",115:"FORIN",116:"FOROF",117:"BY",118:"SWITCH",120:"ELSE",122:"LEADING_WHEN",124:"IF",125:"POST_IF",126:"UNARY",127:"-",128:"+",129:"--",130:"++",131:"?",132:"MATH",133:"SHIFT",134:"COMPARE",135:"LOGIC",136:"RELATION",137:"COMPOUND_ASSIGN"},
-productions_: [0,[3,0],[3,1],[3,2],[4,1],[4,3],[4,2],[7,1],[7,1],[9,1],[9,1],[9,1],[8,1],[8,1],[8,1],[8,1],[8,1],[8,1],[8,1],[8,1],[8,1],[8,1],[8,1],[8,1],[5,2],[5,3],[27,1],[29,1],[29,1],[32,1],[32,1],[32,1],[32,1],[32,1],[32,1],[32,1],[17,3],[17,4],[17,5],[41,1],[41,3],[41,5],[41,1],[42,1],[42,1],[42,1],[10,2],[10,1],[11,1],[15,5],[15,2],[50,1],[50,1],[53,0],[53,1],[48,0],[48,1],[48,3],[48,4],[48,6],[55,1],[55,2],[55,3],[56,1],[56,1],[56,1],[56,1],[60,2],[61,1],[61,2],[61,2],[61,1],[39,1],[39,1],[39,1],[13,1],[13,1],[13,1],[13,1],[13,1],[62,2],[62,2],[62,2],[62,1],[62,1],[69,3],[69,2],[71,1],[71,1],[59,4],[76,0],[76,1],[76,3],[76,4],[76,6],[23,1],[23,2],[23,3],[23,4],[23,2],[23,3],[23,4],[23,5],[14,3],[14,3],[14,1],[14,2],[80,0],[80,1],[81,2],[81,4],[65,1],[65,1],[44,2],[58,2],[58,4],[91,1],[91,1],[64,5],[74,3],[74,2],[74,2],[74,1],[86,1],[86,3],[86,4],[86,4],[86,6],[93,1],[93,1],[94,1],[94,3],[19,2],[19,3],[19,4],[19,5],[96,3],[24,2],[63,3],[63,5],[102,2],[102,4],[102,2],[102,4],[20,2],[20,2],[20,2],[20,1],[106,2],[106,2],[21,2],[21,2],[21,2],[108,2],[108,2],[110,2],[110,3],[114,1],[114,1],[114,1],[114,1],[112,1],[112,3],[111,2],[111,2],[111,4],[111,4],[111,4],[111,6],[111,6],[22,5],[22,7],[22,4],[22,6],[119,1],[119,2],[121,3],[121,4],[123,3],[123,5],[18,1],[18,3],[18,3],[18,3],[16,2],[16,2],[16,2],[16,2],[16,2],[16,2],[16,2],[16,2],[16,3],[16,3],[16,3],[16,3],[16,3],[16,3],[16,3],[16,3],[16,5],[16,3]],
-performAction: function anonymous(yytext,yyleng,yylineno,yy,yystate,$$,_$) {
-
-var $0 = $$.length - 1;
-switch (yystate) {
-case 1:return this.$ = new yy.Block;
-break;
-case 2:return this.$ = $$[$0];
-break;
-case 3:return this.$ = $$[$0-1];
-break;
-case 4:this.$ = yy.Block.wrap([$$[$0]]);
-break;
-case 5:this.$ = $$[$0-2].push($$[$0]);
-break;
-case 6:this.$ = $$[$0-1];
-break;
-case 7:this.$ = $$[$0];
-break;
-case 8:this.$ = $$[$0];
-break;
-case 9:this.$ = $$[$0];
-break;
-case 10:this.$ = $$[$0];
-break;
-case 11:this.$ = new yy.Literal($$[$0]);
-break;
-case 12:this.$ = $$[$0];
-break;
-case 13:this.$ = $$[$0];
-break;
-case 14:this.$ = $$[$0];
-break;
-case 15:this.$ = $$[$0];
-break;
-case 16:this.$ = $$[$0];
-break;
-case 17:this.$ = $$[$0];
-break;
-case 18:this.$ = $$[$0];
-break;
-case 19:this.$ = $$[$0];
-break;
-case 20:this.$ = $$[$0];
-break;
-case 21:this.$ = $$[$0];
-break;
-case 22:this.$ = $$[$0];
-break;
-case 23:this.$ = $$[$0];
-break;
-case 24:this.$ = new yy.Block;
-break;
-case 25:this.$ = $$[$0-1];
-break;
-case 26:this.$ = new yy.Literal($$[$0]);
-break;
-case 27:this.$ = new yy.Literal($$[$0]);
-break;
-case 28:this.$ = new yy.Literal($$[$0]);
-break;
-case 29:this.$ = $$[$0];
-break;
-case 30:this.$ = new yy.Literal($$[$0]);
-break;
-case 31:this.$ = new yy.Literal($$[$0]);
-break;
-case 32:this.$ = new yy.Literal($$[$0]);
-break;
-case 33:this.$ = new yy.Undefined;
-break;
-case 34:this.$ = new yy.Null;
-break;
-case 35:this.$ = new yy.Bool($$[$0]);
-break;
-case 36:this.$ = new yy.Assign($$[$0-2], $$[$0]);
-break;
-case 37:this.$ = new yy.Assign($$[$0-3], $$[$0]);
-break;
-case 38:this.$ = new yy.Assign($$[$0-4], $$[$0-1]);
-break;
-case 39:this.$ = new yy.Value($$[$0]);
-break;
-case 40:this.$ = new yy.Assign(new yy.Value($$[$0-2]), $$[$0], 'object');
-break;
-case 41:this.$ = new yy.Assign(new yy.Value($$[$0-4]), $$[$0-1], 'object');
-break;
-case 42:this.$ = $$[$0];
-break;
-case 43:this.$ = $$[$0];
-break;
-case 44:this.$ = $$[$0];
-break;
-case 45:this.$ = $$[$0];
-break;
-case 46:this.$ = new yy.Return($$[$0]);
-break;
-case 47:this.$ = new yy.Return;
-break;
-case 48:this.$ = new yy.Comment($$[$0]);
-break;
-case 49:this.$ = new yy.Code($$[$0-3], $$[$0], $$[$0-1]);
-break;
-case 50:this.$ = new yy.Code([], $$[$0], $$[$0-1]);
-break;
-case 51:this.$ = 'func';
-break;
-case 52:this.$ = 'boundfunc';
-break;
-case 53:this.$ = $$[$0];
-break;
-case 54:this.$ = $$[$0];
-break;
-case 55:this.$ = [];
-break;
-case 56:this.$ = [$$[$0]];
-break;
-case 57:this.$ = $$[$0-2].concat($$[$0]);
-break;
-case 58:this.$ = $$[$0-3].concat($$[$0]);
-break;
-case 59:this.$ = $$[$0-5].concat($$[$0-2]);
-break;
-case 60:this.$ = new yy.Param($$[$0]);
-break;
-case 61:this.$ = new yy.Param($$[$0-1], null, true);
-break;
-case 62:this.$ = new yy.Param($$[$0-2], $$[$0]);
-break;
-case 63:this.$ = $$[$0];
-break;
-case 64:this.$ = $$[$0];
-break;
-case 65:this.$ = $$[$0];
-break;
-case 66:this.$ = $$[$0];
-break;
-case 67:this.$ = new yy.Splat($$[$0-1]);
-break;
-case 68:this.$ = new yy.Value($$[$0]);
-break;
-case 69:this.$ = $$[$0-1].add($$[$0]);
-break;
-case 70:this.$ = new yy.Value($$[$0-1], [].concat($$[$0]));
-break;
-case 71:this.$ = $$[$0];
-break;
-case 72:this.$ = $$[$0];
-break;
-case 73:this.$ = new yy.Value($$[$0]);
-break;
-case 74:this.$ = new yy.Value($$[$0]);
-break;
-case 75:this.$ = $$[$0];
-break;
-case 76:this.$ = new yy.Value($$[$0]);
-break;
-case 77:this.$ = new yy.Value($$[$0]);
-break;
-case 78:this.$ = new yy.Value($$[$0]);
-break;
-case 79:this.$ = $$[$0];
-break;
-case 80:this.$ = new yy.Access($$[$0]);
-break;
-case 81:this.$ = new yy.Access($$[$0], 'soak');
-break;
-case 82:this.$ = [new yy.Access(new yy.Literal('prototype')), new yy.Access($$[$0])];
-break;
-case 83:this.$ = new yy.Access(new yy.Literal('prototype'));
-break;
-case 84:this.$ = $$[$0];
-break;
-case 85:this.$ = $$[$0-1];
-break;
-case 86:this.$ = yy.extend($$[$0], {
- soak: true
- });
-break;
-case 87:this.$ = new yy.Index($$[$0]);
-break;
-case 88:this.$ = new yy.Slice($$[$0]);
-break;
-case 89:this.$ = new yy.Obj($$[$0-2], $$[$0-3].generated);
-break;
-case 90:this.$ = [];
-break;
-case 91:this.$ = [$$[$0]];
-break;
-case 92:this.$ = $$[$0-2].concat($$[$0]);
-break;
-case 93:this.$ = $$[$0-3].concat($$[$0]);
-break;
-case 94:this.$ = $$[$0-5].concat($$[$0-2]);
-break;
-case 95:this.$ = new yy.Class;
-break;
-case 96:this.$ = new yy.Class(null, null, $$[$0]);
-break;
-case 97:this.$ = new yy.Class(null, $$[$0]);
-break;
-case 98:this.$ = new yy.Class(null, $$[$0-1], $$[$0]);
-break;
-case 99:this.$ = new yy.Class($$[$0]);
-break;
-case 100:this.$ = new yy.Class($$[$0-1], null, $$[$0]);
-break;
-case 101:this.$ = new yy.Class($$[$0-2], $$[$0]);
-break;
-case 102:this.$ = new yy.Class($$[$0-3], $$[$0-1], $$[$0]);
-break;
-case 103:this.$ = new yy.Call($$[$0-2], $$[$0], $$[$0-1]);
-break;
-case 104:this.$ = new yy.Call($$[$0-2], $$[$0], $$[$0-1]);
-break;
-case 105:this.$ = new yy.Call('super', [new yy.Splat(new yy.Literal('arguments'))]);
-break;
-case 106:this.$ = new yy.Call('super', $$[$0]);
-break;
-case 107:this.$ = false;
-break;
-case 108:this.$ = true;
-break;
-case 109:this.$ = [];
-break;
-case 110:this.$ = $$[$0-2];
-break;
-case 111:this.$ = new yy.Value(new yy.Literal('this'));
-break;
-case 112:this.$ = new yy.Value(new yy.Literal('this'));
-break;
-case 113:this.$ = new yy.Value(new yy.Literal('this'), [new yy.Access($$[$0])], 'this');
-break;
-case 114:this.$ = new yy.Arr([]);
-break;
-case 115:this.$ = new yy.Arr($$[$0-2]);
-break;
-case 116:this.$ = 'inclusive';
-break;
-case 117:this.$ = 'exclusive';
-break;
-case 118:this.$ = new yy.Range($$[$0-3], $$[$0-1], $$[$0-2]);
-break;
-case 119:this.$ = new yy.Range($$[$0-2], $$[$0], $$[$0-1]);
-break;
-case 120:this.$ = new yy.Range($$[$0-1], null, $$[$0]);
-break;
-case 121:this.$ = new yy.Range(null, $$[$0], $$[$0-1]);
-break;
-case 122:this.$ = new yy.Range(null, null, $$[$0]);
-break;
-case 123:this.$ = [$$[$0]];
-break;
-case 124:this.$ = $$[$0-2].concat($$[$0]);
-break;
-case 125:this.$ = $$[$0-3].concat($$[$0]);
-break;
-case 126:this.$ = $$[$0-2];
-break;
-case 127:this.$ = $$[$0-5].concat($$[$0-2]);
-break;
-case 128:this.$ = $$[$0];
-break;
-case 129:this.$ = $$[$0];
-break;
-case 130:this.$ = $$[$0];
-break;
-case 131:this.$ = [].concat($$[$0-2], $$[$0]);
-break;
-case 132:this.$ = new yy.Try($$[$0]);
-break;
-case 133:this.$ = new yy.Try($$[$0-1], $$[$0][0], $$[$0][1]);
-break;
-case 134:this.$ = new yy.Try($$[$0-2], null, null, $$[$0]);
-break;
-case 135:this.$ = new yy.Try($$[$0-3], $$[$0-2][0], $$[$0-2][1], $$[$0]);
-break;
-case 136:this.$ = [$$[$0-1], $$[$0]];
-break;
-case 137:this.$ = new yy.Throw($$[$0]);
-break;
-case 138:this.$ = new yy.Parens($$[$0-1]);
-break;
-case 139:this.$ = new yy.Parens($$[$0-2]);
-break;
-case 140:this.$ = new yy.While($$[$0]);
-break;
-case 141:this.$ = new yy.While($$[$0-2], {
- guard: $$[$0]
- });
-break;
-case 142:this.$ = new yy.While($$[$0], {
- invert: true
- });
-break;
-case 143:this.$ = new yy.While($$[$0-2], {
- invert: true,
- guard: $$[$0]
- });
-break;
-case 144:this.$ = $$[$0-1].addBody($$[$0]);
-break;
-case 145:this.$ = $$[$0].addBody(yy.Block.wrap([$$[$0-1]]));
-break;
-case 146:this.$ = $$[$0].addBody(yy.Block.wrap([$$[$0-1]]));
-break;
-case 147:this.$ = $$[$0];
-break;
-case 148:this.$ = new yy.While(new yy.Literal('true')).addBody($$[$0]);
-break;
-case 149:this.$ = new yy.While(new yy.Literal('true')).addBody(yy.Block.wrap([$$[$0]]));
-break;
-case 150:this.$ = new yy.For($$[$0-1], $$[$0]);
-break;
-case 151:this.$ = new yy.For($$[$0-1], $$[$0]);
-break;
-case 152:this.$ = new yy.For($$[$0], $$[$0-1]);
-break;
-case 153:this.$ = {
- source: new yy.Value($$[$0])
- };
-break;
-case 154:this.$ = (function () {
- $$[$0].own = $$[$0-1].own;
- $$[$0].name = $$[$0-1][0];
- $$[$0].index = $$[$0-1][1];
- return $$[$0];
- }());
-break;
-case 155:this.$ = $$[$0];
-break;
-case 156:this.$ = (function () {
- $$[$0].own = true;
- return $$[$0];
- }());
-break;
-case 157:this.$ = $$[$0];
-break;
-case 158:this.$ = $$[$0];
-break;
-case 159:this.$ = new yy.Value($$[$0]);
-break;
-case 160:this.$ = new yy.Value($$[$0]);
-break;
-case 161:this.$ = [$$[$0]];
-break;
-case 162:this.$ = [$$[$0-2], $$[$0]];
-break;
-case 163:this.$ = {
- source: $$[$0]
- };
-break;
-case 164:this.$ = {
- source: $$[$0],
- object: true
- };
-break;
-case 165:this.$ = {
- source: $$[$0-2],
- guard: $$[$0]
- };
-break;
-case 166:this.$ = {
- source: $$[$0-2],
- guard: $$[$0],
- object: true
- };
-break;
-case 167:this.$ = {
- source: $$[$0-2],
- step: $$[$0]
- };
-break;
-case 168:this.$ = {
- source: $$[$0-4],
- guard: $$[$0-2],
- step: $$[$0]
- };
-break;
-case 169:this.$ = {
- source: $$[$0-4],
- step: $$[$0-2],
- guard: $$[$0]
- };
-break;
-case 170:this.$ = new yy.Switch($$[$0-3], $$[$0-1]);
-break;
-case 171:this.$ = new yy.Switch($$[$0-5], $$[$0-3], $$[$0-1]);
-break;
-case 172:this.$ = new yy.Switch(null, $$[$0-1]);
-break;
-case 173:this.$ = new yy.Switch(null, $$[$0-3], $$[$0-1]);
-break;
-case 174:this.$ = $$[$0];
-break;
-case 175:this.$ = $$[$0-1].concat($$[$0]);
-break;
-case 176:this.$ = [[$$[$0-1], $$[$0]]];
-break;
-case 177:this.$ = [[$$[$0-2], $$[$0-1]]];
-break;
-case 178:this.$ = new yy.If($$[$0-1], $$[$0], {
- type: $$[$0-2]
- });
-break;
-case 179:this.$ = $$[$0-4].addElse(new yy.If($$[$0-1], $$[$0], {
- type: $$[$0-2]
- }));
-break;
-case 180:this.$ = $$[$0];
-break;
-case 181:this.$ = $$[$0-2].addElse($$[$0]);
-break;
-case 182:this.$ = new yy.If($$[$0], yy.Block.wrap([$$[$0-2]]), {
- type: $$[$0-1],
- statement: true
- });
-break;
-case 183:this.$ = new yy.If($$[$0], yy.Block.wrap([$$[$0-2]]), {
- type: $$[$0-1],
- statement: true
- });
-break;
-case 184:this.$ = new yy.Op($$[$0-1], $$[$0]);
-break;
-case 185:this.$ = new yy.Op('-', $$[$0]);
-break;
-case 186:this.$ = new yy.Op('+', $$[$0]);
-break;
-case 187:this.$ = new yy.Op('--', $$[$0]);
-break;
-case 188:this.$ = new yy.Op('++', $$[$0]);
-break;
-case 189:this.$ = new yy.Op('--', $$[$0-1], null, true);
-break;
-case 190:this.$ = new yy.Op('++', $$[$0-1], null, true);
-break;
-case 191:this.$ = new yy.Existence($$[$0-1]);
-break;
-case 192:this.$ = new yy.Op('+', $$[$0-2], $$[$0]);
-break;
-case 193:this.$ = new yy.Op('-', $$[$0-2], $$[$0]);
-break;
-case 194:this.$ = new yy.Op($$[$0-1], $$[$0-2], $$[$0]);
-break;
-case 195:this.$ = new yy.Op($$[$0-1], $$[$0-2], $$[$0]);
-break;
-case 196:this.$ = new yy.Op($$[$0-1], $$[$0-2], $$[$0]);
-break;
-case 197:this.$ = new yy.Op($$[$0-1], $$[$0-2], $$[$0]);
-break;
-case 198:this.$ = (function () {
- if ($$[$0-1].charAt(0) === '!') {
- return new yy.Op($$[$0-1].slice(1), $$[$0-2], $$[$0]).invert();
- } else {
- return new yy.Op($$[$0-1], $$[$0-2], $$[$0]);
- }
- }());
-break;
-case 199:this.$ = new yy.Assign($$[$0-2], $$[$0], $$[$0-1]);
-break;
-case 200:this.$ = new yy.Assign($$[$0-4], $$[$0-1], $$[$0-3]);
-break;
-case 201:this.$ = new yy.Extends($$[$0-2], $$[$0]);
-break;
-}
-},
-table: [{1:[2,1],3:1,4:2,5:3,7:4,8:6,9:7,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,25:[1,5],27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{1:[3]},{1:[2,2],6:[1,74]},{6:[1,75]},{1:[2,4],6:[2,4],26:[2,4],101:[2,4]},{4:77,7:4,8:6,9:7,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,26:[1,76],27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{1:[2,7],6:[2,7],26:[2,7],101:[2,7],102:87,103:[1,65],105:[1,66],108:88,109:[1,68],110:69,125:[1,86],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{1:[2,8],6:[2,8],26:[2,8],101:[2,8],102:90,103:[1,65],105:[1,66],108:91,109:[1,68],110:69,125:[1,89]},{1:[2,12],6:[2,12],25:[2,12],26:[2,12],49:[2,12],54:[2,12],57:[2,12],62:93,66:[1,95],67:[1,96],68:[1,97],69:98,70:[1,99],72:[2,12],73:[1,100],77:[2,12],80:92,83:[1,94],84:[2,107],85:[2,12],90:[2,12],92:[2,12],101:[2,12],103:[2,12],104:[2,12],105:[2,12],109:[2,12],117:[2,12],125:[2,12],127:[2,12],128:[2,12],131:[2,12],132:[2,12],133:[2,12],134:[2,12],135:[2,12],136:[2,12]},{1:[2,13],6:[2,13],25:[2,13],26:[2,13],49:[2,13],54:[2,13],57:[2,13],62:102,66:[1,95],67:[1,96],68:[1,97],69:98,70:[1,99],72:[2,13],73:[1,100],77:[2,13],80:101,83:[1,94],84:[2,107],85:[2,13],90:[2,13],92:[2,13],101:[2,13],103:[2,13],104:[2,13],105:[2,13],109:[2,13],117:[2,13],125:[2,13],127:[2,13],128:[2,13],131:[2,13],132:[2,13],133:[2,13],134:[2,13],135:[2,13],136:[2,13]},{1:[2,14],6:[2,14],25:[2,14],26:[2,14],49:[2,14],54:[2,14],57:[2,14],72:[2,14],77:[2,14],85:[2,14],90:[2,14],92:[2,14],101:[2,14],103:[2,14],104:[2,14],105:[2,14],109:[2,14],117:[2,14],125:[2,14],127:[2,14],128:[2,14],131:[2,14],132:[2,14],133:[2,14],134:[2,14],135:[2,14],136:[2,14]},{1:[2,15],6:[2,15],25:[2,15],26:[2,15],49:[2,15],54:[2,15],57:[2,15],72:[2,15],77:[2,15],85:[2,15],90:[2,15],92:[2,15],101:[2,15],103:[2,15],104:[2,15],105:[2,15],109:[2,15],117:[2,15],125:[2,15],127:[2,15],128:[2,15],131:[2,15],132:[2,15],133:[2,15],134:[2,15],135:[2,15],136:[2,15]},{1:[2,16],6:[2,16],25:[2,16],26:[2,16],49:[2,16],54:[2,16],57:[2,16],72:[2,16],77:[2,16],85:[2,16],90:[2,16],92:[2,16],101:[2,16],103:[2,16],104:[2,16],105:[2,16],109:[2,16],117:[2,16],125:[2,16],127:[2,16],128:[2,16],131:[2,16],132:[2,16],133:[2,16],134:[2,16],135:[2,16],136:[2,16]},{1:[2,17],6:[2,17],25:[2,17],26:[2,17],49:[2,17],54:[2,17],57:[2,17],72:[2,17],77:[2,17],85:[2,17],90:[2,17],92:[2,17],101:[2,17],103:[2,17],104:[2,17],105:[2,17],109:[2,17],117:[2,17],125:[2,17],127:[2,17],128:[2,17],131:[2,17],132:[2,17],133:[2,17],134:[2,17],135:[2,17],136:[2,17]},{1:[2,18],6:[2,18],25:[2,18],26:[2,18],49:[2,18],54:[2,18],57:[2,18],72:[2,18],77:[2,18],85:[2,18],90:[2,18],92:[2,18],101:[2,18],103:[2,18],104:[2,18],105:[2,18],109:[2,18],117:[2,18],125:[2,18],127:[2,18],128:[2,18],131:[2,18],132:[2,18],133:[2,18],134:[2,18],135:[2,18],136:[2,18]},{1:[2,19],6:[2,19],25:[2,19],26:[2,19],49:[2,19],54:[2,19],57:[2,19],72:[2,19],77:[2,19],85:[2,19],90:[2,19],92:[2,19],101:[2,19],103:[2,19],104:[2,19],105:[2,19],109:[2,19],117:[2,19],125:[2,19],127:[2,19],128:[2,19],131:[2,19],132:[2,19],133:[2,19],134:[2,19],135:[2,19],136:[2,19]},{1:[2,20],6:[2,20],25:[2,20],26:[2,20],49:[2,20],54:[2,20],57:[2,20],72:[2,20],77:[2,20],85:[2,20],90:[2,20],92:[2,20],101:[2,20],103:[2,20],104:[2,20],105:[2,20],109:[2,20],117:[2,20],125:[2,20],127:[2,20],128:[2,20],131:[2,20],132:[2,20],133:[2,20],134:[2,20],135:[2,20],136:[2,20]},{1:[2,21],6:[2,21],25:[2,21],26:[2,21],49:[2,21],54:[2,21],57:[2,21],72:[2,21],77:[2,21],85:[2,21],90:[2,21],92:[2,21],101:[2,21],103:[2,21],104:[2,21],105:[2,21],109:[2,21],117:[2,21],125:[2,21],127:[2,21],128:[2,21],131:[2,21],132:[2,21],133:[2,21],134:[2,21],135:[2,21],136:[2,21]},{1:[2,22],6:[2,22],25:[2,22],26:[2,22],49:[2,22],54:[2,22],57:[2,22],72:[2,22],77:[2,22],85:[2,22],90:[2,22],92:[2,22],101:[2,22],103:[2,22],104:[2,22],105:[2,22],109:[2,22],117:[2,22],125:[2,22],127:[2,22],128:[2,22],131:[2,22],132:[2,22],133:[2,22],134:[2,22],135:[2,22],136:[2,22]},{1:[2,23],6:[2,23],25:[2,23],26:[2,23],49:[2,23],54:[2,23],57:[2,23],72:[2,23],77:[2,23],85:[2,23],90:[2,23],92:[2,23],101:[2,23],103:[2,23],104:[2,23],105:[2,23],109:[2,23],117:[2,23],125:[2,23],127:[2,23],128:[2,23],131:[2,23],132:[2,23],133:[2,23],134:[2,23],135:[2,23],136:[2,23]},{1:[2,9],6:[2,9],26:[2,9],101:[2,9],103:[2,9],105:[2,9],109:[2,9],125:[2,9]},{1:[2,10],6:[2,10],26:[2,10],101:[2,10],103:[2,10],105:[2,10],109:[2,10],125:[2,10]},{1:[2,11],6:[2,11],26:[2,11],101:[2,11],103:[2,11],105:[2,11],109:[2,11],125:[2,11]},{1:[2,75],6:[2,75],25:[2,75],26:[2,75],40:[1,103],49:[2,75],54:[2,75],57:[2,75],66:[2,75],67:[2,75],68:[2,75],70:[2,75],72:[2,75],73:[2,75],77:[2,75],83:[2,75],84:[2,75],85:[2,75],90:[2,75],92:[2,75],101:[2,75],103:[2,75],104:[2,75],105:[2,75],109:[2,75],117:[2,75],125:[2,75],127:[2,75],128:[2,75],131:[2,75],132:[2,75],133:[2,75],134:[2,75],135:[2,75],136:[2,75]},{1:[2,76],6:[2,76],25:[2,76],26:[2,76],49:[2,76],54:[2,76],57:[2,76],66:[2,76],67:[2,76],68:[2,76],70:[2,76],72:[2,76],73:[2,76],77:[2,76],83:[2,76],84:[2,76],85:[2,76],90:[2,76],92:[2,76],101:[2,76],103:[2,76],104:[2,76],105:[2,76],109:[2,76],117:[2,76],125:[2,76],127:[2,76],128:[2,76],131:[2,76],132:[2,76],133:[2,76],134:[2,76],135:[2,76],136:[2,76]},{1:[2,77],6:[2,77],25:[2,77],26:[2,77],49:[2,77],54:[2,77],57:[2,77],66:[2,77],67:[2,77],68:[2,77],70:[2,77],72:[2,77],73:[2,77],77:[2,77],83:[2,77],84:[2,77],85:[2,77],90:[2,77],92:[2,77],101:[2,77],103:[2,77],104:[2,77],105:[2,77],109:[2,77],117:[2,77],125:[2,77],127:[2,77],128:[2,77],131:[2,77],132:[2,77],133:[2,77],134:[2,77],135:[2,77],136:[2,77]},{1:[2,78],6:[2,78],25:[2,78],26:[2,78],49:[2,78],54:[2,78],57:[2,78],66:[2,78],67:[2,78],68:[2,78],70:[2,78],72:[2,78],73:[2,78],77:[2,78],83:[2,78],84:[2,78],85:[2,78],90:[2,78],92:[2,78],101:[2,78],103:[2,78],104:[2,78],105:[2,78],109:[2,78],117:[2,78],125:[2,78],127:[2,78],128:[2,78],131:[2,78],132:[2,78],133:[2,78],134:[2,78],135:[2,78],136:[2,78]},{1:[2,79],6:[2,79],25:[2,79],26:[2,79],49:[2,79],54:[2,79],57:[2,79],66:[2,79],67:[2,79],68:[2,79],70:[2,79],72:[2,79],73:[2,79],77:[2,79],83:[2,79],84:[2,79],85:[2,79],90:[2,79],92:[2,79],101:[2,79],103:[2,79],104:[2,79],105:[2,79],109:[2,79],117:[2,79],125:[2,79],127:[2,79],128:[2,79],131:[2,79],132:[2,79],133:[2,79],134:[2,79],135:[2,79],136:[2,79]},{1:[2,105],6:[2,105],25:[2,105],26:[2,105],49:[2,105],54:[2,105],57:[2,105],66:[2,105],67:[2,105],68:[2,105],70:[2,105],72:[2,105],73:[2,105],77:[2,105],81:104,83:[2,105],84:[1,105],85:[2,105],90:[2,105],92:[2,105],101:[2,105],103:[2,105],104:[2,105],105:[2,105],109:[2,105],117:[2,105],125:[2,105],127:[2,105],128:[2,105],131:[2,105],132:[2,105],133:[2,105],134:[2,105],135:[2,105],136:[2,105]},{6:[2,55],25:[2,55],27:109,28:[1,73],44:110,48:106,49:[2,55],54:[2,55],55:107,56:108,58:111,59:112,75:[1,70],88:[1,113],89:[1,114]},{5:115,25:[1,5]},{8:116,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{8:118,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{8:119,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{13:121,14:122,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:123,44:63,58:47,59:48,61:120,63:25,64:26,65:27,75:[1,70],82:[1,28],87:[1,58],88:[1,59],89:[1,57],100:[1,56]},{13:121,14:122,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:123,44:63,58:47,59:48,61:124,63:25,64:26,65:27,75:[1,70],82:[1,28],87:[1,58],88:[1,59],89:[1,57],100:[1,56]},{1:[2,72],6:[2,72],25:[2,72],26:[2,72],40:[2,72],49:[2,72],54:[2,72],57:[2,72],66:[2,72],67:[2,72],68:[2,72],70:[2,72],72:[2,72],73:[2,72],77:[2,72],79:[1,128],83:[2,72],84:[2,72],85:[2,72],90:[2,72],92:[2,72],101:[2,72],103:[2,72],104:[2,72],105:[2,72],109:[2,72],117:[2,72],125:[2,72],127:[2,72],128:[2,72],129:[1,125],130:[1,126],131:[2,72],132:[2,72],133:[2,72],134:[2,72],135:[2,72],136:[2,72],137:[1,127]},{1:[2,180],6:[2,180],25:[2,180],26:[2,180],49:[2,180],54:[2,180],57:[2,180],72:[2,180],77:[2,180],85:[2,180],90:[2,180],92:[2,180],101:[2,180],103:[2,180],104:[2,180],105:[2,180],109:[2,180],117:[2,180],120:[1,129],125:[2,180],127:[2,180],128:[2,180],131:[2,180],132:[2,180],133:[2,180],134:[2,180],135:[2,180],136:[2,180]},{5:130,25:[1,5]},{5:131,25:[1,5]},{1:[2,147],6:[2,147],25:[2,147],26:[2,147],49:[2,147],54:[2,147],57:[2,147],72:[2,147],77:[2,147],85:[2,147],90:[2,147],92:[2,147],101:[2,147],103:[2,147],104:[2,147],105:[2,147],109:[2,147],117:[2,147],125:[2,147],127:[2,147],128:[2,147],131:[2,147],132:[2,147],133:[2,147],134:[2,147],135:[2,147],136:[2,147]},{5:132,25:[1,5]},{8:133,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,25:[1,134],27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{1:[2,95],5:135,6:[2,95],13:121,14:122,25:[1,5],26:[2,95],27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:123,44:63,49:[2,95],54:[2,95],57:[2,95],58:47,59:48,61:137,63:25,64:26,65:27,72:[2,95],75:[1,70],77:[2,95],79:[1,136],82:[1,28],85:[2,95],87:[1,58],88:[1,59],89:[1,57],90:[2,95],92:[2,95],100:[1,56],101:[2,95],103:[2,95],104:[2,95],105:[2,95],109:[2,95],117:[2,95],125:[2,95],127:[2,95],128:[2,95],131:[2,95],132:[2,95],133:[2,95],134:[2,95],135:[2,95],136:[2,95]},{8:138,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{1:[2,47],6:[2,47],8:139,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,26:[2,47],27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],101:[2,47],102:39,103:[2,47],105:[2,47],106:40,107:[1,67],108:41,109:[2,47],110:69,118:[1,42],123:37,124:[1,64],125:[2,47],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{1:[2,48],6:[2,48],25:[2,48],26:[2,48],54:[2,48],77:[2,48],101:[2,48],103:[2,48],105:[2,48],109:[2,48],125:[2,48]},{1:[2,73],6:[2,73],25:[2,73],26:[2,73],40:[2,73],49:[2,73],54:[2,73],57:[2,73],66:[2,73],67:[2,73],68:[2,73],70:[2,73],72:[2,73],73:[2,73],77:[2,73],83:[2,73],84:[2,73],85:[2,73],90:[2,73],92:[2,73],101:[2,73],103:[2,73],104:[2,73],105:[2,73],109:[2,73],117:[2,73],125:[2,73],127:[2,73],128:[2,73],131:[2,73],132:[2,73],133:[2,73],134:[2,73],135:[2,73],136:[2,73]},{1:[2,74],6:[2,74],25:[2,74],26:[2,74],40:[2,74],49:[2,74],54:[2,74],57:[2,74],66:[2,74],67:[2,74],68:[2,74],70:[2,74],72:[2,74],73:[2,74],77:[2,74],83:[2,74],84:[2,74],85:[2,74],90:[2,74],92:[2,74],101:[2,74],103:[2,74],104:[2,74],105:[2,74],109:[2,74],117:[2,74],125:[2,74],127:[2,74],128:[2,74],131:[2,74],132:[2,74],133:[2,74],134:[2,74],135:[2,74],136:[2,74]},{1:[2,29],6:[2,29],25:[2,29],26:[2,29],49:[2,29],54:[2,29],57:[2,29],66:[2,29],67:[2,29],68:[2,29],70:[2,29],72:[2,29],73:[2,29],77:[2,29],83:[2,29],84:[2,29],85:[2,29],90:[2,29],92:[2,29],101:[2,29],103:[2,29],104:[2,29],105:[2,29],109:[2,29],117:[2,29],125:[2,29],127:[2,29],128:[2,29],131:[2,29],132:[2,29],133:[2,29],134:[2,29],135:[2,29],136:[2,29]},{1:[2,30],6:[2,30],25:[2,30],26:[2,30],49:[2,30],54:[2,30],57:[2,30],66:[2,30],67:[2,30],68:[2,30],70:[2,30],72:[2,30],73:[2,30],77:[2,30],83:[2,30],84:[2,30],85:[2,30],90:[2,30],92:[2,30],101:[2,30],103:[2,30],104:[2,30],105:[2,30],109:[2,30],117:[2,30],125:[2,30],127:[2,30],128:[2,30],131:[2,30],132:[2,30],133:[2,30],134:[2,30],135:[2,30],136:[2,30]},{1:[2,31],6:[2,31],25:[2,31],26:[2,31],49:[2,31],54:[2,31],57:[2,31],66:[2,31],67:[2,31],68:[2,31],70:[2,31],72:[2,31],73:[2,31],77:[2,31],83:[2,31],84:[2,31],85:[2,31],90:[2,31],92:[2,31],101:[2,31],103:[2,31],104:[2,31],105:[2,31],109:[2,31],117:[2,31],125:[2,31],127:[2,31],128:[2,31],131:[2,31],132:[2,31],133:[2,31],134:[2,31],135:[2,31],136:[2,31]},{1:[2,32],6:[2,32],25:[2,32],26:[2,32],49:[2,32],54:[2,32],57:[2,32],66:[2,32],67:[2,32],68:[2,32],70:[2,32],72:[2,32],73:[2,32],77:[2,32],83:[2,32],84:[2,32],85:[2,32],90:[2,32],92:[2,32],101:[2,32],103:[2,32],104:[2,32],105:[2,32],109:[2,32],117:[2,32],125:[2,32],127:[2,32],128:[2,32],131:[2,32],132:[2,32],133:[2,32],134:[2,32],135:[2,32],136:[2,32]},{1:[2,33],6:[2,33],25:[2,33],26:[2,33],49:[2,33],54:[2,33],57:[2,33],66:[2,33],67:[2,33],68:[2,33],70:[2,33],72:[2,33],73:[2,33],77:[2,33],83:[2,33],84:[2,33],85:[2,33],90:[2,33],92:[2,33],101:[2,33],103:[2,33],104:[2,33],105:[2,33],109:[2,33],117:[2,33],125:[2,33],127:[2,33],128:[2,33],131:[2,33],132:[2,33],133:[2,33],134:[2,33],135:[2,33],136:[2,33]},{1:[2,34],6:[2,34],25:[2,34],26:[2,34],49:[2,34],54:[2,34],57:[2,34],66:[2,34],67:[2,34],68:[2,34],70:[2,34],72:[2,34],73:[2,34],77:[2,34],83:[2,34],84:[2,34],85:[2,34],90:[2,34],92:[2,34],101:[2,34],103:[2,34],104:[2,34],105:[2,34],109:[2,34],117:[2,34],125:[2,34],127:[2,34],128:[2,34],131:[2,34],132:[2,34],133:[2,34],134:[2,34],135:[2,34],136:[2,34]},{1:[2,35],6:[2,35],25:[2,35],26:[2,35],49:[2,35],54:[2,35],57:[2,35],66:[2,35],67:[2,35],68:[2,35],70:[2,35],72:[2,35],73:[2,35],77:[2,35],83:[2,35],84:[2,35],85:[2,35],90:[2,35],92:[2,35],101:[2,35],103:[2,35],104:[2,35],105:[2,35],109:[2,35],117:[2,35],125:[2,35],127:[2,35],128:[2,35],131:[2,35],132:[2,35],133:[2,35],134:[2,35],135:[2,35],136:[2,35]},{4:140,7:4,8:6,9:7,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,25:[1,141],27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{8:142,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,25:[1,146],27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,60:147,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],86:144,87:[1,58],88:[1,59],89:[1,57],90:[1,143],93:145,95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{1:[2,111],6:[2,111],25:[2,111],26:[2,111],49:[2,111],54:[2,111],57:[2,111],66:[2,111],67:[2,111],68:[2,111],70:[2,111],72:[2,111],73:[2,111],77:[2,111],83:[2,111],84:[2,111],85:[2,111],90:[2,111],92:[2,111],101:[2,111],103:[2,111],104:[2,111],105:[2,111],109:[2,111],117:[2,111],125:[2,111],127:[2,111],128:[2,111],131:[2,111],132:[2,111],133:[2,111],134:[2,111],135:[2,111],136:[2,111]},{1:[2,112],6:[2,112],25:[2,112],26:[2,112],27:148,28:[1,73],49:[2,112],54:[2,112],57:[2,112],66:[2,112],67:[2,112],68:[2,112],70:[2,112],72:[2,112],73:[2,112],77:[2,112],83:[2,112],84:[2,112],85:[2,112],90:[2,112],92:[2,112],101:[2,112],103:[2,112],104:[2,112],105:[2,112],109:[2,112],117:[2,112],125:[2,112],127:[2,112],128:[2,112],131:[2,112],132:[2,112],133:[2,112],134:[2,112],135:[2,112],136:[2,112]},{25:[2,51]},{25:[2,52]},{1:[2,68],6:[2,68],25:[2,68],26:[2,68],40:[2,68],49:[2,68],54:[2,68],57:[2,68],66:[2,68],67:[2,68],68:[2,68],70:[2,68],72:[2,68],73:[2,68],77:[2,68],79:[2,68],83:[2,68],84:[2,68],85:[2,68],90:[2,68],92:[2,68],101:[2,68],103:[2,68],104:[2,68],105:[2,68],109:[2,68],117:[2,68],125:[2,68],127:[2,68],128:[2,68],129:[2,68],130:[2,68],131:[2,68],132:[2,68],133:[2,68],134:[2,68],135:[2,68],136:[2,68],137:[2,68]},{1:[2,71],6:[2,71],25:[2,71],26:[2,71],40:[2,71],49:[2,71],54:[2,71],57:[2,71],66:[2,71],67:[2,71],68:[2,71],70:[2,71],72:[2,71],73:[2,71],77:[2,71],79:[2,71],83:[2,71],84:[2,71],85:[2,71],90:[2,71],92:[2,71],101:[2,71],103:[2,71],104:[2,71],105:[2,71],109:[2,71],117:[2,71],125:[2,71],127:[2,71],128:[2,71],129:[2,71],130:[2,71],131:[2,71],132:[2,71],133:[2,71],134:[2,71],135:[2,71],136:[2,71],137:[2,71]},{8:149,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{8:150,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{8:151,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{5:152,8:153,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,25:[1,5],27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{27:158,28:[1,73],44:159,58:160,59:161,64:154,75:[1,70],88:[1,113],89:[1,57],112:155,113:[1,156],114:157},{111:162,115:[1,163],116:[1,164]},{6:[2,90],11:168,25:[2,90],27:169,28:[1,73],29:170,30:[1,71],31:[1,72],41:166,42:167,44:171,46:[1,46],54:[2,90],76:165,77:[2,90],88:[1,113]},{1:[2,27],6:[2,27],25:[2,27],26:[2,27],43:[2,27],49:[2,27],54:[2,27],57:[2,27],66:[2,27],67:[2,27],68:[2,27],70:[2,27],72:[2,27],73:[2,27],77:[2,27],83:[2,27],84:[2,27],85:[2,27],90:[2,27],92:[2,27],101:[2,27],103:[2,27],104:[2,27],105:[2,27],109:[2,27],117:[2,27],125:[2,27],127:[2,27],128:[2,27],131:[2,27],132:[2,27],133:[2,27],134:[2,27],135:[2,27],136:[2,27]},{1:[2,28],6:[2,28],25:[2,28],26:[2,28],43:[2,28],49:[2,28],54:[2,28],57:[2,28],66:[2,28],67:[2,28],68:[2,28],70:[2,28],72:[2,28],73:[2,28],77:[2,28],83:[2,28],84:[2,28],85:[2,28],90:[2,28],92:[2,28],101:[2,28],103:[2,28],104:[2,28],105:[2,28],109:[2,28],117:[2,28],125:[2,28],127:[2,28],128:[2,28],131:[2,28],132:[2,28],133:[2,28],134:[2,28],135:[2,28],136:[2,28]},{1:[2,26],6:[2,26],25:[2,26],26:[2,26],40:[2,26],43:[2,26],49:[2,26],54:[2,26],57:[2,26],66:[2,26],67:[2,26],68:[2,26],70:[2,26],72:[2,26],73:[2,26],77:[2,26],79:[2,26],83:[2,26],84:[2,26],85:[2,26],90:[2,26],92:[2,26],101:[2,26],103:[2,26],104:[2,26],105:[2,26],109:[2,26],115:[2,26],116:[2,26],117:[2,26],125:[2,26],127:[2,26],128:[2,26],129:[2,26],130:[2,26],131:[2,26],132:[2,26],133:[2,26],134:[2,26],135:[2,26],136:[2,26],137:[2,26]},{1:[2,6],6:[2,6],7:172,8:6,9:7,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,26:[2,6],27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],101:[2,6],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{1:[2,3]},{1:[2,24],6:[2,24],25:[2,24],26:[2,24],49:[2,24],54:[2,24],57:[2,24],72:[2,24],77:[2,24],85:[2,24],90:[2,24],92:[2,24],97:[2,24],98:[2,24],101:[2,24],103:[2,24],104:[2,24],105:[2,24],109:[2,24],117:[2,24],120:[2,24],122:[2,24],125:[2,24],127:[2,24],128:[2,24],131:[2,24],132:[2,24],133:[2,24],134:[2,24],135:[2,24],136:[2,24]},{6:[1,74],26:[1,173]},{1:[2,191],6:[2,191],25:[2,191],26:[2,191],49:[2,191],54:[2,191],57:[2,191],72:[2,191],77:[2,191],85:[2,191],90:[2,191],92:[2,191],101:[2,191],103:[2,191],104:[2,191],105:[2,191],109:[2,191],117:[2,191],125:[2,191],127:[2,191],128:[2,191],131:[2,191],132:[2,191],133:[2,191],134:[2,191],135:[2,191],136:[2,191]},{8:174,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{8:175,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{8:176,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{8:177,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{8:178,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{8:179,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{8:180,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{8:181,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{1:[2,146],6:[2,146],25:[2,146],26:[2,146],49:[2,146],54:[2,146],57:[2,146],72:[2,146],77:[2,146],85:[2,146],90:[2,146],92:[2,146],101:[2,146],103:[2,146],104:[2,146],105:[2,146],109:[2,146],117:[2,146],125:[2,146],127:[2,146],128:[2,146],131:[2,146],132:[2,146],133:[2,146],134:[2,146],135:[2,146],136:[2,146]},{1:[2,151],6:[2,151],25:[2,151],26:[2,151],49:[2,151],54:[2,151],57:[2,151],72:[2,151],77:[2,151],85:[2,151],90:[2,151],92:[2,151],101:[2,151],103:[2,151],104:[2,151],105:[2,151],109:[2,151],117:[2,151],125:[2,151],127:[2,151],128:[2,151],131:[2,151],132:[2,151],133:[2,151],134:[2,151],135:[2,151],136:[2,151]},{8:182,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{1:[2,145],6:[2,145],25:[2,145],26:[2,145],49:[2,145],54:[2,145],57:[2,145],72:[2,145],77:[2,145],85:[2,145],90:[2,145],92:[2,145],101:[2,145],103:[2,145],104:[2,145],105:[2,145],109:[2,145],117:[2,145],125:[2,145],127:[2,145],128:[2,145],131:[2,145],132:[2,145],133:[2,145],134:[2,145],135:[2,145],136:[2,145]},{1:[2,150],6:[2,150],25:[2,150],26:[2,150],49:[2,150],54:[2,150],57:[2,150],72:[2,150],77:[2,150],85:[2,150],90:[2,150],92:[2,150],101:[2,150],103:[2,150],104:[2,150],105:[2,150],109:[2,150],117:[2,150],125:[2,150],127:[2,150],128:[2,150],131:[2,150],132:[2,150],133:[2,150],134:[2,150],135:[2,150],136:[2,150]},{81:183,84:[1,105]},{1:[2,69],6:[2,69],25:[2,69],26:[2,69],40:[2,69],49:[2,69],54:[2,69],57:[2,69],66:[2,69],67:[2,69],68:[2,69],70:[2,69],72:[2,69],73:[2,69],77:[2,69],79:[2,69],83:[2,69],84:[2,69],85:[2,69],90:[2,69],92:[2,69],101:[2,69],103:[2,69],104:[2,69],105:[2,69],109:[2,69],117:[2,69],125:[2,69],127:[2,69],128:[2,69],129:[2,69],130:[2,69],131:[2,69],132:[2,69],133:[2,69],134:[2,69],135:[2,69],136:[2,69],137:[2,69]},{84:[2,108]},{27:184,28:[1,73]},{27:185,28:[1,73]},{1:[2,83],6:[2,83],25:[2,83],26:[2,83],27:186,28:[1,73],40:[2,83],49:[2,83],54:[2,83],57:[2,83],66:[2,83],67:[2,83],68:[2,83],70:[2,83],72:[2,83],73:[2,83],77:[2,83],79:[2,83],83:[2,83],84:[2,83],85:[2,83],90:[2,83],92:[2,83],101:[2,83],103:[2,83],104:[2,83],105:[2,83],109:[2,83],117:[2,83],125:[2,83],127:[2,83],128:[2,83],129:[2,83],130:[2,83],131:[2,83],132:[2,83],133:[2,83],134:[2,83],135:[2,83],136:[2,83],137:[2,83]},{1:[2,84],6:[2,84],25:[2,84],26:[2,84],40:[2,84],49:[2,84],54:[2,84],57:[2,84],66:[2,84],67:[2,84],68:[2,84],70:[2,84],72:[2,84],73:[2,84],77:[2,84],79:[2,84],83:[2,84],84:[2,84],85:[2,84],90:[2,84],92:[2,84],101:[2,84],103:[2,84],104:[2,84],105:[2,84],109:[2,84],117:[2,84],125:[2,84],127:[2,84],128:[2,84],129:[2,84],130:[2,84],131:[2,84],132:[2,84],133:[2,84],134:[2,84],135:[2,84],136:[2,84],137:[2,84]},{8:188,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],57:[1,192],58:47,59:48,61:36,63:25,64:26,65:27,71:187,74:189,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],91:190,92:[1,191],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{69:193,70:[1,99],73:[1,100]},{81:194,84:[1,105]},{1:[2,70],6:[2,70],25:[2,70],26:[2,70],40:[2,70],49:[2,70],54:[2,70],57:[2,70],66:[2,70],67:[2,70],68:[2,70],70:[2,70],72:[2,70],73:[2,70],77:[2,70],79:[2,70],83:[2,70],84:[2,70],85:[2,70],90:[2,70],92:[2,70],101:[2,70],103:[2,70],104:[2,70],105:[2,70],109:[2,70],117:[2,70],125:[2,70],127:[2,70],128:[2,70],129:[2,70],130:[2,70],131:[2,70],132:[2,70],133:[2,70],134:[2,70],135:[2,70],136:[2,70],137:[2,70]},{6:[1,196],8:195,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,25:[1,197],27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{1:[2,106],6:[2,106],25:[2,106],26:[2,106],49:[2,106],54:[2,106],57:[2,106],66:[2,106],67:[2,106],68:[2,106],70:[2,106],72:[2,106],73:[2,106],77:[2,106],83:[2,106],84:[2,106],85:[2,106],90:[2,106],92:[2,106],101:[2,106],103:[2,106],104:[2,106],105:[2,106],109:[2,106],117:[2,106],125:[2,106],127:[2,106],128:[2,106],131:[2,106],132:[2,106],133:[2,106],134:[2,106],135:[2,106],136:[2,106]},{8:200,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,25:[1,146],27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,60:147,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],85:[1,198],86:199,87:[1,58],88:[1,59],89:[1,57],93:145,95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{6:[2,53],25:[2,53],49:[1,201],53:203,54:[1,202]},{6:[2,56],25:[2,56],26:[2,56],49:[2,56],54:[2,56]},{6:[2,60],25:[2,60],26:[2,60],40:[1,205],49:[2,60],54:[2,60],57:[1,204]},{6:[2,63],25:[2,63],26:[2,63],40:[2,63],49:[2,63],54:[2,63],57:[2,63]},{6:[2,64],25:[2,64],26:[2,64],40:[2,64],49:[2,64],54:[2,64],57:[2,64]},{6:[2,65],25:[2,65],26:[2,65],40:[2,65],49:[2,65],54:[2,65],57:[2,65]},{6:[2,66],25:[2,66],26:[2,66],40:[2,66],49:[2,66],54:[2,66],57:[2,66]},{27:148,28:[1,73]},{8:200,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,25:[1,146],27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,60:147,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],86:144,87:[1,58],88:[1,59],89:[1,57],90:[1,143],93:145,95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{1:[2,50],6:[2,50],25:[2,50],26:[2,50],49:[2,50],54:[2,50],57:[2,50],72:[2,50],77:[2,50],85:[2,50],90:[2,50],92:[2,50],101:[2,50],103:[2,50],104:[2,50],105:[2,50],109:[2,50],117:[2,50],125:[2,50],127:[2,50],128:[2,50],131:[2,50],132:[2,50],133:[2,50],134:[2,50],135:[2,50],136:[2,50]},{1:[2,184],6:[2,184],25:[2,184],26:[2,184],49:[2,184],54:[2,184],57:[2,184],72:[2,184],77:[2,184],85:[2,184],90:[2,184],92:[2,184],101:[2,184],102:87,103:[2,184],104:[2,184],105:[2,184],108:88,109:[2,184],110:69,117:[2,184],125:[2,184],127:[2,184],128:[2,184],131:[1,78],132:[2,184],133:[2,184],134:[2,184],135:[2,184],136:[2,184]},{102:90,103:[1,65],105:[1,66],108:91,109:[1,68],110:69,125:[1,89]},{1:[2,185],6:[2,185],25:[2,185],26:[2,185],49:[2,185],54:[2,185],57:[2,185],72:[2,185],77:[2,185],85:[2,185],90:[2,185],92:[2,185],101:[2,185],102:87,103:[2,185],104:[2,185],105:[2,185],108:88,109:[2,185],110:69,117:[2,185],125:[2,185],127:[2,185],128:[2,185],131:[1,78],132:[2,185],133:[2,185],134:[2,185],135:[2,185],136:[2,185]},{1:[2,186],6:[2,186],25:[2,186],26:[2,186],49:[2,186],54:[2,186],57:[2,186],72:[2,186],77:[2,186],85:[2,186],90:[2,186],92:[2,186],101:[2,186],102:87,103:[2,186],104:[2,186],105:[2,186],108:88,109:[2,186],110:69,117:[2,186],125:[2,186],127:[2,186],128:[2,186],131:[1,78],132:[2,186],133:[2,186],134:[2,186],135:[2,186],136:[2,186]},{1:[2,187],6:[2,187],25:[2,187],26:[2,187],49:[2,187],54:[2,187],57:[2,187],66:[2,72],67:[2,72],68:[2,72],70:[2,72],72:[2,187],73:[2,72],77:[2,187],83:[2,72],84:[2,72],85:[2,187],90:[2,187],92:[2,187],101:[2,187],103:[2,187],104:[2,187],105:[2,187],109:[2,187],117:[2,187],125:[2,187],127:[2,187],128:[2,187],131:[2,187],132:[2,187],133:[2,187],134:[2,187],135:[2,187],136:[2,187]},{62:93,66:[1,95],67:[1,96],68:[1,97],69:98,70:[1,99],73:[1,100],80:92,83:[1,94],84:[2,107]},{62:102,66:[1,95],67:[1,96],68:[1,97],69:98,70:[1,99],73:[1,100],80:101,83:[1,94],84:[2,107]},{66:[2,75],67:[2,75],68:[2,75],70:[2,75],73:[2,75],83:[2,75],84:[2,75]},{1:[2,188],6:[2,188],25:[2,188],26:[2,188],49:[2,188],54:[2,188],57:[2,188],66:[2,72],67:[2,72],68:[2,72],70:[2,72],72:[2,188],73:[2,72],77:[2,188],83:[2,72],84:[2,72],85:[2,188],90:[2,188],92:[2,188],101:[2,188],103:[2,188],104:[2,188],105:[2,188],109:[2,188],117:[2,188],125:[2,188],127:[2,188],128:[2,188],131:[2,188],132:[2,188],133:[2,188],134:[2,188],135:[2,188],136:[2,188]},{1:[2,189],6:[2,189],25:[2,189],26:[2,189],49:[2,189],54:[2,189],57:[2,189],72:[2,189],77:[2,189],85:[2,189],90:[2,189],92:[2,189],101:[2,189],103:[2,189],104:[2,189],105:[2,189],109:[2,189],117:[2,189],125:[2,189],127:[2,189],128:[2,189],131:[2,189],132:[2,189],133:[2,189],134:[2,189],135:[2,189],136:[2,189]},{1:[2,190],6:[2,190],25:[2,190],26:[2,190],49:[2,190],54:[2,190],57:[2,190],72:[2,190],77:[2,190],85:[2,190],90:[2,190],92:[2,190],101:[2,190],103:[2,190],104:[2,190],105:[2,190],109:[2,190],117:[2,190],125:[2,190],127:[2,190],128:[2,190],131:[2,190],132:[2,190],133:[2,190],134:[2,190],135:[2,190],136:[2,190]},{8:206,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,25:[1,207],27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{8:208,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{5:209,25:[1,5],124:[1,210]},{1:[2,132],6:[2,132],25:[2,132],26:[2,132],49:[2,132],54:[2,132],57:[2,132],72:[2,132],77:[2,132],85:[2,132],90:[2,132],92:[2,132],96:211,97:[1,212],98:[1,213],101:[2,132],103:[2,132],104:[2,132],105:[2,132],109:[2,132],117:[2,132],125:[2,132],127:[2,132],128:[2,132],131:[2,132],132:[2,132],133:[2,132],134:[2,132],135:[2,132],136:[2,132]},{1:[2,144],6:[2,144],25:[2,144],26:[2,144],49:[2,144],54:[2,144],57:[2,144],72:[2,144],77:[2,144],85:[2,144],90:[2,144],92:[2,144],101:[2,144],103:[2,144],104:[2,144],105:[2,144],109:[2,144],117:[2,144],125:[2,144],127:[2,144],128:[2,144],131:[2,144],132:[2,144],133:[2,144],134:[2,144],135:[2,144],136:[2,144]},{1:[2,152],6:[2,152],25:[2,152],26:[2,152],49:[2,152],54:[2,152],57:[2,152],72:[2,152],77:[2,152],85:[2,152],90:[2,152],92:[2,152],101:[2,152],103:[2,152],104:[2,152],105:[2,152],109:[2,152],117:[2,152],125:[2,152],127:[2,152],128:[2,152],131:[2,152],132:[2,152],133:[2,152],134:[2,152],135:[2,152],136:[2,152]},{25:[1,214],102:87,103:[1,65],105:[1,66],108:88,109:[1,68],110:69,125:[1,86],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{119:215,121:216,122:[1,217]},{1:[2,96],6:[2,96],25:[2,96],26:[2,96],49:[2,96],54:[2,96],57:[2,96],72:[2,96],77:[2,96],85:[2,96],90:[2,96],92:[2,96],101:[2,96],103:[2,96],104:[2,96],105:[2,96],109:[2,96],117:[2,96],125:[2,96],127:[2,96],128:[2,96],131:[2,96],132:[2,96],133:[2,96],134:[2,96],135:[2,96],136:[2,96]},{8:218,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{1:[2,99],5:219,6:[2,99],25:[1,5],26:[2,99],49:[2,99],54:[2,99],57:[2,99],66:[2,72],67:[2,72],68:[2,72],70:[2,72],72:[2,99],73:[2,72],77:[2,99],79:[1,220],83:[2,72],84:[2,72],85:[2,99],90:[2,99],92:[2,99],101:[2,99],103:[2,99],104:[2,99],105:[2,99],109:[2,99],117:[2,99],125:[2,99],127:[2,99],128:[2,99],131:[2,99],132:[2,99],133:[2,99],134:[2,99],135:[2,99],136:[2,99]},{1:[2,137],6:[2,137],25:[2,137],26:[2,137],49:[2,137],54:[2,137],57:[2,137],72:[2,137],77:[2,137],85:[2,137],90:[2,137],92:[2,137],101:[2,137],102:87,103:[2,137],104:[2,137],105:[2,137],108:88,109:[2,137],110:69,117:[2,137],125:[2,137],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{1:[2,46],6:[2,46],26:[2,46],101:[2,46],102:87,103:[2,46],105:[2,46],108:88,109:[2,46],110:69,125:[2,46],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{6:[1,74],101:[1,221]},{4:222,7:4,8:6,9:7,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{6:[2,128],25:[2,128],54:[2,128],57:[1,224],90:[2,128],91:223,92:[1,191],102:87,103:[1,65],105:[1,66],108:88,109:[1,68],110:69,125:[1,86],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{1:[2,114],6:[2,114],25:[2,114],26:[2,114],40:[2,114],49:[2,114],54:[2,114],57:[2,114],66:[2,114],67:[2,114],68:[2,114],70:[2,114],72:[2,114],73:[2,114],77:[2,114],83:[2,114],84:[2,114],85:[2,114],90:[2,114],92:[2,114],101:[2,114],103:[2,114],104:[2,114],105:[2,114],109:[2,114],115:[2,114],116:[2,114],117:[2,114],125:[2,114],127:[2,114],128:[2,114],131:[2,114],132:[2,114],133:[2,114],134:[2,114],135:[2,114],136:[2,114]},{6:[2,53],25:[2,53],53:225,54:[1,226],90:[2,53]},{6:[2,123],25:[2,123],26:[2,123],54:[2,123],85:[2,123],90:[2,123]},{8:200,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,25:[1,146],27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,60:147,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],86:227,87:[1,58],88:[1,59],89:[1,57],93:145,95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{6:[2,129],25:[2,129],26:[2,129],54:[2,129],85:[2,129],90:[2,129]},{1:[2,113],6:[2,113],25:[2,113],26:[2,113],40:[2,113],43:[2,113],49:[2,113],54:[2,113],57:[2,113],66:[2,113],67:[2,113],68:[2,113],70:[2,113],72:[2,113],73:[2,113],77:[2,113],79:[2,113],83:[2,113],84:[2,113],85:[2,113],90:[2,113],92:[2,113],101:[2,113],103:[2,113],104:[2,113],105:[2,113],109:[2,113],115:[2,113],116:[2,113],117:[2,113],125:[2,113],127:[2,113],128:[2,113],129:[2,113],130:[2,113],131:[2,113],132:[2,113],133:[2,113],134:[2,113],135:[2,113],136:[2,113],137:[2,113]},{5:228,25:[1,5],102:87,103:[1,65],105:[1,66],108:88,109:[1,68],110:69,125:[1,86],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{1:[2,140],6:[2,140],25:[2,140],26:[2,140],49:[2,140],54:[2,140],57:[2,140],72:[2,140],77:[2,140],85:[2,140],90:[2,140],92:[2,140],101:[2,140],102:87,103:[1,65],104:[1,229],105:[1,66],108:88,109:[1,68],110:69,117:[2,140],125:[2,140],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{1:[2,142],6:[2,142],25:[2,142],26:[2,142],49:[2,142],54:[2,142],57:[2,142],72:[2,142],77:[2,142],85:[2,142],90:[2,142],92:[2,142],101:[2,142],102:87,103:[1,65],104:[1,230],105:[1,66],108:88,109:[1,68],110:69,117:[2,142],125:[2,142],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{1:[2,148],6:[2,148],25:[2,148],26:[2,148],49:[2,148],54:[2,148],57:[2,148],72:[2,148],77:[2,148],85:[2,148],90:[2,148],92:[2,148],101:[2,148],103:[2,148],104:[2,148],105:[2,148],109:[2,148],117:[2,148],125:[2,148],127:[2,148],128:[2,148],131:[2,148],132:[2,148],133:[2,148],134:[2,148],135:[2,148],136:[2,148]},{1:[2,149],6:[2,149],25:[2,149],26:[2,149],49:[2,149],54:[2,149],57:[2,149],72:[2,149],77:[2,149],85:[2,149],90:[2,149],92:[2,149],101:[2,149],102:87,103:[1,65],104:[2,149],105:[1,66],108:88,109:[1,68],110:69,117:[2,149],125:[2,149],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{1:[2,153],6:[2,153],25:[2,153],26:[2,153],49:[2,153],54:[2,153],57:[2,153],72:[2,153],77:[2,153],85:[2,153],90:[2,153],92:[2,153],101:[2,153],103:[2,153],104:[2,153],105:[2,153],109:[2,153],117:[2,153],125:[2,153],127:[2,153],128:[2,153],131:[2,153],132:[2,153],133:[2,153],134:[2,153],135:[2,153],136:[2,153]},{115:[2,155],116:[2,155]},{27:158,28:[1,73],44:159,58:160,59:161,75:[1,70],88:[1,113],89:[1,114],112:231,114:157},{54:[1,232],115:[2,161],116:[2,161]},{54:[2,157],115:[2,157],116:[2,157]},{54:[2,158],115:[2,158],116:[2,158]},{54:[2,159],115:[2,159],116:[2,159]},{54:[2,160],115:[2,160],116:[2,160]},{1:[2,154],6:[2,154],25:[2,154],26:[2,154],49:[2,154],54:[2,154],57:[2,154],72:[2,154],77:[2,154],85:[2,154],90:[2,154],92:[2,154],101:[2,154],103:[2,154],104:[2,154],105:[2,154],109:[2,154],117:[2,154],125:[2,154],127:[2,154],128:[2,154],131:[2,154],132:[2,154],133:[2,154],134:[2,154],135:[2,154],136:[2,154]},{8:233,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{8:234,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{6:[2,53],25:[2,53],53:235,54:[1,236],77:[2,53]},{6:[2,91],25:[2,91],26:[2,91],54:[2,91],77:[2,91]},{6:[2,39],25:[2,39],26:[2,39],43:[1,237],54:[2,39],77:[2,39]},{6:[2,42],25:[2,42],26:[2,42],54:[2,42],77:[2,42]},{6:[2,43],25:[2,43],26:[2,43],43:[2,43],54:[2,43],77:[2,43]},{6:[2,44],25:[2,44],26:[2,44],43:[2,44],54:[2,44],77:[2,44]},{6:[2,45],25:[2,45],26:[2,45],43:[2,45],54:[2,45],77:[2,45]},{1:[2,5],6:[2,5],26:[2,5],101:[2,5]},{1:[2,25],6:[2,25],25:[2,25],26:[2,25],49:[2,25],54:[2,25],57:[2,25],72:[2,25],77:[2,25],85:[2,25],90:[2,25],92:[2,25],97:[2,25],98:[2,25],101:[2,25],103:[2,25],104:[2,25],105:[2,25],109:[2,25],117:[2,25],120:[2,25],122:[2,25],125:[2,25],127:[2,25],128:[2,25],131:[2,25],132:[2,25],133:[2,25],134:[2,25],135:[2,25],136:[2,25]},{1:[2,192],6:[2,192],25:[2,192],26:[2,192],49:[2,192],54:[2,192],57:[2,192],72:[2,192],77:[2,192],85:[2,192],90:[2,192],92:[2,192],101:[2,192],102:87,103:[2,192],104:[2,192],105:[2,192],108:88,109:[2,192],110:69,117:[2,192],125:[2,192],127:[2,192],128:[2,192],131:[1,78],132:[1,81],133:[2,192],134:[2,192],135:[2,192],136:[2,192]},{1:[2,193],6:[2,193],25:[2,193],26:[2,193],49:[2,193],54:[2,193],57:[2,193],72:[2,193],77:[2,193],85:[2,193],90:[2,193],92:[2,193],101:[2,193],102:87,103:[2,193],104:[2,193],105:[2,193],108:88,109:[2,193],110:69,117:[2,193],125:[2,193],127:[2,193],128:[2,193],131:[1,78],132:[1,81],133:[2,193],134:[2,193],135:[2,193],136:[2,193]},{1:[2,194],6:[2,194],25:[2,194],26:[2,194],49:[2,194],54:[2,194],57:[2,194],72:[2,194],77:[2,194],85:[2,194],90:[2,194],92:[2,194],101:[2,194],102:87,103:[2,194],104:[2,194],105:[2,194],108:88,109:[2,194],110:69,117:[2,194],125:[2,194],127:[2,194],128:[2,194],131:[1,78],132:[2,194],133:[2,194],134:[2,194],135:[2,194],136:[2,194]},{1:[2,195],6:[2,195],25:[2,195],26:[2,195],49:[2,195],54:[2,195],57:[2,195],72:[2,195],77:[2,195],85:[2,195],90:[2,195],92:[2,195],101:[2,195],102:87,103:[2,195],104:[2,195],105:[2,195],108:88,109:[2,195],110:69,117:[2,195],125:[2,195],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[2,195],134:[2,195],135:[2,195],136:[2,195]},{1:[2,196],6:[2,196],25:[2,196],26:[2,196],49:[2,196],54:[2,196],57:[2,196],72:[2,196],77:[2,196],85:[2,196],90:[2,196],92:[2,196],101:[2,196],102:87,103:[2,196],104:[2,196],105:[2,196],108:88,109:[2,196],110:69,117:[2,196],125:[2,196],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[2,196],135:[2,196],136:[1,85]},{1:[2,197],6:[2,197],25:[2,197],26:[2,197],49:[2,197],54:[2,197],57:[2,197],72:[2,197],77:[2,197],85:[2,197],90:[2,197],92:[2,197],101:[2,197],102:87,103:[2,197],104:[2,197],105:[2,197],108:88,109:[2,197],110:69,117:[2,197],125:[2,197],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[2,197],136:[1,85]},{1:[2,198],6:[2,198],25:[2,198],26:[2,198],49:[2,198],54:[2,198],57:[2,198],72:[2,198],77:[2,198],85:[2,198],90:[2,198],92:[2,198],101:[2,198],102:87,103:[2,198],104:[2,198],105:[2,198],108:88,109:[2,198],110:69,117:[2,198],125:[2,198],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[2,198],135:[2,198],136:[2,198]},{1:[2,183],6:[2,183],25:[2,183],26:[2,183],49:[2,183],54:[2,183],57:[2,183],72:[2,183],77:[2,183],85:[2,183],90:[2,183],92:[2,183],101:[2,183],102:87,103:[1,65],104:[2,183],105:[1,66],108:88,109:[1,68],110:69,117:[2,183],125:[1,86],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{1:[2,182],6:[2,182],25:[2,182],26:[2,182],49:[2,182],54:[2,182],57:[2,182],72:[2,182],77:[2,182],85:[2,182],90:[2,182],92:[2,182],101:[2,182],102:87,103:[1,65],104:[2,182],105:[1,66],108:88,109:[1,68],110:69,117:[2,182],125:[1,86],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{1:[2,103],6:[2,103],25:[2,103],26:[2,103],49:[2,103],54:[2,103],57:[2,103],66:[2,103],67:[2,103],68:[2,103],70:[2,103],72:[2,103],73:[2,103],77:[2,103],83:[2,103],84:[2,103],85:[2,103],90:[2,103],92:[2,103],101:[2,103],103:[2,103],104:[2,103],105:[2,103],109:[2,103],117:[2,103],125:[2,103],127:[2,103],128:[2,103],131:[2,103],132:[2,103],133:[2,103],134:[2,103],135:[2,103],136:[2,103]},{1:[2,80],6:[2,80],25:[2,80],26:[2,80],40:[2,80],49:[2,80],54:[2,80],57:[2,80],66:[2,80],67:[2,80],68:[2,80],70:[2,80],72:[2,80],73:[2,80],77:[2,80],79:[2,80],83:[2,80],84:[2,80],85:[2,80],90:[2,80],92:[2,80],101:[2,80],103:[2,80],104:[2,80],105:[2,80],109:[2,80],117:[2,80],125:[2,80],127:[2,80],128:[2,80],129:[2,80],130:[2,80],131:[2,80],132:[2,80],133:[2,80],134:[2,80],135:[2,80],136:[2,80],137:[2,80]},{1:[2,81],6:[2,81],25:[2,81],26:[2,81],40:[2,81],49:[2,81],54:[2,81],57:[2,81],66:[2,81],67:[2,81],68:[2,81],70:[2,81],72:[2,81],73:[2,81],77:[2,81],79:[2,81],83:[2,81],84:[2,81],85:[2,81],90:[2,81],92:[2,81],101:[2,81],103:[2,81],104:[2,81],105:[2,81],109:[2,81],117:[2,81],125:[2,81],127:[2,81],128:[2,81],129:[2,81],130:[2,81],131:[2,81],132:[2,81],133:[2,81],134:[2,81],135:[2,81],136:[2,81],137:[2,81]},{1:[2,82],6:[2,82],25:[2,82],26:[2,82],40:[2,82],49:[2,82],54:[2,82],57:[2,82],66:[2,82],67:[2,82],68:[2,82],70:[2,82],72:[2,82],73:[2,82],77:[2,82],79:[2,82],83:[2,82],84:[2,82],85:[2,82],90:[2,82],92:[2,82],101:[2,82],103:[2,82],104:[2,82],105:[2,82],109:[2,82],117:[2,82],125:[2,82],127:[2,82],128:[2,82],129:[2,82],130:[2,82],131:[2,82],132:[2,82],133:[2,82],134:[2,82],135:[2,82],136:[2,82],137:[2,82]},{72:[1,238]},{57:[1,192],72:[2,87],91:239,92:[1,191],102:87,103:[1,65],105:[1,66],108:88,109:[1,68],110:69,125:[1,86],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{72:[2,88]},{8:240,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,72:[2,122],75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{12:[2,116],28:[2,116],30:[2,116],31:[2,116],33:[2,116],34:[2,116],35:[2,116],36:[2,116],37:[2,116],38:[2,116],45:[2,116],46:[2,116],47:[2,116],51:[2,116],52:[2,116],72:[2,116],75:[2,116],78:[2,116],82:[2,116],87:[2,116],88:[2,116],89:[2,116],95:[2,116],99:[2,116],100:[2,116],103:[2,116],105:[2,116],107:[2,116],109:[2,116],118:[2,116],124:[2,116],126:[2,116],127:[2,116],128:[2,116],129:[2,116],130:[2,116]},{12:[2,117],28:[2,117],30:[2,117],31:[2,117],33:[2,117],34:[2,117],35:[2,117],36:[2,117],37:[2,117],38:[2,117],45:[2,117],46:[2,117],47:[2,117],51:[2,117],52:[2,117],72:[2,117],75:[2,117],78:[2,117],82:[2,117],87:[2,117],88:[2,117],89:[2,117],95:[2,117],99:[2,117],100:[2,117],103:[2,117],105:[2,117],107:[2,117],109:[2,117],118:[2,117],124:[2,117],126:[2,117],127:[2,117],128:[2,117],129:[2,117],130:[2,117]},{1:[2,86],6:[2,86],25:[2,86],26:[2,86],40:[2,86],49:[2,86],54:[2,86],57:[2,86],66:[2,86],67:[2,86],68:[2,86],70:[2,86],72:[2,86],73:[2,86],77:[2,86],79:[2,86],83:[2,86],84:[2,86],85:[2,86],90:[2,86],92:[2,86],101:[2,86],103:[2,86],104:[2,86],105:[2,86],109:[2,86],117:[2,86],125:[2,86],127:[2,86],128:[2,86],129:[2,86],130:[2,86],131:[2,86],132:[2,86],133:[2,86],134:[2,86],135:[2,86],136:[2,86],137:[2,86]},{1:[2,104],6:[2,104],25:[2,104],26:[2,104],49:[2,104],54:[2,104],57:[2,104],66:[2,104],67:[2,104],68:[2,104],70:[2,104],72:[2,104],73:[2,104],77:[2,104],83:[2,104],84:[2,104],85:[2,104],90:[2,104],92:[2,104],101:[2,104],103:[2,104],104:[2,104],105:[2,104],109:[2,104],117:[2,104],125:[2,104],127:[2,104],128:[2,104],131:[2,104],132:[2,104],133:[2,104],134:[2,104],135:[2,104],136:[2,104]},{1:[2,36],6:[2,36],25:[2,36],26:[2,36],49:[2,36],54:[2,36],57:[2,36],72:[2,36],77:[2,36],85:[2,36],90:[2,36],92:[2,36],101:[2,36],102:87,103:[2,36],104:[2,36],105:[2,36],108:88,109:[2,36],110:69,117:[2,36],125:[2,36],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{8:241,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{8:242,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{1:[2,109],6:[2,109],25:[2,109],26:[2,109],49:[2,109],54:[2,109],57:[2,109],66:[2,109],67:[2,109],68:[2,109],70:[2,109],72:[2,109],73:[2,109],77:[2,109],83:[2,109],84:[2,109],85:[2,109],90:[2,109],92:[2,109],101:[2,109],103:[2,109],104:[2,109],105:[2,109],109:[2,109],117:[2,109],125:[2,109],127:[2,109],128:[2,109],131:[2,109],132:[2,109],133:[2,109],134:[2,109],135:[2,109],136:[2,109]},{6:[2,53],25:[2,53],53:243,54:[1,226],85:[2,53]},{6:[2,128],25:[2,128],26:[2,128],54:[2,128],57:[1,244],85:[2,128],90:[2,128],102:87,103:[1,65],105:[1,66],108:88,109:[1,68],110:69,125:[1,86],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{50:245,51:[1,60],52:[1,61]},{6:[2,54],25:[2,54],26:[2,54],27:109,28:[1,73],44:110,55:246,56:108,58:111,59:112,75:[1,70],88:[1,113],89:[1,114]},{6:[1,247],25:[1,248]},{6:[2,61],25:[2,61],26:[2,61],49:[2,61],54:[2,61]},{8:249,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{1:[2,199],6:[2,199],25:[2,199],26:[2,199],49:[2,199],54:[2,199],57:[2,199],72:[2,199],77:[2,199],85:[2,199],90:[2,199],92:[2,199],101:[2,199],102:87,103:[2,199],104:[2,199],105:[2,199],108:88,109:[2,199],110:69,117:[2,199],125:[2,199],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{8:250,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{1:[2,201],6:[2,201],25:[2,201],26:[2,201],49:[2,201],54:[2,201],57:[2,201],72:[2,201],77:[2,201],85:[2,201],90:[2,201],92:[2,201],101:[2,201],102:87,103:[2,201],104:[2,201],105:[2,201],108:88,109:[2,201],110:69,117:[2,201],125:[2,201],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{1:[2,181],6:[2,181],25:[2,181],26:[2,181],49:[2,181],54:[2,181],57:[2,181],72:[2,181],77:[2,181],85:[2,181],90:[2,181],92:[2,181],101:[2,181],103:[2,181],104:[2,181],105:[2,181],109:[2,181],117:[2,181],125:[2,181],127:[2,181],128:[2,181],131:[2,181],132:[2,181],133:[2,181],134:[2,181],135:[2,181],136:[2,181]},{8:251,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{1:[2,133],6:[2,133],25:[2,133],26:[2,133],49:[2,133],54:[2,133],57:[2,133],72:[2,133],77:[2,133],85:[2,133],90:[2,133],92:[2,133],97:[1,252],101:[2,133],103:[2,133],104:[2,133],105:[2,133],109:[2,133],117:[2,133],125:[2,133],127:[2,133],128:[2,133],131:[2,133],132:[2,133],133:[2,133],134:[2,133],135:[2,133],136:[2,133]},{5:253,25:[1,5]},{27:254,28:[1,73]},{119:255,121:216,122:[1,217]},{26:[1,256],120:[1,257],121:258,122:[1,217]},{26:[2,174],120:[2,174],122:[2,174]},{8:260,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],94:259,95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{1:[2,97],5:261,6:[2,97],25:[1,5],26:[2,97],49:[2,97],54:[2,97],57:[2,97],72:[2,97],77:[2,97],85:[2,97],90:[2,97],92:[2,97],101:[2,97],102:87,103:[1,65],104:[2,97],105:[1,66],108:88,109:[1,68],110:69,117:[2,97],125:[2,97],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{1:[2,100],6:[2,100],25:[2,100],26:[2,100],49:[2,100],54:[2,100],57:[2,100],72:[2,100],77:[2,100],85:[2,100],90:[2,100],92:[2,100],101:[2,100],103:[2,100],104:[2,100],105:[2,100],109:[2,100],117:[2,100],125:[2,100],127:[2,100],128:[2,100],131:[2,100],132:[2,100],133:[2,100],134:[2,100],135:[2,100],136:[2,100]},{8:262,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{1:[2,138],6:[2,138],25:[2,138],26:[2,138],49:[2,138],54:[2,138],57:[2,138],66:[2,138],67:[2,138],68:[2,138],70:[2,138],72:[2,138],73:[2,138],77:[2,138],83:[2,138],84:[2,138],85:[2,138],90:[2,138],92:[2,138],101:[2,138],103:[2,138],104:[2,138],105:[2,138],109:[2,138],117:[2,138],125:[2,138],127:[2,138],128:[2,138],131:[2,138],132:[2,138],133:[2,138],134:[2,138],135:[2,138],136:[2,138]},{6:[1,74],26:[1,263]},{8:264,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{6:[2,67],12:[2,117],25:[2,67],28:[2,117],30:[2,117],31:[2,117],33:[2,117],34:[2,117],35:[2,117],36:[2,117],37:[2,117],38:[2,117],45:[2,117],46:[2,117],47:[2,117],51:[2,117],52:[2,117],54:[2,67],75:[2,117],78:[2,117],82:[2,117],87:[2,117],88:[2,117],89:[2,117],90:[2,67],95:[2,117],99:[2,117],100:[2,117],103:[2,117],105:[2,117],107:[2,117],109:[2,117],118:[2,117],124:[2,117],126:[2,117],127:[2,117],128:[2,117],129:[2,117],130:[2,117]},{6:[1,266],25:[1,267],90:[1,265]},{6:[2,54],8:200,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,25:[2,54],26:[2,54],27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,60:147,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],85:[2,54],87:[1,58],88:[1,59],89:[1,57],90:[2,54],93:268,95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{6:[2,53],25:[2,53],26:[2,53],53:269,54:[1,226]},{1:[2,178],6:[2,178],25:[2,178],26:[2,178],49:[2,178],54:[2,178],57:[2,178],72:[2,178],77:[2,178],85:[2,178],90:[2,178],92:[2,178],101:[2,178],103:[2,178],104:[2,178],105:[2,178],109:[2,178],117:[2,178],120:[2,178],125:[2,178],127:[2,178],128:[2,178],131:[2,178],132:[2,178],133:[2,178],134:[2,178],135:[2,178],136:[2,178]},{8:270,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{8:271,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{115:[2,156],116:[2,156]},{27:158,28:[1,73],44:159,58:160,59:161,75:[1,70],88:[1,113],89:[1,114],114:272},{1:[2,163],6:[2,163],25:[2,163],26:[2,163],49:[2,163],54:[2,163],57:[2,163],72:[2,163],77:[2,163],85:[2,163],90:[2,163],92:[2,163],101:[2,163],102:87,103:[2,163],104:[1,273],105:[2,163],108:88,109:[2,163],110:69,117:[1,274],125:[2,163],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{1:[2,164],6:[2,164],25:[2,164],26:[2,164],49:[2,164],54:[2,164],57:[2,164],72:[2,164],77:[2,164],85:[2,164],90:[2,164],92:[2,164],101:[2,164],102:87,103:[2,164],104:[1,275],105:[2,164],108:88,109:[2,164],110:69,117:[2,164],125:[2,164],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{6:[1,277],25:[1,278],77:[1,276]},{6:[2,54],11:168,25:[2,54],26:[2,54],27:169,28:[1,73],29:170,30:[1,71],31:[1,72],41:279,42:167,44:171,46:[1,46],77:[2,54],88:[1,113]},{8:280,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,25:[1,281],27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{1:[2,85],6:[2,85],25:[2,85],26:[2,85],40:[2,85],49:[2,85],54:[2,85],57:[2,85],66:[2,85],67:[2,85],68:[2,85],70:[2,85],72:[2,85],73:[2,85],77:[2,85],79:[2,85],83:[2,85],84:[2,85],85:[2,85],90:[2,85],92:[2,85],101:[2,85],103:[2,85],104:[2,85],105:[2,85],109:[2,85],117:[2,85],125:[2,85],127:[2,85],128:[2,85],129:[2,85],130:[2,85],131:[2,85],132:[2,85],133:[2,85],134:[2,85],135:[2,85],136:[2,85],137:[2,85]},{8:282,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,72:[2,120],75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{72:[2,121],102:87,103:[1,65],105:[1,66],108:88,109:[1,68],110:69,125:[1,86],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{1:[2,37],6:[2,37],25:[2,37],26:[2,37],49:[2,37],54:[2,37],57:[2,37],72:[2,37],77:[2,37],85:[2,37],90:[2,37],92:[2,37],101:[2,37],102:87,103:[2,37],104:[2,37],105:[2,37],108:88,109:[2,37],110:69,117:[2,37],125:[2,37],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{26:[1,283],102:87,103:[1,65],105:[1,66],108:88,109:[1,68],110:69,125:[1,86],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{6:[1,266],25:[1,267],85:[1,284]},{6:[2,67],25:[2,67],26:[2,67],54:[2,67],85:[2,67],90:[2,67]},{5:285,25:[1,5]},{6:[2,57],25:[2,57],26:[2,57],49:[2,57],54:[2,57]},{27:109,28:[1,73],44:110,55:286,56:108,58:111,59:112,75:[1,70],88:[1,113],89:[1,114]},{6:[2,55],25:[2,55],26:[2,55],27:109,28:[1,73],44:110,48:287,54:[2,55],55:107,56:108,58:111,59:112,75:[1,70],88:[1,113],89:[1,114]},{6:[2,62],25:[2,62],26:[2,62],49:[2,62],54:[2,62],102:87,103:[1,65],105:[1,66],108:88,109:[1,68],110:69,125:[1,86],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{26:[1,288],102:87,103:[1,65],105:[1,66],108:88,109:[1,68],110:69,125:[1,86],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{5:289,25:[1,5],102:87,103:[1,65],105:[1,66],108:88,109:[1,68],110:69,125:[1,86],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{5:290,25:[1,5]},{1:[2,134],6:[2,134],25:[2,134],26:[2,134],49:[2,134],54:[2,134],57:[2,134],72:[2,134],77:[2,134],85:[2,134],90:[2,134],92:[2,134],101:[2,134],103:[2,134],104:[2,134],105:[2,134],109:[2,134],117:[2,134],125:[2,134],127:[2,134],128:[2,134],131:[2,134],132:[2,134],133:[2,134],134:[2,134],135:[2,134],136:[2,134]},{5:291,25:[1,5]},{26:[1,292],120:[1,293],121:258,122:[1,217]},{1:[2,172],6:[2,172],25:[2,172],26:[2,172],49:[2,172],54:[2,172],57:[2,172],72:[2,172],77:[2,172],85:[2,172],90:[2,172],92:[2,172],101:[2,172],103:[2,172],104:[2,172],105:[2,172],109:[2,172],117:[2,172],125:[2,172],127:[2,172],128:[2,172],131:[2,172],132:[2,172],133:[2,172],134:[2,172],135:[2,172],136:[2,172]},{5:294,25:[1,5]},{26:[2,175],120:[2,175],122:[2,175]},{5:295,25:[1,5],54:[1,296]},{25:[2,130],54:[2,130],102:87,103:[1,65],105:[1,66],108:88,109:[1,68],110:69,125:[1,86],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{1:[2,98],6:[2,98],25:[2,98],26:[2,98],49:[2,98],54:[2,98],57:[2,98],72:[2,98],77:[2,98],85:[2,98],90:[2,98],92:[2,98],101:[2,98],103:[2,98],104:[2,98],105:[2,98],109:[2,98],117:[2,98],125:[2,98],127:[2,98],128:[2,98],131:[2,98],132:[2,98],133:[2,98],134:[2,98],135:[2,98],136:[2,98]},{1:[2,101],5:297,6:[2,101],25:[1,5],26:[2,101],49:[2,101],54:[2,101],57:[2,101],72:[2,101],77:[2,101],85:[2,101],90:[2,101],92:[2,101],101:[2,101],102:87,103:[1,65],104:[2,101],105:[1,66],108:88,109:[1,68],110:69,117:[2,101],125:[2,101],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{101:[1,298]},{90:[1,299],102:87,103:[1,65],105:[1,66],108:88,109:[1,68],110:69,125:[1,86],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{1:[2,115],6:[2,115],25:[2,115],26:[2,115],40:[2,115],49:[2,115],54:[2,115],57:[2,115],66:[2,115],67:[2,115],68:[2,115],70:[2,115],72:[2,115],73:[2,115],77:[2,115],83:[2,115],84:[2,115],85:[2,115],90:[2,115],92:[2,115],101:[2,115],103:[2,115],104:[2,115],105:[2,115],109:[2,115],115:[2,115],116:[2,115],117:[2,115],125:[2,115],127:[2,115],128:[2,115],131:[2,115],132:[2,115],133:[2,115],134:[2,115],135:[2,115],136:[2,115]},{8:200,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,60:147,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],93:300,95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{8:200,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,25:[1,146],27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,60:147,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],86:301,87:[1,58],88:[1,59],89:[1,57],93:145,95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{6:[2,124],25:[2,124],26:[2,124],54:[2,124],85:[2,124],90:[2,124]},{6:[1,266],25:[1,267],26:[1,302]},{1:[2,141],6:[2,141],25:[2,141],26:[2,141],49:[2,141],54:[2,141],57:[2,141],72:[2,141],77:[2,141],85:[2,141],90:[2,141],92:[2,141],101:[2,141],102:87,103:[1,65],104:[2,141],105:[1,66],108:88,109:[1,68],110:69,117:[2,141],125:[2,141],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{1:[2,143],6:[2,143],25:[2,143],26:[2,143],49:[2,143],54:[2,143],57:[2,143],72:[2,143],77:[2,143],85:[2,143],90:[2,143],92:[2,143],101:[2,143],102:87,103:[1,65],104:[2,143],105:[1,66],108:88,109:[1,68],110:69,117:[2,143],125:[2,143],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{115:[2,162],116:[2,162]},{8:303,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{8:304,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{8:305,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{1:[2,89],6:[2,89],25:[2,89],26:[2,89],40:[2,89],49:[2,89],54:[2,89],57:[2,89],66:[2,89],67:[2,89],68:[2,89],70:[2,89],72:[2,89],73:[2,89],77:[2,89],83:[2,89],84:[2,89],85:[2,89],90:[2,89],92:[2,89],101:[2,89],103:[2,89],104:[2,89],105:[2,89],109:[2,89],115:[2,89],116:[2,89],117:[2,89],125:[2,89],127:[2,89],128:[2,89],131:[2,89],132:[2,89],133:[2,89],134:[2,89],135:[2,89],136:[2,89]},{11:168,27:169,28:[1,73],29:170,30:[1,71],31:[1,72],41:306,42:167,44:171,46:[1,46],88:[1,113]},{6:[2,90],11:168,25:[2,90],26:[2,90],27:169,28:[1,73],29:170,30:[1,71],31:[1,72],41:166,42:167,44:171,46:[1,46],54:[2,90],76:307,88:[1,113]},{6:[2,92],25:[2,92],26:[2,92],54:[2,92],77:[2,92]},{6:[2,40],25:[2,40],26:[2,40],54:[2,40],77:[2,40],102:87,103:[1,65],105:[1,66],108:88,109:[1,68],110:69,125:[1,86],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{8:308,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{72:[2,119],102:87,103:[1,65],105:[1,66],108:88,109:[1,68],110:69,125:[1,86],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{1:[2,38],6:[2,38],25:[2,38],26:[2,38],49:[2,38],54:[2,38],57:[2,38],72:[2,38],77:[2,38],85:[2,38],90:[2,38],92:[2,38],101:[2,38],103:[2,38],104:[2,38],105:[2,38],109:[2,38],117:[2,38],125:[2,38],127:[2,38],128:[2,38],131:[2,38],132:[2,38],133:[2,38],134:[2,38],135:[2,38],136:[2,38]},{1:[2,110],6:[2,110],25:[2,110],26:[2,110],49:[2,110],54:[2,110],57:[2,110],66:[2,110],67:[2,110],68:[2,110],70:[2,110],72:[2,110],73:[2,110],77:[2,110],83:[2,110],84:[2,110],85:[2,110],90:[2,110],92:[2,110],101:[2,110],103:[2,110],104:[2,110],105:[2,110],109:[2,110],117:[2,110],125:[2,110],127:[2,110],128:[2,110],131:[2,110],132:[2,110],133:[2,110],134:[2,110],135:[2,110],136:[2,110]},{1:[2,49],6:[2,49],25:[2,49],26:[2,49],49:[2,49],54:[2,49],57:[2,49],72:[2,49],77:[2,49],85:[2,49],90:[2,49],92:[2,49],101:[2,49],103:[2,49],104:[2,49],105:[2,49],109:[2,49],117:[2,49],125:[2,49],127:[2,49],128:[2,49],131:[2,49],132:[2,49],133:[2,49],134:[2,49],135:[2,49],136:[2,49]},{6:[2,58],25:[2,58],26:[2,58],49:[2,58],54:[2,58]},{6:[2,53],25:[2,53],26:[2,53],53:309,54:[1,202]},{1:[2,200],6:[2,200],25:[2,200],26:[2,200],49:[2,200],54:[2,200],57:[2,200],72:[2,200],77:[2,200],85:[2,200],90:[2,200],92:[2,200],101:[2,200],103:[2,200],104:[2,200],105:[2,200],109:[2,200],117:[2,200],125:[2,200],127:[2,200],128:[2,200],131:[2,200],132:[2,200],133:[2,200],134:[2,200],135:[2,200],136:[2,200]},{1:[2,179],6:[2,179],25:[2,179],26:[2,179],49:[2,179],54:[2,179],57:[2,179],72:[2,179],77:[2,179],85:[2,179],90:[2,179],92:[2,179],101:[2,179],103:[2,179],104:[2,179],105:[2,179],109:[2,179],117:[2,179],120:[2,179],125:[2,179],127:[2,179],128:[2,179],131:[2,179],132:[2,179],133:[2,179],134:[2,179],135:[2,179],136:[2,179]},{1:[2,135],6:[2,135],25:[2,135],26:[2,135],49:[2,135],54:[2,135],57:[2,135],72:[2,135],77:[2,135],85:[2,135],90:[2,135],92:[2,135],101:[2,135],103:[2,135],104:[2,135],105:[2,135],109:[2,135],117:[2,135],125:[2,135],127:[2,135],128:[2,135],131:[2,135],132:[2,135],133:[2,135],134:[2,135],135:[2,135],136:[2,135]},{1:[2,136],6:[2,136],25:[2,136],26:[2,136],49:[2,136],54:[2,136],57:[2,136],72:[2,136],77:[2,136],85:[2,136],90:[2,136],92:[2,136],97:[2,136],101:[2,136],103:[2,136],104:[2,136],105:[2,136],109:[2,136],117:[2,136],125:[2,136],127:[2,136],128:[2,136],131:[2,136],132:[2,136],133:[2,136],134:[2,136],135:[2,136],136:[2,136]},{1:[2,170],6:[2,170],25:[2,170],26:[2,170],49:[2,170],54:[2,170],57:[2,170],72:[2,170],77:[2,170],85:[2,170],90:[2,170],92:[2,170],101:[2,170],103:[2,170],104:[2,170],105:[2,170],109:[2,170],117:[2,170],125:[2,170],127:[2,170],128:[2,170],131:[2,170],132:[2,170],133:[2,170],134:[2,170],135:[2,170],136:[2,170]},{5:310,25:[1,5]},{26:[1,311]},{6:[1,312],26:[2,176],120:[2,176],122:[2,176]},{8:313,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{1:[2,102],6:[2,102],25:[2,102],26:[2,102],49:[2,102],54:[2,102],57:[2,102],72:[2,102],77:[2,102],85:[2,102],90:[2,102],92:[2,102],101:[2,102],103:[2,102],104:[2,102],105:[2,102],109:[2,102],117:[2,102],125:[2,102],127:[2,102],128:[2,102],131:[2,102],132:[2,102],133:[2,102],134:[2,102],135:[2,102],136:[2,102]},{1:[2,139],6:[2,139],25:[2,139],26:[2,139],49:[2,139],54:[2,139],57:[2,139],66:[2,139],67:[2,139],68:[2,139],70:[2,139],72:[2,139],73:[2,139],77:[2,139],83:[2,139],84:[2,139],85:[2,139],90:[2,139],92:[2,139],101:[2,139],103:[2,139],104:[2,139],105:[2,139],109:[2,139],117:[2,139],125:[2,139],127:[2,139],128:[2,139],131:[2,139],132:[2,139],133:[2,139],134:[2,139],135:[2,139],136:[2,139]},{1:[2,118],6:[2,118],25:[2,118],26:[2,118],49:[2,118],54:[2,118],57:[2,118],66:[2,118],67:[2,118],68:[2,118],70:[2,118],72:[2,118],73:[2,118],77:[2,118],83:[2,118],84:[2,118],85:[2,118],90:[2,118],92:[2,118],101:[2,118],103:[2,118],104:[2,118],105:[2,118],109:[2,118],117:[2,118],125:[2,118],127:[2,118],128:[2,118],131:[2,118],132:[2,118],133:[2,118],134:[2,118],135:[2,118],136:[2,118]},{6:[2,125],25:[2,125],26:[2,125],54:[2,125],85:[2,125],90:[2,125]},{6:[2,53],25:[2,53],26:[2,53],53:314,54:[1,226]},{6:[2,126],25:[2,126],26:[2,126],54:[2,126],85:[2,126],90:[2,126]},{1:[2,165],6:[2,165],25:[2,165],26:[2,165],49:[2,165],54:[2,165],57:[2,165],72:[2,165],77:[2,165],85:[2,165],90:[2,165],92:[2,165],101:[2,165],102:87,103:[2,165],104:[2,165],105:[2,165],108:88,109:[2,165],110:69,117:[1,315],125:[2,165],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{1:[2,167],6:[2,167],25:[2,167],26:[2,167],49:[2,167],54:[2,167],57:[2,167],72:[2,167],77:[2,167],85:[2,167],90:[2,167],92:[2,167],101:[2,167],102:87,103:[2,167],104:[1,316],105:[2,167],108:88,109:[2,167],110:69,117:[2,167],125:[2,167],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{1:[2,166],6:[2,166],25:[2,166],26:[2,166],49:[2,166],54:[2,166],57:[2,166],72:[2,166],77:[2,166],85:[2,166],90:[2,166],92:[2,166],101:[2,166],102:87,103:[2,166],104:[2,166],105:[2,166],108:88,109:[2,166],110:69,117:[2,166],125:[2,166],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{6:[2,93],25:[2,93],26:[2,93],54:[2,93],77:[2,93]},{6:[2,53],25:[2,53],26:[2,53],53:317,54:[1,236]},{26:[1,318],102:87,103:[1,65],105:[1,66],108:88,109:[1,68],110:69,125:[1,86],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{6:[1,247],25:[1,248],26:[1,319]},{26:[1,320]},{1:[2,173],6:[2,173],25:[2,173],26:[2,173],49:[2,173],54:[2,173],57:[2,173],72:[2,173],77:[2,173],85:[2,173],90:[2,173],92:[2,173],101:[2,173],103:[2,173],104:[2,173],105:[2,173],109:[2,173],117:[2,173],125:[2,173],127:[2,173],128:[2,173],131:[2,173],132:[2,173],133:[2,173],134:[2,173],135:[2,173],136:[2,173]},{26:[2,177],120:[2,177],122:[2,177]},{25:[2,131],54:[2,131],102:87,103:[1,65],105:[1,66],108:88,109:[1,68],110:69,125:[1,86],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{6:[1,266],25:[1,267],26:[1,321]},{8:322,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{8:323,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{6:[1,277],25:[1,278],26:[1,324]},{6:[2,41],25:[2,41],26:[2,41],54:[2,41],77:[2,41]},{6:[2,59],25:[2,59],26:[2,59],49:[2,59],54:[2,59]},{1:[2,171],6:[2,171],25:[2,171],26:[2,171],49:[2,171],54:[2,171],57:[2,171],72:[2,171],77:[2,171],85:[2,171],90:[2,171],92:[2,171],101:[2,171],103:[2,171],104:[2,171],105:[2,171],109:[2,171],117:[2,171],125:[2,171],127:[2,171],128:[2,171],131:[2,171],132:[2,171],133:[2,171],134:[2,171],135:[2,171],136:[2,171]},{6:[2,127],25:[2,127],26:[2,127],54:[2,127],85:[2,127],90:[2,127]},{1:[2,168],6:[2,168],25:[2,168],26:[2,168],49:[2,168],54:[2,168],57:[2,168],72:[2,168],77:[2,168],85:[2,168],90:[2,168],92:[2,168],101:[2,168],102:87,103:[2,168],104:[2,168],105:[2,168],108:88,109:[2,168],110:69,117:[2,168],125:[2,168],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{1:[2,169],6:[2,169],25:[2,169],26:[2,169],49:[2,169],54:[2,169],57:[2,169],72:[2,169],77:[2,169],85:[2,169],90:[2,169],92:[2,169],101:[2,169],102:87,103:[2,169],104:[2,169],105:[2,169],108:88,109:[2,169],110:69,117:[2,169],125:[2,169],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{6:[2,94],25:[2,94],26:[2,94],54:[2,94],77:[2,94]}],
-defaultActions: {60:[2,51],61:[2,52],75:[2,3],94:[2,108],189:[2,88]},
-parseError: function parseError(str, hash) {
- throw new Error(str);
-},
-parse: function parse(input) {
- var self = this,
- stack = [0],
- vstack = [null], // semantic value stack
- lstack = [], // location stack
- table = this.table,
- yytext = '',
- yylineno = 0,
- yyleng = 0,
- recovering = 0,
- TERROR = 2,
- EOF = 1;
-
- //this.reductionCount = this.shiftCount = 0;
-
- this.lexer.setInput(input);
- this.lexer.yy = this.yy;
- this.yy.lexer = this.lexer;
- if (typeof this.lexer.yylloc == 'undefined')
- this.lexer.yylloc = {};
- var yyloc = this.lexer.yylloc;
- lstack.push(yyloc);
-
- if (typeof this.yy.parseError === 'function')
- this.parseError = this.yy.parseError;
-
- function popStack (n) {
- stack.length = stack.length - 2*n;
- vstack.length = vstack.length - n;
- lstack.length = lstack.length - n;
- }
-
- function lex() {
- var token;
- token = self.lexer.lex() || 1; // $end = 1
- // if token isn't its numeric value, convert
- if (typeof token !== 'number') {
- token = self.symbols_[token] || token;
- }
- return token;
- }
-
- var symbol, preErrorSymbol, state, action, a, r, yyval={},p,len,newState, expected;
- while (true) {
- // retreive state number from top of stack
- state = stack[stack.length-1];
-
- // use default actions if available
- if (this.defaultActions[state]) {
- action = this.defaultActions[state];
- } else {
- if (symbol == null)
- symbol = lex();
- // read action for current state and first input
- action = table[state] && table[state][symbol];
- }
-
- // handle parse error
- _handle_error:
- if (typeof action === 'undefined' || !action.length || !action[0]) {
-
- if (!recovering) {
- // Report error
- expected = [];
- for (p in table[state]) if (this.terminals_[p] && p > 2) {
- expected.push("'"+this.terminals_[p]+"'");
- }
- var errStr = '';
- if (this.lexer.showPosition) {
- errStr = 'Parse error on line '+(yylineno+1)+":\n"+this.lexer.showPosition()+"\nExpecting "+expected.join(', ') + ", got '" + this.terminals_[symbol]+ "'";
- } else {
- errStr = 'Parse error on line '+(yylineno+1)+": Unexpected " +
- (symbol == 1 /*EOF*/ ? "end of input" :
- ("'"+(this.terminals_[symbol] || symbol)+"'"));
- }
- this.parseError(errStr,
- {text: this.lexer.match, token: this.terminals_[symbol] || symbol, line: this.lexer.yylineno, loc: yyloc, expected: expected});
- }
-
- // just recovered from another error
- if (recovering == 3) {
- if (symbol == EOF) {
- throw new Error(errStr || 'Parsing halted.');
- }
-
- // discard current lookahead and grab another
- yyleng = this.lexer.yyleng;
- yytext = this.lexer.yytext;
- yylineno = this.lexer.yylineno;
- yyloc = this.lexer.yylloc;
- symbol = lex();
- }
-
- // try to recover from error
- while (1) {
- // check for error recovery rule in this state
- if ((TERROR.toString()) in table[state]) {
- break;
- }
- if (state == 0) {
- throw new Error(errStr || 'Parsing halted.');
- }
- popStack(1);
- state = stack[stack.length-1];
- }
-
- preErrorSymbol = symbol; // save the lookahead token
- symbol = TERROR; // insert generic error symbol as new lookahead
- state = stack[stack.length-1];
- action = table[state] && table[state][TERROR];
- recovering = 3; // allow 3 real symbols to be shifted before reporting a new error
- }
-
- // this shouldn't happen, unless resolve defaults are off
- if (action[0] instanceof Array && action.length > 1) {
- throw new Error('Parse Error: multiple actions possible at state: '+state+', token: '+symbol);
- }
-
- switch (action[0]) {
-
- case 1: // shift
- //this.shiftCount++;
-
- stack.push(symbol);
- vstack.push(this.lexer.yytext);
- lstack.push(this.lexer.yylloc);
- stack.push(action[1]); // push state
- symbol = null;
- if (!preErrorSymbol) { // normal execution/no error
- yyleng = this.lexer.yyleng;
- yytext = this.lexer.yytext;
- yylineno = this.lexer.yylineno;
- yyloc = this.lexer.yylloc;
- if (recovering > 0)
- recovering--;
- } else { // error just occurred, resume old lookahead f/ before error
- symbol = preErrorSymbol;
- preErrorSymbol = null;
- }
- break;
-
- case 2: // reduce
- //this.reductionCount++;
-
- len = this.productions_[action[1]][1];
-
- // perform semantic action
- yyval.$ = vstack[vstack.length-len]; // default to $$ = $1
- // default location, uses first token for firsts, last for lasts
- yyval._$ = {
- first_line: lstack[lstack.length-(len||1)].first_line,
- last_line: lstack[lstack.length-1].last_line,
- first_column: lstack[lstack.length-(len||1)].first_column,
- last_column: lstack[lstack.length-1].last_column
- };
- r = this.performAction.call(yyval, yytext, yyleng, yylineno, this.yy, action[1], vstack, lstack);
-
- if (typeof r !== 'undefined') {
- return r;
- }
-
- // pop off stack
- if (len) {
- stack = stack.slice(0,-1*len*2);
- vstack = vstack.slice(0, -1*len);
- lstack = lstack.slice(0, -1*len);
- }
-
- stack.push(this.productions_[action[1]][0]); // push nonterminal (reduce)
- vstack.push(yyval.$);
- lstack.push(yyval._$);
- // goto new state = table[STATE][NONTERMINAL]
- newState = table[stack[stack.length-2]][stack[stack.length-1]];
- stack.push(newState);
- break;
-
- case 3: // accept
- return true;
- }
-
- }
-
- return true;
-}};
-undefined
-return parser;
-})();
-if (typeof require !== 'undefined' && typeof exports !== 'undefined') {
-exports.parser = parser;
-exports.parse = function () { return parser.parse.apply(parser, arguments); }
-exports.main = function commonjsMain(args) {
- if (!args[1])
- throw new Error('Usage: '+args[0]+' FILE');
- if (typeof process !== 'undefined') {
- var source = require('fs').readFileSync(require('path').join(process.cwd(), args[1]), "utf8");
- } else {
- var cwd = require("file").path(require("file").cwd());
- var source = cwd.join(args[1]).read({charset: "utf-8"});
- }
- return exports.parser.parse(source);
-}
-if (typeof module !== 'undefined' && require.main === module) {
- exports.main(typeof process !== 'undefined' ? process.argv.slice(1) : require("system").args);
-}
-}
\ No newline at end of file
diff --git a/spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/repl.js b/spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/repl.js
deleted file mode 100644
index b4a4765d..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/repl.js
+++ /dev/null
@@ -1,261 +0,0 @@
-// Generated by CoffeeScript 1.3.3
-(function() {
- var ACCESSOR, CoffeeScript, Module, REPL_PROMPT, REPL_PROMPT_CONTINUATION, REPL_PROMPT_MULTILINE, SIMPLEVAR, Script, autocomplete, backlog, completeAttribute, completeVariable, enableColours, error, getCompletions, inspect, multilineMode, pipedInput, readline, repl, run, stdin, stdout;
-
- stdin = process.openStdin();
-
- stdout = process.stdout;
-
- CoffeeScript = require('./coffee-script');
-
- readline = require('readline');
-
- inspect = require('util').inspect;
-
- Script = require('vm').Script;
-
- Module = require('module');
-
- REPL_PROMPT = 'coffee> ';
-
- REPL_PROMPT_MULTILINE = '------> ';
-
- REPL_PROMPT_CONTINUATION = '......> ';
-
- enableColours = false;
-
- if (process.platform !== 'win32') {
- enableColours = !process.env.NODE_DISABLE_COLORS;
- }
-
- error = function(err) {
- return stdout.write((err.stack || err.toString()) + '\n');
- };
-
- ACCESSOR = /\s*([\w\.]+)(?:\.(\w*))$/;
-
- SIMPLEVAR = /(\w+)$/i;
-
- autocomplete = function(text) {
- return completeAttribute(text) || completeVariable(text) || [[], text];
- };
-
- completeAttribute = function(text) {
- var all, completions, key, match, obj, possibilities, prefix, val;
- if (match = text.match(ACCESSOR)) {
- all = match[0], obj = match[1], prefix = match[2];
- try {
- val = Script.runInThisContext(obj);
- } catch (error) {
- return;
- }
- val = Object(val);
- possibilities = Object.getOwnPropertyNames(val);
- for (key in val) {
- if (~possibilities.indexOf(val)) {
- possibilities.push(key);
- }
- }
- completions = getCompletions(prefix, possibilities);
- return [completions, prefix];
- }
- };
-
- completeVariable = function(text) {
- var completions, free, keywords, possibilities, r, vars, _ref;
- free = (_ref = text.match(SIMPLEVAR)) != null ? _ref[1] : void 0;
- if (text === "") {
- free = "";
- }
- if (free != null) {
- vars = Script.runInThisContext('Object.getOwnPropertyNames(Object(this))');
- keywords = (function() {
- var _i, _len, _ref1, _results;
- _ref1 = CoffeeScript.RESERVED;
- _results = [];
- for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
- r = _ref1[_i];
- if (r.slice(0, 2) !== '__') {
- _results.push(r);
- }
- }
- return _results;
- })();
- possibilities = vars.concat(keywords);
- completions = getCompletions(free, possibilities);
- return [completions, free];
- }
- };
-
- getCompletions = function(prefix, candidates) {
- var el, _i, _len, _results;
- _results = [];
- for (_i = 0, _len = candidates.length; _i < _len; _i++) {
- el = candidates[_i];
- if (el.indexOf(prefix) === 0) {
- _results.push(el);
- }
- }
- return _results;
- };
-
- process.on('uncaughtException', error);
-
- backlog = '';
-
- run = function(buffer) {
- var code, returnValue, _;
- buffer = buffer.replace(/(^|[\r\n]+)(\s*)##?(?:[^#\r\n][^\r\n]*|)($|[\r\n])/, "$1$2$3");
- buffer = buffer.replace(/[\r\n]+$/, "");
- if (multilineMode) {
- backlog += "" + buffer + "\n";
- repl.setPrompt(REPL_PROMPT_CONTINUATION);
- repl.prompt();
- return;
- }
- if (!buffer.toString().trim() && !backlog) {
- repl.prompt();
- return;
- }
- code = backlog += buffer;
- if (code[code.length - 1] === '\\') {
- backlog = "" + backlog.slice(0, -1) + "\n";
- repl.setPrompt(REPL_PROMPT_CONTINUATION);
- repl.prompt();
- return;
- }
- repl.setPrompt(REPL_PROMPT);
- backlog = '';
- try {
- _ = global._;
- returnValue = CoffeeScript["eval"]("_=(" + code + "\n)", {
- filename: 'repl',
- modulename: 'repl'
- });
- if (returnValue === void 0) {
- global._ = _;
- }
- repl.output.write("" + (inspect(returnValue, false, 2, enableColours)) + "\n");
- } catch (err) {
- error(err);
- }
- return repl.prompt();
- };
-
- if (stdin.readable) {
- pipedInput = '';
- repl = {
- prompt: function() {
- return stdout.write(this._prompt);
- },
- setPrompt: function(p) {
- return this._prompt = p;
- },
- input: stdin,
- output: stdout,
- on: function() {}
- };
- stdin.on('data', function(chunk) {
- var line, lines, _i, _len, _ref;
- pipedInput += chunk;
- if (!/\n/.test(pipedInput)) {
- return;
- }
- lines = pipedInput.split("\n");
- pipedInput = lines[lines.length - 1];
- _ref = lines.slice(0, -1);
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
- line = _ref[_i];
- if (!(line)) {
- continue;
- }
- stdout.write("" + line + "\n");
- run(line);
- }
- });
- stdin.on('end', function() {
- var line, _i, _len, _ref;
- _ref = pipedInput.trim().split("\n");
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
- line = _ref[_i];
- if (!(line)) {
- continue;
- }
- stdout.write("" + line + "\n");
- run(line);
- }
- stdout.write('\n');
- return process.exit(0);
- });
- } else {
- if (readline.createInterface.length < 3) {
- repl = readline.createInterface(stdin, autocomplete);
- stdin.on('data', function(buffer) {
- return repl.write(buffer);
- });
- } else {
- repl = readline.createInterface(stdin, stdout, autocomplete);
- }
- }
-
- multilineMode = false;
-
- repl.input.on('keypress', function(char, key) {
- var cursorPos, newPrompt;
- if (!(key && key.ctrl && !key.meta && !key.shift && key.name === 'v')) {
- return;
- }
- cursorPos = repl.cursor;
- repl.output.cursorTo(0);
- repl.output.clearLine(1);
- multilineMode = !multilineMode;
- if (!multilineMode && backlog) {
- repl._line();
- }
- backlog = '';
- repl.setPrompt((newPrompt = multilineMode ? REPL_PROMPT_MULTILINE : REPL_PROMPT));
- repl.prompt();
- return repl.output.cursorTo(newPrompt.length + (repl.cursor = cursorPos));
- });
-
- repl.input.on('keypress', function(char, key) {
- if (!(multilineMode && repl.line)) {
- return;
- }
- if (!(key && key.ctrl && !key.meta && !key.shift && key.name === 'd')) {
- return;
- }
- multilineMode = false;
- return repl._line();
- });
-
- repl.on('attemptClose', function() {
- if (multilineMode) {
- multilineMode = false;
- repl.output.cursorTo(0);
- repl.output.clearLine(1);
- repl._onLine(repl.line);
- return;
- }
- if (backlog) {
- backlog = '';
- repl.output.write('\n');
- repl.setPrompt(REPL_PROMPT);
- return repl.prompt();
- } else {
- return repl.close();
- }
- });
-
- repl.on('close', function() {
- repl.output.write('\n');
- return repl.input.destroy();
- });
-
- repl.on('line', run);
-
- repl.setPrompt(REPL_PROMPT);
-
- repl.prompt();
-
-}).call(this);
diff --git a/spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/rewriter.js b/spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/rewriter.js
deleted file mode 100644
index d26133ca..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/rewriter.js
+++ /dev/null
@@ -1,349 +0,0 @@
-// Generated by CoffeeScript 1.3.3
-(function() {
- var BALANCED_PAIRS, EXPRESSION_CLOSE, EXPRESSION_END, EXPRESSION_START, IMPLICIT_BLOCK, IMPLICIT_CALL, IMPLICIT_END, IMPLICIT_FUNC, IMPLICIT_UNSPACED_CALL, INVERSES, LINEBREAKS, SINGLE_CLOSERS, SINGLE_LINERS, left, rite, _i, _len, _ref,
- __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; },
- __slice = [].slice;
-
- exports.Rewriter = (function() {
-
- function Rewriter() {}
-
- Rewriter.prototype.rewrite = function(tokens) {
- this.tokens = tokens;
- this.removeLeadingNewlines();
- this.removeMidExpressionNewlines();
- this.closeOpenCalls();
- this.closeOpenIndexes();
- this.addImplicitIndentation();
- this.tagPostfixConditionals();
- this.addImplicitBraces();
- this.addImplicitParentheses();
- return this.tokens;
- };
-
- Rewriter.prototype.scanTokens = function(block) {
- var i, token, tokens;
- tokens = this.tokens;
- i = 0;
- while (token = tokens[i]) {
- i += block.call(this, token, i, tokens);
- }
- return true;
- };
-
- Rewriter.prototype.detectEnd = function(i, condition, action) {
- var levels, token, tokens, _ref, _ref1;
- tokens = this.tokens;
- levels = 0;
- while (token = tokens[i]) {
- if (levels === 0 && condition.call(this, token, i)) {
- return action.call(this, token, i);
- }
- if (!token || levels < 0) {
- return action.call(this, token, i - 1);
- }
- if (_ref = token[0], __indexOf.call(EXPRESSION_START, _ref) >= 0) {
- levels += 1;
- } else if (_ref1 = token[0], __indexOf.call(EXPRESSION_END, _ref1) >= 0) {
- levels -= 1;
- }
- i += 1;
- }
- return i - 1;
- };
-
- Rewriter.prototype.removeLeadingNewlines = function() {
- var i, tag, _i, _len, _ref;
- _ref = this.tokens;
- for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {
- tag = _ref[i][0];
- if (tag !== 'TERMINATOR') {
- break;
- }
- }
- if (i) {
- return this.tokens.splice(0, i);
- }
- };
-
- Rewriter.prototype.removeMidExpressionNewlines = function() {
- return this.scanTokens(function(token, i, tokens) {
- var _ref;
- if (!(token[0] === 'TERMINATOR' && (_ref = this.tag(i + 1), __indexOf.call(EXPRESSION_CLOSE, _ref) >= 0))) {
- return 1;
- }
- tokens.splice(i, 1);
- return 0;
- });
- };
-
- Rewriter.prototype.closeOpenCalls = function() {
- var action, condition;
- condition = function(token, i) {
- var _ref;
- return ((_ref = token[0]) === ')' || _ref === 'CALL_END') || token[0] === 'OUTDENT' && this.tag(i - 1) === ')';
- };
- action = function(token, i) {
- return this.tokens[token[0] === 'OUTDENT' ? i - 1 : i][0] = 'CALL_END';
- };
- return this.scanTokens(function(token, i) {
- if (token[0] === 'CALL_START') {
- this.detectEnd(i + 1, condition, action);
- }
- return 1;
- });
- };
-
- Rewriter.prototype.closeOpenIndexes = function() {
- var action, condition;
- condition = function(token, i) {
- var _ref;
- return (_ref = token[0]) === ']' || _ref === 'INDEX_END';
- };
- action = function(token, i) {
- return token[0] = 'INDEX_END';
- };
- return this.scanTokens(function(token, i) {
- if (token[0] === 'INDEX_START') {
- this.detectEnd(i + 1, condition, action);
- }
- return 1;
- });
- };
-
- Rewriter.prototype.addImplicitBraces = function() {
- var action, condition, sameLine, stack, start, startIndent, startIndex, startsLine;
- stack = [];
- start = null;
- startsLine = null;
- sameLine = true;
- startIndent = 0;
- startIndex = 0;
- condition = function(token, i) {
- var one, tag, three, two, _ref, _ref1;
- _ref = this.tokens.slice(i + 1, (i + 3) + 1 || 9e9), one = _ref[0], two = _ref[1], three = _ref[2];
- if ('HERECOMMENT' === (one != null ? one[0] : void 0)) {
- return false;
- }
- tag = token[0];
- if (__indexOf.call(LINEBREAKS, tag) >= 0) {
- sameLine = false;
- }
- return (((tag === 'TERMINATOR' || tag === 'OUTDENT') || (__indexOf.call(IMPLICIT_END, tag) >= 0 && sameLine && !(i - startIndex === 1))) && ((!startsLine && this.tag(i - 1) !== ',') || !((two != null ? two[0] : void 0) === ':' || (one != null ? one[0] : void 0) === '@' && (three != null ? three[0] : void 0) === ':'))) || (tag === ',' && one && ((_ref1 = one[0]) !== 'IDENTIFIER' && _ref1 !== 'NUMBER' && _ref1 !== 'STRING' && _ref1 !== '@' && _ref1 !== 'TERMINATOR' && _ref1 !== 'OUTDENT'));
- };
- action = function(token, i) {
- var tok;
- tok = this.generate('}', '}', token[2]);
- return this.tokens.splice(i, 0, tok);
- };
- return this.scanTokens(function(token, i, tokens) {
- var ago, idx, prevTag, tag, tok, value, _ref, _ref1;
- if (_ref = (tag = token[0]), __indexOf.call(EXPRESSION_START, _ref) >= 0) {
- stack.push([(tag === 'INDENT' && this.tag(i - 1) === '{' ? '{' : tag), i]);
- return 1;
- }
- if (__indexOf.call(EXPRESSION_END, tag) >= 0) {
- start = stack.pop();
- return 1;
- }
- if (!(tag === ':' && ((ago = this.tag(i - 2)) === ':' || ((_ref1 = stack[stack.length - 1]) != null ? _ref1[0] : void 0) !== '{'))) {
- return 1;
- }
- sameLine = true;
- startIndex = i + 1;
- stack.push(['{']);
- idx = ago === '@' ? i - 2 : i - 1;
- while (this.tag(idx - 2) === 'HERECOMMENT') {
- idx -= 2;
- }
- prevTag = this.tag(idx - 1);
- startsLine = !prevTag || (__indexOf.call(LINEBREAKS, prevTag) >= 0);
- value = new String('{');
- value.generated = true;
- tok = this.generate('{', value, token[2]);
- tokens.splice(idx, 0, tok);
- this.detectEnd(i + 2, condition, action);
- return 2;
- });
- };
-
- Rewriter.prototype.addImplicitParentheses = function() {
- var action, condition, noCall, seenControl, seenSingle;
- noCall = seenSingle = seenControl = false;
- condition = function(token, i) {
- var post, tag, _ref, _ref1;
- tag = token[0];
- if (!seenSingle && token.fromThen) {
- return true;
- }
- if (tag === 'IF' || tag === 'ELSE' || tag === 'CATCH' || tag === '->' || tag === '=>' || tag === 'CLASS') {
- seenSingle = true;
- }
- if (tag === 'IF' || tag === 'ELSE' || tag === 'SWITCH' || tag === 'TRY' || tag === '=') {
- seenControl = true;
- }
- if ((tag === '.' || tag === '?.' || tag === '::') && this.tag(i - 1) === 'OUTDENT') {
- return true;
- }
- return !token.generated && this.tag(i - 1) !== ',' && (__indexOf.call(IMPLICIT_END, tag) >= 0 || (tag === 'INDENT' && !seenControl)) && (tag !== 'INDENT' || (((_ref = this.tag(i - 2)) !== 'CLASS' && _ref !== 'EXTENDS') && (_ref1 = this.tag(i - 1), __indexOf.call(IMPLICIT_BLOCK, _ref1) < 0) && !((post = this.tokens[i + 1]) && post.generated && post[0] === '{')));
- };
- action = function(token, i) {
- return this.tokens.splice(i, 0, this.generate('CALL_END', ')', token[2]));
- };
- return this.scanTokens(function(token, i, tokens) {
- var callObject, current, next, prev, tag, _ref, _ref1, _ref2;
- tag = token[0];
- if (tag === 'CLASS' || tag === 'IF' || tag === 'FOR' || tag === 'WHILE') {
- noCall = true;
- }
- _ref = tokens.slice(i - 1, (i + 1) + 1 || 9e9), prev = _ref[0], current = _ref[1], next = _ref[2];
- callObject = !noCall && tag === 'INDENT' && next && next.generated && next[0] === '{' && prev && (_ref1 = prev[0], __indexOf.call(IMPLICIT_FUNC, _ref1) >= 0);
- seenSingle = false;
- seenControl = false;
- if (__indexOf.call(LINEBREAKS, tag) >= 0) {
- noCall = false;
- }
- if (prev && !prev.spaced && tag === '?') {
- token.call = true;
- }
- if (token.fromThen) {
- return 1;
- }
- if (!(callObject || (prev != null ? prev.spaced : void 0) && (prev.call || (_ref2 = prev[0], __indexOf.call(IMPLICIT_FUNC, _ref2) >= 0)) && (__indexOf.call(IMPLICIT_CALL, tag) >= 0 || !(token.spaced || token.newLine) && __indexOf.call(IMPLICIT_UNSPACED_CALL, tag) >= 0))) {
- return 1;
- }
- tokens.splice(i, 0, this.generate('CALL_START', '(', token[2]));
- this.detectEnd(i + 1, condition, action);
- if (prev[0] === '?') {
- prev[0] = 'FUNC_EXIST';
- }
- return 2;
- });
- };
-
- Rewriter.prototype.addImplicitIndentation = function() {
- var action, condition, indent, outdent, starter;
- starter = indent = outdent = null;
- condition = function(token, i) {
- var _ref;
- return token[1] !== ';' && (_ref = token[0], __indexOf.call(SINGLE_CLOSERS, _ref) >= 0) && !(token[0] === 'ELSE' && (starter !== 'IF' && starter !== 'THEN'));
- };
- action = function(token, i) {
- return this.tokens.splice((this.tag(i - 1) === ',' ? i - 1 : i), 0, outdent);
- };
- return this.scanTokens(function(token, i, tokens) {
- var tag, _ref, _ref1;
- tag = token[0];
- if (tag === 'TERMINATOR' && this.tag(i + 1) === 'THEN') {
- tokens.splice(i, 1);
- return 0;
- }
- if (tag === 'ELSE' && this.tag(i - 1) !== 'OUTDENT') {
- tokens.splice.apply(tokens, [i, 0].concat(__slice.call(this.indentation(token))));
- return 2;
- }
- if (tag === 'CATCH' && ((_ref = this.tag(i + 2)) === 'OUTDENT' || _ref === 'TERMINATOR' || _ref === 'FINALLY')) {
- tokens.splice.apply(tokens, [i + 2, 0].concat(__slice.call(this.indentation(token))));
- return 4;
- }
- if (__indexOf.call(SINGLE_LINERS, tag) >= 0 && this.tag(i + 1) !== 'INDENT' && !(tag === 'ELSE' && this.tag(i + 1) === 'IF')) {
- starter = tag;
- _ref1 = this.indentation(token, true), indent = _ref1[0], outdent = _ref1[1];
- if (starter === 'THEN') {
- indent.fromThen = true;
- }
- tokens.splice(i + 1, 0, indent);
- this.detectEnd(i + 2, condition, action);
- if (tag === 'THEN') {
- tokens.splice(i, 1);
- }
- return 1;
- }
- return 1;
- });
- };
-
- Rewriter.prototype.tagPostfixConditionals = function() {
- var action, condition, original;
- original = null;
- condition = function(token, i) {
- var _ref;
- return (_ref = token[0]) === 'TERMINATOR' || _ref === 'INDENT';
- };
- action = function(token, i) {
- if (token[0] !== 'INDENT' || (token.generated && !token.fromThen)) {
- return original[0] = 'POST_' + original[0];
- }
- };
- return this.scanTokens(function(token, i) {
- if (token[0] !== 'IF') {
- return 1;
- }
- original = token;
- this.detectEnd(i + 1, condition, action);
- return 1;
- });
- };
-
- Rewriter.prototype.indentation = function(token, implicit) {
- var indent, outdent;
- if (implicit == null) {
- implicit = false;
- }
- indent = ['INDENT', 2, token[2]];
- outdent = ['OUTDENT', 2, token[2]];
- if (implicit) {
- indent.generated = outdent.generated = true;
- }
- return [indent, outdent];
- };
-
- Rewriter.prototype.generate = function(tag, value, line) {
- var tok;
- tok = [tag, value, line];
- tok.generated = true;
- return tok;
- };
-
- Rewriter.prototype.tag = function(i) {
- var _ref;
- return (_ref = this.tokens[i]) != null ? _ref[0] : void 0;
- };
-
- return Rewriter;
-
- })();
-
- BALANCED_PAIRS = [['(', ')'], ['[', ']'], ['{', '}'], ['INDENT', 'OUTDENT'], ['CALL_START', 'CALL_END'], ['PARAM_START', 'PARAM_END'], ['INDEX_START', 'INDEX_END']];
-
- exports.INVERSES = INVERSES = {};
-
- EXPRESSION_START = [];
-
- EXPRESSION_END = [];
-
- for (_i = 0, _len = BALANCED_PAIRS.length; _i < _len; _i++) {
- _ref = BALANCED_PAIRS[_i], left = _ref[0], rite = _ref[1];
- EXPRESSION_START.push(INVERSES[rite] = left);
- EXPRESSION_END.push(INVERSES[left] = rite);
- }
-
- EXPRESSION_CLOSE = ['CATCH', 'WHEN', 'ELSE', 'FINALLY'].concat(EXPRESSION_END);
-
- IMPLICIT_FUNC = ['IDENTIFIER', 'SUPER', ')', 'CALL_END', ']', 'INDEX_END', '@', 'THIS'];
-
- IMPLICIT_CALL = ['IDENTIFIER', 'NUMBER', 'STRING', 'JS', 'REGEX', 'NEW', 'PARAM_START', 'CLASS', 'IF', 'TRY', 'SWITCH', 'THIS', 'BOOL', 'NULL', 'UNDEFINED', 'UNARY', 'SUPER', '@', '->', '=>', '[', '(', '{', '--', '++'];
-
- IMPLICIT_UNSPACED_CALL = ['+', '-'];
-
- IMPLICIT_BLOCK = ['->', '=>', '{', '[', ','];
-
- IMPLICIT_END = ['POST_IF', 'FOR', 'WHILE', 'UNTIL', 'WHEN', 'BY', 'LOOP', 'TERMINATOR'];
-
- SINGLE_LINERS = ['ELSE', '->', '=>', 'TRY', 'FINALLY', 'THEN'];
-
- SINGLE_CLOSERS = ['TERMINATOR', 'CATCH', 'FINALLY', 'ELSE', 'OUTDENT', 'LEADING_WHEN'];
-
- LINEBREAKS = ['TERMINATOR', 'INDENT', 'OUTDENT'];
-
-}).call(this);
diff --git a/spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/scope.js b/spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/scope.js
deleted file mode 100644
index 3efc4ede..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/scope.js
+++ /dev/null
@@ -1,146 +0,0 @@
-// Generated by CoffeeScript 1.3.3
-(function() {
- var Scope, extend, last, _ref;
-
- _ref = require('./helpers'), extend = _ref.extend, last = _ref.last;
-
- exports.Scope = Scope = (function() {
-
- Scope.root = null;
-
- function Scope(parent, expressions, method) {
- this.parent = parent;
- this.expressions = expressions;
- this.method = method;
- this.variables = [
- {
- name: 'arguments',
- type: 'arguments'
- }
- ];
- this.positions = {};
- if (!this.parent) {
- Scope.root = this;
- }
- }
-
- Scope.prototype.add = function(name, type, immediate) {
- if (this.shared && !immediate) {
- return this.parent.add(name, type, immediate);
- }
- if (Object.prototype.hasOwnProperty.call(this.positions, name)) {
- return this.variables[this.positions[name]].type = type;
- } else {
- return this.positions[name] = this.variables.push({
- name: name,
- type: type
- }) - 1;
- }
- };
-
- Scope.prototype.namedMethod = function() {
- if (this.method.name || !this.parent) {
- return this.method;
- }
- return this.parent.namedMethod();
- };
-
- Scope.prototype.find = function(name) {
- if (this.check(name)) {
- return true;
- }
- this.add(name, 'var');
- return false;
- };
-
- Scope.prototype.parameter = function(name) {
- if (this.shared && this.parent.check(name, true)) {
- return;
- }
- return this.add(name, 'param');
- };
-
- Scope.prototype.check = function(name) {
- var _ref1;
- return !!(this.type(name) || ((_ref1 = this.parent) != null ? _ref1.check(name) : void 0));
- };
-
- Scope.prototype.temporary = function(name, index) {
- if (name.length > 1) {
- return '_' + name + (index > 1 ? index - 1 : '');
- } else {
- return '_' + (index + parseInt(name, 36)).toString(36).replace(/\d/g, 'a');
- }
- };
-
- Scope.prototype.type = function(name) {
- var v, _i, _len, _ref1;
- _ref1 = this.variables;
- for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
- v = _ref1[_i];
- if (v.name === name) {
- return v.type;
- }
- }
- return null;
- };
-
- Scope.prototype.freeVariable = function(name, reserve) {
- var index, temp;
- if (reserve == null) {
- reserve = true;
- }
- index = 0;
- while (this.check((temp = this.temporary(name, index)))) {
- index++;
- }
- if (reserve) {
- this.add(temp, 'var', true);
- }
- return temp;
- };
-
- Scope.prototype.assign = function(name, value) {
- this.add(name, {
- value: value,
- assigned: true
- }, true);
- return this.hasAssignments = true;
- };
-
- Scope.prototype.hasDeclarations = function() {
- return !!this.declaredVariables().length;
- };
-
- Scope.prototype.declaredVariables = function() {
- var realVars, tempVars, v, _i, _len, _ref1;
- realVars = [];
- tempVars = [];
- _ref1 = this.variables;
- for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
- v = _ref1[_i];
- if (v.type === 'var') {
- (v.name.charAt(0) === '_' ? tempVars : realVars).push(v.name);
- }
- }
- return realVars.sort().concat(tempVars.sort());
- };
-
- Scope.prototype.assignedVariables = function() {
- var v, _i, _len, _ref1, _results;
- _ref1 = this.variables;
- _results = [];
- for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
- v = _ref1[_i];
- if (v.type.assigned) {
- _results.push("" + v.name + " = " + v.type.value);
- }
- }
- return _results;
- };
-
- return Scope;
-
- })();
-
-}).call(this);
diff --git a/spec/fixture/node_modules/grunt/node_modules/coffee-script/package.json b/spec/fixture/node_modules/grunt/node_modules/coffee-script/package.json
deleted file mode 100644
index 1fac7cae..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/coffee-script/package.json
+++ /dev/null
@@ -1,68 +0,0 @@
-{
- "name": "coffee-script",
- "description": "Unfancy JavaScript",
- "keywords": [
- "javascript",
- "language",
- "coffeescript",
- "compiler"
- ],
- "author": {
- "name": "Jeremy Ashkenas"
- },
- "version": "1.3.3",
- "licenses": [
- {
- "type": "MIT",
- "url": "https://raw.github.com/jashkenas/coffee-script/master/LICENSE"
- }
- ],
- "engines": {
- "node": ">=0.4.0"
- },
- "directories": {
- "lib": "./lib/coffee-script"
- },
- "main": "./lib/coffee-script/coffee-script",
- "bin": {
- "coffee": "./bin/coffee",
- "cake": "./bin/cake"
- },
- "homepage": "http://coffeescript.org",
- "bugs": {
- "url": "https://github.com/jashkenas/coffee-script/issues"
- },
- "repository": {
- "type": "git",
- "url": "git://github.com/jashkenas/coffee-script.git"
- },
- "devDependencies": {
- "uglify-js": ">=1.0.0",
- "jison": ">=0.2.0"
- },
- "_npmUser": {
- "name": "jashkenas",
- "email": "jashkenas@gmail.com"
- },
- "_id": "coffee-script@1.3.3",
- "dependencies": {},
- "optionalDependencies": {},
- "_engineSupported": true,
- "_npmVersion": "1.1.18",
- "_nodeVersion": "v0.6.16",
- "_defaultsLoaded": true,
- "dist": {
- "shasum": "150d6b4cb522894369efed6a2101c20bc7f4a4f4",
- "tarball": "http://registry.npmjs.org/coffee-script/-/coffee-script-1.3.3.tgz"
- },
- "maintainers": [
- {
- "name": "jashkenas",
- "email": "jashkenas@gmail.com"
- }
- ],
- "_shasum": "150d6b4cb522894369efed6a2101c20bc7f4a4f4",
- "_from": "coffee-script@~1.3.3",
- "_resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.3.3.tgz",
- "readme": "ERROR: No README data found!"
-}
diff --git a/spec/fixture/node_modules/grunt/node_modules/colors/MIT-LICENSE.txt b/spec/fixture/node_modules/grunt/node_modules/colors/MIT-LICENSE.txt
deleted file mode 100644
index 7dca1070..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/colors/MIT-LICENSE.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-Copyright (c) 2010
-
-Marak Squires
-Alexis Sellier (cloudhead)
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
\ No newline at end of file
diff --git a/spec/fixture/node_modules/grunt/node_modules/colors/ReadMe.md b/spec/fixture/node_modules/grunt/node_modules/colors/ReadMe.md
deleted file mode 100644
index 0eda52db..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/colors/ReadMe.md
+++ /dev/null
@@ -1,77 +0,0 @@
-# colors.js - get color and style in your node.js console ( and browser ) like what
-
-
-
-
-## Installation
-
- npm install colors
-
-## colors and styles!
-
-- bold
-- italic
-- underline
-- inverse
-- yellow
-- cyan
-- white
-- magenta
-- green
-- red
-- grey
-- blue
-- rainbow
-- zebra
-- random
-
-## Usage
-
-``` js
-var colors = require('./colors');
-
-console.log('hello'.green); // outputs green text
-console.log('i like cake and pies'.underline.red) // outputs red underlined text
-console.log('inverse the color'.inverse); // inverses the color
-console.log('OMG Rainbows!'.rainbow); // rainbow (ignores spaces)
-```
-
-# Creating Custom themes
-
-```js
-
-var colors = require('colors');
-
-colors.setTheme({
- silly: 'rainbow',
- input: 'grey',
- verbose: 'cyan',
- prompt: 'grey',
- info: 'green',
- data: 'grey',
- help: 'cyan',
- warn: 'yellow',
- debug: 'blue',
- error: 'red'
-});
-
-// outputs red text
-console.log("this is an error".error);
-
-// outputs yellow text
-console.log("this is a warning".warn);
-```
-
-
-### Contributors
-
-Marak (Marak Squires)
-Alexis Sellier (cloudhead)
-mmalecki (Maciej Małecki)
-nicoreed (Nico Reed)
-morganrallen (Morgan Allen)
-JustinCampbell (Justin Campbell)
-ded (Dustin Diaz)
-
-
-#### , Marak Squires , Justin Campbell, Dustin Diaz (@ded)
diff --git a/spec/fixture/node_modules/grunt/node_modules/colors/colors.js b/spec/fixture/node_modules/grunt/node_modules/colors/colors.js
deleted file mode 100644
index 7a537d8d..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/colors/colors.js
+++ /dev/null
@@ -1,342 +0,0 @@
-/*
-colors.js
-
-Copyright (c) 2010
-
-Marak Squires
-Alexis Sellier (cloudhead)
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-
-*/
-
-var isHeadless = false;
-
-if (typeof module !== 'undefined') {
- isHeadless = true;
-}
-
-if (!isHeadless) {
- var exports = {};
- var module = {};
- var colors = exports;
- exports.mode = "browser";
-} else {
- exports.mode = "console";
-}
-
-//
-// Prototypes the string object to have additional method calls that add terminal colors
-//
-var addProperty = function (color, func) {
- exports[color] = function (str) {
- return func.apply(str);
- };
- String.prototype.__defineGetter__(color, func);
-};
-
-function stylize(str, style) {
-
- var styles;
-
- if (exports.mode === 'console') {
- styles = {
- //styles
- 'bold' : ['\x1B[1m', '\x1B[22m'],
- 'italic' : ['\x1B[3m', '\x1B[23m'],
- 'underline' : ['\x1B[4m', '\x1B[24m'],
- 'inverse' : ['\x1B[7m', '\x1B[27m'],
- 'strikethrough' : ['\x1B[9m', '\x1B[29m'],
- //text colors
- //grayscale
- 'white' : ['\x1B[37m', '\x1B[39m'],
- 'grey' : ['\x1B[90m', '\x1B[39m'],
- 'black' : ['\x1B[30m', '\x1B[39m'],
- //colors
- 'blue' : ['\x1B[34m', '\x1B[39m'],
- 'cyan' : ['\x1B[36m', '\x1B[39m'],
- 'green' : ['\x1B[32m', '\x1B[39m'],
- 'magenta' : ['\x1B[35m', '\x1B[39m'],
- 'red' : ['\x1B[31m', '\x1B[39m'],
- 'yellow' : ['\x1B[33m', '\x1B[39m'],
- //background colors
- //grayscale
- 'whiteBG' : ['\x1B[47m', '\x1B[49m'],
- 'greyBG' : ['\x1B[49;5;8m', '\x1B[49m'],
- 'blackBG' : ['\x1B[40m', '\x1B[49m'],
- //colors
- 'blueBG' : ['\x1B[44m', '\x1B[49m'],
- 'cyanBG' : ['\x1B[46m', '\x1B[49m'],
- 'greenBG' : ['\x1B[42m', '\x1B[49m'],
- 'magentaBG' : ['\x1B[45m', '\x1B[49m'],
- 'redBG' : ['\x1B[41m', '\x1B[49m'],
- 'yellowBG' : ['\x1B[43m', '\x1B[49m']
- };
- } else if (exports.mode === 'browser') {
- styles = {
- //styles
- 'bold' : ['', ''],
- 'italic' : ['', ''],
- 'underline' : ['', ''],
- 'inverse' : ['', ''],
- 'strikethrough' : ['', ''],
- //text colors
- //grayscale
- 'white' : ['', ''],
- 'grey' : ['', ''],
- 'black' : ['', ''],
- //colors
- 'blue' : ['', ''],
- 'cyan' : ['', ''],
- 'green' : ['', ''],
- 'magenta' : ['', ''],
- 'red' : ['', ''],
- 'yellow' : ['', ''],
- //background colors
- //grayscale
- 'whiteBG' : ['', ''],
- 'greyBG' : ['', ''],
- 'blackBG' : ['', ''],
- //colors
- 'blueBG' : ['', ''],
- 'cyanBG' : ['', ''],
- 'greenBG' : ['', ''],
- 'magentaBG' : ['', ''],
- 'redBG' : ['', ''],
- 'yellowBG' : ['', '']
- };
- } else if (exports.mode === 'none') {
- return str + '';
- } else {
- console.log('unsupported mode, try "browser", "console" or "none"');
- }
- return styles[style][0] + str + styles[style][1];
-}
-
-function applyTheme(theme) {
-
- //
- // Remark: This is a list of methods that exist
- // on String that you should not overwrite.
- //
- var stringPrototypeBlacklist = [
- '__defineGetter__', '__defineSetter__', '__lookupGetter__', '__lookupSetter__', 'charAt', 'constructor',
- 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', 'toLocaleString', 'toString', 'valueOf', 'charCodeAt',
- 'indexOf', 'lastIndexof', 'length', 'localeCompare', 'match', 'replace', 'search', 'slice', 'split', 'substring',
- 'toLocaleLowerCase', 'toLocaleUpperCase', 'toLowerCase', 'toUpperCase', 'trim', 'trimLeft', 'trimRight'
- ];
-
- Object.keys(theme).forEach(function (prop) {
- if (stringPrototypeBlacklist.indexOf(prop) !== -1) {
- console.log('warn: '.red + ('String.prototype' + prop).magenta + ' is probably something you don\'t want to override. Ignoring style name');
- }
- else {
- if (typeof(theme[prop]) === 'string') {
- addProperty(prop, function () {
- return exports[theme[prop]](this);
- });
- }
- else {
- addProperty(prop, function () {
- var ret = this;
- for (var t = 0; t < theme[prop].length; t++) {
- ret = exports[theme[prop][t]](ret);
- }
- return ret;
- });
- }
- }
- });
-}
-
-
-//
-// Iterate through all default styles and colors
-//
-var x = ['bold', 'underline', 'strikethrough', 'italic', 'inverse', 'grey', 'black', 'yellow', 'red', 'green', 'blue', 'white', 'cyan', 'magenta', 'greyBG', 'blackBG', 'yellowBG', 'redBG', 'greenBG', 'blueBG', 'whiteBG', 'cyanBG', 'magentaBG'];
-x.forEach(function (style) {
-
- // __defineGetter__ at the least works in more browsers
- // http://robertnyman.com/javascript/javascript-getters-setters.html
- // Object.defineProperty only works in Chrome
- addProperty(style, function () {
- return stylize(this, style);
- });
-});
-
-function sequencer(map) {
- return function () {
- if (!isHeadless) {
- return this.replace(/( )/, '$1');
- }
- var exploded = this.split(""), i = 0;
- exploded = exploded.map(map);
- return exploded.join("");
- };
-}
-
-var rainbowMap = (function () {
- var rainbowColors = ['red', 'yellow', 'green', 'blue', 'magenta']; //RoY G BiV
- return function (letter, i, exploded) {
- if (letter === " ") {
- return letter;
- } else {
- return stylize(letter, rainbowColors[i++ % rainbowColors.length]);
- }
- };
-})();
-
-exports.themes = {};
-
-exports.addSequencer = function (name, map) {
- addProperty(name, sequencer(map));
-};
-
-exports.addSequencer('rainbow', rainbowMap);
-exports.addSequencer('zebra', function (letter, i, exploded) {
- return i % 2 === 0 ? letter : letter.inverse;
-});
-
-exports.setTheme = function (theme) {
- if (typeof theme === 'string') {
- try {
- exports.themes[theme] = require(theme);
- applyTheme(exports.themes[theme]);
- return exports.themes[theme];
- } catch (err) {
- console.log(err);
- return err;
- }
- } else {
- applyTheme(theme);
- }
-};
-
-
-addProperty('stripColors', function () {
- return ("" + this).replace(/\x1B\[\d+m/g, '');
-});
-
-// please no
-function zalgo(text, options) {
- var soul = {
- "up" : [
- '̍', '̎', '̄', '̅',
- '̿', '̑', '̆', '̐',
- '͒', '͗', '͑', '̇',
- '̈', '̊', '͂', '̓',
- '̈', '͊', '͋', '͌',
- '̃', '̂', '̌', '͐',
- '̀', '́', '̋', '̏',
- '̒', '̓', '̔', '̽',
- '̉', 'ͣ', 'ͤ', 'ͥ',
- 'ͦ', 'ͧ', 'ͨ', 'ͩ',
- 'ͪ', 'ͫ', 'ͬ', 'ͭ',
- 'ͮ', 'ͯ', '̾', '͛',
- '͆', '̚'
- ],
- "down" : [
- '̖', '̗', '̘', '̙',
- '̜', '̝', '̞', '̟',
- '̠', '̤', '̥', '̦',
- '̩', '̪', '̫', '̬',
- '̭', '̮', '̯', '̰',
- '̱', '̲', '̳', '̹',
- '̺', '̻', '̼', 'ͅ',
- '͇', '͈', '͉', '͍',
- '͎', '͓', '͔', '͕',
- '͖', '͙', '͚', '̣'
- ],
- "mid" : [
- '̕', '̛', '̀', '́',
- '͘', '̡', '̢', '̧',
- '̨', '̴', '̵', '̶',
- '͜', '͝', '͞',
- '͟', '͠', '͢', '̸',
- '̷', '͡', ' ҉'
- ]
- },
- all = [].concat(soul.up, soul.down, soul.mid),
- zalgo = {};
-
- function randomNumber(range) {
- var r = Math.floor(Math.random() * range);
- return r;
- }
-
- function is_char(character) {
- var bool = false;
- all.filter(function (i) {
- bool = (i === character);
- });
- return bool;
- }
-
- function heComes(text, options) {
- var result = '', counts, l;
- options = options || {};
- options["up"] = options["up"] || true;
- options["mid"] = options["mid"] || true;
- options["down"] = options["down"] || true;
- options["size"] = options["size"] || "maxi";
- text = text.split('');
- for (l in text) {
- if (is_char(l)) {
- continue;
- }
- result = result + text[l];
- counts = {"up" : 0, "down" : 0, "mid" : 0};
- switch (options.size) {
- case 'mini':
- counts.up = randomNumber(8);
- counts.min = randomNumber(2);
- counts.down = randomNumber(8);
- break;
- case 'maxi':
- counts.up = randomNumber(16) + 3;
- counts.min = randomNumber(4) + 1;
- counts.down = randomNumber(64) + 3;
- break;
- default:
- counts.up = randomNumber(8) + 1;
- counts.mid = randomNumber(6) / 2;
- counts.down = randomNumber(8) + 1;
- break;
- }
-
- var arr = ["up", "mid", "down"];
- for (var d in arr) {
- var index = arr[d];
- for (var i = 0 ; i <= counts[index]; i++) {
- if (options[index]) {
- result = result + soul[index][randomNumber(soul[index].length)];
- }
- }
- }
- }
- return result;
- }
- return heComes(text);
-}
-
-
-// don't summon zalgo
-addProperty('zalgo', function () {
- return zalgo(this);
-});
diff --git a/spec/fixture/node_modules/grunt/node_modules/colors/example.html b/spec/fixture/node_modules/grunt/node_modules/colors/example.html
deleted file mode 100644
index 7a2ae605..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/colors/example.html
+++ /dev/null
@@ -1,76 +0,0 @@
-
-
-
-
- Colors Example
-
-
-
-
-
-
\ No newline at end of file
diff --git a/spec/fixture/node_modules/grunt/node_modules/colors/example.js b/spec/fixture/node_modules/grunt/node_modules/colors/example.js
deleted file mode 100644
index b1e03a4f..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/colors/example.js
+++ /dev/null
@@ -1,77 +0,0 @@
-var colors = require('./colors');
-
-//colors.mode = "browser";
-
-var test = colors.red("hopefully colorless output");
-console.log('Rainbows are fun!'.rainbow);
-console.log('So '.italic + 'are'.underline + ' styles! '.bold + 'inverse'.inverse); // styles not widely supported
-console.log('Chains are also cool.'.bold.italic.underline.red); // styles not widely supported
-//console.log('zalgo time!'.zalgo);
-console.log(test.stripColors);
-console.log("a".grey + " b".black);
-console.log("Zebras are so fun!".zebra);
-console.log('background color attack!'.black.whiteBG)
-
-//
-// Remark: .strikethrough may not work with Mac OS Terminal App
-//
-console.log("This is " + "not".strikethrough + " fun.");
-console.log(colors.rainbow('Rainbows are fun!'));
-console.log(colors.italic('So ') + colors.underline('are') + colors.bold(' styles! ') + colors.inverse('inverse')); // styles not widely supported
-console.log(colors.bold(colors.italic(colors.underline(colors.red('Chains are also cool.'))))); // styles not widely supported
-//console.log(colors.zalgo('zalgo time!'));
-console.log(colors.stripColors(test));
-console.log(colors.grey("a") + colors.black(" b"));
-
-colors.addSequencer("america", function(letter, i, exploded) {
- if(letter === " ") return letter;
- switch(i%3) {
- case 0: return letter.red;
- case 1: return letter.white;
- case 2: return letter.blue;
- }
-});
-
-colors.addSequencer("random", (function() {
- var available = ['bold', 'underline', 'italic', 'inverse', 'grey', 'yellow', 'red', 'green', 'blue', 'white', 'cyan', 'magenta'];
-
- return function(letter, i, exploded) {
- return letter === " " ? letter : letter[available[Math.round(Math.random() * (available.length - 1))]];
- };
-})());
-
-console.log("AMERICA! F--K YEAH!".america);
-console.log("So apparently I've been to Mars, with all the little green men. But you know, I don't recall.".random);
-
-//
-// Custom themes
-//
-
-// Load theme with JSON literal
-colors.setTheme({
- silly: 'rainbow',
- input: 'grey',
- verbose: 'cyan',
- prompt: 'grey',
- info: 'green',
- data: 'grey',
- help: 'cyan',
- warn: 'yellow',
- debug: 'blue',
- error: 'red'
-});
-
-// outputs red text
-console.log("this is an error".error);
-
-// outputs yellow text
-console.log("this is a warning".warn);
-
-// outputs grey text
-console.log("this is an input".input);
-
-// Load a theme from file
-colors.setTheme('./themes/winston-dark.js');
-
-console.log("this is an input".input);
-
diff --git a/spec/fixture/node_modules/grunt/node_modules/colors/package.json b/spec/fixture/node_modules/grunt/node_modules/colors/package.json
deleted file mode 100644
index 00a2f658..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/colors/package.json
+++ /dev/null
@@ -1,47 +0,0 @@
-{
- "name": "colors",
- "description": "get colors in your node.js console like what",
- "version": "0.6.2",
- "author": {
- "name": "Marak Squires"
- },
- "homepage": "https://github.com/Marak/colors.js",
- "bugs": {
- "url": "https://github.com/Marak/colors.js/issues"
- },
- "keywords": [
- "ansi",
- "terminal",
- "colors"
- ],
- "repository": {
- "type": "git",
- "url": "http://github.com/Marak/colors.js.git"
- },
- "engines": {
- "node": ">=0.1.90"
- },
- "main": "colors",
- "_id": "colors@0.6.2",
- "dist": {
- "shasum": "2423fe6678ac0c5dae8852e5d0e5be08c997abcc",
- "tarball": "http://registry.npmjs.org/colors/-/colors-0.6.2.tgz"
- },
- "_from": "colors@~0.6.2",
- "_npmVersion": "1.2.30",
- "_npmUser": {
- "name": "marak",
- "email": "marak.squires@gmail.com"
- },
- "maintainers": [
- {
- "name": "marak",
- "email": "marak.squires@gmail.com"
- }
- ],
- "directories": {},
- "_shasum": "2423fe6678ac0c5dae8852e5d0e5be08c997abcc",
- "_resolved": "https://registry.npmjs.org/colors/-/colors-0.6.2.tgz",
- "readme": "ERROR: No README data found!",
- "scripts": {}
-}
diff --git a/spec/fixture/node_modules/grunt/node_modules/colors/test.js b/spec/fixture/node_modules/grunt/node_modules/colors/test.js
deleted file mode 100644
index c32417d6..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/colors/test.js
+++ /dev/null
@@ -1,70 +0,0 @@
-var assert = require('assert'),
- colors = require('./colors');
-
-var s = 'string';
-
-function a(s, code) {
- return '\x1B[' + code.toString() + 'm' + s + '\x1B[39m';
-}
-
-function aE(s, color, code) {
- assert.equal(s[color], a(s, code));
- assert.equal(colors[color](s), a(s, code));
- assert.equal(s[color], colors[color](s));
- assert.equal(s[color].stripColors, s);
- assert.equal(s[color].stripColors, colors.stripColors(s));
-}
-
-function h(s, color) {
- return '' + s + '';
-}
-
-var stylesColors = ['white', 'black', 'blue', 'cyan', 'green', 'magenta', 'red', 'yellow'];
-var stylesAll = stylesColors.concat(['bold', 'italic', 'underline', 'inverse', 'rainbow']);
-
-colors.mode = 'console';
-assert.equal(s.bold, '\x1B[1m' + s + '\x1B[22m');
-assert.equal(s.italic, '\x1B[3m' + s + '\x1B[23m');
-assert.equal(s.underline, '\x1B[4m' + s + '\x1B[24m');
-assert.equal(s.strikethrough, '\x1B[9m' + s + '\x1B[29m');
-assert.equal(s.inverse, '\x1B[7m' + s + '\x1B[27m');
-assert.ok(s.rainbow);
-aE(s, 'white', 37);
-aE(s, 'grey', 90);
-aE(s, 'black', 30);
-aE(s, 'blue', 34);
-aE(s, 'cyan', 36);
-aE(s, 'green', 32);
-aE(s, 'magenta', 35);
-aE(s, 'red', 31);
-aE(s, 'yellow', 33);
-assert.equal(s, 'string');
-
-colors.setTheme({error:'red'});
-
-assert.equal(typeof("astring".red),'string');
-assert.equal(typeof("astring".error),'string');
-
-colors.mode = 'browser';
-assert.equal(s.bold, '' + s + '');
-assert.equal(s.italic, '' + s + '');
-assert.equal(s.underline, '' + s + '');
-assert.equal(s.strikethrough, '' + s + '');
-assert.equal(s.inverse, '' + s + '');
-assert.ok(s.rainbow);
-stylesColors.forEach(function (color) {
- assert.equal(s[color], h(s, color));
- assert.equal(colors[color](s), h(s, color));
-});
-
-assert.equal(typeof("astring".red),'string');
-assert.equal(typeof("astring".error),'string');
-
-colors.mode = 'none';
-stylesAll.forEach(function (style) {
- assert.equal(s[style], s);
- assert.equal(colors[style](s), s);
-});
-
-assert.equal(typeof("astring".red),'string');
-assert.equal(typeof("astring".error),'string');
diff --git a/spec/fixture/node_modules/grunt/node_modules/colors/themes/winston-dark.js b/spec/fixture/node_modules/grunt/node_modules/colors/themes/winston-dark.js
deleted file mode 100644
index 49a905ba..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/colors/themes/winston-dark.js
+++ /dev/null
@@ -1,12 +0,0 @@
-module['exports'] = {
- silly: 'rainbow',
- input: 'black',
- verbose: 'cyan',
- prompt: 'grey',
- info: 'green',
- data: 'grey',
- help: 'cyan',
- warn: 'yellow',
- debug: 'blue',
- error: 'red'
-};
\ No newline at end of file
diff --git a/spec/fixture/node_modules/grunt/node_modules/colors/themes/winston-light.js b/spec/fixture/node_modules/grunt/node_modules/colors/themes/winston-light.js
deleted file mode 100644
index 571972c1..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/colors/themes/winston-light.js
+++ /dev/null
@@ -1,12 +0,0 @@
-module['exports'] = {
- silly: 'rainbow',
- input: 'grey',
- verbose: 'cyan',
- prompt: 'grey',
- info: 'green',
- data: 'grey',
- help: 'cyan',
- warn: 'yellow',
- debug: 'blue',
- error: 'red'
-};
\ No newline at end of file
diff --git a/spec/fixture/node_modules/grunt/node_modules/dateformat/Readme.md b/spec/fixture/node_modules/grunt/node_modules/dateformat/Readme.md
deleted file mode 100644
index d469e6d7..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/dateformat/Readme.md
+++ /dev/null
@@ -1,67 +0,0 @@
-# node-dateformat
-
-A node.js package for Steven Levithan's excellent [dateFormat()][dateformat] function.
-
-## Modifications
-
-* Removed the `Date.prototype.format` method. Sorry folks, but extending native prototypes is for suckers.
-* Added a `module.exports = dateFormat;` statement at the bottom
-
-## Usage
-
-As taken from Steven's post, modified to match the Modifications listed above:
-
- var dateFormat = require('dateformat');
- var now = new Date();
-
- // Basic usage
- dateFormat(now, "dddd, mmmm dS, yyyy, h:MM:ss TT");
- // Saturday, June 9th, 2007, 5:46:21 PM
-
- // You can use one of several named masks
- dateFormat(now, "isoDateTime");
- // 2007-06-09T17:46:21
-
- // ...Or add your own
- dateFormat.masks.hammerTime = 'HH:MM! "Can\'t touch this!"';
- dateFormat(now, "hammerTime");
- // 17:46! Can't touch this!
-
- // When using the standalone dateFormat function,
- // you can also provide the date as a string
- dateFormat("Jun 9 2007", "fullDate");
- // Saturday, June 9, 2007
-
- // Note that if you don't include the mask argument,
- // dateFormat.masks.default is used
- dateFormat(now);
- // Sat Jun 09 2007 17:46:21
-
- // And if you don't include the date argument,
- // the current date and time is used
- dateFormat();
- // Sat Jun 09 2007 17:46:22
-
- // You can also skip the date argument (as long as your mask doesn't
- // contain any numbers), in which case the current date/time is used
- dateFormat("longTime");
- // 5:46:22 PM EST
-
- // And finally, you can convert local time to UTC time. Simply pass in
- // true as an additional argument (no argument skipping allowed in this case):
- dateFormat(now, "longTime", true);
- // 10:46:21 PM UTC
-
- // ...Or add the prefix "UTC:" to your mask.
- dateFormat(now, "UTC:h:MM:ss TT Z");
- // 10:46:21 PM UTC
-
- // You can also get the ISO 8601 week of the year:
- dateFormat(now, "W");
- // 42
-## License
-
-(c) 2007-2009 Steven Levithan [stevenlevithan.com][stevenlevithan], MIT license.
-
-[dateformat]: http://blog.stevenlevithan.com/archives/date-time-format
-[stevenlevithan]: http://stevenlevithan.com/
diff --git a/spec/fixture/node_modules/grunt/node_modules/dateformat/lib/dateformat.js b/spec/fixture/node_modules/grunt/node_modules/dateformat/lib/dateformat.js
deleted file mode 100644
index 92294246..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/dateformat/lib/dateformat.js
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * Date Format 1.2.3
- * (c) 2007-2009 Steven Levithan
- * MIT license
- *
- * Includes enhancements by Scott Trenda
- * and Kris Kowal
- *
- * Accepts a date, a mask, or a date and a mask.
- * Returns a formatted version of the given date.
- * The date defaults to the current date/time.
- * The mask defaults to dateFormat.masks.default.
- */
-
-var dateFormat = function () {
- var token = /d{1,4}|m{1,4}|yy(?:yy)?|([HhMsTt])\1?|[LloSZW]|"[^"]*"|'[^']*'/g,
- timezone = /\b(?:[PMCEA][SDP]T|(?:Pacific|Mountain|Central|Eastern|Atlantic) (?:Standard|Daylight|Prevailing) Time|(?:GMT|UTC)(?:[-+]\d{4})?)\b/g,
- timezoneClip = /[^-+\dA-Z]/g,
- pad = function (val, len) {
- val = String(val);
- len = len || 2;
- while (val.length < len) val = "0" + val;
- return val;
- },
- /**
- * Get the ISO 8601 week number
- * Based on comments from
- * http://techblog.procurios.nl/k/n618/news/view/33796/14863/Calculate-ISO-8601-week-and-year-in-javascript.html
- */
- getWeek = function (date) {
- // Remove time components of date
- var targetThursday = new Date(date.getFullYear(), date.getMonth(), date.getDate());
-
- // Change date to Thursday same week
- targetThursday.setDate(targetThursday.getDate() - ((targetThursday.getDay() + 6) % 7) + 3);
-
- // Take January 4th as it is always in week 1 (see ISO 8601)
- var firstThursday = new Date(targetThursday.getFullYear(), 0, 4);
-
- // Change date to Thursday same week
- firstThursday.setDate(firstThursday.getDate() - ((firstThursday.getDay() + 6) % 7) + 3);
-
- // Check if daylight-saving-time-switch occured and correct for it
- var ds = targetThursday.getTimezoneOffset()/firstThursday.getTimezoneOffset()-1;
- targetThursday.setHours(targetThursday.getHours()+ds);
-
- // Number of weeks between target Thursday and first Thursday
- var weekDiff = (targetThursday - firstThursday) / (86400000*7);
- return 1 + weekDiff;
- };
-
- // Regexes and supporting functions are cached through closure
- return function (date, mask, utc) {
- var dF = dateFormat;
-
- // You can't provide utc if you skip other args (use the "UTC:" mask prefix)
- if (arguments.length == 1 && Object.prototype.toString.call(date) == "[object String]" && !/\d/.test(date)) {
- mask = date;
- date = undefined;
- }
-
- date = date || new Date;
-
- if(!(date instanceof Date)) {
- date = new Date(date);
- }
-
- if (isNaN(date)) {
- throw TypeError("Invalid date");
- }
-
- mask = String(dF.masks[mask] || mask || dF.masks["default"]);
-
- // Allow setting the utc argument via the mask
- if (mask.slice(0, 4) == "UTC:") {
- mask = mask.slice(4);
- utc = true;
- }
-
- var _ = utc ? "getUTC" : "get",
- d = date[_ + "Date"](),
- D = date[_ + "Day"](),
- m = date[_ + "Month"](),
- y = date[_ + "FullYear"](),
- H = date[_ + "Hours"](),
- M = date[_ + "Minutes"](),
- s = date[_ + "Seconds"](),
- L = date[_ + "Milliseconds"](),
- o = utc ? 0 : date.getTimezoneOffset(),
- W = getWeek(date),
- flags = {
- d: d,
- dd: pad(d),
- ddd: dF.i18n.dayNames[D],
- dddd: dF.i18n.dayNames[D + 7],
- m: m + 1,
- mm: pad(m + 1),
- mmm: dF.i18n.monthNames[m],
- mmmm: dF.i18n.monthNames[m + 12],
- yy: String(y).slice(2),
- yyyy: y,
- h: H % 12 || 12,
- hh: pad(H % 12 || 12),
- H: H,
- HH: pad(H),
- M: M,
- MM: pad(M),
- s: s,
- ss: pad(s),
- l: pad(L, 3),
- L: pad(L > 99 ? Math.round(L / 10) : L),
- t: H < 12 ? "a" : "p",
- tt: H < 12 ? "am" : "pm",
- T: H < 12 ? "A" : "P",
- TT: H < 12 ? "AM" : "PM",
- Z: utc ? "UTC" : (String(date).match(timezone) || [""]).pop().replace(timezoneClip, ""),
- o: (o > 0 ? "-" : "+") + pad(Math.floor(Math.abs(o) / 60) * 100 + Math.abs(o) % 60, 4),
- S: ["th", "st", "nd", "rd"][d % 10 > 3 ? 0 : (d % 100 - d % 10 != 10) * d % 10],
- W: W
- };
-
- return mask.replace(token, function ($0) {
- return $0 in flags ? flags[$0] : $0.slice(1, $0.length - 1);
- });
- };
-}();
-
-// Some common format strings
-dateFormat.masks = {
- "default": "ddd mmm dd yyyy HH:MM:ss",
- shortDate: "m/d/yy",
- mediumDate: "mmm d, yyyy",
- longDate: "mmmm d, yyyy",
- fullDate: "dddd, mmmm d, yyyy",
- shortTime: "h:MM TT",
- mediumTime: "h:MM:ss TT",
- longTime: "h:MM:ss TT Z",
- isoDate: "yyyy-mm-dd",
- isoTime: "HH:MM:ss",
- isoDateTime: "yyyy-mm-dd'T'HH:MM:ss",
- isoUtcDateTime: "UTC:yyyy-mm-dd'T'HH:MM:ss'Z'"
-};
-
-// Internationalization strings
-dateFormat.i18n = {
- dayNames: [
- "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat",
- "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"
- ],
- monthNames: [
- "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
- "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"
- ]
-};
-
-/*
-// For convenience...
-Date.prototype.format = function (mask, utc) {
- return dateFormat(this, mask, utc);
-};
-*/
-
-if (typeof exports !== "undefined") {
- module.exports = dateFormat;
-}
diff --git a/spec/fixture/node_modules/grunt/node_modules/dateformat/package.json b/spec/fixture/node_modules/grunt/node_modules/dateformat/package.json
deleted file mode 100644
index 47cf7250..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/dateformat/package.json
+++ /dev/null
@@ -1,42 +0,0 @@
-{
- "name": "dateformat",
- "description": "A node.js package for Steven Levithan's excellent dateFormat() function.",
- "maintainers": [
- {
- "name": "felixge",
- "email": "felix@debuggable.com"
- }
- ],
- "homepage": "https://github.com/felixge/node-dateformat",
- "author": {
- "name": "Steven Levithan"
- },
- "version": "1.0.2-1.2.3",
- "main": "./lib/dateformat",
- "dependencies": {},
- "devDependencies": {},
- "engines": {
- "node": "*"
- },
- "_npmJsonOpts": {
- "file": "/Users/felix/.npm/dateformat/1.0.2-1.2.3/package/package.json",
- "wscript": false,
- "contributors": false,
- "serverjs": false
- },
- "_id": "dateformat@1.0.2-1.2.3",
- "_engineSupported": true,
- "_npmVersion": "1.0.26",
- "_nodeVersion": "v0.4.10-pre",
- "_defaultsLoaded": true,
- "dist": {
- "shasum": "b0220c02de98617433b72851cf47de3df2cdbee9",
- "tarball": "http://registry.npmjs.org/dateformat/-/dateformat-1.0.2-1.2.3.tgz"
- },
- "scripts": {},
- "directories": {},
- "_shasum": "b0220c02de98617433b72851cf47de3df2cdbee9",
- "_from": "dateformat@1.0.2-1.2.3",
- "_resolved": "https://registry.npmjs.org/dateformat/-/dateformat-1.0.2-1.2.3.tgz",
- "readme": "ERROR: No README data found!"
-}
diff --git a/spec/fixture/node_modules/grunt/node_modules/dateformat/test/test_weekofyear.js b/spec/fixture/node_modules/grunt/node_modules/dateformat/test/test_weekofyear.js
deleted file mode 100644
index d1ddbe81..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/dateformat/test/test_weekofyear.js
+++ /dev/null
@@ -1,4 +0,0 @@
-var dateFormat = require('../lib/dateformat.js');
-
-var val = process.argv[2] || new Date();
-console.log(dateFormat(val, 'W'));
diff --git a/spec/fixture/node_modules/grunt/node_modules/dateformat/test/test_weekofyear.sh b/spec/fixture/node_modules/grunt/node_modules/dateformat/test/test_weekofyear.sh
deleted file mode 100644
index 3c3e69b3..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/dateformat/test/test_weekofyear.sh
+++ /dev/null
@@ -1,27 +0,0 @@
-#!/bin/bash
-
-# this just takes php's date() function as a reference to check if week of year
-# is calculated correctly in the range from 1970 .. 2038 by brute force...
-
-SEQ="seq"
-SYSTEM=`uname`
-if [ "$SYSTEM" = "Darwin" ]; then
- SEQ="jot"
-fi
-
-for YEAR in {1970..2038}; do
- for MONTH in {1..12}; do
- DAYS=$(cal $MONTH $YEAR | egrep "28|29|30|31" |tail -1 |awk '{print $NF}')
- for DAY in $( $SEQ $DAYS ); do
- DATE=$YEAR-$MONTH-$DAY
- echo -n $DATE ...
- NODEVAL=$(node test_weekofyear.js $DATE)
- PHPVAL=$(php -r "echo intval(date('W', strtotime('$DATE')));")
- if [ "$NODEVAL" -ne "$PHPVAL" ]; then
- echo "MISMATCH: node: $NODEVAL vs php: $PHPVAL for date $DATE"
- else
- echo " OK"
- fi
- done
- done
-done
diff --git a/spec/fixture/node_modules/grunt/node_modules/eventemitter2/README.md b/spec/fixture/node_modules/grunt/node_modules/eventemitter2/README.md
deleted file mode 100644
index e1f6edd6..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/eventemitter2/README.md
+++ /dev/null
@@ -1,248 +0,0 @@
-[](https://www.codeship.io/projects/11259)
-
-# SYNOPSIS
-
-EventEmitter2 is an implementation of the EventEmitter found in Node.js
-
-# DESCRIPTION
-
-### FEATURES
- - Namespaces/Wildcards.
- - Times To Listen (TTL), extends the `once` concept with `many`.
- - Browser environment compatibility.
- - Demonstrates good performance in benchmarks
-
-```
-EventEmitterHeatUp x 3,728,965 ops/sec \302\2610.68% (60 runs sampled)
-EventEmitter x 2,822,904 ops/sec \302\2610.74% (63 runs sampled)
-EventEmitter2 x 7,251,227 ops/sec \302\2610.55% (58 runs sampled)
-EventEmitter2 (wild) x 3,220,268 ops/sec \302\2610.44% (65 runs sampled)
-Fastest is EventEmitter2
-```
-
-### Differences (Non breaking, compatible with existing EventEmitter)
-
- - The constructor takes a configuration object.
-
-```javascript
- var EventEmitter2 = require('eventemitter2').EventEmitter2;
- var server = new EventEmitter2({
-
- //
- // use wildcards.
- //
- wildcard: true,
-
- //
- // the delimiter used to segment namespaces, defaults to `.`.
- //
- delimiter: '::',
-
- //
- // if you want to emit the newListener event set to true.
- //
- newListener: false,
-
- //
- // max listeners that can be assigned to an event, default 10.
- //
- maxListeners: 20
- });
-```
-
- - Getting the actual event that fired.
-
-```javascript
- server.on('foo.*', function(value1, value2) {
- console.log(this.event, value1, value2);
- });
-```
-
- - Fire an event N times and then remove it, an extension of the `once` concept.
-
-```javascript
- server.many('foo', 4, function() {
- console.log('hello');
- });
-```
-
- - Pass in a namespaced event as an array rather than a delimited string.
-
-```javascript
- server.many(['foo', 'bar', 'bazz'], function() {
- console.log('hello');
- });
-```
-
-
-# API
-
-When an `EventEmitter` instance experiences an error, the typical action is
-to emit an `error` event. Error events are treated as a special case.
-If there is no listener for it, then the default action is to print a stack
-trace and exit the program.
-
-All EventEmitters emit the event `newListener` when new listeners are
-added.
-
-
-**Namespaces** with **Wildcards**
-To use namespaces/wildcards, pass the `wildcard` option into the EventEmitter
-constructor. When namespaces/wildcards are enabled, events can either be
-strings (`foo.bar`) separated by a delimiter or arrays (`['foo', 'bar']`). The
-delimiter is also configurable as a constructor option.
-
-An event name passed to any event emitter method can contain a wild card (the
-`*` character). If the event name is a string, a wildcard may appear as `foo.*`.
-If the event name is an array, the wildcard may appear as `['foo', '*']`.
-
-If either of the above described events were passed to the `on` method,
-subsequent emits such as the following would be observed...
-
-```javascript
- emitter.emit('foo.bazz');
- emitter.emit(['foo', 'bar']);
-```
-
-
-### emitter.addListener(event, listener)
-### emitter.on(event, listener)
-
-Adds a listener to the end of the listeners array for the specified event.
-
-```javascript
- server.on('data', function(value1, value2, value3, ...) {
- console.log('The event was raised!');
- });
-```
-
-```javascript
- server.on('data', function(value) {
- console.log('The event was raised!');
- });
-```
-
-### emitter.onAny(listener)
-
-Adds a listener that will be fired when any event is emitted.
-
-```javascript
- server.onAny(function(value) {
- console.log('All events trigger this.');
- });
-```
-
-### emitter.offAny(listener)
-
-Removes the listener that will be fired when any event is emitted.
-
-```javascript
- server.offAny(function(value) {
- console.log('The event was raised!');
- });
-```
-
-#### emitter.once(event, listener)
-
-Adds a **one time** listener for the event. The listener is invoked
-only the first time the event is fired, after which it is removed.
-
-```javascript
- server.once('get', function (value) {
- console.log('Ah, we have our first value!');
- });
-```
-
-### emitter.many(event, timesToListen, listener)
-
-Adds a listener that will execute **n times** for the event before being
-removed. The listener is invoked only the first **n times** the event is
-fired, after which it is removed.
-
-```javascript
- server.many('get', 4, function (value) {
- console.log('This event will be listened to exactly four times.');
- });
-```
-
-
-### emitter.removeListener(event, listener)
-### emitter.off(event, listener)
-
-Remove a listener from the listener array for the specified event.
-**Caution**: changes array indices in the listener array behind the listener.
-
-```javascript
- var callback = function(value) {
- console.log('someone connected!');
- };
- server.on('get', callback);
- // ...
- server.removeListener('get', callback);
-```
-
-
-### emitter.removeAllListeners([event])
-
-Removes all listeners, or those of the specified event.
-
-
-### emitter.setMaxListeners(n)
-
-By default EventEmitters will print a warning if more than 10 listeners
-are added to it. This is a useful default which helps finding memory leaks.
-Obviously not all Emitters should be limited to 10. This function allows
-that to be increased. Set to zero for unlimited.
-
-
-### emitter.listeners(event)
-
-Returns an array of listeners for the specified event. This array can be
-manipulated, e.g. to remove listeners.
-
-```javascript
- server.on('get', function(value) {
- console.log('someone connected!');
- });
- console.log(server.listeners('get')); // [ [Function] ]
-```
-
-### emitter.listenersAny()
-
-Returns an array of listeners that are listening for any event that is
-specified. This array can be manipulated, e.g. to remove listeners.
-
-```javascript
- server.onAny(function(value) {
- console.log('someone connected!');
- });
- console.log(server.listenersAny()[0]); // [ [Function] ]
-```
-
-### emitter.emit(event, [arg1], [arg2], [...])
-
-Execute each of the listeners that may be listening for the specified event
-name in order with the list of arguments.
-
-# LICENSE
-
-(The MIT License)
-
-Copyright (c) 2011 hij1nx
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the 'Software'), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is furnished
-to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
-FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
-AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/spec/fixture/node_modules/grunt/node_modules/eventemitter2/index.js b/spec/fixture/node_modules/grunt/node_modules/eventemitter2/index.js
deleted file mode 100644
index 6f583b5f..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/eventemitter2/index.js
+++ /dev/null
@@ -1 +0,0 @@
-module.exports = require('./lib/eventemitter2');
diff --git a/spec/fixture/node_modules/grunt/node_modules/eventemitter2/lib/eventemitter2.js b/spec/fixture/node_modules/grunt/node_modules/eventemitter2/lib/eventemitter2.js
deleted file mode 100644
index bde69e85..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/eventemitter2/lib/eventemitter2.js
+++ /dev/null
@@ -1,573 +0,0 @@
-/*!
- * EventEmitter2
- * https://github.com/hij1nx/EventEmitter2
- *
- * Copyright (c) 2013 hij1nx
- * Licensed under the MIT license.
- */
-;!function(undefined) {
-
- var isArray = Array.isArray ? Array.isArray : function _isArray(obj) {
- return Object.prototype.toString.call(obj) === "[object Array]";
- };
- var defaultMaxListeners = 10;
-
- function init() {
- this._events = {};
- if (this._conf) {
- configure.call(this, this._conf);
- }
- }
-
- function configure(conf) {
- if (conf) {
-
- this._conf = conf;
-
- conf.delimiter && (this.delimiter = conf.delimiter);
- conf.maxListeners && (this._events.maxListeners = conf.maxListeners);
- conf.wildcard && (this.wildcard = conf.wildcard);
- conf.newListener && (this.newListener = conf.newListener);
-
- if (this.wildcard) {
- this.listenerTree = {};
- }
- }
- }
-
- function EventEmitter(conf) {
- this._events = {};
- this.newListener = false;
- configure.call(this, conf);
- }
-
- //
- // Attention, function return type now is array, always !
- // It has zero elements if no any matches found and one or more
- // elements (leafs) if there are matches
- //
- function searchListenerTree(handlers, type, tree, i) {
- if (!tree) {
- return [];
- }
- var listeners=[], leaf, len, branch, xTree, xxTree, isolatedBranch, endReached,
- typeLength = type.length, currentType = type[i], nextType = type[i+1];
- if (i === typeLength && tree._listeners) {
- //
- // If at the end of the event(s) list and the tree has listeners
- // invoke those listeners.
- //
- if (typeof tree._listeners === 'function') {
- handlers && handlers.push(tree._listeners);
- return [tree];
- } else {
- for (leaf = 0, len = tree._listeners.length; leaf < len; leaf++) {
- handlers && handlers.push(tree._listeners[leaf]);
- }
- return [tree];
- }
- }
-
- if ((currentType === '*' || currentType === '**') || tree[currentType]) {
- //
- // If the event emitted is '*' at this part
- // or there is a concrete match at this patch
- //
- if (currentType === '*') {
- for (branch in tree) {
- if (branch !== '_listeners' && tree.hasOwnProperty(branch)) {
- listeners = listeners.concat(searchListenerTree(handlers, type, tree[branch], i+1));
- }
- }
- return listeners;
- } else if(currentType === '**') {
- endReached = (i+1 === typeLength || (i+2 === typeLength && nextType === '*'));
- if(endReached && tree._listeners) {
- // The next element has a _listeners, add it to the handlers.
- listeners = listeners.concat(searchListenerTree(handlers, type, tree, typeLength));
- }
-
- for (branch in tree) {
- if (branch !== '_listeners' && tree.hasOwnProperty(branch)) {
- if(branch === '*' || branch === '**') {
- if(tree[branch]._listeners && !endReached) {
- listeners = listeners.concat(searchListenerTree(handlers, type, tree[branch], typeLength));
- }
- listeners = listeners.concat(searchListenerTree(handlers, type, tree[branch], i));
- } else if(branch === nextType) {
- listeners = listeners.concat(searchListenerTree(handlers, type, tree[branch], i+2));
- } else {
- // No match on this one, shift into the tree but not in the type array.
- listeners = listeners.concat(searchListenerTree(handlers, type, tree[branch], i));
- }
- }
- }
- return listeners;
- }
-
- listeners = listeners.concat(searchListenerTree(handlers, type, tree[currentType], i+1));
- }
-
- xTree = tree['*'];
- if (xTree) {
- //
- // If the listener tree will allow any match for this part,
- // then recursively explore all branches of the tree
- //
- searchListenerTree(handlers, type, xTree, i+1);
- }
-
- xxTree = tree['**'];
- if(xxTree) {
- if(i < typeLength) {
- if(xxTree._listeners) {
- // If we have a listener on a '**', it will catch all, so add its handler.
- searchListenerTree(handlers, type, xxTree, typeLength);
- }
-
- // Build arrays of matching next branches and others.
- for(branch in xxTree) {
- if(branch !== '_listeners' && xxTree.hasOwnProperty(branch)) {
- if(branch === nextType) {
- // We know the next element will match, so jump twice.
- searchListenerTree(handlers, type, xxTree[branch], i+2);
- } else if(branch === currentType) {
- // Current node matches, move into the tree.
- searchListenerTree(handlers, type, xxTree[branch], i+1);
- } else {
- isolatedBranch = {};
- isolatedBranch[branch] = xxTree[branch];
- searchListenerTree(handlers, type, { '**': isolatedBranch }, i+1);
- }
- }
- }
- } else if(xxTree._listeners) {
- // We have reached the end and still on a '**'
- searchListenerTree(handlers, type, xxTree, typeLength);
- } else if(xxTree['*'] && xxTree['*']._listeners) {
- searchListenerTree(handlers, type, xxTree['*'], typeLength);
- }
- }
-
- return listeners;
- }
-
- function growListenerTree(type, listener) {
-
- type = typeof type === 'string' ? type.split(this.delimiter) : type.slice();
-
- //
- // Looks for two consecutive '**', if so, don't add the event at all.
- //
- for(var i = 0, len = type.length; i+1 < len; i++) {
- if(type[i] === '**' && type[i+1] === '**') {
- return;
- }
- }
-
- var tree = this.listenerTree;
- var name = type.shift();
-
- while (name) {
-
- if (!tree[name]) {
- tree[name] = {};
- }
-
- tree = tree[name];
-
- if (type.length === 0) {
-
- if (!tree._listeners) {
- tree._listeners = listener;
- }
- else if(typeof tree._listeners === 'function') {
- tree._listeners = [tree._listeners, listener];
- }
- else if (isArray(tree._listeners)) {
-
- tree._listeners.push(listener);
-
- if (!tree._listeners.warned) {
-
- var m = defaultMaxListeners;
-
- if (typeof this._events.maxListeners !== 'undefined') {
- m = this._events.maxListeners;
- }
-
- if (m > 0 && tree._listeners.length > m) {
-
- tree._listeners.warned = true;
- console.error('(node) warning: possible EventEmitter memory ' +
- 'leak detected. %d listeners added. ' +
- 'Use emitter.setMaxListeners() to increase limit.',
- tree._listeners.length);
- console.trace();
- }
- }
- }
- return true;
- }
- name = type.shift();
- }
- return true;
- }
-
- // By default EventEmitters will print a warning if more than
- // 10 listeners are added to it. This is a useful default which
- // helps finding memory leaks.
- //
- // Obviously not all Emitters should be limited to 10. This function allows
- // that to be increased. Set to zero for unlimited.
-
- EventEmitter.prototype.delimiter = '.';
-
- EventEmitter.prototype.setMaxListeners = function(n) {
- this._events || init.call(this);
- this._events.maxListeners = n;
- if (!this._conf) this._conf = {};
- this._conf.maxListeners = n;
- };
-
- EventEmitter.prototype.event = '';
-
- EventEmitter.prototype.once = function(event, fn) {
- this.many(event, 1, fn);
- return this;
- };
-
- EventEmitter.prototype.many = function(event, ttl, fn) {
- var self = this;
-
- if (typeof fn !== 'function') {
- throw new Error('many only accepts instances of Function');
- }
-
- function listener() {
- if (--ttl === 0) {
- self.off(event, listener);
- }
- fn.apply(this, arguments);
- }
-
- listener._origin = fn;
-
- this.on(event, listener);
-
- return self;
- };
-
- EventEmitter.prototype.emit = function() {
-
- this._events || init.call(this);
-
- var type = arguments[0];
-
- if (type === 'newListener' && !this.newListener) {
- if (!this._events.newListener) { return false; }
- }
-
- // Loop through the *_all* functions and invoke them.
- if (this._all) {
- var l = arguments.length;
- var args = new Array(l - 1);
- for (var i = 1; i < l; i++) args[i - 1] = arguments[i];
- for (i = 0, l = this._all.length; i < l; i++) {
- this.event = type;
- this._all[i].apply(this, args);
- }
- }
-
- // If there is no 'error' event listener then throw.
- if (type === 'error') {
-
- if (!this._all &&
- !this._events.error &&
- !(this.wildcard && this.listenerTree.error)) {
-
- if (arguments[1] instanceof Error) {
- throw arguments[1]; // Unhandled 'error' event
- } else {
- throw new Error("Uncaught, unspecified 'error' event.");
- }
- return false;
- }
- }
-
- var handler;
-
- if(this.wildcard) {
- handler = [];
- var ns = typeof type === 'string' ? type.split(this.delimiter) : type.slice();
- searchListenerTree.call(this, handler, ns, this.listenerTree, 0);
- }
- else {
- handler = this._events[type];
- }
-
- if (typeof handler === 'function') {
- this.event = type;
- if (arguments.length === 1) {
- handler.call(this);
- }
- else if (arguments.length > 1)
- switch (arguments.length) {
- case 2:
- handler.call(this, arguments[1]);
- break;
- case 3:
- handler.call(this, arguments[1], arguments[2]);
- break;
- // slower
- default:
- var l = arguments.length;
- var args = new Array(l - 1);
- for (var i = 1; i < l; i++) args[i - 1] = arguments[i];
- handler.apply(this, args);
- }
- return true;
- }
- else if (handler) {
- var l = arguments.length;
- var args = new Array(l - 1);
- for (var i = 1; i < l; i++) args[i - 1] = arguments[i];
-
- var listeners = handler.slice();
- for (var i = 0, l = listeners.length; i < l; i++) {
- this.event = type;
- listeners[i].apply(this, args);
- }
- return (listeners.length > 0) || !!this._all;
- }
- else {
- return !!this._all;
- }
-
- };
-
- EventEmitter.prototype.on = function(type, listener) {
-
- if (typeof type === 'function') {
- this.onAny(type);
- return this;
- }
-
- if (typeof listener !== 'function') {
- throw new Error('on only accepts instances of Function');
- }
- this._events || init.call(this);
-
- // To avoid recursion in the case that type == "newListeners"! Before
- // adding it to the listeners, first emit "newListeners".
- this.emit('newListener', type, listener);
-
- if(this.wildcard) {
- growListenerTree.call(this, type, listener);
- return this;
- }
-
- if (!this._events[type]) {
- // Optimize the case of one listener. Don't need the extra array object.
- this._events[type] = listener;
- }
- else if(typeof this._events[type] === 'function') {
- // Adding the second element, need to change to array.
- this._events[type] = [this._events[type], listener];
- }
- else if (isArray(this._events[type])) {
- // If we've already got an array, just append.
- this._events[type].push(listener);
-
- // Check for listener leak
- if (!this._events[type].warned) {
-
- var m = defaultMaxListeners;
-
- if (typeof this._events.maxListeners !== 'undefined') {
- m = this._events.maxListeners;
- }
-
- if (m > 0 && this._events[type].length > m) {
-
- this._events[type].warned = true;
- console.error('(node) warning: possible EventEmitter memory ' +
- 'leak detected. %d listeners added. ' +
- 'Use emitter.setMaxListeners() to increase limit.',
- this._events[type].length);
- console.trace();
- }
- }
- }
- return this;
- };
-
- EventEmitter.prototype.onAny = function(fn) {
-
- if (typeof fn !== 'function') {
- throw new Error('onAny only accepts instances of Function');
- }
-
- if(!this._all) {
- this._all = [];
- }
-
- // Add the function to the event listener collection.
- this._all.push(fn);
- return this;
- };
-
- EventEmitter.prototype.addListener = EventEmitter.prototype.on;
-
- EventEmitter.prototype.off = function(type, listener) {
- if (typeof listener !== 'function') {
- throw new Error('removeListener only takes instances of Function');
- }
-
- var handlers,leafs=[];
-
- if(this.wildcard) {
- var ns = typeof type === 'string' ? type.split(this.delimiter) : type.slice();
- leafs = searchListenerTree.call(this, null, ns, this.listenerTree, 0);
- }
- else {
- // does not use listeners(), so no side effect of creating _events[type]
- if (!this._events[type]) return this;
- handlers = this._events[type];
- leafs.push({_listeners:handlers});
- }
-
- for (var iLeaf=0; iLeaf 0) {
- fns = this._all;
- for(i = 0, l = fns.length; i < l; i++) {
- if(fn === fns[i]) {
- fns.splice(i, 1);
- return this;
- }
- }
- } else {
- this._all = [];
- }
- return this;
- };
-
- EventEmitter.prototype.removeListener = EventEmitter.prototype.off;
-
- EventEmitter.prototype.removeAllListeners = function(type) {
- if (arguments.length === 0) {
- !this._events || init.call(this);
- return this;
- }
-
- if(this.wildcard) {
- var ns = typeof type === 'string' ? type.split(this.delimiter) : type.slice();
- var leafs = searchListenerTree.call(this, null, ns, this.listenerTree, 0);
-
- for (var iLeaf=0; iLeaf= 0.2.2"
- },
- "main": "./lib/eventemitter2.js",
- "scripts": {
- "test": "nodeunit test/simple/ && nodeunit test/wildcardEvents/",
- "benchmark": "node test/perf/benchmark.js"
- },
- "files": [
- "lib/eventemitter2.js",
- "index.js"
- ],
- "bugs": {
- "url": "https://github.com/hij1nx/EventEmitter2/issues"
- },
- "homepage": "https://github.com/hij1nx/EventEmitter2",
- "_id": "eventemitter2@0.4.14",
- "_shasum": "8f61b75cde012b2e9eb284d4545583b5643b61ab",
- "_from": "eventemitter2@~0.4.13",
- "_npmVersion": "1.4.7",
- "_npmUser": {
- "name": "jasonkuhrt",
- "email": "jasonkuhrt@me.com"
- },
- "maintainers": [
- {
- "name": "hij1nx",
- "email": "hij1nx@me.com"
- },
- {
- "name": "jasonkuhrt",
- "email": "jasonkuhrt@me.com"
- }
- ],
- "dist": {
- "shasum": "8f61b75cde012b2e9eb284d4545583b5643b61ab",
- "tarball": "http://registry.npmjs.org/eventemitter2/-/eventemitter2-0.4.14.tgz"
- },
- "directories": {},
- "_resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-0.4.14.tgz",
- "readme": "ERROR: No README data found!"
-}
diff --git a/spec/fixture/node_modules/grunt/node_modules/exit/.jshintrc b/spec/fixture/node_modules/grunt/node_modules/exit/.jshintrc
deleted file mode 100644
index 2b7e39bf..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/exit/.jshintrc
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "curly": true,
- "eqeqeq": true,
- "immed": true,
- "latedef": "nofunc",
- "newcap": true,
- "noarg": true,
- "sub": true,
- "undef": true,
- "unused": true,
- "boss": true,
- "eqnull": true,
- "node": true
-}
diff --git a/spec/fixture/node_modules/grunt/node_modules/exit/.npmignore b/spec/fixture/node_modules/grunt/node_modules/exit/.npmignore
deleted file mode 100644
index e69de29b..00000000
diff --git a/spec/fixture/node_modules/grunt/node_modules/exit/.travis.yml b/spec/fixture/node_modules/grunt/node_modules/exit/.travis.yml
deleted file mode 100644
index 42d43029..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/exit/.travis.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-language: node_js
-node_js:
- - 0.8
- - '0.10'
-before_script:
- - npm install -g grunt-cli
diff --git a/spec/fixture/node_modules/grunt/node_modules/exit/Gruntfile.js b/spec/fixture/node_modules/grunt/node_modules/exit/Gruntfile.js
deleted file mode 100644
index ff37751b..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/exit/Gruntfile.js
+++ /dev/null
@@ -1,48 +0,0 @@
-'use strict';
-
-module.exports = function(grunt) {
-
- // Project configuration.
- grunt.initConfig({
- nodeunit: {
- files: ['test/**/*_test.js'],
- },
- jshint: {
- options: {
- jshintrc: '.jshintrc'
- },
- gruntfile: {
- src: 'Gruntfile.js'
- },
- lib: {
- src: ['lib/**/*.js']
- },
- test: {
- src: ['test/**/*.js']
- },
- },
- watch: {
- gruntfile: {
- files: '<%= jshint.gruntfile.src %>',
- tasks: ['jshint:gruntfile']
- },
- lib: {
- files: '<%= jshint.lib.src %>',
- tasks: ['jshint:lib', 'nodeunit']
- },
- test: {
- files: '<%= jshint.test.src %>',
- tasks: ['jshint:test', 'nodeunit']
- },
- },
- });
-
- // These plugins provide necessary tasks.
- grunt.loadNpmTasks('grunt-contrib-nodeunit');
- grunt.loadNpmTasks('grunt-contrib-jshint');
- grunt.loadNpmTasks('grunt-contrib-watch');
-
- // Default task.
- grunt.registerTask('default', ['jshint', 'nodeunit']);
-
-};
diff --git a/spec/fixture/node_modules/grunt/node_modules/exit/LICENSE-MIT b/spec/fixture/node_modules/grunt/node_modules/exit/LICENSE-MIT
deleted file mode 100644
index bb2aad6d..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/exit/LICENSE-MIT
+++ /dev/null
@@ -1,22 +0,0 @@
-Copyright (c) 2013 "Cowboy" Ben Alman
-
-Permission is hereby granted, free of charge, to any person
-obtaining a copy of this software and associated documentation
-files (the "Software"), to deal in the Software without
-restriction, including without limitation the rights to use,
-copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the
-Software is furnished to do so, subject to the following
-conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-OTHER DEALINGS IN THE SOFTWARE.
diff --git a/spec/fixture/node_modules/grunt/node_modules/exit/README.md b/spec/fixture/node_modules/grunt/node_modules/exit/README.md
deleted file mode 100644
index 20c364eb..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/exit/README.md
+++ /dev/null
@@ -1,75 +0,0 @@
-# exit [](http://travis-ci.org/cowboy/node-exit)
-
-A replacement for process.exit that ensures stdio are fully drained before exiting.
-
-To make a long story short, if `process.exit` is called on Windows, script output is often truncated when pipe-redirecting `stdout` or `stderr`. This module attempts to work around this issue by waiting until those streams have been completely drained before actually calling `process.exit`.
-
-See [Node.js issue #3584](https://github.com/joyent/node/issues/3584) for further reference.
-
-Tested in OS X 10.8, Windows 7 on Node.js 0.8.25 and 0.10.18.
-
-Based on some code by [@vladikoff](https://github.com/vladikoff).
-
-## Getting Started
-Install the module with: `npm install exit`
-
-```javascript
-var exit = require('exit');
-
-// These lines should appear in the output, EVEN ON WINDOWS.
-console.log("omg");
-console.error("yay");
-
-// process.exit(5);
-exit(5);
-
-// These lines shouldn't appear in the output.
-console.log("wtf");
-console.error("bro");
-```
-
-## Don't believe me? Try it for yourself.
-
-In Windows, clone the repo and cd to the `test\fixtures` directory. The only difference between [log.js](test/fixtures/log.js) and [log-broken.js](test/fixtures/log-broken.js) is that the former uses `exit` while the latter calls `process.exit` directly.
-
-This test was done using cmd.exe, but you can see the same results using `| grep "std"` in either PowerShell or git-bash.
-
-```
-C:\node-exit\test\fixtures>node log.js 0 10 stdout stderr 2>&1 | find "std"
-stdout 0
-stderr 0
-stdout 1
-stderr 1
-stdout 2
-stderr 2
-stdout 3
-stderr 3
-stdout 4
-stderr 4
-stdout 5
-stderr 5
-stdout 6
-stderr 6
-stdout 7
-stderr 7
-stdout 8
-stderr 8
-stdout 9
-stderr 9
-
-C:\node-exit\test\fixtures>node log-broken.js 0 10 stdout stderr 2>&1 | find "std"
-
-C:\node-exit\test\fixtures>
-```
-
-## Contributing
-In lieu of a formal styleguide, take care to maintain the existing coding style. Add unit tests for any new or changed functionality. Lint and test your code using [Grunt](http://gruntjs.com/).
-
-## Release History
-2013-11-26 - v0.1.2 - Fixed a bug with hanging processes.
-2013-09-26 - v0.1.1 - Fixed some bugs. It seems to actually work now!
-2013-09-20 - v0.1.0 - Initial release.
-
-## License
-Copyright (c) 2013 "Cowboy" Ben Alman
-Licensed under the MIT license.
diff --git a/spec/fixture/node_modules/grunt/node_modules/exit/lib/exit.js b/spec/fixture/node_modules/grunt/node_modules/exit/lib/exit.js
deleted file mode 100644
index 2883e059..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/exit/lib/exit.js
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * exit
- * https://github.com/cowboy/node-exit
- *
- * Copyright (c) 2013 "Cowboy" Ben Alman
- * Licensed under the MIT license.
- */
-
-'use strict';
-
-module.exports = function exit(exitCode, streams) {
- if (!streams) { streams = [process.stdout, process.stderr]; }
- var drainCount = 0;
- // Actually exit if all streams are drained.
- function tryToExit() {
- if (drainCount === streams.length) {
- process.exit(exitCode);
- }
- }
- streams.forEach(function(stream) {
- // Count drained streams now, but monitor non-drained streams.
- if (stream.bufferSize === 0) {
- drainCount++;
- } else {
- stream.write('', 'utf-8', function() {
- drainCount++;
- tryToExit();
- });
- }
- // Prevent further writing.
- stream.write = function() {};
- });
- // If all streams were already drained, exit now.
- tryToExit();
- // In Windows, when run as a Node.js child process, a script utilizing
- // this library might just exit with a 0 exit code, regardless. This code,
- // despite the fact that it looks a bit crazy, appears to fix that.
- process.on('exit', function() {
- process.exit(exitCode);
- });
-};
diff --git a/spec/fixture/node_modules/grunt/node_modules/exit/package.json b/spec/fixture/node_modules/grunt/node_modules/exit/package.json
deleted file mode 100644
index eb27d998..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/exit/package.json
+++ /dev/null
@@ -1,69 +0,0 @@
-{
- "name": "exit",
- "description": "A replacement for process.exit that ensures stdio are fully drained before exiting.",
- "version": "0.1.2",
- "homepage": "https://github.com/cowboy/node-exit",
- "author": {
- "name": "\"Cowboy\" Ben Alman",
- "url": "http://benalman.com/"
- },
- "repository": {
- "type": "git",
- "url": "git://github.com/cowboy/node-exit.git"
- },
- "bugs": {
- "url": "https://github.com/cowboy/node-exit/issues"
- },
- "licenses": [
- {
- "type": "MIT",
- "url": "https://github.com/cowboy/node-exit/blob/master/LICENSE-MIT"
- }
- ],
- "main": "lib/exit",
- "engines": {
- "node": ">= 0.8.0"
- },
- "scripts": {
- "test": "grunt nodeunit"
- },
- "devDependencies": {
- "grunt-contrib-jshint": "~0.6.4",
- "grunt-contrib-nodeunit": "~0.2.0",
- "grunt-contrib-watch": "~0.5.3",
- "grunt": "~0.4.1",
- "which": "~1.0.5"
- },
- "keywords": [
- "exit",
- "process",
- "stdio",
- "stdout",
- "stderr",
- "drain",
- "flush",
- "3584"
- ],
- "readme": "# exit [](http://travis-ci.org/cowboy/node-exit)\n\nA replacement for process.exit that ensures stdio are fully drained before exiting.\n\nTo make a long story short, if `process.exit` is called on Windows, script output is often truncated when pipe-redirecting `stdout` or `stderr`. This module attempts to work around this issue by waiting until those streams have been completely drained before actually calling `process.exit`.\n\nSee [Node.js issue #3584](https://github.com/joyent/node/issues/3584) for further reference.\n\nTested in OS X 10.8, Windows 7 on Node.js 0.8.25 and 0.10.18.\n\nBased on some code by [@vladikoff](https://github.com/vladikoff).\n\n## Getting Started\nInstall the module with: `npm install exit`\n\n```javascript\nvar exit = require('exit');\n\n// These lines should appear in the output, EVEN ON WINDOWS.\nconsole.log(\"omg\");\nconsole.error(\"yay\");\n\n// process.exit(5);\nexit(5);\n\n// These lines shouldn't appear in the output.\nconsole.log(\"wtf\");\nconsole.error(\"bro\");\n```\n\n## Don't believe me? Try it for yourself.\n\nIn Windows, clone the repo and cd to the `test\\fixtures` directory. The only difference between [log.js](test/fixtures/log.js) and [log-broken.js](test/fixtures/log-broken.js) is that the former uses `exit` while the latter calls `process.exit` directly.\n\nThis test was done using cmd.exe, but you can see the same results using `| grep \"std\"` in either PowerShell or git-bash.\n\n```\nC:\\node-exit\\test\\fixtures>node log.js 0 10 stdout stderr 2>&1 | find \"std\"\nstdout 0\nstderr 0\nstdout 1\nstderr 1\nstdout 2\nstderr 2\nstdout 3\nstderr 3\nstdout 4\nstderr 4\nstdout 5\nstderr 5\nstdout 6\nstderr 6\nstdout 7\nstderr 7\nstdout 8\nstderr 8\nstdout 9\nstderr 9\n\nC:\\node-exit\\test\\fixtures>node log-broken.js 0 10 stdout stderr 2>&1 | find \"std\"\n\nC:\\node-exit\\test\\fixtures>\n```\n\n## Contributing\nIn lieu of a formal styleguide, take care to maintain the existing coding style. Add unit tests for any new or changed functionality. Lint and test your code using [Grunt](http://gruntjs.com/).\n\n## Release History\n2013-11-26 - v0.1.2 - Fixed a bug with hanging processes. \n2013-09-26 - v0.1.1 - Fixed some bugs. It seems to actually work now! \n2013-09-20 - v0.1.0 - Initial release.\n\n## License\nCopyright (c) 2013 \"Cowboy\" Ben Alman \nLicensed under the MIT license.\n",
- "readmeFilename": "README.md",
- "_id": "exit@0.1.2",
- "dist": {
- "shasum": "0632638f8d877cc82107d30a0fff1a17cba1cd0c",
- "tarball": "http://registry.npmjs.org/exit/-/exit-0.1.2.tgz"
- },
- "_from": "exit@~0.1.1",
- "_npmVersion": "1.3.11",
- "_npmUser": {
- "name": "cowboy",
- "email": "cowboy@rj3.net"
- },
- "maintainers": [
- {
- "name": "cowboy",
- "email": "cowboy@rj3.net"
- }
- ],
- "directories": {},
- "_shasum": "0632638f8d877cc82107d30a0fff1a17cba1cd0c",
- "_resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz"
-}
diff --git a/spec/fixture/node_modules/grunt/node_modules/exit/test/exit_test.js b/spec/fixture/node_modules/grunt/node_modules/exit/test/exit_test.js
deleted file mode 100644
index a91afb91..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/exit/test/exit_test.js
+++ /dev/null
@@ -1,121 +0,0 @@
-'use strict';
-
-/*
- ======== A Handy Little Nodeunit Reference ========
- https://github.com/caolan/nodeunit
-
- Test methods:
- test.expect(numAssertions)
- test.done()
- Test assertions:
- test.ok(value, [message])
- test.equal(actual, expected, [message])
- test.notEqual(actual, expected, [message])
- test.deepEqual(actual, expected, [message])
- test.notDeepEqual(actual, expected, [message])
- test.strictEqual(actual, expected, [message])
- test.notStrictEqual(actual, expected, [message])
- test.throws(block, [error], [message])
- test.doesNotThrow(block, [error], [message])
- test.ifError(value)
-*/
-
-var fs = require('fs');
-var exec = require('child_process').exec;
-
-var _which = require('which').sync;
-function which(command) {
- try {
- _which(command);
- return command;
- } catch (err) {
- return false;
- }
-}
-
-// Look for grep first (any OS). If not found (but on Windows) look for find,
-// which is Windows' horribly crippled grep alternative.
-var grep = which('grep') || process.platform === 'win32' && which('find');
-
-exports['exit'] = {
- setUp: function(done) {
- this.origCwd = process.cwd();
- process.chdir('test/fixtures');
- done();
- },
- tearDown: function(done) {
- process.chdir(this.origCwd);
- done();
- },
- 'grep': function(test) {
- test.expect(1);
- // Many unit tests depend on this.
- test.ok(grep, 'A suitable "grep" or "find" program was not found in the PATH.');
- test.done();
- },
- // The rest of the tests are built dynamically, to keep things sane.
-};
-
-// A few helper functions.
-function normalizeLineEndings(s) {
- return s.replace(/\r?\n/g, '\n');
-}
-
-// Capture command output, normalizing captured stdout to unix file endings.
-function run(command, callback) {
- exec(command, function(error, stdout) {
- callback(error ? error.code : 0, normalizeLineEndings(stdout));
- });
-}
-
-// Read a fixture file, normalizing file contents to unix file endings.
-function fixture(filename) {
- return normalizeLineEndings(String(fs.readFileSync(filename)));
-}
-
-function buildTests() {
- // Build individual unit tests for command output.
- var counts = [10, 100, 1000];
- var outputs = [' stdout stderr', ' stdout', ' stderr'];
- var pipes = ['', ' | ' + grep + ' "std"'];
- counts.forEach(function(count) {
- outputs.forEach(function(output) {
- pipes.forEach(function(pipe) {
- var command = 'node log.js 0 ' + count + output + ' 2>&1' + pipe;
- exports['exit']['output (' + command + ')'] = function(test) {
- test.expect(2);
- run(command, function(code, actual) {
- var expected = fixture(count + output.replace(/ /g, '-') + '.txt');
- // Sometimes, the actual file lines are out of order on Windows.
- // But since the point of this lib is to drain the buffer and not
- // guarantee output order, we only test the length.
- test.equal(actual.length, expected.length, 'should be the same length.');
- // The "fail" lines in log.js should NOT be output!
- test.ok(actual.indexOf('fail') === -1, 'should not output after exit is called.');
- test.done();
- });
- };
- });
- });
- });
-
- // Build individual unit tests for exit codes.
- var codes = [0, 1, 123];
- codes.forEach(function(code) {
- var command = 'node log.js ' + code + ' 10 stdout stderr';
- exports['exit']['exit code (' + command + ')'] = function(test) {
- test.expect(1);
- run(command, function(actual) {
- // The specified exit code should be passed through.
- test.equal(actual, code, 'should exit with ' + code + ' error code.');
- test.done();
- });
- };
- });
-}
-
-// Don't bother building tests if grep wasn't found, otherwise everything will
-// fail and the error will get lost.
-if (grep) {
- buildTests();
-}
diff --git a/spec/fixture/node_modules/grunt/node_modules/exit/test/fixtures/10-stderr.txt b/spec/fixture/node_modules/grunt/node_modules/exit/test/fixtures/10-stderr.txt
deleted file mode 100644
index 28592003..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/exit/test/fixtures/10-stderr.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-stderr 0
-stderr 1
-stderr 2
-stderr 3
-stderr 4
-stderr 5
-stderr 6
-stderr 7
-stderr 8
-stderr 9
diff --git a/spec/fixture/node_modules/grunt/node_modules/exit/test/fixtures/10-stdout-stderr.txt b/spec/fixture/node_modules/grunt/node_modules/exit/test/fixtures/10-stdout-stderr.txt
deleted file mode 100644
index 9de86166..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/exit/test/fixtures/10-stdout-stderr.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-stdout 0
-stderr 0
-stdout 1
-stdout 2
-stderr 1
-stdout 3
-stderr 2
-stderr 3
-stdout 4
-stderr 4
-stdout 5
-stderr 5
-stdout 6
-stderr 6
-stdout 7
-stderr 7
-stdout 8
-stderr 8
-stdout 9
-stderr 9
diff --git a/spec/fixture/node_modules/grunt/node_modules/exit/test/fixtures/10-stdout.txt b/spec/fixture/node_modules/grunt/node_modules/exit/test/fixtures/10-stdout.txt
deleted file mode 100644
index 1ce90dcc..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/exit/test/fixtures/10-stdout.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-stdout 0
-stdout 1
-stdout 2
-stdout 3
-stdout 4
-stdout 5
-stdout 6
-stdout 7
-stdout 8
-stdout 9
diff --git a/spec/fixture/node_modules/grunt/node_modules/exit/test/fixtures/100-stderr.txt b/spec/fixture/node_modules/grunt/node_modules/exit/test/fixtures/100-stderr.txt
deleted file mode 100644
index 3a78c857..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/exit/test/fixtures/100-stderr.txt
+++ /dev/null
@@ -1,100 +0,0 @@
-stderr 0
-stderr 1
-stderr 2
-stderr 3
-stderr 4
-stderr 5
-stderr 6
-stderr 7
-stderr 8
-stderr 9
-stderr 10
-stderr 11
-stderr 12
-stderr 13
-stderr 14
-stderr 15
-stderr 16
-stderr 17
-stderr 18
-stderr 19
-stderr 20
-stderr 21
-stderr 22
-stderr 23
-stderr 24
-stderr 25
-stderr 26
-stderr 27
-stderr 28
-stderr 29
-stderr 30
-stderr 31
-stderr 32
-stderr 33
-stderr 34
-stderr 35
-stderr 36
-stderr 37
-stderr 38
-stderr 39
-stderr 40
-stderr 41
-stderr 42
-stderr 43
-stderr 44
-stderr 45
-stderr 46
-stderr 47
-stderr 48
-stderr 49
-stderr 50
-stderr 51
-stderr 52
-stderr 53
-stderr 54
-stderr 55
-stderr 56
-stderr 57
-stderr 58
-stderr 59
-stderr 60
-stderr 61
-stderr 62
-stderr 63
-stderr 64
-stderr 65
-stderr 66
-stderr 67
-stderr 68
-stderr 69
-stderr 70
-stderr 71
-stderr 72
-stderr 73
-stderr 74
-stderr 75
-stderr 76
-stderr 77
-stderr 78
-stderr 79
-stderr 80
-stderr 81
-stderr 82
-stderr 83
-stderr 84
-stderr 85
-stderr 86
-stderr 87
-stderr 88
-stderr 89
-stderr 90
-stderr 91
-stderr 92
-stderr 93
-stderr 94
-stderr 95
-stderr 96
-stderr 97
-stderr 98
-stderr 99
diff --git a/spec/fixture/node_modules/grunt/node_modules/exit/test/fixtures/100-stdout-stderr.txt b/spec/fixture/node_modules/grunt/node_modules/exit/test/fixtures/100-stdout-stderr.txt
deleted file mode 100644
index 65f35f45..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/exit/test/fixtures/100-stdout-stderr.txt
+++ /dev/null
@@ -1,200 +0,0 @@
-stdout 0
-stderr 0
-stdout 1
-stderr 1
-stdout 2
-stderr 2
-stdout 3
-stderr 3
-stdout 4
-stderr 4
-stdout 5
-stderr 5
-stdout 6
-stderr 6
-stdout 7
-stderr 7
-stdout 8
-stderr 8
-stdout 9
-stderr 9
-stdout 10
-stderr 10
-stdout 11
-stderr 11
-stdout 12
-stderr 12
-stdout 13
-stderr 13
-stdout 14
-stderr 14
-stdout 15
-stderr 15
-stdout 16
-stderr 16
-stdout 17
-stderr 17
-stdout 18
-stderr 18
-stdout 19
-stderr 19
-stdout 20
-stderr 20
-stdout 21
-stderr 21
-stdout 22
-stderr 22
-stdout 23
-stderr 23
-stdout 24
-stderr 24
-stdout 25
-stderr 25
-stdout 26
-stderr 26
-stdout 27
-stderr 27
-stdout 28
-stderr 28
-stdout 29
-stderr 29
-stdout 30
-stderr 30
-stdout 31
-stderr 31
-stdout 32
-stderr 32
-stdout 33
-stderr 33
-stdout 34
-stderr 34
-stdout 35
-stderr 35
-stdout 36
-stderr 36
-stdout 37
-stderr 37
-stdout 38
-stderr 38
-stdout 39
-stderr 39
-stdout 40
-stderr 40
-stdout 41
-stderr 41
-stdout 42
-stderr 42
-stdout 43
-stderr 43
-stdout 44
-stderr 44
-stdout 45
-stderr 45
-stdout 46
-stderr 46
-stdout 47
-stderr 47
-stdout 48
-stderr 48
-stdout 49
-stderr 49
-stdout 50
-stderr 50
-stdout 51
-stderr 51
-stdout 52
-stderr 52
-stdout 53
-stderr 53
-stdout 54
-stderr 54
-stdout 55
-stderr 55
-stdout 56
-stderr 56
-stdout 57
-stderr 57
-stdout 58
-stderr 58
-stdout 59
-stderr 59
-stdout 60
-stderr 60
-stdout 61
-stderr 61
-stdout 62
-stderr 62
-stdout 63
-stderr 63
-stdout 64
-stderr 64
-stdout 65
-stderr 65
-stdout 66
-stderr 66
-stdout 67
-stderr 67
-stdout 68
-stderr 68
-stdout 69
-stderr 69
-stdout 70
-stderr 70
-stdout 71
-stderr 71
-stdout 72
-stderr 72
-stdout 73
-stderr 73
-stdout 74
-stderr 74
-stdout 75
-stderr 75
-stdout 76
-stderr 76
-stdout 77
-stderr 77
-stdout 78
-stderr 78
-stdout 79
-stderr 79
-stdout 80
-stderr 80
-stdout 81
-stderr 81
-stdout 82
-stderr 82
-stdout 83
-stderr 83
-stdout 84
-stderr 84
-stdout 85
-stderr 85
-stdout 86
-stderr 86
-stdout 87
-stderr 87
-stdout 88
-stderr 88
-stdout 89
-stderr 89
-stdout 90
-stderr 90
-stdout 91
-stderr 91
-stdout 92
-stderr 92
-stdout 93
-stderr 93
-stdout 94
-stderr 94
-stdout 95
-stderr 95
-stdout 96
-stderr 96
-stdout 97
-stderr 97
-stdout 98
-stderr 98
-stdout 99
-stderr 99
diff --git a/spec/fixture/node_modules/grunt/node_modules/exit/test/fixtures/100-stdout.txt b/spec/fixture/node_modules/grunt/node_modules/exit/test/fixtures/100-stdout.txt
deleted file mode 100644
index 5d9cac25..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/exit/test/fixtures/100-stdout.txt
+++ /dev/null
@@ -1,100 +0,0 @@
-stdout 0
-stdout 1
-stdout 2
-stdout 3
-stdout 4
-stdout 5
-stdout 6
-stdout 7
-stdout 8
-stdout 9
-stdout 10
-stdout 11
-stdout 12
-stdout 13
-stdout 14
-stdout 15
-stdout 16
-stdout 17
-stdout 18
-stdout 19
-stdout 20
-stdout 21
-stdout 22
-stdout 23
-stdout 24
-stdout 25
-stdout 26
-stdout 27
-stdout 28
-stdout 29
-stdout 30
-stdout 31
-stdout 32
-stdout 33
-stdout 34
-stdout 35
-stdout 36
-stdout 37
-stdout 38
-stdout 39
-stdout 40
-stdout 41
-stdout 42
-stdout 43
-stdout 44
-stdout 45
-stdout 46
-stdout 47
-stdout 48
-stdout 49
-stdout 50
-stdout 51
-stdout 52
-stdout 53
-stdout 54
-stdout 55
-stdout 56
-stdout 57
-stdout 58
-stdout 59
-stdout 60
-stdout 61
-stdout 62
-stdout 63
-stdout 64
-stdout 65
-stdout 66
-stdout 67
-stdout 68
-stdout 69
-stdout 70
-stdout 71
-stdout 72
-stdout 73
-stdout 74
-stdout 75
-stdout 76
-stdout 77
-stdout 78
-stdout 79
-stdout 80
-stdout 81
-stdout 82
-stdout 83
-stdout 84
-stdout 85
-stdout 86
-stdout 87
-stdout 88
-stdout 89
-stdout 90
-stdout 91
-stdout 92
-stdout 93
-stdout 94
-stdout 95
-stdout 96
-stdout 97
-stdout 98
-stdout 99
diff --git a/spec/fixture/node_modules/grunt/node_modules/exit/test/fixtures/1000-stderr.txt b/spec/fixture/node_modules/grunt/node_modules/exit/test/fixtures/1000-stderr.txt
deleted file mode 100644
index d6375102..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/exit/test/fixtures/1000-stderr.txt
+++ /dev/null
@@ -1,1000 +0,0 @@
-stderr 0
-stderr 1
-stderr 2
-stderr 3
-stderr 4
-stderr 5
-stderr 6
-stderr 7
-stderr 8
-stderr 9
-stderr 10
-stderr 11
-stderr 12
-stderr 13
-stderr 14
-stderr 15
-stderr 16
-stderr 17
-stderr 18
-stderr 19
-stderr 20
-stderr 21
-stderr 22
-stderr 23
-stderr 24
-stderr 25
-stderr 26
-stderr 27
-stderr 28
-stderr 29
-stderr 30
-stderr 31
-stderr 32
-stderr 33
-stderr 34
-stderr 35
-stderr 36
-stderr 37
-stderr 38
-stderr 39
-stderr 40
-stderr 41
-stderr 42
-stderr 43
-stderr 44
-stderr 45
-stderr 46
-stderr 47
-stderr 48
-stderr 49
-stderr 50
-stderr 51
-stderr 52
-stderr 53
-stderr 54
-stderr 55
-stderr 56
-stderr 57
-stderr 58
-stderr 59
-stderr 60
-stderr 61
-stderr 62
-stderr 63
-stderr 64
-stderr 65
-stderr 66
-stderr 67
-stderr 68
-stderr 69
-stderr 70
-stderr 71
-stderr 72
-stderr 73
-stderr 74
-stderr 75
-stderr 76
-stderr 77
-stderr 78
-stderr 79
-stderr 80
-stderr 81
-stderr 82
-stderr 83
-stderr 84
-stderr 85
-stderr 86
-stderr 87
-stderr 88
-stderr 89
-stderr 90
-stderr 91
-stderr 92
-stderr 93
-stderr 94
-stderr 95
-stderr 96
-stderr 97
-stderr 98
-stderr 99
-stderr 100
-stderr 101
-stderr 102
-stderr 103
-stderr 104
-stderr 105
-stderr 106
-stderr 107
-stderr 108
-stderr 109
-stderr 110
-stderr 111
-stderr 112
-stderr 113
-stderr 114
-stderr 115
-stderr 116
-stderr 117
-stderr 118
-stderr 119
-stderr 120
-stderr 121
-stderr 122
-stderr 123
-stderr 124
-stderr 125
-stderr 126
-stderr 127
-stderr 128
-stderr 129
-stderr 130
-stderr 131
-stderr 132
-stderr 133
-stderr 134
-stderr 135
-stderr 136
-stderr 137
-stderr 138
-stderr 139
-stderr 140
-stderr 141
-stderr 142
-stderr 143
-stderr 144
-stderr 145
-stderr 146
-stderr 147
-stderr 148
-stderr 149
-stderr 150
-stderr 151
-stderr 152
-stderr 153
-stderr 154
-stderr 155
-stderr 156
-stderr 157
-stderr 158
-stderr 159
-stderr 160
-stderr 161
-stderr 162
-stderr 163
-stderr 164
-stderr 165
-stderr 166
-stderr 167
-stderr 168
-stderr 169
-stderr 170
-stderr 171
-stderr 172
-stderr 173
-stderr 174
-stderr 175
-stderr 176
-stderr 177
-stderr 178
-stderr 179
-stderr 180
-stderr 181
-stderr 182
-stderr 183
-stderr 184
-stderr 185
-stderr 186
-stderr 187
-stderr 188
-stderr 189
-stderr 190
-stderr 191
-stderr 192
-stderr 193
-stderr 194
-stderr 195
-stderr 196
-stderr 197
-stderr 198
-stderr 199
-stderr 200
-stderr 201
-stderr 202
-stderr 203
-stderr 204
-stderr 205
-stderr 206
-stderr 207
-stderr 208
-stderr 209
-stderr 210
-stderr 211
-stderr 212
-stderr 213
-stderr 214
-stderr 215
-stderr 216
-stderr 217
-stderr 218
-stderr 219
-stderr 220
-stderr 221
-stderr 222
-stderr 223
-stderr 224
-stderr 225
-stderr 226
-stderr 227
-stderr 228
-stderr 229
-stderr 230
-stderr 231
-stderr 232
-stderr 233
-stderr 234
-stderr 235
-stderr 236
-stderr 237
-stderr 238
-stderr 239
-stderr 240
-stderr 241
-stderr 242
-stderr 243
-stderr 244
-stderr 245
-stderr 246
-stderr 247
-stderr 248
-stderr 249
-stderr 250
-stderr 251
-stderr 252
-stderr 253
-stderr 254
-stderr 255
-stderr 256
-stderr 257
-stderr 258
-stderr 259
-stderr 260
-stderr 261
-stderr 262
-stderr 263
-stderr 264
-stderr 265
-stderr 266
-stderr 267
-stderr 268
-stderr 269
-stderr 270
-stderr 271
-stderr 272
-stderr 273
-stderr 274
-stderr 275
-stderr 276
-stderr 277
-stderr 278
-stderr 279
-stderr 280
-stderr 281
-stderr 282
-stderr 283
-stderr 284
-stderr 285
-stderr 286
-stderr 287
-stderr 288
-stderr 289
-stderr 290
-stderr 291
-stderr 292
-stderr 293
-stderr 294
-stderr 295
-stderr 296
-stderr 297
-stderr 298
-stderr 299
-stderr 300
-stderr 301
-stderr 302
-stderr 303
-stderr 304
-stderr 305
-stderr 306
-stderr 307
-stderr 308
-stderr 309
-stderr 310
-stderr 311
-stderr 312
-stderr 313
-stderr 314
-stderr 315
-stderr 316
-stderr 317
-stderr 318
-stderr 319
-stderr 320
-stderr 321
-stderr 322
-stderr 323
-stderr 324
-stderr 325
-stderr 326
-stderr 327
-stderr 328
-stderr 329
-stderr 330
-stderr 331
-stderr 332
-stderr 333
-stderr 334
-stderr 335
-stderr 336
-stderr 337
-stderr 338
-stderr 339
-stderr 340
-stderr 341
-stderr 342
-stderr 343
-stderr 344
-stderr 345
-stderr 346
-stderr 347
-stderr 348
-stderr 349
-stderr 350
-stderr 351
-stderr 352
-stderr 353
-stderr 354
-stderr 355
-stderr 356
-stderr 357
-stderr 358
-stderr 359
-stderr 360
-stderr 361
-stderr 362
-stderr 363
-stderr 364
-stderr 365
-stderr 366
-stderr 367
-stderr 368
-stderr 369
-stderr 370
-stderr 371
-stderr 372
-stderr 373
-stderr 374
-stderr 375
-stderr 376
-stderr 377
-stderr 378
-stderr 379
-stderr 380
-stderr 381
-stderr 382
-stderr 383
-stderr 384
-stderr 385
-stderr 386
-stderr 387
-stderr 388
-stderr 389
-stderr 390
-stderr 391
-stderr 392
-stderr 393
-stderr 394
-stderr 395
-stderr 396
-stderr 397
-stderr 398
-stderr 399
-stderr 400
-stderr 401
-stderr 402
-stderr 403
-stderr 404
-stderr 405
-stderr 406
-stderr 407
-stderr 408
-stderr 409
-stderr 410
-stderr 411
-stderr 412
-stderr 413
-stderr 414
-stderr 415
-stderr 416
-stderr 417
-stderr 418
-stderr 419
-stderr 420
-stderr 421
-stderr 422
-stderr 423
-stderr 424
-stderr 425
-stderr 426
-stderr 427
-stderr 428
-stderr 429
-stderr 430
-stderr 431
-stderr 432
-stderr 433
-stderr 434
-stderr 435
-stderr 436
-stderr 437
-stderr 438
-stderr 439
-stderr 440
-stderr 441
-stderr 442
-stderr 443
-stderr 444
-stderr 445
-stderr 446
-stderr 447
-stderr 448
-stderr 449
-stderr 450
-stderr 451
-stderr 452
-stderr 453
-stderr 454
-stderr 455
-stderr 456
-stderr 457
-stderr 458
-stderr 459
-stderr 460
-stderr 461
-stderr 462
-stderr 463
-stderr 464
-stderr 465
-stderr 466
-stderr 467
-stderr 468
-stderr 469
-stderr 470
-stderr 471
-stderr 472
-stderr 473
-stderr 474
-stderr 475
-stderr 476
-stderr 477
-stderr 478
-stderr 479
-stderr 480
-stderr 481
-stderr 482
-stderr 483
-stderr 484
-stderr 485
-stderr 486
-stderr 487
-stderr 488
-stderr 489
-stderr 490
-stderr 491
-stderr 492
-stderr 493
-stderr 494
-stderr 495
-stderr 496
-stderr 497
-stderr 498
-stderr 499
-stderr 500
-stderr 501
-stderr 502
-stderr 503
-stderr 504
-stderr 505
-stderr 506
-stderr 507
-stderr 508
-stderr 509
-stderr 510
-stderr 511
-stderr 512
-stderr 513
-stderr 514
-stderr 515
-stderr 516
-stderr 517
-stderr 518
-stderr 519
-stderr 520
-stderr 521
-stderr 522
-stderr 523
-stderr 524
-stderr 525
-stderr 526
-stderr 527
-stderr 528
-stderr 529
-stderr 530
-stderr 531
-stderr 532
-stderr 533
-stderr 534
-stderr 535
-stderr 536
-stderr 537
-stderr 538
-stderr 539
-stderr 540
-stderr 541
-stderr 542
-stderr 543
-stderr 544
-stderr 545
-stderr 546
-stderr 547
-stderr 548
-stderr 549
-stderr 550
-stderr 551
-stderr 552
-stderr 553
-stderr 554
-stderr 555
-stderr 556
-stderr 557
-stderr 558
-stderr 559
-stderr 560
-stderr 561
-stderr 562
-stderr 563
-stderr 564
-stderr 565
-stderr 566
-stderr 567
-stderr 568
-stderr 569
-stderr 570
-stderr 571
-stderr 572
-stderr 573
-stderr 574
-stderr 575
-stderr 576
-stderr 577
-stderr 578
-stderr 579
-stderr 580
-stderr 581
-stderr 582
-stderr 583
-stderr 584
-stderr 585
-stderr 586
-stderr 587
-stderr 588
-stderr 589
-stderr 590
-stderr 591
-stderr 592
-stderr 593
-stderr 594
-stderr 595
-stderr 596
-stderr 597
-stderr 598
-stderr 599
-stderr 600
-stderr 601
-stderr 602
-stderr 603
-stderr 604
-stderr 605
-stderr 606
-stderr 607
-stderr 608
-stderr 609
-stderr 610
-stderr 611
-stderr 612
-stderr 613
-stderr 614
-stderr 615
-stderr 616
-stderr 617
-stderr 618
-stderr 619
-stderr 620
-stderr 621
-stderr 622
-stderr 623
-stderr 624
-stderr 625
-stderr 626
-stderr 627
-stderr 628
-stderr 629
-stderr 630
-stderr 631
-stderr 632
-stderr 633
-stderr 634
-stderr 635
-stderr 636
-stderr 637
-stderr 638
-stderr 639
-stderr 640
-stderr 641
-stderr 642
-stderr 643
-stderr 644
-stderr 645
-stderr 646
-stderr 647
-stderr 648
-stderr 649
-stderr 650
-stderr 651
-stderr 652
-stderr 653
-stderr 654
-stderr 655
-stderr 656
-stderr 657
-stderr 658
-stderr 659
-stderr 660
-stderr 661
-stderr 662
-stderr 663
-stderr 664
-stderr 665
-stderr 666
-stderr 667
-stderr 668
-stderr 669
-stderr 670
-stderr 671
-stderr 672
-stderr 673
-stderr 674
-stderr 675
-stderr 676
-stderr 677
-stderr 678
-stderr 679
-stderr 680
-stderr 681
-stderr 682
-stderr 683
-stderr 684
-stderr 685
-stderr 686
-stderr 687
-stderr 688
-stderr 689
-stderr 690
-stderr 691
-stderr 692
-stderr 693
-stderr 694
-stderr 695
-stderr 696
-stderr 697
-stderr 698
-stderr 699
-stderr 700
-stderr 701
-stderr 702
-stderr 703
-stderr 704
-stderr 705
-stderr 706
-stderr 707
-stderr 708
-stderr 709
-stderr 710
-stderr 711
-stderr 712
-stderr 713
-stderr 714
-stderr 715
-stderr 716
-stderr 717
-stderr 718
-stderr 719
-stderr 720
-stderr 721
-stderr 722
-stderr 723
-stderr 724
-stderr 725
-stderr 726
-stderr 727
-stderr 728
-stderr 729
-stderr 730
-stderr 731
-stderr 732
-stderr 733
-stderr 734
-stderr 735
-stderr 736
-stderr 737
-stderr 738
-stderr 739
-stderr 740
-stderr 741
-stderr 742
-stderr 743
-stderr 744
-stderr 745
-stderr 746
-stderr 747
-stderr 748
-stderr 749
-stderr 750
-stderr 751
-stderr 752
-stderr 753
-stderr 754
-stderr 755
-stderr 756
-stderr 757
-stderr 758
-stderr 759
-stderr 760
-stderr 761
-stderr 762
-stderr 763
-stderr 764
-stderr 765
-stderr 766
-stderr 767
-stderr 768
-stderr 769
-stderr 770
-stderr 771
-stderr 772
-stderr 773
-stderr 774
-stderr 775
-stderr 776
-stderr 777
-stderr 778
-stderr 779
-stderr 780
-stderr 781
-stderr 782
-stderr 783
-stderr 784
-stderr 785
-stderr 786
-stderr 787
-stderr 788
-stderr 789
-stderr 790
-stderr 791
-stderr 792
-stderr 793
-stderr 794
-stderr 795
-stderr 796
-stderr 797
-stderr 798
-stderr 799
-stderr 800
-stderr 801
-stderr 802
-stderr 803
-stderr 804
-stderr 805
-stderr 806
-stderr 807
-stderr 808
-stderr 809
-stderr 810
-stderr 811
-stderr 812
-stderr 813
-stderr 814
-stderr 815
-stderr 816
-stderr 817
-stderr 818
-stderr 819
-stderr 820
-stderr 821
-stderr 822
-stderr 823
-stderr 824
-stderr 825
-stderr 826
-stderr 827
-stderr 828
-stderr 829
-stderr 830
-stderr 831
-stderr 832
-stderr 833
-stderr 834
-stderr 835
-stderr 836
-stderr 837
-stderr 838
-stderr 839
-stderr 840
-stderr 841
-stderr 842
-stderr 843
-stderr 844
-stderr 845
-stderr 846
-stderr 847
-stderr 848
-stderr 849
-stderr 850
-stderr 851
-stderr 852
-stderr 853
-stderr 854
-stderr 855
-stderr 856
-stderr 857
-stderr 858
-stderr 859
-stderr 860
-stderr 861
-stderr 862
-stderr 863
-stderr 864
-stderr 865
-stderr 866
-stderr 867
-stderr 868
-stderr 869
-stderr 870
-stderr 871
-stderr 872
-stderr 873
-stderr 874
-stderr 875
-stderr 876
-stderr 877
-stderr 878
-stderr 879
-stderr 880
-stderr 881
-stderr 882
-stderr 883
-stderr 884
-stderr 885
-stderr 886
-stderr 887
-stderr 888
-stderr 889
-stderr 890
-stderr 891
-stderr 892
-stderr 893
-stderr 894
-stderr 895
-stderr 896
-stderr 897
-stderr 898
-stderr 899
-stderr 900
-stderr 901
-stderr 902
-stderr 903
-stderr 904
-stderr 905
-stderr 906
-stderr 907
-stderr 908
-stderr 909
-stderr 910
-stderr 911
-stderr 912
-stderr 913
-stderr 914
-stderr 915
-stderr 916
-stderr 917
-stderr 918
-stderr 919
-stderr 920
-stderr 921
-stderr 922
-stderr 923
-stderr 924
-stderr 925
-stderr 926
-stderr 927
-stderr 928
-stderr 929
-stderr 930
-stderr 931
-stderr 932
-stderr 933
-stderr 934
-stderr 935
-stderr 936
-stderr 937
-stderr 938
-stderr 939
-stderr 940
-stderr 941
-stderr 942
-stderr 943
-stderr 944
-stderr 945
-stderr 946
-stderr 947
-stderr 948
-stderr 949
-stderr 950
-stderr 951
-stderr 952
-stderr 953
-stderr 954
-stderr 955
-stderr 956
-stderr 957
-stderr 958
-stderr 959
-stderr 960
-stderr 961
-stderr 962
-stderr 963
-stderr 964
-stderr 965
-stderr 966
-stderr 967
-stderr 968
-stderr 969
-stderr 970
-stderr 971
-stderr 972
-stderr 973
-stderr 974
-stderr 975
-stderr 976
-stderr 977
-stderr 978
-stderr 979
-stderr 980
-stderr 981
-stderr 982
-stderr 983
-stderr 984
-stderr 985
-stderr 986
-stderr 987
-stderr 988
-stderr 989
-stderr 990
-stderr 991
-stderr 992
-stderr 993
-stderr 994
-stderr 995
-stderr 996
-stderr 997
-stderr 998
-stderr 999
diff --git a/spec/fixture/node_modules/grunt/node_modules/exit/test/fixtures/1000-stdout-stderr.txt b/spec/fixture/node_modules/grunt/node_modules/exit/test/fixtures/1000-stdout-stderr.txt
deleted file mode 100644
index 4fde2b4d..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/exit/test/fixtures/1000-stdout-stderr.txt
+++ /dev/null
@@ -1,2000 +0,0 @@
-stdout 0
-stderr 0
-stdout 1
-stderr 1
-stdout 2
-stderr 2
-stdout 3
-stderr 3
-stdout 4
-stderr 4
-stdout 5
-stderr 5
-stdout 6
-stderr 6
-stdout 7
-stderr 7
-stdout 8
-stderr 8
-stdout 9
-stderr 9
-stdout 10
-stderr 10
-stdout 11
-stderr 11
-stdout 12
-stderr 12
-stdout 13
-stderr 13
-stdout 14
-stderr 14
-stdout 15
-stderr 15
-stdout 16
-stderr 16
-stdout 17
-stderr 17
-stdout 18
-stderr 18
-stdout 19
-stderr 19
-stdout 20
-stderr 20
-stdout 21
-stderr 21
-stdout 22
-stderr 22
-stdout 23
-stderr 23
-stdout 24
-stderr 24
-stdout 25
-stderr 25
-stdout 26
-stderr 26
-stdout 27
-stderr 27
-stdout 28
-stderr 28
-stdout 29
-stderr 29
-stdout 30
-stderr 30
-stdout 31
-stderr 31
-stdout 32
-stderr 32
-stdout 33
-stderr 33
-stdout 34
-stderr 34
-stdout 35
-stderr 35
-stdout 36
-stderr 36
-stdout 37
-stderr 37
-stdout 38
-stderr 38
-stdout 39
-stderr 39
-stdout 40
-stderr 40
-stdout 41
-stderr 41
-stdout 42
-stderr 42
-stdout 43
-stderr 43
-stdout 44
-stderr 44
-stdout 45
-stderr 45
-stdout 46
-stderr 46
-stdout 47
-stderr 47
-stdout 48
-stderr 48
-stdout 49
-stderr 49
-stdout 50
-stderr 50
-stdout 51
-stderr 51
-stdout 52
-stderr 52
-stdout 53
-stderr 53
-stdout 54
-stderr 54
-stdout 55
-stderr 55
-stdout 56
-stderr 56
-stdout 57
-stderr 57
-stdout 58
-stderr 58
-stdout 59
-stderr 59
-stdout 60
-stderr 60
-stdout 61
-stderr 61
-stdout 62
-stderr 62
-stdout 63
-stderr 63
-stdout 64
-stderr 64
-stdout 65
-stderr 65
-stdout 66
-stderr 66
-stdout 67
-stderr 67
-stdout 68
-stderr 68
-stdout 69
-stderr 69
-stdout 70
-stderr 70
-stdout 71
-stderr 71
-stdout 72
-stderr 72
-stdout 73
-stderr 73
-stdout 74
-stderr 74
-stdout 75
-stderr 75
-stdout 76
-stderr 76
-stdout 77
-stderr 77
-stdout 78
-stderr 78
-stdout 79
-stderr 79
-stdout 80
-stderr 80
-stdout 81
-stderr 81
-stdout 82
-stderr 82
-stdout 83
-stderr 83
-stdout 84
-stderr 84
-stdout 85
-stderr 85
-stdout 86
-stderr 86
-stdout 87
-stderr 87
-stdout 88
-stderr 88
-stdout 89
-stderr 89
-stdout 90
-stderr 90
-stdout 91
-stderr 91
-stdout 92
-stderr 92
-stdout 93
-stderr 93
-stdout 94
-stderr 94
-stdout 95
-stderr 95
-stdout 96
-stderr 96
-stdout 97
-stderr 97
-stdout 98
-stderr 98
-stdout 99
-stderr 99
-stdout 100
-stderr 100
-stdout 101
-stderr 101
-stdout 102
-stderr 102
-stdout 103
-stderr 103
-stdout 104
-stderr 104
-stdout 105
-stderr 105
-stdout 106
-stderr 106
-stdout 107
-stderr 107
-stdout 108
-stderr 108
-stdout 109
-stderr 109
-stdout 110
-stderr 110
-stdout 111
-stderr 111
-stdout 112
-stderr 112
-stdout 113
-stderr 113
-stdout 114
-stderr 114
-stdout 115
-stderr 115
-stdout 116
-stderr 116
-stdout 117
-stderr 117
-stdout 118
-stderr 118
-stdout 119
-stderr 119
-stdout 120
-stderr 120
-stdout 121
-stderr 121
-stdout 122
-stderr 122
-stdout 123
-stderr 123
-stdout 124
-stderr 124
-stdout 125
-stderr 125
-stdout 126
-stderr 126
-stdout 127
-stderr 127
-stdout 128
-stderr 128
-stdout 129
-stderr 129
-stdout 130
-stderr 130
-stdout 131
-stderr 131
-stdout 132
-stderr 132
-stdout 133
-stderr 133
-stdout 134
-stderr 134
-stdout 135
-stderr 135
-stdout 136
-stderr 136
-stdout 137
-stderr 137
-stdout 138
-stderr 138
-stdout 139
-stderr 139
-stdout 140
-stderr 140
-stdout 141
-stderr 141
-stdout 142
-stderr 142
-stdout 143
-stderr 143
-stdout 144
-stderr 144
-stdout 145
-stderr 145
-stdout 146
-stderr 146
-stdout 147
-stderr 147
-stdout 148
-stderr 148
-stdout 149
-stderr 149
-stdout 150
-stderr 150
-stdout 151
-stderr 151
-stdout 152
-stderr 152
-stdout 153
-stderr 153
-stdout 154
-stderr 154
-stdout 155
-stderr 155
-stdout 156
-stderr 156
-stdout 157
-stderr 157
-stdout 158
-stderr 158
-stdout 159
-stderr 159
-stdout 160
-stderr 160
-stdout 161
-stderr 161
-stdout 162
-stderr 162
-stdout 163
-stderr 163
-stdout 164
-stderr 164
-stdout 165
-stderr 165
-stdout 166
-stderr 166
-stdout 167
-stderr 167
-stdout 168
-stderr 168
-stdout 169
-stderr 169
-stdout 170
-stderr 170
-stdout 171
-stderr 171
-stdout 172
-stderr 172
-stdout 173
-stderr 173
-stdout 174
-stderr 174
-stdout 175
-stderr 175
-stdout 176
-stderr 176
-stdout 177
-stderr 177
-stdout 178
-stderr 178
-stdout 179
-stderr 179
-stdout 180
-stderr 180
-stdout 181
-stderr 181
-stdout 182
-stderr 182
-stdout 183
-stderr 183
-stdout 184
-stderr 184
-stdout 185
-stderr 185
-stdout 186
-stderr 186
-stdout 187
-stderr 187
-stdout 188
-stderr 188
-stdout 189
-stderr 189
-stdout 190
-stderr 190
-stdout 191
-stderr 191
-stdout 192
-stderr 192
-stdout 193
-stderr 193
-stdout 194
-stderr 194
-stdout 195
-stderr 195
-stdout 196
-stderr 196
-stdout 197
-stderr 197
-stdout 198
-stderr 198
-stdout 199
-stderr 199
-stdout 200
-stderr 200
-stdout 201
-stderr 201
-stdout 202
-stderr 202
-stdout 203
-stderr 203
-stdout 204
-stderr 204
-stdout 205
-stderr 205
-stdout 206
-stderr 206
-stdout 207
-stderr 207
-stdout 208
-stderr 208
-stdout 209
-stderr 209
-stdout 210
-stderr 210
-stdout 211
-stderr 211
-stdout 212
-stderr 212
-stdout 213
-stderr 213
-stdout 214
-stderr 214
-stdout 215
-stderr 215
-stdout 216
-stderr 216
-stdout 217
-stderr 217
-stdout 218
-stderr 218
-stdout 219
-stderr 219
-stdout 220
-stderr 220
-stdout 221
-stderr 221
-stdout 222
-stderr 222
-stdout 223
-stderr 223
-stdout 224
-stderr 224
-stdout 225
-stderr 225
-stdout 226
-stderr 226
-stdout 227
-stderr 227
-stdout 228
-stderr 228
-stdout 229
-stderr 229
-stdout 230
-stderr 230
-stdout 231
-stderr 231
-stdout 232
-stderr 232
-stdout 233
-stderr 233
-stdout 234
-stderr 234
-stdout 235
-stderr 235
-stdout 236
-stderr 236
-stdout 237
-stderr 237
-stdout 238
-stderr 238
-stdout 239
-stderr 239
-stdout 240
-stderr 240
-stdout 241
-stderr 241
-stdout 242
-stderr 242
-stdout 243
-stderr 243
-stdout 244
-stderr 244
-stdout 245
-stderr 245
-stdout 246
-stderr 246
-stdout 247
-stderr 247
-stdout 248
-stderr 248
-stdout 249
-stderr 249
-stdout 250
-stderr 250
-stdout 251
-stderr 251
-stdout 252
-stderr 252
-stdout 253
-stderr 253
-stdout 254
-stderr 254
-stdout 255
-stderr 255
-stdout 256
-stderr 256
-stdout 257
-stderr 257
-stdout 258
-stderr 258
-stdout 259
-stderr 259
-stdout 260
-stderr 260
-stdout 261
-stderr 261
-stdout 262
-stderr 262
-stdout 263
-stderr 263
-stdout 264
-stderr 264
-stdout 265
-stderr 265
-stdout 266
-stderr 266
-stdout 267
-stderr 267
-stdout 268
-stderr 268
-stdout 269
-stderr 269
-stdout 270
-stderr 270
-stdout 271
-stderr 271
-stdout 272
-stderr 272
-stdout 273
-stderr 273
-stdout 274
-stderr 274
-stdout 275
-stderr 275
-stdout 276
-stderr 276
-stdout 277
-stderr 277
-stdout 278
-stderr 278
-stdout 279
-stderr 279
-stdout 280
-stderr 280
-stdout 281
-stderr 281
-stdout 282
-stderr 282
-stdout 283
-stderr 283
-stdout 284
-stderr 284
-stdout 285
-stderr 285
-stdout 286
-stderr 286
-stdout 287
-stderr 287
-stdout 288
-stderr 288
-stdout 289
-stderr 289
-stdout 290
-stderr 290
-stdout 291
-stderr 291
-stdout 292
-stderr 292
-stdout 293
-stderr 293
-stdout 294
-stderr 294
-stdout 295
-stderr 295
-stdout 296
-stderr 296
-stdout 297
-stderr 297
-stdout 298
-stderr 298
-stdout 299
-stderr 299
-stdout 300
-stderr 300
-stdout 301
-stderr 301
-stdout 302
-stderr 302
-stdout 303
-stderr 303
-stdout 304
-stderr 304
-stdout 305
-stderr 305
-stdout 306
-stderr 306
-stdout 307
-stderr 307
-stdout 308
-stderr 308
-stdout 309
-stderr 309
-stdout 310
-stderr 310
-stdout 311
-stderr 311
-stdout 312
-stderr 312
-stdout 313
-stderr 313
-stdout 314
-stderr 314
-stdout 315
-stderr 315
-stdout 316
-stderr 316
-stdout 317
-stderr 317
-stdout 318
-stderr 318
-stdout 319
-stderr 319
-stdout 320
-stderr 320
-stdout 321
-stderr 321
-stdout 322
-stderr 322
-stdout 323
-stderr 323
-stdout 324
-stderr 324
-stdout 325
-stderr 325
-stdout 326
-stderr 326
-stdout 327
-stderr 327
-stdout 328
-stderr 328
-stdout 329
-stderr 329
-stdout 330
-stderr 330
-stdout 331
-stderr 331
-stdout 332
-stderr 332
-stdout 333
-stderr 333
-stdout 334
-stderr 334
-stdout 335
-stderr 335
-stdout 336
-stderr 336
-stdout 337
-stderr 337
-stdout 338
-stderr 338
-stdout 339
-stderr 339
-stdout 340
-stderr 340
-stdout 341
-stderr 341
-stdout 342
-stderr 342
-stdout 343
-stderr 343
-stdout 344
-stderr 344
-stdout 345
-stderr 345
-stdout 346
-stderr 346
-stdout 347
-stderr 347
-stdout 348
-stderr 348
-stdout 349
-stderr 349
-stdout 350
-stderr 350
-stdout 351
-stderr 351
-stdout 352
-stderr 352
-stdout 353
-stderr 353
-stdout 354
-stderr 354
-stdout 355
-stderr 355
-stdout 356
-stderr 356
-stdout 357
-stderr 357
-stdout 358
-stderr 358
-stdout 359
-stderr 359
-stdout 360
-stderr 360
-stdout 361
-stderr 361
-stdout 362
-stderr 362
-stdout 363
-stderr 363
-stdout 364
-stderr 364
-stdout 365
-stderr 365
-stdout 366
-stderr 366
-stdout 367
-stderr 367
-stdout 368
-stderr 368
-stdout 369
-stderr 369
-stdout 370
-stderr 370
-stdout 371
-stderr 371
-stdout 372
-stderr 372
-stdout 373
-stderr 373
-stdout 374
-stderr 374
-stdout 375
-stderr 375
-stdout 376
-stderr 376
-stdout 377
-stderr 377
-stdout 378
-stderr 378
-stdout 379
-stderr 379
-stdout 380
-stderr 380
-stdout 381
-stderr 381
-stdout 382
-stderr 382
-stdout 383
-stderr 383
-stdout 384
-stderr 384
-stdout 385
-stderr 385
-stdout 386
-stderr 386
-stdout 387
-stderr 387
-stdout 388
-stderr 388
-stdout 389
-stderr 389
-stdout 390
-stderr 390
-stdout 391
-stderr 391
-stdout 392
-stderr 392
-stdout 393
-stderr 393
-stdout 394
-stderr 394
-stdout 395
-stderr 395
-stdout 396
-stderr 396
-stdout 397
-stderr 397
-stdout 398
-stderr 398
-stdout 399
-stderr 399
-stdout 400
-stderr 400
-stdout 401
-stderr 401
-stdout 402
-stderr 402
-stdout 403
-stderr 403
-stdout 404
-stderr 404
-stdout 405
-stderr 405
-stdout 406
-stderr 406
-stdout 407
-stderr 407
-stdout 408
-stderr 408
-stdout 409
-stderr 409
-stdout 410
-stderr 410
-stdout 411
-stderr 411
-stdout 412
-stderr 412
-stdout 413
-stderr 413
-stdout 414
-stderr 414
-stdout 415
-stderr 415
-stdout 416
-stderr 416
-stdout 417
-stderr 417
-stdout 418
-stderr 418
-stdout 419
-stderr 419
-stdout 420
-stderr 420
-stdout 421
-stderr 421
-stdout 422
-stderr 422
-stdout 423
-stderr 423
-stdout 424
-stderr 424
-stdout 425
-stderr 425
-stdout 426
-stderr 426
-stdout 427
-stderr 427
-stdout 428
-stderr 428
-stdout 429
-stderr 429
-stdout 430
-stderr 430
-stdout 431
-stderr 431
-stdout 432
-stderr 432
-stdout 433
-stderr 433
-stdout 434
-stderr 434
-stdout 435
-stderr 435
-stdout 436
-stderr 436
-stdout 437
-stderr 437
-stdout 438
-stderr 438
-stdout 439
-stderr 439
-stdout 440
-stderr 440
-stdout 441
-stderr 441
-stdout 442
-stderr 442
-stdout 443
-stderr 443
-stdout 444
-stderr 444
-stdout 445
-stderr 445
-stdout 446
-stderr 446
-stdout 447
-stderr 447
-stdout 448
-stderr 448
-stdout 449
-stderr 449
-stdout 450
-stderr 450
-stdout 451
-stderr 451
-stdout 452
-stderr 452
-stdout 453
-stderr 453
-stdout 454
-stderr 454
-stdout 455
-stderr 455
-stdout 456
-stderr 456
-stdout 457
-stderr 457
-stdout 458
-stderr 458
-stdout 459
-stderr 459
-stdout 460
-stderr 460
-stdout 461
-stderr 461
-stdout 462
-stderr 462
-stdout 463
-stderr 463
-stdout 464
-stderr 464
-stdout 465
-stderr 465
-stdout 466
-stderr 466
-stdout 467
-stderr 467
-stdout 468
-stderr 468
-stdout 469
-stderr 469
-stdout 470
-stderr 470
-stdout 471
-stderr 471
-stdout 472
-stderr 472
-stdout 473
-stderr 473
-stdout 474
-stderr 474
-stdout 475
-stderr 475
-stdout 476
-stderr 476
-stdout 477
-stderr 477
-stdout 478
-stderr 478
-stdout 479
-stderr 479
-stdout 480
-stderr 480
-stdout 481
-stderr 481
-stdout 482
-stderr 482
-stdout 483
-stderr 483
-stdout 484
-stderr 484
-stdout 485
-stderr 485
-stdout 486
-stderr 486
-stdout 487
-stderr 487
-stdout 488
-stderr 488
-stdout 489
-stderr 489
-stdout 490
-stderr 490
-stdout 491
-stderr 491
-stdout 492
-stderr 492
-stdout 493
-stderr 493
-stdout 494
-stderr 494
-stdout 495
-stderr 495
-stdout 496
-stderr 496
-stdout 497
-stderr 497
-stdout 498
-stderr 498
-stdout 499
-stderr 499
-stdout 500
-stderr 500
-stdout 501
-stderr 501
-stdout 502
-stderr 502
-stdout 503
-stderr 503
-stdout 504
-stderr 504
-stdout 505
-stderr 505
-stdout 506
-stderr 506
-stdout 507
-stderr 507
-stdout 508
-stderr 508
-stdout 509
-stderr 509
-stdout 510
-stderr 510
-stdout 511
-stderr 511
-stdout 512
-stderr 512
-stdout 513
-stderr 513
-stdout 514
-stderr 514
-stdout 515
-stderr 515
-stdout 516
-stderr 516
-stdout 517
-stderr 517
-stdout 518
-stderr 518
-stdout 519
-stderr 519
-stdout 520
-stderr 520
-stdout 521
-stderr 521
-stdout 522
-stderr 522
-stdout 523
-stderr 523
-stdout 524
-stderr 524
-stdout 525
-stderr 525
-stdout 526
-stderr 526
-stdout 527
-stderr 527
-stdout 528
-stderr 528
-stdout 529
-stderr 529
-stdout 530
-stderr 530
-stdout 531
-stderr 531
-stdout 532
-stderr 532
-stdout 533
-stderr 533
-stdout 534
-stderr 534
-stdout 535
-stderr 535
-stdout 536
-stderr 536
-stdout 537
-stderr 537
-stdout 538
-stderr 538
-stdout 539
-stderr 539
-stdout 540
-stderr 540
-stdout 541
-stderr 541
-stdout 542
-stderr 542
-stdout 543
-stderr 543
-stdout 544
-stderr 544
-stdout 545
-stderr 545
-stdout 546
-stderr 546
-stdout 547
-stderr 547
-stdout 548
-stderr 548
-stdout 549
-stderr 549
-stdout 550
-stderr 550
-stdout 551
-stderr 551
-stdout 552
-stderr 552
-stdout 553
-stderr 553
-stdout 554
-stderr 554
-stdout 555
-stderr 555
-stdout 556
-stderr 556
-stdout 557
-stderr 557
-stdout 558
-stderr 558
-stdout 559
-stderr 559
-stdout 560
-stderr 560
-stdout 561
-stderr 561
-stdout 562
-stderr 562
-stdout 563
-stderr 563
-stdout 564
-stderr 564
-stdout 565
-stderr 565
-stdout 566
-stderr 566
-stdout 567
-stderr 567
-stdout 568
-stderr 568
-stdout 569
-stderr 569
-stdout 570
-stderr 570
-stdout 571
-stderr 571
-stdout 572
-stderr 572
-stdout 573
-stderr 573
-stdout 574
-stderr 574
-stdout 575
-stderr 575
-stdout 576
-stderr 576
-stdout 577
-stderr 577
-stdout 578
-stderr 578
-stdout 579
-stderr 579
-stdout 580
-stderr 580
-stdout 581
-stderr 581
-stdout 582
-stderr 582
-stdout 583
-stderr 583
-stdout 584
-stderr 584
-stdout 585
-stderr 585
-stdout 586
-stderr 586
-stdout 587
-stderr 587
-stdout 588
-stderr 588
-stdout 589
-stderr 589
-stdout 590
-stderr 590
-stdout 591
-stderr 591
-stdout 592
-stderr 592
-stdout 593
-stderr 593
-stdout 594
-stderr 594
-stdout 595
-stderr 595
-stdout 596
-stderr 596
-stdout 597
-stderr 597
-stdout 598
-stderr 598
-stdout 599
-stderr 599
-stdout 600
-stderr 600
-stdout 601
-stderr 601
-stdout 602
-stderr 602
-stdout 603
-stderr 603
-stdout 604
-stderr 604
-stdout 605
-stderr 605
-stdout 606
-stderr 606
-stdout 607
-stderr 607
-stdout 608
-stderr 608
-stdout 609
-stderr 609
-stdout 610
-stderr 610
-stdout 611
-stderr 611
-stdout 612
-stderr 612
-stdout 613
-stderr 613
-stdout 614
-stderr 614
-stdout 615
-stderr 615
-stdout 616
-stderr 616
-stdout 617
-stderr 617
-stdout 618
-stderr 618
-stdout 619
-stderr 619
-stdout 620
-stderr 620
-stdout 621
-stderr 621
-stdout 622
-stderr 622
-stdout 623
-stderr 623
-stdout 624
-stderr 624
-stdout 625
-stderr 625
-stdout 626
-stderr 626
-stdout 627
-stderr 627
-stdout 628
-stderr 628
-stdout 629
-stderr 629
-stdout 630
-stderr 630
-stdout 631
-stderr 631
-stdout 632
-stderr 632
-stdout 633
-stderr 633
-stdout 634
-stderr 634
-stdout 635
-stderr 635
-stdout 636
-stderr 636
-stdout 637
-stderr 637
-stdout 638
-stderr 638
-stdout 639
-stderr 639
-stdout 640
-stderr 640
-stdout 641
-stderr 641
-stdout 642
-stderr 642
-stdout 643
-stderr 643
-stdout 644
-stderr 644
-stdout 645
-stderr 645
-stdout 646
-stderr 646
-stdout 647
-stderr 647
-stdout 648
-stderr 648
-stdout 649
-stderr 649
-stdout 650
-stderr 650
-stdout 651
-stderr 651
-stdout 652
-stderr 652
-stdout 653
-stderr 653
-stdout 654
-stderr 654
-stdout 655
-stderr 655
-stdout 656
-stderr 656
-stdout 657
-stderr 657
-stdout 658
-stderr 658
-stdout 659
-stderr 659
-stdout 660
-stderr 660
-stdout 661
-stderr 661
-stdout 662
-stderr 662
-stdout 663
-stderr 663
-stdout 664
-stderr 664
-stdout 665
-stderr 665
-stdout 666
-stderr 666
-stdout 667
-stderr 667
-stdout 668
-stderr 668
-stdout 669
-stderr 669
-stdout 670
-stderr 670
-stdout 671
-stderr 671
-stdout 672
-stderr 672
-stdout 673
-stderr 673
-stdout 674
-stderr 674
-stdout 675
-stderr 675
-stdout 676
-stderr 676
-stdout 677
-stderr 677
-stdout 678
-stderr 678
-stdout 679
-stderr 679
-stdout 680
-stderr 680
-stdout 681
-stderr 681
-stdout 682
-stderr 682
-stdout 683
-stderr 683
-stdout 684
-stderr 684
-stdout 685
-stderr 685
-stdout 686
-stderr 686
-stdout 687
-stderr 687
-stdout 688
-stderr 688
-stdout 689
-stderr 689
-stdout 690
-stderr 690
-stdout 691
-stderr 691
-stdout 692
-stderr 692
-stdout 693
-stderr 693
-stdout 694
-stderr 694
-stdout 695
-stderr 695
-stdout 696
-stderr 696
-stdout 697
-stderr 697
-stdout 698
-stderr 698
-stdout 699
-stderr 699
-stdout 700
-stderr 700
-stdout 701
-stderr 701
-stdout 702
-stderr 702
-stdout 703
-stderr 703
-stdout 704
-stderr 704
-stdout 705
-stderr 705
-stdout 706
-stderr 706
-stdout 707
-stderr 707
-stdout 708
-stderr 708
-stdout 709
-stderr 709
-stdout 710
-stderr 710
-stdout 711
-stderr 711
-stdout 712
-stderr 712
-stdout 713
-stderr 713
-stdout 714
-stderr 714
-stdout 715
-stderr 715
-stdout 716
-stderr 716
-stdout 717
-stderr 717
-stdout 718
-stderr 718
-stdout 719
-stderr 719
-stdout 720
-stderr 720
-stdout 721
-stderr 721
-stdout 722
-stderr 722
-stdout 723
-stderr 723
-stdout 724
-stderr 724
-stdout 725
-stderr 725
-stdout 726
-stderr 726
-stdout 727
-stderr 727
-stdout 728
-stderr 728
-stdout 729
-stderr 729
-stdout 730
-stderr 730
-stdout 731
-stderr 731
-stdout 732
-stderr 732
-stdout 733
-stderr 733
-stdout 734
-stderr 734
-stdout 735
-stderr 735
-stdout 736
-stderr 736
-stdout 737
-stderr 737
-stdout 738
-stderr 738
-stdout 739
-stderr 739
-stdout 740
-stderr 740
-stdout 741
-stderr 741
-stdout 742
-stderr 742
-stdout 743
-stderr 743
-stdout 744
-stderr 744
-stdout 745
-stderr 745
-stdout 746
-stderr 746
-stdout 747
-stderr 747
-stdout 748
-stderr 748
-stdout 749
-stderr 749
-stdout 750
-stderr 750
-stdout 751
-stderr 751
-stdout 752
-stderr 752
-stdout 753
-stderr 753
-stdout 754
-stderr 754
-stdout 755
-stderr 755
-stdout 756
-stderr 756
-stdout 757
-stderr 757
-stdout 758
-stderr 758
-stdout 759
-stderr 759
-stdout 760
-stderr 760
-stdout 761
-stderr 761
-stdout 762
-stderr 762
-stdout 763
-stderr 763
-stdout 764
-stderr 764
-stdout 765
-stderr 765
-stdout 766
-stderr 766
-stdout 767
-stderr 767
-stdout 768
-stderr 768
-stdout 769
-stderr 769
-stdout 770
-stderr 770
-stdout 771
-stderr 771
-stdout 772
-stderr 772
-stdout 773
-stderr 773
-stdout 774
-stderr 774
-stdout 775
-stderr 775
-stdout 776
-stderr 776
-stdout 777
-stderr 777
-stdout 778
-stderr 778
-stdout 779
-stderr 779
-stdout 780
-stderr 780
-stdout 781
-stderr 781
-stdout 782
-stderr 782
-stdout 783
-stderr 783
-stdout 784
-stderr 784
-stdout 785
-stderr 785
-stdout 786
-stderr 786
-stdout 787
-stderr 787
-stdout 788
-stderr 788
-stdout 789
-stderr 789
-stdout 790
-stderr 790
-stdout 791
-stderr 791
-stdout 792
-stderr 792
-stdout 793
-stderr 793
-stdout 794
-stderr 794
-stdout 795
-stderr 795
-stdout 796
-stderr 796
-stdout 797
-stderr 797
-stdout 798
-stderr 798
-stdout 799
-stderr 799
-stdout 800
-stderr 800
-stdout 801
-stderr 801
-stdout 802
-stderr 802
-stdout 803
-stderr 803
-stdout 804
-stderr 804
-stdout 805
-stderr 805
-stdout 806
-stderr 806
-stdout 807
-stderr 807
-stdout 808
-stderr 808
-stdout 809
-stderr 809
-stdout 810
-stderr 810
-stdout 811
-stderr 811
-stdout 812
-stderr 812
-stdout 813
-stderr 813
-stdout 814
-stderr 814
-stdout 815
-stderr 815
-stdout 816
-stderr 816
-stdout 817
-stderr 817
-stdout 818
-stderr 818
-stdout 819
-stderr 819
-stdout 820
-stderr 820
-stdout 821
-stderr 821
-stdout 822
-stderr 822
-stdout 823
-stderr 823
-stdout 824
-stderr 824
-stdout 825
-stderr 825
-stdout 826
-stderr 826
-stdout 827
-stderr 827
-stdout 828
-stderr 828
-stdout 829
-stderr 829
-stdout 830
-stderr 830
-stdout 831
-stderr 831
-stdout 832
-stderr 832
-stdout 833
-stderr 833
-stdout 834
-stderr 834
-stdout 835
-stderr 835
-stdout 836
-stderr 836
-stdout 837
-stderr 837
-stdout 838
-stderr 838
-stdout 839
-stderr 839
-stdout 840
-stderr 840
-stdout 841
-stderr 841
-stdout 842
-stderr 842
-stdout 843
-stderr 843
-stdout 844
-stderr 844
-stdout 845
-stderr 845
-stdout 846
-stderr 846
-stdout 847
-stderr 847
-stdout 848
-stderr 848
-stdout 849
-stderr 849
-stdout 850
-stderr 850
-stdout 851
-stderr 851
-stdout 852
-stderr 852
-stdout 853
-stderr 853
-stdout 854
-stderr 854
-stdout 855
-stderr 855
-stdout 856
-stderr 856
-stdout 857
-stderr 857
-stdout 858
-stderr 858
-stdout 859
-stderr 859
-stdout 860
-stderr 860
-stdout 861
-stderr 861
-stdout 862
-stderr 862
-stdout 863
-stderr 863
-stdout 864
-stderr 864
-stdout 865
-stderr 865
-stdout 866
-stderr 866
-stdout 867
-stderr 867
-stdout 868
-stderr 868
-stdout 869
-stderr 869
-stdout 870
-stderr 870
-stdout 871
-stderr 871
-stdout 872
-stderr 872
-stdout 873
-stderr 873
-stdout 874
-stderr 874
-stdout 875
-stderr 875
-stdout 876
-stderr 876
-stdout 877
-stderr 877
-stdout 878
-stderr 878
-stdout 879
-stderr 879
-stdout 880
-stderr 880
-stdout 881
-stderr 881
-stdout 882
-stderr 882
-stdout 883
-stderr 883
-stdout 884
-stderr 884
-stdout 885
-stderr 885
-stdout 886
-stderr 886
-stdout 887
-stderr 887
-stdout 888
-stderr 888
-stdout 889
-stderr 889
-stdout 890
-stderr 890
-stdout 891
-stderr 891
-stdout 892
-stderr 892
-stdout 893
-stderr 893
-stdout 894
-stderr 894
-stdout 895
-stderr 895
-stdout 896
-stderr 896
-stdout 897
-stderr 897
-stdout 898
-stderr 898
-stdout 899
-stderr 899
-stdout 900
-stderr 900
-stdout 901
-stderr 901
-stdout 902
-stderr 902
-stdout 903
-stderr 903
-stdout 904
-stderr 904
-stdout 905
-stderr 905
-stdout 906
-stderr 906
-stdout 907
-stderr 907
-stdout 908
-stderr 908
-stdout 909
-stderr 909
-stdout 910
-stderr 910
-stdout 911
-stderr 911
-stdout 912
-stderr 912
-stdout 913
-stderr 913
-stdout 914
-stderr 914
-stdout 915
-stderr 915
-stdout 916
-stderr 916
-stdout 917
-stderr 917
-stdout 918
-stderr 918
-stdout 919
-stderr 919
-stdout 920
-stderr 920
-stdout 921
-stderr 921
-stdout 922
-stderr 922
-stdout 923
-stderr 923
-stdout 924
-stderr 924
-stdout 925
-stderr 925
-stdout 926
-stderr 926
-stdout 927
-stderr 927
-stdout 928
-stderr 928
-stdout 929
-stderr 929
-stdout 930
-stderr 930
-stdout 931
-stderr 931
-stdout 932
-stderr 932
-stdout 933
-stderr 933
-stdout 934
-stderr 934
-stdout 935
-stderr 935
-stdout 936
-stderr 936
-stdout 937
-stderr 937
-stdout 938
-stderr 938
-stdout 939
-stderr 939
-stdout 940
-stderr 940
-stdout 941
-stderr 941
-stdout 942
-stderr 942
-stdout 943
-stderr 943
-stdout 944
-stderr 944
-stdout 945
-stderr 945
-stdout 946
-stderr 946
-stdout 947
-stderr 947
-stdout 948
-stderr 948
-stdout 949
-stderr 949
-stdout 950
-stderr 950
-stdout 951
-stderr 951
-stdout 952
-stderr 952
-stdout 953
-stderr 953
-stdout 954
-stderr 954
-stdout 955
-stderr 955
-stdout 956
-stderr 956
-stdout 957
-stderr 957
-stdout 958
-stderr 958
-stdout 959
-stderr 959
-stdout 960
-stderr 960
-stdout 961
-stderr 961
-stdout 962
-stderr 962
-stdout 963
-stderr 963
-stdout 964
-stderr 964
-stdout 965
-stderr 965
-stdout 966
-stderr 966
-stdout 967
-stderr 967
-stdout 968
-stderr 968
-stdout 969
-stderr 969
-stdout 970
-stderr 970
-stdout 971
-stderr 971
-stdout 972
-stderr 972
-stdout 973
-stderr 973
-stdout 974
-stderr 974
-stdout 975
-stderr 975
-stdout 976
-stderr 976
-stdout 977
-stderr 977
-stdout 978
-stderr 978
-stdout 979
-stderr 979
-stdout 980
-stderr 980
-stdout 981
-stderr 981
-stdout 982
-stderr 982
-stdout 983
-stderr 983
-stdout 984
-stderr 984
-stdout 985
-stderr 985
-stdout 986
-stderr 986
-stdout 987
-stderr 987
-stdout 988
-stderr 988
-stdout 989
-stderr 989
-stdout 990
-stderr 990
-stdout 991
-stderr 991
-stdout 992
-stderr 992
-stdout 993
-stderr 993
-stdout 994
-stderr 994
-stdout 995
-stderr 995
-stdout 996
-stderr 996
-stdout 997
-stderr 997
-stdout 998
-stderr 998
-stdout 999
-stderr 999
diff --git a/spec/fixture/node_modules/grunt/node_modules/exit/test/fixtures/1000-stdout.txt b/spec/fixture/node_modules/grunt/node_modules/exit/test/fixtures/1000-stdout.txt
deleted file mode 100644
index d3649d00..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/exit/test/fixtures/1000-stdout.txt
+++ /dev/null
@@ -1,1000 +0,0 @@
-stdout 0
-stdout 1
-stdout 2
-stdout 3
-stdout 4
-stdout 5
-stdout 6
-stdout 7
-stdout 8
-stdout 9
-stdout 10
-stdout 11
-stdout 12
-stdout 13
-stdout 14
-stdout 15
-stdout 16
-stdout 17
-stdout 18
-stdout 19
-stdout 20
-stdout 21
-stdout 22
-stdout 23
-stdout 24
-stdout 25
-stdout 26
-stdout 27
-stdout 28
-stdout 29
-stdout 30
-stdout 31
-stdout 32
-stdout 33
-stdout 34
-stdout 35
-stdout 36
-stdout 37
-stdout 38
-stdout 39
-stdout 40
-stdout 41
-stdout 42
-stdout 43
-stdout 44
-stdout 45
-stdout 46
-stdout 47
-stdout 48
-stdout 49
-stdout 50
-stdout 51
-stdout 52
-stdout 53
-stdout 54
-stdout 55
-stdout 56
-stdout 57
-stdout 58
-stdout 59
-stdout 60
-stdout 61
-stdout 62
-stdout 63
-stdout 64
-stdout 65
-stdout 66
-stdout 67
-stdout 68
-stdout 69
-stdout 70
-stdout 71
-stdout 72
-stdout 73
-stdout 74
-stdout 75
-stdout 76
-stdout 77
-stdout 78
-stdout 79
-stdout 80
-stdout 81
-stdout 82
-stdout 83
-stdout 84
-stdout 85
-stdout 86
-stdout 87
-stdout 88
-stdout 89
-stdout 90
-stdout 91
-stdout 92
-stdout 93
-stdout 94
-stdout 95
-stdout 96
-stdout 97
-stdout 98
-stdout 99
-stdout 100
-stdout 101
-stdout 102
-stdout 103
-stdout 104
-stdout 105
-stdout 106
-stdout 107
-stdout 108
-stdout 109
-stdout 110
-stdout 111
-stdout 112
-stdout 113
-stdout 114
-stdout 115
-stdout 116
-stdout 117
-stdout 118
-stdout 119
-stdout 120
-stdout 121
-stdout 122
-stdout 123
-stdout 124
-stdout 125
-stdout 126
-stdout 127
-stdout 128
-stdout 129
-stdout 130
-stdout 131
-stdout 132
-stdout 133
-stdout 134
-stdout 135
-stdout 136
-stdout 137
-stdout 138
-stdout 139
-stdout 140
-stdout 141
-stdout 142
-stdout 143
-stdout 144
-stdout 145
-stdout 146
-stdout 147
-stdout 148
-stdout 149
-stdout 150
-stdout 151
-stdout 152
-stdout 153
-stdout 154
-stdout 155
-stdout 156
-stdout 157
-stdout 158
-stdout 159
-stdout 160
-stdout 161
-stdout 162
-stdout 163
-stdout 164
-stdout 165
-stdout 166
-stdout 167
-stdout 168
-stdout 169
-stdout 170
-stdout 171
-stdout 172
-stdout 173
-stdout 174
-stdout 175
-stdout 176
-stdout 177
-stdout 178
-stdout 179
-stdout 180
-stdout 181
-stdout 182
-stdout 183
-stdout 184
-stdout 185
-stdout 186
-stdout 187
-stdout 188
-stdout 189
-stdout 190
-stdout 191
-stdout 192
-stdout 193
-stdout 194
-stdout 195
-stdout 196
-stdout 197
-stdout 198
-stdout 199
-stdout 200
-stdout 201
-stdout 202
-stdout 203
-stdout 204
-stdout 205
-stdout 206
-stdout 207
-stdout 208
-stdout 209
-stdout 210
-stdout 211
-stdout 212
-stdout 213
-stdout 214
-stdout 215
-stdout 216
-stdout 217
-stdout 218
-stdout 219
-stdout 220
-stdout 221
-stdout 222
-stdout 223
-stdout 224
-stdout 225
-stdout 226
-stdout 227
-stdout 228
-stdout 229
-stdout 230
-stdout 231
-stdout 232
-stdout 233
-stdout 234
-stdout 235
-stdout 236
-stdout 237
-stdout 238
-stdout 239
-stdout 240
-stdout 241
-stdout 242
-stdout 243
-stdout 244
-stdout 245
-stdout 246
-stdout 247
-stdout 248
-stdout 249
-stdout 250
-stdout 251
-stdout 252
-stdout 253
-stdout 254
-stdout 255
-stdout 256
-stdout 257
-stdout 258
-stdout 259
-stdout 260
-stdout 261
-stdout 262
-stdout 263
-stdout 264
-stdout 265
-stdout 266
-stdout 267
-stdout 268
-stdout 269
-stdout 270
-stdout 271
-stdout 272
-stdout 273
-stdout 274
-stdout 275
-stdout 276
-stdout 277
-stdout 278
-stdout 279
-stdout 280
-stdout 281
-stdout 282
-stdout 283
-stdout 284
-stdout 285
-stdout 286
-stdout 287
-stdout 288
-stdout 289
-stdout 290
-stdout 291
-stdout 292
-stdout 293
-stdout 294
-stdout 295
-stdout 296
-stdout 297
-stdout 298
-stdout 299
-stdout 300
-stdout 301
-stdout 302
-stdout 303
-stdout 304
-stdout 305
-stdout 306
-stdout 307
-stdout 308
-stdout 309
-stdout 310
-stdout 311
-stdout 312
-stdout 313
-stdout 314
-stdout 315
-stdout 316
-stdout 317
-stdout 318
-stdout 319
-stdout 320
-stdout 321
-stdout 322
-stdout 323
-stdout 324
-stdout 325
-stdout 326
-stdout 327
-stdout 328
-stdout 329
-stdout 330
-stdout 331
-stdout 332
-stdout 333
-stdout 334
-stdout 335
-stdout 336
-stdout 337
-stdout 338
-stdout 339
-stdout 340
-stdout 341
-stdout 342
-stdout 343
-stdout 344
-stdout 345
-stdout 346
-stdout 347
-stdout 348
-stdout 349
-stdout 350
-stdout 351
-stdout 352
-stdout 353
-stdout 354
-stdout 355
-stdout 356
-stdout 357
-stdout 358
-stdout 359
-stdout 360
-stdout 361
-stdout 362
-stdout 363
-stdout 364
-stdout 365
-stdout 366
-stdout 367
-stdout 368
-stdout 369
-stdout 370
-stdout 371
-stdout 372
-stdout 373
-stdout 374
-stdout 375
-stdout 376
-stdout 377
-stdout 378
-stdout 379
-stdout 380
-stdout 381
-stdout 382
-stdout 383
-stdout 384
-stdout 385
-stdout 386
-stdout 387
-stdout 388
-stdout 389
-stdout 390
-stdout 391
-stdout 392
-stdout 393
-stdout 394
-stdout 395
-stdout 396
-stdout 397
-stdout 398
-stdout 399
-stdout 400
-stdout 401
-stdout 402
-stdout 403
-stdout 404
-stdout 405
-stdout 406
-stdout 407
-stdout 408
-stdout 409
-stdout 410
-stdout 411
-stdout 412
-stdout 413
-stdout 414
-stdout 415
-stdout 416
-stdout 417
-stdout 418
-stdout 419
-stdout 420
-stdout 421
-stdout 422
-stdout 423
-stdout 424
-stdout 425
-stdout 426
-stdout 427
-stdout 428
-stdout 429
-stdout 430
-stdout 431
-stdout 432
-stdout 433
-stdout 434
-stdout 435
-stdout 436
-stdout 437
-stdout 438
-stdout 439
-stdout 440
-stdout 441
-stdout 442
-stdout 443
-stdout 444
-stdout 445
-stdout 446
-stdout 447
-stdout 448
-stdout 449
-stdout 450
-stdout 451
-stdout 452
-stdout 453
-stdout 454
-stdout 455
-stdout 456
-stdout 457
-stdout 458
-stdout 459
-stdout 460
-stdout 461
-stdout 462
-stdout 463
-stdout 464
-stdout 465
-stdout 466
-stdout 467
-stdout 468
-stdout 469
-stdout 470
-stdout 471
-stdout 472
-stdout 473
-stdout 474
-stdout 475
-stdout 476
-stdout 477
-stdout 478
-stdout 479
-stdout 480
-stdout 481
-stdout 482
-stdout 483
-stdout 484
-stdout 485
-stdout 486
-stdout 487
-stdout 488
-stdout 489
-stdout 490
-stdout 491
-stdout 492
-stdout 493
-stdout 494
-stdout 495
-stdout 496
-stdout 497
-stdout 498
-stdout 499
-stdout 500
-stdout 501
-stdout 502
-stdout 503
-stdout 504
-stdout 505
-stdout 506
-stdout 507
-stdout 508
-stdout 509
-stdout 510
-stdout 511
-stdout 512
-stdout 513
-stdout 514
-stdout 515
-stdout 516
-stdout 517
-stdout 518
-stdout 519
-stdout 520
-stdout 521
-stdout 522
-stdout 523
-stdout 524
-stdout 525
-stdout 526
-stdout 527
-stdout 528
-stdout 529
-stdout 530
-stdout 531
-stdout 532
-stdout 533
-stdout 534
-stdout 535
-stdout 536
-stdout 537
-stdout 538
-stdout 539
-stdout 540
-stdout 541
-stdout 542
-stdout 543
-stdout 544
-stdout 545
-stdout 546
-stdout 547
-stdout 548
-stdout 549
-stdout 550
-stdout 551
-stdout 552
-stdout 553
-stdout 554
-stdout 555
-stdout 556
-stdout 557
-stdout 558
-stdout 559
-stdout 560
-stdout 561
-stdout 562
-stdout 563
-stdout 564
-stdout 565
-stdout 566
-stdout 567
-stdout 568
-stdout 569
-stdout 570
-stdout 571
-stdout 572
-stdout 573
-stdout 574
-stdout 575
-stdout 576
-stdout 577
-stdout 578
-stdout 579
-stdout 580
-stdout 581
-stdout 582
-stdout 583
-stdout 584
-stdout 585
-stdout 586
-stdout 587
-stdout 588
-stdout 589
-stdout 590
-stdout 591
-stdout 592
-stdout 593
-stdout 594
-stdout 595
-stdout 596
-stdout 597
-stdout 598
-stdout 599
-stdout 600
-stdout 601
-stdout 602
-stdout 603
-stdout 604
-stdout 605
-stdout 606
-stdout 607
-stdout 608
-stdout 609
-stdout 610
-stdout 611
-stdout 612
-stdout 613
-stdout 614
-stdout 615
-stdout 616
-stdout 617
-stdout 618
-stdout 619
-stdout 620
-stdout 621
-stdout 622
-stdout 623
-stdout 624
-stdout 625
-stdout 626
-stdout 627
-stdout 628
-stdout 629
-stdout 630
-stdout 631
-stdout 632
-stdout 633
-stdout 634
-stdout 635
-stdout 636
-stdout 637
-stdout 638
-stdout 639
-stdout 640
-stdout 641
-stdout 642
-stdout 643
-stdout 644
-stdout 645
-stdout 646
-stdout 647
-stdout 648
-stdout 649
-stdout 650
-stdout 651
-stdout 652
-stdout 653
-stdout 654
-stdout 655
-stdout 656
-stdout 657
-stdout 658
-stdout 659
-stdout 660
-stdout 661
-stdout 662
-stdout 663
-stdout 664
-stdout 665
-stdout 666
-stdout 667
-stdout 668
-stdout 669
-stdout 670
-stdout 671
-stdout 672
-stdout 673
-stdout 674
-stdout 675
-stdout 676
-stdout 677
-stdout 678
-stdout 679
-stdout 680
-stdout 681
-stdout 682
-stdout 683
-stdout 684
-stdout 685
-stdout 686
-stdout 687
-stdout 688
-stdout 689
-stdout 690
-stdout 691
-stdout 692
-stdout 693
-stdout 694
-stdout 695
-stdout 696
-stdout 697
-stdout 698
-stdout 699
-stdout 700
-stdout 701
-stdout 702
-stdout 703
-stdout 704
-stdout 705
-stdout 706
-stdout 707
-stdout 708
-stdout 709
-stdout 710
-stdout 711
-stdout 712
-stdout 713
-stdout 714
-stdout 715
-stdout 716
-stdout 717
-stdout 718
-stdout 719
-stdout 720
-stdout 721
-stdout 722
-stdout 723
-stdout 724
-stdout 725
-stdout 726
-stdout 727
-stdout 728
-stdout 729
-stdout 730
-stdout 731
-stdout 732
-stdout 733
-stdout 734
-stdout 735
-stdout 736
-stdout 737
-stdout 738
-stdout 739
-stdout 740
-stdout 741
-stdout 742
-stdout 743
-stdout 744
-stdout 745
-stdout 746
-stdout 747
-stdout 748
-stdout 749
-stdout 750
-stdout 751
-stdout 752
-stdout 753
-stdout 754
-stdout 755
-stdout 756
-stdout 757
-stdout 758
-stdout 759
-stdout 760
-stdout 761
-stdout 762
-stdout 763
-stdout 764
-stdout 765
-stdout 766
-stdout 767
-stdout 768
-stdout 769
-stdout 770
-stdout 771
-stdout 772
-stdout 773
-stdout 774
-stdout 775
-stdout 776
-stdout 777
-stdout 778
-stdout 779
-stdout 780
-stdout 781
-stdout 782
-stdout 783
-stdout 784
-stdout 785
-stdout 786
-stdout 787
-stdout 788
-stdout 789
-stdout 790
-stdout 791
-stdout 792
-stdout 793
-stdout 794
-stdout 795
-stdout 796
-stdout 797
-stdout 798
-stdout 799
-stdout 800
-stdout 801
-stdout 802
-stdout 803
-stdout 804
-stdout 805
-stdout 806
-stdout 807
-stdout 808
-stdout 809
-stdout 810
-stdout 811
-stdout 812
-stdout 813
-stdout 814
-stdout 815
-stdout 816
-stdout 817
-stdout 818
-stdout 819
-stdout 820
-stdout 821
-stdout 822
-stdout 823
-stdout 824
-stdout 825
-stdout 826
-stdout 827
-stdout 828
-stdout 829
-stdout 830
-stdout 831
-stdout 832
-stdout 833
-stdout 834
-stdout 835
-stdout 836
-stdout 837
-stdout 838
-stdout 839
-stdout 840
-stdout 841
-stdout 842
-stdout 843
-stdout 844
-stdout 845
-stdout 846
-stdout 847
-stdout 848
-stdout 849
-stdout 850
-stdout 851
-stdout 852
-stdout 853
-stdout 854
-stdout 855
-stdout 856
-stdout 857
-stdout 858
-stdout 859
-stdout 860
-stdout 861
-stdout 862
-stdout 863
-stdout 864
-stdout 865
-stdout 866
-stdout 867
-stdout 868
-stdout 869
-stdout 870
-stdout 871
-stdout 872
-stdout 873
-stdout 874
-stdout 875
-stdout 876
-stdout 877
-stdout 878
-stdout 879
-stdout 880
-stdout 881
-stdout 882
-stdout 883
-stdout 884
-stdout 885
-stdout 886
-stdout 887
-stdout 888
-stdout 889
-stdout 890
-stdout 891
-stdout 892
-stdout 893
-stdout 894
-stdout 895
-stdout 896
-stdout 897
-stdout 898
-stdout 899
-stdout 900
-stdout 901
-stdout 902
-stdout 903
-stdout 904
-stdout 905
-stdout 906
-stdout 907
-stdout 908
-stdout 909
-stdout 910
-stdout 911
-stdout 912
-stdout 913
-stdout 914
-stdout 915
-stdout 916
-stdout 917
-stdout 918
-stdout 919
-stdout 920
-stdout 921
-stdout 922
-stdout 923
-stdout 924
-stdout 925
-stdout 926
-stdout 927
-stdout 928
-stdout 929
-stdout 930
-stdout 931
-stdout 932
-stdout 933
-stdout 934
-stdout 935
-stdout 936
-stdout 937
-stdout 938
-stdout 939
-stdout 940
-stdout 941
-stdout 942
-stdout 943
-stdout 944
-stdout 945
-stdout 946
-stdout 947
-stdout 948
-stdout 949
-stdout 950
-stdout 951
-stdout 952
-stdout 953
-stdout 954
-stdout 955
-stdout 956
-stdout 957
-stdout 958
-stdout 959
-stdout 960
-stdout 961
-stdout 962
-stdout 963
-stdout 964
-stdout 965
-stdout 966
-stdout 967
-stdout 968
-stdout 969
-stdout 970
-stdout 971
-stdout 972
-stdout 973
-stdout 974
-stdout 975
-stdout 976
-stdout 977
-stdout 978
-stdout 979
-stdout 980
-stdout 981
-stdout 982
-stdout 983
-stdout 984
-stdout 985
-stdout 986
-stdout 987
-stdout 988
-stdout 989
-stdout 990
-stdout 991
-stdout 992
-stdout 993
-stdout 994
-stdout 995
-stdout 996
-stdout 997
-stdout 998
-stdout 999
diff --git a/spec/fixture/node_modules/grunt/node_modules/exit/test/fixtures/create-files.sh b/spec/fixture/node_modules/grunt/node_modules/exit/test/fixtures/create-files.sh
deleted file mode 100755
index 6a526de0..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/exit/test/fixtures/create-files.sh
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/usr/bin/env bash
-
-rm 10*.txt
-for n in 10 100 1000; do
- node log.js 0 $n stdout stderr &> $n-stdout-stderr.txt
- node log.js 0 $n stdout &> $n-stdout.txt
- node log.js 0 $n stderr &> $n-stderr.txt
-done
diff --git a/spec/fixture/node_modules/grunt/node_modules/exit/test/fixtures/log-broken.js b/spec/fixture/node_modules/grunt/node_modules/exit/test/fixtures/log-broken.js
deleted file mode 100644
index 74c8f120..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/exit/test/fixtures/log-broken.js
+++ /dev/null
@@ -1,23 +0,0 @@
-var errorCode = process.argv[2];
-var max = process.argv[3];
-var modes = process.argv.slice(4);
-
-function stdout(message) {
- if (modes.indexOf('stdout') === -1) { return; }
- process.stdout.write('stdout ' + message + '\n');
-}
-
-function stderr(message) {
- if (modes.indexOf('stderr') === -1) { return; }
- process.stderr.write('stderr ' + message + '\n');
-}
-
-for (var i = 0; i < max; i++) {
- stdout(i);
- stderr(i);
-}
-
-process.exit(errorCode);
-
-stdout('fail');
-stderr('fail');
diff --git a/spec/fixture/node_modules/grunt/node_modules/exit/test/fixtures/log.js b/spec/fixture/node_modules/grunt/node_modules/exit/test/fixtures/log.js
deleted file mode 100644
index 8a9ed9a4..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/exit/test/fixtures/log.js
+++ /dev/null
@@ -1,25 +0,0 @@
-var exit = require('../../lib/exit');
-
-var errorCode = process.argv[2];
-var max = process.argv[3];
-var modes = process.argv.slice(4);
-
-function stdout(message) {
- if (modes.indexOf('stdout') === -1) { return; }
- process.stdout.write('stdout ' + message + '\n');
-}
-
-function stderr(message) {
- if (modes.indexOf('stderr') === -1) { return; }
- process.stderr.write('stderr ' + message + '\n');
-}
-
-for (var i = 0; i < max; i++) {
- stdout(i);
- stderr(i);
-}
-
-exit(errorCode);
-
-stdout('fail');
-stderr('fail');
diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/.jshintrc b/spec/fixture/node_modules/grunt/node_modules/findup-sync/.jshintrc
deleted file mode 100644
index 87189522..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/.jshintrc
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "loopfunc": true,
- "curly": true,
- "eqeqeq": true,
- "immed": true,
- "latedef": true,
- "newcap": true,
- "noarg": true,
- "sub": true,
- "undef": true,
- "unused": true,
- "boss": true,
- "eqnull": true,
- "node": true
-}
diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/.npmignore b/spec/fixture/node_modules/grunt/node_modules/findup-sync/.npmignore
deleted file mode 100644
index e69de29b..00000000
diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/.travis.yml b/spec/fixture/node_modules/grunt/node_modules/findup-sync/.travis.yml
deleted file mode 100644
index b30fcb75..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/.travis.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-language: node_js
-node_js:
- - 0.8
-before_script:
- - npm install -g grunt-cli
diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/Gruntfile.js b/spec/fixture/node_modules/grunt/node_modules/findup-sync/Gruntfile.js
deleted file mode 100644
index 2f964a5b..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/Gruntfile.js
+++ /dev/null
@@ -1,25 +0,0 @@
-'use strict';
-
-module.exports = function(grunt) {
-
- // Project configuration.
- grunt.initConfig({
- nodeunit: {
- files: ['test/**/*_test.js'],
- },
- jshint: {
- options: {
- jshintrc: '.jshintrc'
- },
- all: ['Gruntfile.js', 'lib/**/*.js', 'test/**/*.js']
- }
- });
-
- // Load plugins.
- grunt.loadNpmTasks('grunt-contrib-jshint');
- grunt.loadNpmTasks('grunt-contrib-nodeunit');
-
- // Default task.
- grunt.registerTask('default', ['jshint', 'nodeunit']);
-
-};
diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/LICENSE-MIT b/spec/fixture/node_modules/grunt/node_modules/findup-sync/LICENSE-MIT
deleted file mode 100644
index bb2aad6d..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/LICENSE-MIT
+++ /dev/null
@@ -1,22 +0,0 @@
-Copyright (c) 2013 "Cowboy" Ben Alman
-
-Permission is hereby granted, free of charge, to any person
-obtaining a copy of this software and associated documentation
-files (the "Software"), to deal in the Software without
-restriction, including without limitation the rights to use,
-copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the
-Software is furnished to do so, subject to the following
-conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-OTHER DEALINGS IN THE SOFTWARE.
diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/README.md b/spec/fixture/node_modules/grunt/node_modules/findup-sync/README.md
deleted file mode 100644
index 5459b93f..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/README.md
+++ /dev/null
@@ -1,45 +0,0 @@
-# findup-sync [](http://travis-ci.org/cowboy/node-findup-sync)
-
-Find the first file matching a given pattern in the current directory or the nearest ancestor directory.
-
-## Getting Started
-Install the module with: `npm install findup-sync`
-
-```js
-var findup = require('findup-sync');
-
-// Start looking in the CWD.
-var filepath1 = findup('{a,b}*.txt');
-
-// Start looking somewhere else, and ignore case (probably a good idea).
-var filepath2 = findup('{a,b}*.txt', {cwd: '/some/path', nocase: true});
-```
-
-## Usage
-
-```js
-findup(patternOrPatterns [, minimatchOptions])
-```
-
-### patternOrPatterns
-Type: `String` or `Array`
-Default: none
-
-One or more wildcard glob patterns. Or just filenames.
-
-### minimatchOptions
-Type: `Object`
-Default: `{}`
-
-Options to be passed to [minimatch](https://github.com/isaacs/minimatch).
-
-Note that if you want to start in a different directory than the current working directory, specify a `cwd` property here.
-
-## Contributing
-In lieu of a formal styleguide, take care to maintain the existing coding style. Add unit tests for any new or changed functionality. Lint and test your code using [Grunt](http://gruntjs.com/).
-
-## Release History
-2014-03-14 - v0.1.3 - Updated dependencies.
-2013-03-08 - v0.1.2 - Updated dependencies. Fixed a Node 0.9.x bug. Updated unit tests to work cross-platform.
-2012-11-15 - v0.1.1 - Now works without an options object.
-2012-11-01 - v0.1.0 - Initial release.
diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/lib/findup-sync.js b/spec/fixture/node_modules/grunt/node_modules/findup-sync/lib/findup-sync.js
deleted file mode 100644
index 742a4781..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/lib/findup-sync.js
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * findup-sync
- * https://github.com/cowboy/node-findup-sync
- *
- * Copyright (c) 2013 "Cowboy" Ben Alman
- * Licensed under the MIT license.
- */
-
-'use strict';
-
-// Nodejs libs.
-var path = require('path');
-
-// External libs.
-var glob = require('glob');
-var _ = require('lodash');
-
-// Search for a filename in the given directory or all parent directories.
-module.exports = function(patterns, options) {
- // Normalize patterns to an array.
- if (!Array.isArray(patterns)) { patterns = [patterns]; }
- // Create globOptions so that it can be modified without mutating the
- // original object.
- var globOptions = Object.create(options || {});
- globOptions.maxDepth = 1;
- globOptions.cwd = path.resolve(globOptions.cwd || '.');
-
- var files, lastpath;
- do {
- // Search for files matching patterns.
- files = _(patterns).map(function(pattern) {
- return glob.sync(pattern, globOptions);
- }).flatten().uniq().value();
- // Return file if found.
- if (files.length > 0) {
- return path.resolve(path.join(globOptions.cwd, files[0]));
- }
- // Go up a directory.
- lastpath = globOptions.cwd;
- globOptions.cwd = path.resolve(globOptions.cwd, '..');
- // If parentpath is the same as basedir, we can't go any higher.
- } while (globOptions.cwd !== lastpath);
-
- // No files were found!
- return null;
-};
diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/.npmignore b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/.npmignore
deleted file mode 100644
index 2af4b71c..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/.npmignore
+++ /dev/null
@@ -1,2 +0,0 @@
-.*.swp
-test/a/
diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/.travis.yml b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/.travis.yml
deleted file mode 100644
index baa0031d..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/.travis.yml
+++ /dev/null
@@ -1,3 +0,0 @@
-language: node_js
-node_js:
- - 0.8
diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/LICENSE b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/LICENSE
deleted file mode 100644
index 0c44ae71..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/LICENSE
+++ /dev/null
@@ -1,27 +0,0 @@
-Copyright (c) Isaac Z. Schlueter ("Author")
-All rights reserved.
-
-The BSD License
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
-2. 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.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 THE AUTHOR OR CONTRIBUTORS
-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.
diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/README.md b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/README.md
deleted file mode 100644
index cc691645..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/README.md
+++ /dev/null
@@ -1,250 +0,0 @@
-# Glob
-
-Match files using the patterns the shell uses, like stars and stuff.
-
-This is a glob implementation in JavaScript. It uses the `minimatch`
-library to do its matching.
-
-## Attention: node-glob users!
-
-The API has changed dramatically between 2.x and 3.x. This library is
-now 100% JavaScript, and the integer flags have been replaced with an
-options object.
-
-Also, there's an event emitter class, proper tests, and all the other
-things you've come to expect from node modules.
-
-And best of all, no compilation!
-
-## Usage
-
-```javascript
-var glob = require("glob")
-
-// options is optional
-glob("**/*.js", options, function (er, files) {
- // files is an array of filenames.
- // If the `nonull` option is set, and nothing
- // was found, then files is ["**/*.js"]
- // er is an error object or null.
-})
-```
-
-## Features
-
-Please see the [minimatch
-documentation](https://github.com/isaacs/minimatch) for more details.
-
-Supports these glob features:
-
-* Brace Expansion
-* Extended glob matching
-* "Globstar" `**` matching
-
-See:
-
-* `man sh`
-* `man bash`
-* `man 3 fnmatch`
-* `man 5 gitignore`
-* [minimatch documentation](https://github.com/isaacs/minimatch)
-
-## glob(pattern, [options], cb)
-
-* `pattern` {String} Pattern to be matched
-* `options` {Object}
-* `cb` {Function}
- * `err` {Error | null}
- * `matches` {Array} filenames found matching the pattern
-
-Perform an asynchronous glob search.
-
-## glob.sync(pattern, [options])
-
-* `pattern` {String} Pattern to be matched
-* `options` {Object}
-* return: {Array} filenames found matching the pattern
-
-Perform a synchronous glob search.
-
-## Class: glob.Glob
-
-Create a Glob object by instanting the `glob.Glob` class.
-
-```javascript
-var Glob = require("glob").Glob
-var mg = new Glob(pattern, options, cb)
-```
-
-It's an EventEmitter, and starts walking the filesystem to find matches
-immediately.
-
-### new glob.Glob(pattern, [options], [cb])
-
-* `pattern` {String} pattern to search for
-* `options` {Object}
-* `cb` {Function} Called when an error occurs, or matches are found
- * `err` {Error | null}
- * `matches` {Array} filenames found matching the pattern
-
-Note that if the `sync` flag is set in the options, then matches will
-be immediately available on the `g.found` member.
-
-### Properties
-
-* `minimatch` The minimatch object that the glob uses.
-* `options` The options object passed in.
-* `error` The error encountered. When an error is encountered, the
- glob object is in an undefined state, and should be discarded.
-* `aborted` Boolean which is set to true when calling `abort()`. There
- is no way at this time to continue a glob search after aborting, but
- you can re-use the statCache to avoid having to duplicate syscalls.
-* `statCache` Collection of all the stat results the glob search
- performed.
-* `cache` Convenience object. Each field has the following possible
- values:
- * `false` - Path does not exist
- * `true` - Path exists
- * `1` - Path exists, and is not a directory
- * `2` - Path exists, and is a directory
- * `[file, entries, ...]` - Path exists, is a directory, and the
- array value is the results of `fs.readdir`
-
-### Events
-
-* `end` When the matching is finished, this is emitted with all the
- matches found. If the `nonull` option is set, and no match was found,
- then the `matches` list contains the original pattern. The matches
- are sorted, unless the `nosort` flag is set.
-* `match` Every time a match is found, this is emitted with the matched.
-* `error` Emitted when an unexpected error is encountered, or whenever
- any fs error occurs if `options.strict` is set.
-* `abort` When `abort()` is called, this event is raised.
-
-### Methods
-
-* `abort` Stop the search.
-
-### Options
-
-All the options that can be passed to Minimatch can also be passed to
-Glob to change pattern matching behavior. Also, some have been added,
-or have glob-specific ramifications.
-
-All options are false by default, unless otherwise noted.
-
-All options are added to the glob object, as well.
-
-* `cwd` The current working directory in which to search. Defaults
- to `process.cwd()`.
-* `root` The place where patterns starting with `/` will be mounted
- onto. Defaults to `path.resolve(options.cwd, "/")` (`/` on Unix
- systems, and `C:\` or some such on Windows.)
-* `dot` Include `.dot` files in normal matches and `globstar` matches.
- Note that an explicit dot in a portion of the pattern will always
- match dot files.
-* `nomount` By default, a pattern starting with a forward-slash will be
- "mounted" onto the root setting, so that a valid filesystem path is
- returned. Set this flag to disable that behavior.
-* `mark` Add a `/` character to directory matches. Note that this
- requires additional stat calls.
-* `nosort` Don't sort the results.
-* `stat` Set to true to stat *all* results. This reduces performance
- somewhat, and is completely unnecessary, unless `readdir` is presumed
- to be an untrustworthy indicator of file existence. It will cause
- ELOOP to be triggered one level sooner in the case of cyclical
- symbolic links.
-* `silent` When an unusual error is encountered
- when attempting to read a directory, a warning will be printed to
- stderr. Set the `silent` option to true to suppress these warnings.
-* `strict` When an unusual error is encountered
- when attempting to read a directory, the process will just continue on
- in search of other matches. Set the `strict` option to raise an error
- in these cases.
-* `cache` See `cache` property above. Pass in a previously generated
- cache object to save some fs calls.
-* `statCache` A cache of results of filesystem information, to prevent
- unnecessary stat calls. While it should not normally be necessary to
- set this, you may pass the statCache from one glob() call to the
- options object of another, if you know that the filesystem will not
- change between calls. (See "Race Conditions" below.)
-* `sync` Perform a synchronous glob search.
-* `nounique` In some cases, brace-expanded patterns can result in the
- same file showing up multiple times in the result set. By default,
- this implementation prevents duplicates in the result set.
- Set this flag to disable that behavior.
-* `nonull` Set to never return an empty set, instead returning a set
- containing the pattern itself. This is the default in glob(3).
-* `nocase` Perform a case-insensitive match. Note that case-insensitive
- filesystems will sometimes result in glob returning results that are
- case-insensitively matched anyway, since readdir and stat will not
- raise an error.
-* `debug` Set to enable debug logging in minimatch and glob.
-* `globDebug` Set to enable debug logging in glob, but not minimatch.
-
-## Comparisons to other fnmatch/glob implementations
-
-While strict compliance with the existing standards is a worthwhile
-goal, some discrepancies exist between node-glob and other
-implementations, and are intentional.
-
-If the pattern starts with a `!` character, then it is negated. Set the
-`nonegate` flag to suppress this behavior, and treat leading `!`
-characters normally. This is perhaps relevant if you wish to start the
-pattern with a negative extglob pattern like `!(a|B)`. Multiple `!`
-characters at the start of a pattern will negate the pattern multiple
-times.
-
-If a pattern starts with `#`, then it is treated as a comment, and
-will not match anything. Use `\#` to match a literal `#` at the
-start of a line, or set the `nocomment` flag to suppress this behavior.
-
-The double-star character `**` is supported by default, unless the
-`noglobstar` flag is set. This is supported in the manner of bsdglob
-and bash 4.1, where `**` only has special significance if it is the only
-thing in a path part. That is, `a/**/b` will match `a/x/y/b`, but
-`a/**b` will not.
-
-If an escaped pattern has no matches, and the `nonull` flag is set,
-then glob returns the pattern as-provided, rather than
-interpreting the character escapes. For example,
-`glob.match([], "\\*a\\?")` will return `"\\*a\\?"` rather than
-`"*a?"`. This is akin to setting the `nullglob` option in bash, except
-that it does not resolve escaped pattern characters.
-
-If brace expansion is not disabled, then it is performed before any
-other interpretation of the glob pattern. Thus, a pattern like
-`+(a|{b),c)}`, which would not be valid in bash or zsh, is expanded
-**first** into the set of `+(a|b)` and `+(a|c)`, and those patterns are
-checked for validity. Since those two are valid, matching proceeds.
-
-## Windows
-
-**Please only use forward-slashes in glob expressions.**
-
-Though windows uses either `/` or `\` as its path separator, only `/`
-characters are used by this glob implementation. You must use
-forward-slashes **only** in glob expressions. Back-slashes will always
-be interpreted as escape characters, not path separators.
-
-Results from absolute patterns such as `/foo/*` are mounted onto the
-root setting using `path.join`. On windows, this will by default result
-in `/foo/*` matching `C:\foo\bar.txt`.
-
-## Race Conditions
-
-Glob searching, by its very nature, is susceptible to race conditions,
-since it relies on directory walking and such.
-
-As a result, it is possible that a file that exists when glob looks for
-it may have been deleted or modified by the time it returns the result.
-
-As part of its internal implementation, this program caches all stat
-and readdir calls that it makes, in order to cut down on system
-overhead. However, this also makes it even more susceptible to races,
-especially if the cache or statCache objects are reused between glob
-calls.
-
-Users are thus advised not to use a glob result as a guarantee of
-filesystem state in the face of rapid changes. For the vast majority
-of operations, this is never a problem.
diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/examples/g.js b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/examples/g.js
deleted file mode 100644
index be122df0..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/examples/g.js
+++ /dev/null
@@ -1,9 +0,0 @@
-var Glob = require("../").Glob
-
-var pattern = "test/a/**/[cg]/../[cg]"
-console.log(pattern)
-
-var mg = new Glob(pattern, {mark: true, sync:true}, function (er, matches) {
- console.log("matches", matches)
-})
-console.log("after")
diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/examples/usr-local.js b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/examples/usr-local.js
deleted file mode 100644
index 327a425e..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/examples/usr-local.js
+++ /dev/null
@@ -1,9 +0,0 @@
-var Glob = require("../").Glob
-
-var pattern = "{./*/*,/*,/usr/local/*}"
-console.log(pattern)
-
-var mg = new Glob(pattern, {mark: true}, function (er, matches) {
- console.log("matches", matches)
-})
-console.log("after")
diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/glob.js b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/glob.js
deleted file mode 100644
index f646c448..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/glob.js
+++ /dev/null
@@ -1,728 +0,0 @@
-// Approach:
-//
-// 1. Get the minimatch set
-// 2. For each pattern in the set, PROCESS(pattern)
-// 3. Store matches per-set, then uniq them
-//
-// PROCESS(pattern)
-// Get the first [n] items from pattern that are all strings
-// Join these together. This is PREFIX.
-// If there is no more remaining, then stat(PREFIX) and
-// add to matches if it succeeds. END.
-// readdir(PREFIX) as ENTRIES
-// If fails, END
-// If pattern[n] is GLOBSTAR
-// // handle the case where the globstar match is empty
-// // by pruning it out, and testing the resulting pattern
-// PROCESS(pattern[0..n] + pattern[n+1 .. $])
-// // handle other cases.
-// for ENTRY in ENTRIES (not dotfiles)
-// // attach globstar + tail onto the entry
-// PROCESS(pattern[0..n] + ENTRY + pattern[n .. $])
-//
-// else // not globstar
-// for ENTRY in ENTRIES (not dotfiles, unless pattern[n] is dot)
-// Test ENTRY against pattern[n]
-// If fails, continue
-// If passes, PROCESS(pattern[0..n] + item + pattern[n+1 .. $])
-//
-// Caveat:
-// Cache all stats and readdirs results to minimize syscall. Since all
-// we ever care about is existence and directory-ness, we can just keep
-// `true` for files, and [children,...] for directories, or `false` for
-// things that don't exist.
-
-
-
-module.exports = glob
-
-var fs = require("fs")
-, minimatch = require("minimatch")
-, Minimatch = minimatch.Minimatch
-, inherits = require("inherits")
-, EE = require("events").EventEmitter
-, path = require("path")
-, isDir = {}
-, assert = require("assert").ok
-
-function glob (pattern, options, cb) {
- if (typeof options === "function") cb = options, options = {}
- if (!options) options = {}
-
- if (typeof options === "number") {
- deprecated()
- return
- }
-
- var g = new Glob(pattern, options, cb)
- return g.sync ? g.found : g
-}
-
-glob.fnmatch = deprecated
-
-function deprecated () {
- throw new Error("glob's interface has changed. Please see the docs.")
-}
-
-glob.sync = globSync
-function globSync (pattern, options) {
- if (typeof options === "number") {
- deprecated()
- return
- }
-
- options = options || {}
- options.sync = true
- return glob(pattern, options)
-}
-
-this._processingEmitQueue = false
-
-glob.Glob = Glob
-inherits(Glob, EE)
-function Glob (pattern, options, cb) {
- if (!(this instanceof Glob)) {
- return new Glob(pattern, options, cb)
- }
-
- if (typeof options === "function") {
- cb = options
- options = null
- }
-
- if (typeof cb === "function") {
- this.on("error", cb)
- this.on("end", function (matches) {
- cb(null, matches)
- })
- }
-
- options = options || {}
-
- this._endEmitted = false
- this.EOF = {}
- this._emitQueue = []
-
- this.paused = false
- this._processingEmitQueue = false
-
- this.maxDepth = options.maxDepth || 1000
- this.maxLength = options.maxLength || Infinity
- this.cache = options.cache || {}
- this.statCache = options.statCache || {}
-
- this.changedCwd = false
- var cwd = process.cwd()
- if (!options.hasOwnProperty("cwd")) this.cwd = cwd
- else {
- this.cwd = options.cwd
- this.changedCwd = path.resolve(options.cwd) !== cwd
- }
-
- this.root = options.root || path.resolve(this.cwd, "/")
- this.root = path.resolve(this.root)
- if (process.platform === "win32")
- this.root = this.root.replace(/\\/g, "/")
-
- this.nomount = !!options.nomount
-
- if (!pattern) {
- throw new Error("must provide pattern")
- }
-
- // base-matching: just use globstar for that.
- if (options.matchBase && -1 === pattern.indexOf("/")) {
- if (options.noglobstar) {
- throw new Error("base matching requires globstar")
- }
- pattern = "**/" + pattern
- }
-
- this.strict = options.strict !== false
- this.dot = !!options.dot
- this.mark = !!options.mark
- this.sync = !!options.sync
- this.nounique = !!options.nounique
- this.nonull = !!options.nonull
- this.nosort = !!options.nosort
- this.nocase = !!options.nocase
- this.stat = !!options.stat
-
- this.debug = !!options.debug || !!options.globDebug
- if (this.debug)
- this.log = console.error
-
- this.silent = !!options.silent
-
- var mm = this.minimatch = new Minimatch(pattern, options)
- this.options = mm.options
- pattern = this.pattern = mm.pattern
-
- this.error = null
- this.aborted = false
-
- // list of all the patterns that ** has resolved do, so
- // we can avoid visiting multiple times.
- this._globstars = {}
-
- EE.call(this)
-
- // process each pattern in the minimatch set
- var n = this.minimatch.set.length
-
- // The matches are stored as {: true,...} so that
- // duplicates are automagically pruned.
- // Later, we do an Object.keys() on these.
- // Keep them as a list so we can fill in when nonull is set.
- this.matches = new Array(n)
-
- this.minimatch.set.forEach(iterator.bind(this))
- function iterator (pattern, i, set) {
- this._process(pattern, 0, i, function (er) {
- if (er) this.emit("error", er)
- if (-- n <= 0) this._finish()
- })
- }
-}
-
-Glob.prototype.log = function () {}
-
-Glob.prototype._finish = function () {
- assert(this instanceof Glob)
-
- var nou = this.nounique
- , all = nou ? [] : {}
-
- for (var i = 0, l = this.matches.length; i < l; i ++) {
- var matches = this.matches[i]
- this.log("matches[%d] =", i, matches)
- // do like the shell, and spit out the literal glob
- if (!matches) {
- if (this.nonull) {
- var literal = this.minimatch.globSet[i]
- if (nou) all.push(literal)
- else all[literal] = true
- }
- } else {
- // had matches
- var m = Object.keys(matches)
- if (nou) all.push.apply(all, m)
- else m.forEach(function (m) {
- all[m] = true
- })
- }
- }
-
- if (!nou) all = Object.keys(all)
-
- if (!this.nosort) {
- all = all.sort(this.nocase ? alphasorti : alphasort)
- }
-
- if (this.mark) {
- // at *some* point we statted all of these
- all = all.map(this._mark, this)
- }
-
- this.log("emitting end", all)
-
- this.EOF = this.found = all
- this.emitMatch(this.EOF)
-}
-
-function alphasorti (a, b) {
- a = a.toLowerCase()
- b = b.toLowerCase()
- return alphasort(a, b)
-}
-
-function alphasort (a, b) {
- return a > b ? 1 : a < b ? -1 : 0
-}
-
-Glob.prototype._mark = function (p) {
- var c = this.cache[p]
- var m = p
- if (c) {
- var isDir = c === 2 || Array.isArray(c)
- var slash = p.slice(-1) === '/'
-
- if (isDir && !slash)
- m += '/'
- else if (!isDir && slash)
- m = m.slice(0, -1)
-
- if (m !== p) {
- this.statCache[m] = this.statCache[p]
- this.cache[m] = this.cache[p]
- }
- }
-
- return m
-}
-
-Glob.prototype.abort = function () {
- this.aborted = true
- this.emit("abort")
-}
-
-Glob.prototype.pause = function () {
- if (this.paused) return
- if (this.sync)
- this.emit("error", new Error("Can't pause/resume sync glob"))
- this.paused = true
- this.emit("pause")
-}
-
-Glob.prototype.resume = function () {
- if (!this.paused) return
- if (this.sync)
- this.emit("error", new Error("Can't pause/resume sync glob"))
- this.paused = false
- this.emit("resume")
- this._processEmitQueue()
- //process.nextTick(this.emit.bind(this, "resume"))
-}
-
-Glob.prototype.emitMatch = function (m) {
- this.log('emitMatch', m)
- this._emitQueue.push(m)
- this._processEmitQueue()
-}
-
-Glob.prototype._processEmitQueue = function (m) {
- this.log("pEQ paused=%j processing=%j m=%j", this.paused,
- this._processingEmitQueue, m)
- var done = false
- while (!this._processingEmitQueue &&
- !this.paused) {
- this._processingEmitQueue = true
- var m = this._emitQueue.shift()
- this.log(">processEmitQueue", m === this.EOF ? ":EOF:" : m)
- if (!m) {
- this.log(">processEmitQueue, falsey m")
- this._processingEmitQueue = false
- break
- }
-
- if (m === this.EOF || !(this.mark && !this.stat)) {
- this.log("peq: unmarked, or eof")
- next.call(this, 0, false)
- } else if (this.statCache[m]) {
- var sc = this.statCache[m]
- var exists
- if (sc)
- exists = sc.isDirectory() ? 2 : 1
- this.log("peq: stat cached")
- next.call(this, exists, exists === 2)
- } else {
- this.log("peq: _stat, then next")
- this._stat(m, next)
- }
-
- function next(exists, isDir) {
- this.log("next", m, exists, isDir)
- var ev = m === this.EOF ? "end" : "match"
-
- // "end" can only happen once.
- assert(!this._endEmitted)
- if (ev === "end")
- this._endEmitted = true
-
- if (exists) {
- // Doesn't mean it necessarily doesn't exist, it's possible
- // we just didn't check because we don't care that much, or
- // this is EOF anyway.
- if (isDir && !m.match(/\/$/)) {
- m = m + "/"
- } else if (!isDir && m.match(/\/$/)) {
- m = m.replace(/\/+$/, "")
- }
- }
- this.log("emit", ev, m)
- this.emit(ev, m)
- this._processingEmitQueue = false
- if (done && m !== this.EOF && !this.paused)
- this._processEmitQueue()
- }
- }
- done = true
-}
-
-Glob.prototype._process = function (pattern, depth, index, cb_) {
- assert(this instanceof Glob)
-
- var cb = function cb (er, res) {
- assert(this instanceof Glob)
- if (this.paused) {
- if (!this._processQueue) {
- this._processQueue = []
- this.once("resume", function () {
- var q = this._processQueue
- this._processQueue = null
- q.forEach(function (cb) { cb() })
- })
- }
- this._processQueue.push(cb_.bind(this, er, res))
- } else {
- cb_.call(this, er, res)
- }
- }.bind(this)
-
- if (this.aborted) return cb()
-
- if (depth > this.maxDepth) return cb()
-
- // Get the first [n] parts of pattern that are all strings.
- var n = 0
- while (typeof pattern[n] === "string") {
- n ++
- }
- // now n is the index of the first one that is *not* a string.
-
- // see if there's anything else
- var prefix
- switch (n) {
- // if not, then this is rather simple
- case pattern.length:
- prefix = pattern.join("/")
- this._stat(prefix, function (exists, isDir) {
- // either it's there, or it isn't.
- // nothing more to do, either way.
- if (exists) {
- if (prefix && isAbsolute(prefix) && !this.nomount) {
- if (prefix.charAt(0) === "/") {
- prefix = path.join(this.root, prefix)
- } else {
- prefix = path.resolve(this.root, prefix)
- }
- }
-
- if (process.platform === "win32")
- prefix = prefix.replace(/\\/g, "/")
-
- this.matches[index] = this.matches[index] || {}
- this.matches[index][prefix] = true
- this.emitMatch(prefix)
- }
- return cb()
- })
- return
-
- case 0:
- // pattern *starts* with some non-trivial item.
- // going to readdir(cwd), but not include the prefix in matches.
- prefix = null
- break
-
- default:
- // pattern has some string bits in the front.
- // whatever it starts with, whether that's "absolute" like /foo/bar,
- // or "relative" like "../baz"
- prefix = pattern.slice(0, n)
- prefix = prefix.join("/")
- break
- }
-
- // get the list of entries.
- var read
- if (prefix === null) read = "."
- else if (isAbsolute(prefix) || isAbsolute(pattern.join("/"))) {
- if (!prefix || !isAbsolute(prefix)) {
- prefix = path.join("/", prefix)
- }
- read = prefix = path.resolve(prefix)
-
- // if (process.platform === "win32")
- // read = prefix = prefix.replace(/^[a-zA-Z]:|\\/g, "/")
-
- this.log('absolute: ', prefix, this.root, pattern, read)
- } else {
- read = prefix
- }
-
- this.log('readdir(%j)', read, this.cwd, this.root)
-
- return this._readdir(read, function (er, entries) {
- if (er) {
- // not a directory!
- // this means that, whatever else comes after this, it can never match
- return cb()
- }
-
- // globstar is special
- if (pattern[n] === minimatch.GLOBSTAR) {
- // test without the globstar, and with every child both below
- // and replacing the globstar.
- var s = [ pattern.slice(0, n).concat(pattern.slice(n + 1)) ]
- entries.forEach(function (e) {
- if (e.charAt(0) === "." && !this.dot) return
- // instead of the globstar
- s.push(pattern.slice(0, n).concat(e).concat(pattern.slice(n + 1)))
- // below the globstar
- s.push(pattern.slice(0, n).concat(e).concat(pattern.slice(n)))
- }, this)
-
- s = s.filter(function (pattern) {
- var key = gsKey(pattern)
- var seen = !this._globstars[key]
- this._globstars[key] = true
- return seen
- }, this)
-
- if (!s.length)
- return cb()
-
- // now asyncForEach over this
- var l = s.length
- , errState = null
- s.forEach(function (gsPattern) {
- this._process(gsPattern, depth + 1, index, function (er) {
- if (errState) return
- if (er) return cb(errState = er)
- if (--l <= 0) return cb()
- })
- }, this)
-
- return
- }
-
- // not a globstar
- // It will only match dot entries if it starts with a dot, or if
- // dot is set. Stuff like @(.foo|.bar) isn't allowed.
- var pn = pattern[n]
- var rawGlob = pattern[n]._glob
- , dotOk = this.dot || rawGlob.charAt(0) === "."
-
- entries = entries.filter(function (e) {
- return (e.charAt(0) !== "." || dotOk) &&
- e.match(pattern[n])
- })
-
- // If n === pattern.length - 1, then there's no need for the extra stat
- // *unless* the user has specified "mark" or "stat" explicitly.
- // We know that they exist, since the readdir returned them.
- if (n === pattern.length - 1 &&
- !this.mark &&
- !this.stat) {
- entries.forEach(function (e) {
- if (prefix) {
- if (prefix !== "/") e = prefix + "/" + e
- else e = prefix + e
- }
- if (e.charAt(0) === "/" && !this.nomount) {
- e = path.join(this.root, e)
- }
-
- if (process.platform === "win32")
- e = e.replace(/\\/g, "/")
-
- this.matches[index] = this.matches[index] || {}
- this.matches[index][e] = true
- this.emitMatch(e)
- }, this)
- return cb.call(this)
- }
-
-
- // now test all the remaining entries as stand-ins for that part
- // of the pattern.
- var l = entries.length
- , errState = null
- if (l === 0) return cb() // no matches possible
- entries.forEach(function (e) {
- var p = pattern.slice(0, n).concat(e).concat(pattern.slice(n + 1))
- this._process(p, depth + 1, index, function (er) {
- if (errState) return
- if (er) return cb(errState = er)
- if (--l === 0) return cb.call(this)
- })
- }, this)
- })
-
-}
-
-function gsKey (pattern) {
- return '**' + pattern.map(function (p) {
- return (p === minimatch.GLOBSTAR) ? '**' : (''+p)
- }).join('/')
-}
-
-Glob.prototype._stat = function (f, cb) {
- assert(this instanceof Glob)
- var abs = f
- if (f.charAt(0) === "/") {
- abs = path.join(this.root, f)
- } else if (this.changedCwd) {
- abs = path.resolve(this.cwd, f)
- }
-
- if (f.length > this.maxLength) {
- var er = new Error("Path name too long")
- er.code = "ENAMETOOLONG"
- er.path = f
- return this._afterStat(f, abs, cb, er)
- }
-
- this.log('stat', [this.cwd, f, '=', abs])
-
- if (!this.stat && this.cache.hasOwnProperty(f)) {
- var exists = this.cache[f]
- , isDir = exists && (Array.isArray(exists) || exists === 2)
- if (this.sync) return cb.call(this, !!exists, isDir)
- return process.nextTick(cb.bind(this, !!exists, isDir))
- }
-
- var stat = this.statCache[abs]
- if (this.sync || stat) {
- var er
- try {
- stat = fs.statSync(abs)
- } catch (e) {
- er = e
- }
- this._afterStat(f, abs, cb, er, stat)
- } else {
- fs.stat(abs, this._afterStat.bind(this, f, abs, cb))
- }
-}
-
-Glob.prototype._afterStat = function (f, abs, cb, er, stat) {
- var exists
- assert(this instanceof Glob)
-
- if (abs.slice(-1) === "/" && stat && !stat.isDirectory()) {
- this.log("should be ENOTDIR, fake it")
-
- er = new Error("ENOTDIR, not a directory '" + abs + "'")
- er.path = abs
- er.code = "ENOTDIR"
- stat = null
- }
-
- var emit = !this.statCache[abs]
- this.statCache[abs] = stat
-
- if (er || !stat) {
- exists = false
- } else {
- exists = stat.isDirectory() ? 2 : 1
- if (emit)
- this.emit('stat', f, stat)
- }
- this.cache[f] = this.cache[f] || exists
- cb.call(this, !!exists, exists === 2)
-}
-
-Glob.prototype._readdir = function (f, cb) {
- assert(this instanceof Glob)
- var abs = f
- if (f.charAt(0) === "/") {
- abs = path.join(this.root, f)
- } else if (isAbsolute(f)) {
- abs = f
- } else if (this.changedCwd) {
- abs = path.resolve(this.cwd, f)
- }
-
- if (f.length > this.maxLength) {
- var er = new Error("Path name too long")
- er.code = "ENAMETOOLONG"
- er.path = f
- return this._afterReaddir(f, abs, cb, er)
- }
-
- this.log('readdir', [this.cwd, f, abs])
- if (this.cache.hasOwnProperty(f)) {
- var c = this.cache[f]
- if (Array.isArray(c)) {
- if (this.sync) return cb.call(this, null, c)
- return process.nextTick(cb.bind(this, null, c))
- }
-
- if (!c || c === 1) {
- // either ENOENT or ENOTDIR
- var code = c ? "ENOTDIR" : "ENOENT"
- , er = new Error((c ? "Not a directory" : "Not found") + ": " + f)
- er.path = f
- er.code = code
- this.log(f, er)
- if (this.sync) return cb.call(this, er)
- return process.nextTick(cb.bind(this, er))
- }
-
- // at this point, c === 2, meaning it's a dir, but we haven't
- // had to read it yet, or c === true, meaning it's *something*
- // but we don't have any idea what. Need to read it, either way.
- }
-
- if (this.sync) {
- var er, entries
- try {
- entries = fs.readdirSync(abs)
- } catch (e) {
- er = e
- }
- return this._afterReaddir(f, abs, cb, er, entries)
- }
-
- fs.readdir(abs, this._afterReaddir.bind(this, f, abs, cb))
-}
-
-Glob.prototype._afterReaddir = function (f, abs, cb, er, entries) {
- assert(this instanceof Glob)
- if (entries && !er) {
- this.cache[f] = entries
- // if we haven't asked to stat everything for suresies, then just
- // assume that everything in there exists, so we can avoid
- // having to stat it a second time. This also gets us one step
- // further into ELOOP territory.
- if (!this.mark && !this.stat) {
- entries.forEach(function (e) {
- if (f === "/") e = f + e
- else e = f + "/" + e
- this.cache[e] = true
- }, this)
- }
-
- return cb.call(this, er, entries)
- }
-
- // now handle errors, and cache the information
- if (er) switch (er.code) {
- case "ENOTDIR": // totally normal. means it *does* exist.
- this.cache[f] = 1
- return cb.call(this, er)
- case "ENOENT": // not terribly unusual
- case "ELOOP":
- case "ENAMETOOLONG":
- case "UNKNOWN":
- this.cache[f] = false
- return cb.call(this, er)
- default: // some unusual error. Treat as failure.
- this.cache[f] = false
- if (this.strict) this.emit("error", er)
- if (!this.silent) console.error("glob error", er)
- return cb.call(this, er)
- }
-}
-
-var isAbsolute = process.platform === "win32" ? absWin : absUnix
-
-function absWin (p) {
- if (absUnix(p)) return true
- // pull off the device/UNC bit from a windows path.
- // from node's lib/path.js
- var splitDeviceRe =
- /^([a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/]+[^\\\/]+)?([\\\/])?([\s\S]*?)$/
- , result = splitDeviceRe.exec(p)
- , device = result[1] || ''
- , isUnc = device && device.charAt(1) !== ':'
- , isAbsolute = !!result[2] || isUnc // UNC paths are always absolute
-
- return isAbsolute
-}
-
-function absUnix (p) {
- return p.charAt(0) === "/" || p === ""
-}
diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/inherits/LICENSE b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/inherits/LICENSE
deleted file mode 100644
index dea3013d..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/inherits/LICENSE
+++ /dev/null
@@ -1,16 +0,0 @@
-The ISC License
-
-Copyright (c) Isaac Z. Schlueter
-
-Permission to use, copy, modify, and/or distribute this software for any
-purpose with or without fee is hereby granted, provided that the above
-copyright notice and this permission notice appear in all copies.
-
-THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
-REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
-FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
-INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
-OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-PERFORMANCE OF THIS SOFTWARE.
-
diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/inherits/README.md b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/inherits/README.md
deleted file mode 100644
index b1c56658..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/inherits/README.md
+++ /dev/null
@@ -1,42 +0,0 @@
-Browser-friendly inheritance fully compatible with standard node.js
-[inherits](http://nodejs.org/api/util.html#util_util_inherits_constructor_superconstructor).
-
-This package exports standard `inherits` from node.js `util` module in
-node environment, but also provides alternative browser-friendly
-implementation through [browser
-field](https://gist.github.com/shtylman/4339901). Alternative
-implementation is a literal copy of standard one located in standalone
-module to avoid requiring of `util`. It also has a shim for old
-browsers with no `Object.create` support.
-
-While keeping you sure you are using standard `inherits`
-implementation in node.js environment, it allows bundlers such as
-[browserify](https://github.com/substack/node-browserify) to not
-include full `util` package to your client code if all you need is
-just `inherits` function. It worth, because browser shim for `util`
-package is large and `inherits` is often the single function you need
-from it.
-
-It's recommended to use this package instead of
-`require('util').inherits` for any code that has chances to be used
-not only in node.js but in browser too.
-
-## usage
-
-```js
-var inherits = require('inherits');
-// then use exactly as the standard one
-```
-
-## note on version ~1.0
-
-Version ~1.0 had completely different motivation and is not compatible
-neither with 2.0 nor with standard node.js `inherits`.
-
-If you are using version ~1.0 and planning to switch to ~2.0, be
-careful:
-
-* new version uses `super_` instead of `super` for referencing
- superclass
-* new version overwrites current prototype while old one preserves any
- existing fields on it
diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/inherits/inherits.js b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/inherits/inherits.js
deleted file mode 100644
index 29f5e24f..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/inherits/inherits.js
+++ /dev/null
@@ -1 +0,0 @@
-module.exports = require('util').inherits
diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/inherits/inherits_browser.js b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/inherits/inherits_browser.js
deleted file mode 100644
index c1e78a75..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/inherits/inherits_browser.js
+++ /dev/null
@@ -1,23 +0,0 @@
-if (typeof Object.create === 'function') {
- // implementation from standard node.js 'util' module
- module.exports = function inherits(ctor, superCtor) {
- ctor.super_ = superCtor
- ctor.prototype = Object.create(superCtor.prototype, {
- constructor: {
- value: ctor,
- enumerable: false,
- writable: true,
- configurable: true
- }
- });
- };
-} else {
- // old school shim for old browsers
- module.exports = function inherits(ctor, superCtor) {
- ctor.super_ = superCtor
- var TempCtor = function () {}
- TempCtor.prototype = superCtor.prototype
- ctor.prototype = new TempCtor()
- ctor.prototype.constructor = ctor
- }
-}
diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/inherits/package.json b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/inherits/package.json
deleted file mode 100644
index 754a1144..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/inherits/package.json
+++ /dev/null
@@ -1,51 +0,0 @@
-{
- "name": "inherits",
- "description": "Browser-friendly inheritance fully compatible with standard node.js inherits()",
- "version": "2.0.1",
- "keywords": [
- "inheritance",
- "class",
- "klass",
- "oop",
- "object-oriented",
- "inherits",
- "browser",
- "browserify"
- ],
- "main": "./inherits.js",
- "browser": "./inherits_browser.js",
- "repository": {
- "type": "git",
- "url": "git://github.com/isaacs/inherits"
- },
- "license": "ISC",
- "scripts": {
- "test": "node test"
- },
- "readme": "Browser-friendly inheritance fully compatible with standard node.js\n[inherits](http://nodejs.org/api/util.html#util_util_inherits_constructor_superconstructor).\n\nThis package exports standard `inherits` from node.js `util` module in\nnode environment, but also provides alternative browser-friendly\nimplementation through [browser\nfield](https://gist.github.com/shtylman/4339901). Alternative\nimplementation is a literal copy of standard one located in standalone\nmodule to avoid requiring of `util`. It also has a shim for old\nbrowsers with no `Object.create` support.\n\nWhile keeping you sure you are using standard `inherits`\nimplementation in node.js environment, it allows bundlers such as\n[browserify](https://github.com/substack/node-browserify) to not\ninclude full `util` package to your client code if all you need is\njust `inherits` function. It worth, because browser shim for `util`\npackage is large and `inherits` is often the single function you need\nfrom it.\n\nIt's recommended to use this package instead of\n`require('util').inherits` for any code that has chances to be used\nnot only in node.js but in browser too.\n\n## usage\n\n```js\nvar inherits = require('inherits');\n// then use exactly as the standard one\n```\n\n## note on version ~1.0\n\nVersion ~1.0 had completely different motivation and is not compatible\nneither with 2.0 nor with standard node.js `inherits`.\n\nIf you are using version ~1.0 and planning to switch to ~2.0, be\ncareful:\n\n* new version uses `super_` instead of `super` for referencing\n superclass\n* new version overwrites current prototype while old one preserves any\n existing fields on it\n",
- "readmeFilename": "README.md",
- "bugs": {
- "url": "https://github.com/isaacs/inherits/issues"
- },
- "_id": "inherits@2.0.1",
- "dist": {
- "shasum": "b17d08d326b4423e568eff719f91b0b1cbdf69f1",
- "tarball": "http://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz"
- },
- "_from": "inherits@2",
- "_npmVersion": "1.3.8",
- "_npmUser": {
- "name": "isaacs",
- "email": "i@izs.me"
- },
- "maintainers": [
- {
- "name": "isaacs",
- "email": "i@izs.me"
- }
- ],
- "directories": {},
- "_shasum": "b17d08d326b4423e568eff719f91b0b1cbdf69f1",
- "_resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz",
- "homepage": "https://github.com/isaacs/inherits"
-}
diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/inherits/test.js b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/inherits/test.js
deleted file mode 100644
index fc53012d..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/inherits/test.js
+++ /dev/null
@@ -1,25 +0,0 @@
-var inherits = require('./inherits.js')
-var assert = require('assert')
-
-function test(c) {
- assert(c.constructor === Child)
- assert(c.constructor.super_ === Parent)
- assert(Object.getPrototypeOf(c) === Child.prototype)
- assert(Object.getPrototypeOf(Object.getPrototypeOf(c)) === Parent.prototype)
- assert(c instanceof Child)
- assert(c instanceof Parent)
-}
-
-function Child() {
- Parent.call(this)
- test(this)
-}
-
-function Parent() {}
-
-inherits(Child, Parent)
-
-var c = new Child
-test(c)
-
-console.log('ok')
diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/.npmignore b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/.npmignore
deleted file mode 100644
index 3c3629e6..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/.npmignore
+++ /dev/null
@@ -1 +0,0 @@
-node_modules
diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/LICENSE b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/LICENSE
deleted file mode 100644
index 05a40109..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/LICENSE
+++ /dev/null
@@ -1,23 +0,0 @@
-Copyright 2009, 2010, 2011 Isaac Z. Schlueter.
-All rights reserved.
-
-Permission is hereby granted, free of charge, to any person
-obtaining a copy of this software and associated documentation
-files (the "Software"), to deal in the Software without
-restriction, including without limitation the rights to use,
-copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the
-Software is furnished to do so, subject to the following
-conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-OTHER DEALINGS IN THE SOFTWARE.
diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/README.md b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/README.md
deleted file mode 100644
index 5b3967ea..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/README.md
+++ /dev/null
@@ -1,218 +0,0 @@
-# minimatch
-
-A minimal matching utility.
-
-[](http://travis-ci.org/isaacs/minimatch)
-
-
-This is the matching library used internally by npm.
-
-Eventually, it will replace the C binding in node-glob.
-
-It works by converting glob expressions into JavaScript `RegExp`
-objects.
-
-## Usage
-
-```javascript
-var minimatch = require("minimatch")
-
-minimatch("bar.foo", "*.foo") // true!
-minimatch("bar.foo", "*.bar") // false!
-minimatch("bar.foo", "*.+(bar|foo)", { debug: true }) // true, and noisy!
-```
-
-## Features
-
-Supports these glob features:
-
-* Brace Expansion
-* Extended glob matching
-* "Globstar" `**` matching
-
-See:
-
-* `man sh`
-* `man bash`
-* `man 3 fnmatch`
-* `man 5 gitignore`
-
-## Minimatch Class
-
-Create a minimatch object by instanting the `minimatch.Minimatch` class.
-
-```javascript
-var Minimatch = require("minimatch").Minimatch
-var mm = new Minimatch(pattern, options)
-```
-
-### Properties
-
-* `pattern` The original pattern the minimatch object represents.
-* `options` The options supplied to the constructor.
-* `set` A 2-dimensional array of regexp or string expressions.
- Each row in the
- array corresponds to a brace-expanded pattern. Each item in the row
- corresponds to a single path-part. For example, the pattern
- `{a,b/c}/d` would expand to a set of patterns like:
-
- [ [ a, d ]
- , [ b, c, d ] ]
-
- If a portion of the pattern doesn't have any "magic" in it
- (that is, it's something like `"foo"` rather than `fo*o?`), then it
- will be left as a string rather than converted to a regular
- expression.
-
-* `regexp` Created by the `makeRe` method. A single regular expression
- expressing the entire pattern. This is useful in cases where you wish
- to use the pattern somewhat like `fnmatch(3)` with `FNM_PATH` enabled.
-* `negate` True if the pattern is negated.
-* `comment` True if the pattern is a comment.
-* `empty` True if the pattern is `""`.
-
-### Methods
-
-* `makeRe` Generate the `regexp` member if necessary, and return it.
- Will return `false` if the pattern is invalid.
-* `match(fname)` Return true if the filename matches the pattern, or
- false otherwise.
-* `matchOne(fileArray, patternArray, partial)` Take a `/`-split
- filename, and match it against a single row in the `regExpSet`. This
- method is mainly for internal use, but is exposed so that it can be
- used by a glob-walker that needs to avoid excessive filesystem calls.
-
-All other methods are internal, and will be called as necessary.
-
-## Functions
-
-The top-level exported function has a `cache` property, which is an LRU
-cache set to store 100 items. So, calling these methods repeatedly
-with the same pattern and options will use the same Minimatch object,
-saving the cost of parsing it multiple times.
-
-### minimatch(path, pattern, options)
-
-Main export. Tests a path against the pattern using the options.
-
-```javascript
-var isJS = minimatch(file, "*.js", { matchBase: true })
-```
-
-### minimatch.filter(pattern, options)
-
-Returns a function that tests its
-supplied argument, suitable for use with `Array.filter`. Example:
-
-```javascript
-var javascripts = fileList.filter(minimatch.filter("*.js", {matchBase: true}))
-```
-
-### minimatch.match(list, pattern, options)
-
-Match against the list of
-files, in the style of fnmatch or glob. If nothing is matched, and
-options.nonull is set, then return a list containing the pattern itself.
-
-```javascript
-var javascripts = minimatch.match(fileList, "*.js", {matchBase: true}))
-```
-
-### minimatch.makeRe(pattern, options)
-
-Make a regular expression object from the pattern.
-
-## Options
-
-All options are `false` by default.
-
-### debug
-
-Dump a ton of stuff to stderr.
-
-### nobrace
-
-Do not expand `{a,b}` and `{1..3}` brace sets.
-
-### noglobstar
-
-Disable `**` matching against multiple folder names.
-
-### dot
-
-Allow patterns to match filenames starting with a period, even if
-the pattern does not explicitly have a period in that spot.
-
-Note that by default, `a/**/b` will **not** match `a/.d/b`, unless `dot`
-is set.
-
-### noext
-
-Disable "extglob" style patterns like `+(a|b)`.
-
-### nocase
-
-Perform a case-insensitive match.
-
-### nonull
-
-When a match is not found by `minimatch.match`, return a list containing
-the pattern itself if this option is set. When not set, an empty list
-is returned if there are no matches.
-
-### matchBase
-
-If set, then patterns without slashes will be matched
-against the basename of the path if it contains slashes. For example,
-`a?b` would match the path `/xyz/123/acb`, but not `/xyz/acb/123`.
-
-### nocomment
-
-Suppress the behavior of treating `#` at the start of a pattern as a
-comment.
-
-### nonegate
-
-Suppress the behavior of treating a leading `!` character as negation.
-
-### flipNegate
-
-Returns from negate expressions the same as if they were not negated.
-(Ie, true on a hit, false on a miss.)
-
-
-## Comparisons to other fnmatch/glob implementations
-
-While strict compliance with the existing standards is a worthwhile
-goal, some discrepancies exist between minimatch and other
-implementations, and are intentional.
-
-If the pattern starts with a `!` character, then it is negated. Set the
-`nonegate` flag to suppress this behavior, and treat leading `!`
-characters normally. This is perhaps relevant if you wish to start the
-pattern with a negative extglob pattern like `!(a|B)`. Multiple `!`
-characters at the start of a pattern will negate the pattern multiple
-times.
-
-If a pattern starts with `#`, then it is treated as a comment, and
-will not match anything. Use `\#` to match a literal `#` at the
-start of a line, or set the `nocomment` flag to suppress this behavior.
-
-The double-star character `**` is supported by default, unless the
-`noglobstar` flag is set. This is supported in the manner of bsdglob
-and bash 4.1, where `**` only has special significance if it is the only
-thing in a path part. That is, `a/**/b` will match `a/x/y/b`, but
-`a/**b` will not.
-
-If an escaped pattern has no matches, and the `nonull` flag is set,
-then minimatch.match returns the pattern as-provided, rather than
-interpreting the character escapes. For example,
-`minimatch.match([], "\\*a\\?")` will return `"\\*a\\?"` rather than
-`"*a?"`. This is akin to setting the `nullglob` option in bash, except
-that it does not resolve escaped pattern characters.
-
-If brace expansion is not disabled, then it is performed before any
-other interpretation of the glob pattern. Thus, a pattern like
-`+(a|{b),c)}`, which would not be valid in bash or zsh, is expanded
-**first** into the set of `+(a|b)` and `+(a|c)`, and those patterns are
-checked for validity. Since those two are valid, matching proceeds.
diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/minimatch.js b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/minimatch.js
deleted file mode 100644
index 45396789..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/minimatch.js
+++ /dev/null
@@ -1,1061 +0,0 @@
-;(function (require, exports, module, platform) {
-
-if (module) module.exports = minimatch
-else exports.minimatch = minimatch
-
-if (!require) {
- require = function (id) {
- switch (id) {
- case "sigmund": return function sigmund (obj) {
- return JSON.stringify(obj)
- }
- case "path": return { basename: function (f) {
- f = f.split(/[\/\\]/)
- var e = f.pop()
- if (!e) e = f.pop()
- return e
- }}
- case "lru-cache": return function LRUCache () {
- // not quite an LRU, but still space-limited.
- var cache = {}
- var cnt = 0
- this.set = function (k, v) {
- cnt ++
- if (cnt >= 100) cache = {}
- cache[k] = v
- }
- this.get = function (k) { return cache[k] }
- }
- }
- }
-}
-
-minimatch.Minimatch = Minimatch
-
-var LRU = require("lru-cache")
- , cache = minimatch.cache = new LRU({max: 100})
- , GLOBSTAR = minimatch.GLOBSTAR = Minimatch.GLOBSTAR = {}
- , sigmund = require("sigmund")
-
-var path = require("path")
- // any single thing other than /
- // don't need to escape / when using new RegExp()
- , qmark = "[^/]"
-
- // * => any number of characters
- , star = qmark + "*?"
-
- // ** when dots are allowed. Anything goes, except .. and .
- // not (^ or / followed by one or two dots followed by $ or /),
- // followed by anything, any number of times.
- , twoStarDot = "(?:(?!(?:\\\/|^)(?:\\.{1,2})($|\\\/)).)*?"
-
- // not a ^ or / followed by a dot,
- // followed by anything, any number of times.
- , twoStarNoDot = "(?:(?!(?:\\\/|^)\\.).)*?"
-
- // characters that need to be escaped in RegExp.
- , reSpecials = charSet("().*{}+?[]^$\\!")
-
-// "abc" -> { a:true, b:true, c:true }
-function charSet (s) {
- return s.split("").reduce(function (set, c) {
- set[c] = true
- return set
- }, {})
-}
-
-// normalizes slashes.
-var slashSplit = /\/+/
-
-minimatch.filter = filter
-function filter (pattern, options) {
- options = options || {}
- return function (p, i, list) {
- return minimatch(p, pattern, options)
- }
-}
-
-function ext (a, b) {
- a = a || {}
- b = b || {}
- var t = {}
- Object.keys(b).forEach(function (k) {
- t[k] = b[k]
- })
- Object.keys(a).forEach(function (k) {
- t[k] = a[k]
- })
- return t
-}
-
-minimatch.defaults = function (def) {
- if (!def || !Object.keys(def).length) return minimatch
-
- var orig = minimatch
-
- var m = function minimatch (p, pattern, options) {
- return orig.minimatch(p, pattern, ext(def, options))
- }
-
- m.Minimatch = function Minimatch (pattern, options) {
- return new orig.Minimatch(pattern, ext(def, options))
- }
-
- return m
-}
-
-Minimatch.defaults = function (def) {
- if (!def || !Object.keys(def).length) return Minimatch
- return minimatch.defaults(def).Minimatch
-}
-
-
-function minimatch (p, pattern, options) {
- if (typeof pattern !== "string") {
- throw new TypeError("glob pattern string required")
- }
-
- if (!options) options = {}
-
- // shortcut: comments match nothing.
- if (!options.nocomment && pattern.charAt(0) === "#") {
- return false
- }
-
- // "" only matches ""
- if (pattern.trim() === "") return p === ""
-
- return new Minimatch(pattern, options).match(p)
-}
-
-function Minimatch (pattern, options) {
- if (!(this instanceof Minimatch)) {
- return new Minimatch(pattern, options, cache)
- }
-
- if (typeof pattern !== "string") {
- throw new TypeError("glob pattern string required")
- }
-
- if (!options) options = {}
- pattern = pattern.trim()
-
- // windows: need to use /, not \
- // On other platforms, \ is a valid (albeit bad) filename char.
- if (platform === "win32") {
- pattern = pattern.split("\\").join("/")
- }
-
- // lru storage.
- // these things aren't particularly big, but walking down the string
- // and turning it into a regexp can get pretty costly.
- var cacheKey = pattern + "\n" + sigmund(options)
- var cached = minimatch.cache.get(cacheKey)
- if (cached) return cached
- minimatch.cache.set(cacheKey, this)
-
- this.options = options
- this.set = []
- this.pattern = pattern
- this.regexp = null
- this.negate = false
- this.comment = false
- this.empty = false
-
- // make the set of regexps etc.
- this.make()
-}
-
-Minimatch.prototype.debug = function() {}
-
-Minimatch.prototype.make = make
-function make () {
- // don't do it more than once.
- if (this._made) return
-
- var pattern = this.pattern
- var options = this.options
-
- // empty patterns and comments match nothing.
- if (!options.nocomment && pattern.charAt(0) === "#") {
- this.comment = true
- return
- }
- if (!pattern) {
- this.empty = true
- return
- }
-
- // step 1: figure out negation, etc.
- this.parseNegate()
-
- // step 2: expand braces
- var set = this.globSet = this.braceExpand()
-
- if (options.debug) this.debug = console.error
-
- this.debug(this.pattern, set)
-
- // step 3: now we have a set, so turn each one into a series of path-portion
- // matching patterns.
- // These will be regexps, except in the case of "**", which is
- // set to the GLOBSTAR object for globstar behavior,
- // and will not contain any / characters
- set = this.globParts = set.map(function (s) {
- return s.split(slashSplit)
- })
-
- this.debug(this.pattern, set)
-
- // glob --> regexps
- set = set.map(function (s, si, set) {
- return s.map(this.parse, this)
- }, this)
-
- this.debug(this.pattern, set)
-
- // filter out everything that didn't compile properly.
- set = set.filter(function (s) {
- return -1 === s.indexOf(false)
- })
-
- this.debug(this.pattern, set)
-
- this.set = set
-}
-
-Minimatch.prototype.parseNegate = parseNegate
-function parseNegate () {
- var pattern = this.pattern
- , negate = false
- , options = this.options
- , negateOffset = 0
-
- if (options.nonegate) return
-
- for ( var i = 0, l = pattern.length
- ; i < l && pattern.charAt(i) === "!"
- ; i ++) {
- negate = !negate
- negateOffset ++
- }
-
- if (negateOffset) this.pattern = pattern.substr(negateOffset)
- this.negate = negate
-}
-
-// Brace expansion:
-// a{b,c}d -> abd acd
-// a{b,}c -> abc ac
-// a{0..3}d -> a0d a1d a2d a3d
-// a{b,c{d,e}f}g -> abg acdfg acefg
-// a{b,c}d{e,f}g -> abdeg acdeg abdeg abdfg
-//
-// Invalid sets are not expanded.
-// a{2..}b -> a{2..}b
-// a{b}c -> a{b}c
-minimatch.braceExpand = function (pattern, options) {
- return new Minimatch(pattern, options).braceExpand()
-}
-
-Minimatch.prototype.braceExpand = braceExpand
-function braceExpand (pattern, options) {
- options = options || this.options
- pattern = typeof pattern === "undefined"
- ? this.pattern : pattern
-
- if (typeof pattern === "undefined") {
- throw new Error("undefined pattern")
- }
-
- if (options.nobrace ||
- !pattern.match(/\{.*\}/)) {
- // shortcut. no need to expand.
- return [pattern]
- }
-
- var escaping = false
-
- // examples and comments refer to this crazy pattern:
- // a{b,c{d,e},{f,g}h}x{y,z}
- // expected:
- // abxy
- // abxz
- // acdxy
- // acdxz
- // acexy
- // acexz
- // afhxy
- // afhxz
- // aghxy
- // aghxz
-
- // everything before the first \{ is just a prefix.
- // So, we pluck that off, and work with the rest,
- // and then prepend it to everything we find.
- if (pattern.charAt(0) !== "{") {
- this.debug(pattern)
- var prefix = null
- for (var i = 0, l = pattern.length; i < l; i ++) {
- var c = pattern.charAt(i)
- this.debug(i, c)
- if (c === "\\") {
- escaping = !escaping
- } else if (c === "{" && !escaping) {
- prefix = pattern.substr(0, i)
- break
- }
- }
-
- // actually no sets, all { were escaped.
- if (prefix === null) {
- this.debug("no sets")
- return [pattern]
- }
-
- var tail = braceExpand.call(this, pattern.substr(i), options)
- return tail.map(function (t) {
- return prefix + t
- })
- }
-
- // now we have something like:
- // {b,c{d,e},{f,g}h}x{y,z}
- // walk through the set, expanding each part, until
- // the set ends. then, we'll expand the suffix.
- // If the set only has a single member, then'll put the {} back
-
- // first, handle numeric sets, since they're easier
- var numset = pattern.match(/^\{(-?[0-9]+)\.\.(-?[0-9]+)\}/)
- if (numset) {
- this.debug("numset", numset[1], numset[2])
- var suf = braceExpand.call(this, pattern.substr(numset[0].length), options)
- , start = +numset[1]
- , end = +numset[2]
- , inc = start > end ? -1 : 1
- , set = []
- for (var i = start; i != (end + inc); i += inc) {
- // append all the suffixes
- for (var ii = 0, ll = suf.length; ii < ll; ii ++) {
- set.push(i + suf[ii])
- }
- }
- return set
- }
-
- // ok, walk through the set
- // We hope, somewhat optimistically, that there
- // will be a } at the end.
- // If the closing brace isn't found, then the pattern is
- // interpreted as braceExpand("\\" + pattern) so that
- // the leading \{ will be interpreted literally.
- var i = 1 // skip the \{
- , depth = 1
- , set = []
- , member = ""
- , sawEnd = false
- , escaping = false
-
- function addMember () {
- set.push(member)
- member = ""
- }
-
- this.debug("Entering for")
- FOR: for (i = 1, l = pattern.length; i < l; i ++) {
- var c = pattern.charAt(i)
- this.debug("", i, c)
-
- if (escaping) {
- escaping = false
- member += "\\" + c
- } else {
- switch (c) {
- case "\\":
- escaping = true
- continue
-
- case "{":
- depth ++
- member += "{"
- continue
-
- case "}":
- depth --
- // if this closes the actual set, then we're done
- if (depth === 0) {
- addMember()
- // pluck off the close-brace
- i ++
- break FOR
- } else {
- member += c
- continue
- }
-
- case ",":
- if (depth === 1) {
- addMember()
- } else {
- member += c
- }
- continue
-
- default:
- member += c
- continue
- } // switch
- } // else
- } // for
-
- // now we've either finished the set, and the suffix is
- // pattern.substr(i), or we have *not* closed the set,
- // and need to escape the leading brace
- if (depth !== 0) {
- this.debug("didn't close", pattern)
- return braceExpand.call(this, "\\" + pattern, options)
- }
-
- // x{y,z} -> ["xy", "xz"]
- this.debug("set", set)
- this.debug("suffix", pattern.substr(i))
- var suf = braceExpand.call(this, pattern.substr(i), options)
- // ["b", "c{d,e}","{f,g}h"] ->
- // [["b"], ["cd", "ce"], ["fh", "gh"]]
- var addBraces = set.length === 1
- this.debug("set pre-expanded", set)
- set = set.map(function (p) {
- return braceExpand.call(this, p, options)
- }, this)
- this.debug("set expanded", set)
-
-
- // [["b"], ["cd", "ce"], ["fh", "gh"]] ->
- // ["b", "cd", "ce", "fh", "gh"]
- set = set.reduce(function (l, r) {
- return l.concat(r)
- })
-
- if (addBraces) {
- set = set.map(function (s) {
- return "{" + s + "}"
- })
- }
-
- // now attach the suffixes.
- var ret = []
- for (var i = 0, l = set.length; i < l; i ++) {
- for (var ii = 0, ll = suf.length; ii < ll; ii ++) {
- ret.push(set[i] + suf[ii])
- }
- }
- return ret
-}
-
-// parse a component of the expanded set.
-// At this point, no pattern may contain "/" in it
-// so we're going to return a 2d array, where each entry is the full
-// pattern, split on '/', and then turned into a regular expression.
-// A regexp is made at the end which joins each array with an
-// escaped /, and another full one which joins each regexp with |.
-//
-// Following the lead of Bash 4.1, note that "**" only has special meaning
-// when it is the *only* thing in a path portion. Otherwise, any series
-// of * is equivalent to a single *. Globstar behavior is enabled by
-// default, and can be disabled by setting options.noglobstar.
-Minimatch.prototype.parse = parse
-var SUBPARSE = {}
-function parse (pattern, isSub) {
- var options = this.options
-
- // shortcuts
- if (!options.noglobstar && pattern === "**") return GLOBSTAR
- if (pattern === "") return ""
-
- var re = ""
- , hasMagic = !!options.nocase
- , escaping = false
- // ? => one single character
- , patternListStack = []
- , plType
- , stateChar
- , inClass = false
- , reClassStart = -1
- , classStart = -1
- // . and .. never match anything that doesn't start with .,
- // even when options.dot is set.
- , patternStart = pattern.charAt(0) === "." ? "" // anything
- // not (start or / followed by . or .. followed by / or end)
- : options.dot ? "(?!(?:^|\\\/)\\.{1,2}(?:$|\\\/))"
- : "(?!\\.)"
- , self = this
-
- function clearStateChar () {
- if (stateChar) {
- // we had some state-tracking character
- // that wasn't consumed by this pass.
- switch (stateChar) {
- case "*":
- re += star
- hasMagic = true
- break
- case "?":
- re += qmark
- hasMagic = true
- break
- default:
- re += "\\"+stateChar
- break
- }
- self.debug('clearStateChar %j %j', stateChar, re)
- stateChar = false
- }
- }
-
- for ( var i = 0, len = pattern.length, c
- ; (i < len) && (c = pattern.charAt(i))
- ; i ++ ) {
-
- this.debug("%s\t%s %s %j", pattern, i, re, c)
-
- // skip over any that are escaped.
- if (escaping && reSpecials[c]) {
- re += "\\" + c
- escaping = false
- continue
- }
-
- SWITCH: switch (c) {
- case "/":
- // completely not allowed, even escaped.
- // Should already be path-split by now.
- return false
-
- case "\\":
- clearStateChar()
- escaping = true
- continue
-
- // the various stateChar values
- // for the "extglob" stuff.
- case "?":
- case "*":
- case "+":
- case "@":
- case "!":
- this.debug("%s\t%s %s %j <-- stateChar", pattern, i, re, c)
-
- // all of those are literals inside a class, except that
- // the glob [!a] means [^a] in regexp
- if (inClass) {
- this.debug(' in class')
- if (c === "!" && i === classStart + 1) c = "^"
- re += c
- continue
- }
-
- // if we already have a stateChar, then it means
- // that there was something like ** or +? in there.
- // Handle the stateChar, then proceed with this one.
- self.debug('call clearStateChar %j', stateChar)
- clearStateChar()
- stateChar = c
- // if extglob is disabled, then +(asdf|foo) isn't a thing.
- // just clear the statechar *now*, rather than even diving into
- // the patternList stuff.
- if (options.noext) clearStateChar()
- continue
-
- case "(":
- if (inClass) {
- re += "("
- continue
- }
-
- if (!stateChar) {
- re += "\\("
- continue
- }
-
- plType = stateChar
- patternListStack.push({ type: plType
- , start: i - 1
- , reStart: re.length })
- // negation is (?:(?!js)[^/]*)
- re += stateChar === "!" ? "(?:(?!" : "(?:"
- this.debug('plType %j %j', stateChar, re)
- stateChar = false
- continue
-
- case ")":
- if (inClass || !patternListStack.length) {
- re += "\\)"
- continue
- }
-
- clearStateChar()
- hasMagic = true
- re += ")"
- plType = patternListStack.pop().type
- // negation is (?:(?!js)[^/]*)
- // The others are (?:)
- switch (plType) {
- case "!":
- re += "[^/]*?)"
- break
- case "?":
- case "+":
- case "*": re += plType
- case "@": break // the default anyway
- }
- continue
-
- case "|":
- if (inClass || !patternListStack.length || escaping) {
- re += "\\|"
- escaping = false
- continue
- }
-
- clearStateChar()
- re += "|"
- continue
-
- // these are mostly the same in regexp and glob
- case "[":
- // swallow any state-tracking char before the [
- clearStateChar()
-
- if (inClass) {
- re += "\\" + c
- continue
- }
-
- inClass = true
- classStart = i
- reClassStart = re.length
- re += c
- continue
-
- case "]":
- // a right bracket shall lose its special
- // meaning and represent itself in
- // a bracket expression if it occurs
- // first in the list. -- POSIX.2 2.8.3.2
- if (i === classStart + 1 || !inClass) {
- re += "\\" + c
- escaping = false
- continue
- }
-
- // finish up the class.
- hasMagic = true
- inClass = false
- re += c
- continue
-
- default:
- // swallow any state char that wasn't consumed
- clearStateChar()
-
- if (escaping) {
- // no need
- escaping = false
- } else if (reSpecials[c]
- && !(c === "^" && inClass)) {
- re += "\\"
- }
-
- re += c
-
- } // switch
- } // for
-
-
- // handle the case where we left a class open.
- // "[abc" is valid, equivalent to "\[abc"
- if (inClass) {
- // split where the last [ was, and escape it
- // this is a huge pita. We now have to re-walk
- // the contents of the would-be class to re-translate
- // any characters that were passed through as-is
- var cs = pattern.substr(classStart + 1)
- , sp = this.parse(cs, SUBPARSE)
- re = re.substr(0, reClassStart) + "\\[" + sp[0]
- hasMagic = hasMagic || sp[1]
- }
-
- // handle the case where we had a +( thing at the *end*
- // of the pattern.
- // each pattern list stack adds 3 chars, and we need to go through
- // and escape any | chars that were passed through as-is for the regexp.
- // Go through and escape them, taking care not to double-escape any
- // | chars that were already escaped.
- var pl
- while (pl = patternListStack.pop()) {
- var tail = re.slice(pl.reStart + 3)
- // maybe some even number of \, then maybe 1 \, followed by a |
- tail = tail.replace(/((?:\\{2})*)(\\?)\|/g, function (_, $1, $2) {
- if (!$2) {
- // the | isn't already escaped, so escape it.
- $2 = "\\"
- }
-
- // need to escape all those slashes *again*, without escaping the
- // one that we need for escaping the | character. As it works out,
- // escaping an even number of slashes can be done by simply repeating
- // it exactly after itself. That's why this trick works.
- //
- // I am sorry that you have to see this.
- return $1 + $1 + $2 + "|"
- })
-
- this.debug("tail=%j\n %s", tail, tail)
- var t = pl.type === "*" ? star
- : pl.type === "?" ? qmark
- : "\\" + pl.type
-
- hasMagic = true
- re = re.slice(0, pl.reStart)
- + t + "\\("
- + tail
- }
-
- // handle trailing things that only matter at the very end.
- clearStateChar()
- if (escaping) {
- // trailing \\
- re += "\\\\"
- }
-
- // only need to apply the nodot start if the re starts with
- // something that could conceivably capture a dot
- var addPatternStart = false
- switch (re.charAt(0)) {
- case ".":
- case "[":
- case "(": addPatternStart = true
- }
-
- // if the re is not "" at this point, then we need to make sure
- // it doesn't match against an empty path part.
- // Otherwise a/* will match a/, which it should not.
- if (re !== "" && hasMagic) re = "(?=.)" + re
-
- if (addPatternStart) re = patternStart + re
-
- // parsing just a piece of a larger pattern.
- if (isSub === SUBPARSE) {
- return [ re, hasMagic ]
- }
-
- // skip the regexp for non-magical patterns
- // unescape anything in it, though, so that it'll be
- // an exact match against a file etc.
- if (!hasMagic) {
- return globUnescape(pattern)
- }
-
- var flags = options.nocase ? "i" : ""
- , regExp = new RegExp("^" + re + "$", flags)
-
- regExp._glob = pattern
- regExp._src = re
-
- return regExp
-}
-
-minimatch.makeRe = function (pattern, options) {
- return new Minimatch(pattern, options || {}).makeRe()
-}
-
-Minimatch.prototype.makeRe = makeRe
-function makeRe () {
- if (this.regexp || this.regexp === false) return this.regexp
-
- // at this point, this.set is a 2d array of partial
- // pattern strings, or "**".
- //
- // It's better to use .match(). This function shouldn't
- // be used, really, but it's pretty convenient sometimes,
- // when you just want to work with a regex.
- var set = this.set
-
- if (!set.length) return this.regexp = false
- var options = this.options
-
- var twoStar = options.noglobstar ? star
- : options.dot ? twoStarDot
- : twoStarNoDot
- , flags = options.nocase ? "i" : ""
-
- var re = set.map(function (pattern) {
- return pattern.map(function (p) {
- return (p === GLOBSTAR) ? twoStar
- : (typeof p === "string") ? regExpEscape(p)
- : p._src
- }).join("\\\/")
- }).join("|")
-
- // must match entire pattern
- // ending in a * or ** will make it less strict.
- re = "^(?:" + re + ")$"
-
- // can match anything, as long as it's not this.
- if (this.negate) re = "^(?!" + re + ").*$"
-
- try {
- return this.regexp = new RegExp(re, flags)
- } catch (ex) {
- return this.regexp = false
- }
-}
-
-minimatch.match = function (list, pattern, options) {
- options = options || {}
- var mm = new Minimatch(pattern, options)
- list = list.filter(function (f) {
- return mm.match(f)
- })
- if (mm.options.nonull && !list.length) {
- list.push(pattern)
- }
- return list
-}
-
-Minimatch.prototype.match = match
-function match (f, partial) {
- this.debug("match", f, this.pattern)
- // short-circuit in the case of busted things.
- // comments, etc.
- if (this.comment) return false
- if (this.empty) return f === ""
-
- if (f === "/" && partial) return true
-
- var options = this.options
-
- // windows: need to use /, not \
- // On other platforms, \ is a valid (albeit bad) filename char.
- if (platform === "win32") {
- f = f.split("\\").join("/")
- }
-
- // treat the test path as a set of pathparts.
- f = f.split(slashSplit)
- this.debug(this.pattern, "split", f)
-
- // just ONE of the pattern sets in this.set needs to match
- // in order for it to be valid. If negating, then just one
- // match means that we have failed.
- // Either way, return on the first hit.
-
- var set = this.set
- this.debug(this.pattern, "set", set)
-
- // Find the basename of the path by looking for the last non-empty segment
- var filename;
- for (var i = f.length - 1; i >= 0; i--) {
- filename = f[i]
- if (filename) break
- }
-
- for (var i = 0, l = set.length; i < l; i ++) {
- var pattern = set[i], file = f
- if (options.matchBase && pattern.length === 1) {
- file = [filename]
- }
- var hit = this.matchOne(file, pattern, partial)
- if (hit) {
- if (options.flipNegate) return true
- return !this.negate
- }
- }
-
- // didn't get any hits. this is success if it's a negative
- // pattern, failure otherwise.
- if (options.flipNegate) return false
- return this.negate
-}
-
-// set partial to true to test if, for example,
-// "/a/b" matches the start of "/*/b/*/d"
-// Partial means, if you run out of file before you run
-// out of pattern, then that's fine, as long as all
-// the parts match.
-Minimatch.prototype.matchOne = function (file, pattern, partial) {
- var options = this.options
-
- this.debug("matchOne",
- { "this": this
- , file: file
- , pattern: pattern })
-
- this.debug("matchOne", file.length, pattern.length)
-
- for ( var fi = 0
- , pi = 0
- , fl = file.length
- , pl = pattern.length
- ; (fi < fl) && (pi < pl)
- ; fi ++, pi ++ ) {
-
- this.debug("matchOne loop")
- var p = pattern[pi]
- , f = file[fi]
-
- this.debug(pattern, p, f)
-
- // should be impossible.
- // some invalid regexp stuff in the set.
- if (p === false) return false
-
- if (p === GLOBSTAR) {
- this.debug('GLOBSTAR', [pattern, p, f])
-
- // "**"
- // a/**/b/**/c would match the following:
- // a/b/x/y/z/c
- // a/x/y/z/b/c
- // a/b/x/b/x/c
- // a/b/c
- // To do this, take the rest of the pattern after
- // the **, and see if it would match the file remainder.
- // If so, return success.
- // If not, the ** "swallows" a segment, and try again.
- // This is recursively awful.
- //
- // a/**/b/**/c matching a/b/x/y/z/c
- // - a matches a
- // - doublestar
- // - matchOne(b/x/y/z/c, b/**/c)
- // - b matches b
- // - doublestar
- // - matchOne(x/y/z/c, c) -> no
- // - matchOne(y/z/c, c) -> no
- // - matchOne(z/c, c) -> no
- // - matchOne(c, c) yes, hit
- var fr = fi
- , pr = pi + 1
- if (pr === pl) {
- this.debug('** at the end')
- // a ** at the end will just swallow the rest.
- // We have found a match.
- // however, it will not swallow /.x, unless
- // options.dot is set.
- // . and .. are *never* matched by **, for explosively
- // exponential reasons.
- for ( ; fi < fl; fi ++) {
- if (file[fi] === "." || file[fi] === ".." ||
- (!options.dot && file[fi].charAt(0) === ".")) return false
- }
- return true
- }
-
- // ok, let's see if we can swallow whatever we can.
- WHILE: while (fr < fl) {
- var swallowee = file[fr]
-
- this.debug('\nglobstar while',
- file, fr, pattern, pr, swallowee)
-
- // XXX remove this slice. Just pass the start index.
- if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) {
- this.debug('globstar found match!', fr, fl, swallowee)
- // found a match.
- return true
- } else {
- // can't swallow "." or ".." ever.
- // can only swallow ".foo" when explicitly asked.
- if (swallowee === "." || swallowee === ".." ||
- (!options.dot && swallowee.charAt(0) === ".")) {
- this.debug("dot detected!", file, fr, pattern, pr)
- break WHILE
- }
-
- // ** swallows a segment, and continue.
- this.debug('globstar swallow a segment, and continue')
- fr ++
- }
- }
- // no match was found.
- // However, in partial mode, we can't say this is necessarily over.
- // If there's more *pattern* left, then
- if (partial) {
- // ran out of file
- this.debug("\n>>> no match, partial?", file, fr, pattern, pr)
- if (fr === fl) return true
- }
- return false
- }
-
- // something other than **
- // non-magic patterns just have to match exactly
- // patterns with magic have been turned into regexps.
- var hit
- if (typeof p === "string") {
- if (options.nocase) {
- hit = f.toLowerCase() === p.toLowerCase()
- } else {
- hit = f === p
- }
- this.debug("string match", p, f, hit)
- } else {
- hit = f.match(p)
- this.debug("pattern match", p, f, hit)
- }
-
- if (!hit) return false
- }
-
- // Note: ending in / means that we'll get a final ""
- // at the end of the pattern. This can only match a
- // corresponding "" at the end of the file.
- // If the file ends in /, then it can only match a
- // a pattern that ends in /, unless the pattern just
- // doesn't have any more for it. But, a/b/ should *not*
- // match "a/b/*", even though "" matches against the
- // [^/]*? pattern, except in partial mode, where it might
- // simply not be reached yet.
- // However, a/b/ should still satisfy a/*
-
- // now either we fell off the end of the pattern, or we're done.
- if (fi === fl && pi === pl) {
- // ran out of pattern and filename at the same time.
- // an exact hit!
- return true
- } else if (fi === fl) {
- // ran out of file, but still had pattern left.
- // this is ok if we're doing the match as part of
- // a glob fs traversal.
- return partial
- } else if (pi === pl) {
- // ran out of pattern, still have file left.
- // this is only acceptable if we're on the very last
- // empty segment of a file with a trailing slash.
- // a/* should match a/b/
- var emptyFileEnd = (fi === fl - 1) && (file[fi] === "")
- return emptyFileEnd
- }
-
- // should be unreachable.
- throw new Error("wtf?")
-}
-
-
-// replace stuff like \* with *
-function globUnescape (s) {
- return s.replace(/\\(.)/g, "$1")
-}
-
-
-function regExpEscape (s) {
- return s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&")
-}
-
-})( typeof require === "function" ? require : null,
- this,
- typeof module === "object" ? module : null,
- typeof process === "object" ? process.platform : "win32"
- )
diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/.npmignore b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/.npmignore
deleted file mode 100644
index 07e6e472..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/.npmignore
+++ /dev/null
@@ -1 +0,0 @@
-/node_modules
diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/CONTRIBUTORS b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/CONTRIBUTORS
deleted file mode 100644
index 4a0bc503..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/CONTRIBUTORS
+++ /dev/null
@@ -1,14 +0,0 @@
-# Authors, sorted by whether or not they are me
-Isaac Z. Schlueter
-Brian Cottingham
-Carlos Brito Lage
-Jesse Dailey
-Kevin O'Hara
-Marco Rogers
-Mark Cavage
-Marko Mikulicic
-Nathan Rajlich
-Satheesh Natesan
-Trent Mick
-ashleybrener
-n4kz
diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/LICENSE b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/LICENSE
deleted file mode 100644
index 05a40109..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/LICENSE
+++ /dev/null
@@ -1,23 +0,0 @@
-Copyright 2009, 2010, 2011 Isaac Z. Schlueter.
-All rights reserved.
-
-Permission is hereby granted, free of charge, to any person
-obtaining a copy of this software and associated documentation
-files (the "Software"), to deal in the Software without
-restriction, including without limitation the rights to use,
-copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the
-Software is furnished to do so, subject to the following
-conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-OTHER DEALINGS IN THE SOFTWARE.
diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/README.md b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/README.md
deleted file mode 100644
index 03ee0f98..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/README.md
+++ /dev/null
@@ -1,97 +0,0 @@
-# lru cache
-
-A cache object that deletes the least-recently-used items.
-
-## Usage:
-
-```javascript
-var LRU = require("lru-cache")
- , options = { max: 500
- , length: function (n) { return n * 2 }
- , dispose: function (key, n) { n.close() }
- , maxAge: 1000 * 60 * 60 }
- , cache = LRU(options)
- , otherCache = LRU(50) // sets just the max size
-
-cache.set("key", "value")
-cache.get("key") // "value"
-
-cache.reset() // empty the cache
-```
-
-If you put more stuff in it, then items will fall out.
-
-If you try to put an oversized thing in it, then it'll fall out right
-away.
-
-## Options
-
-* `max` The maximum size of the cache, checked by applying the length
- function to all values in the cache. Not setting this is kind of
- silly, since that's the whole purpose of this lib, but it defaults
- to `Infinity`.
-* `maxAge` Maximum age in ms. Items are not pro-actively pruned out
- as they age, but if you try to get an item that is too old, it'll
- drop it and return undefined instead of giving it to you.
-* `length` Function that is used to calculate the length of stored
- items. If you're storing strings or buffers, then you probably want
- to do something like `function(n){return n.length}`. The default is
- `function(n){return 1}`, which is fine if you want to store `n`
- like-sized things.
-* `dispose` Function that is called on items when they are dropped
- from the cache. This can be handy if you want to close file
- descriptors or do other cleanup tasks when items are no longer
- accessible. Called with `key, value`. It's called *before*
- actually removing the item from the internal cache, so if you want
- to immediately put it back in, you'll have to do that in a
- `nextTick` or `setTimeout` callback or it won't do anything.
-* `stale` By default, if you set a `maxAge`, it'll only actually pull
- stale items out of the cache when you `get(key)`. (That is, it's
- not pre-emptively doing a `setTimeout` or anything.) If you set
- `stale:true`, it'll return the stale value before deleting it. If
- you don't set this, then it'll return `undefined` when you try to
- get a stale entry, as if it had already been deleted.
-
-## API
-
-* `set(key, value)`
-* `get(key) => value`
-
- Both of these will update the "recently used"-ness of the key.
- They do what you think.
-
-* `peek(key)`
-
- Returns the key value (or `undefined` if not found) without
- updating the "recently used"-ness of the key.
-
- (If you find yourself using this a lot, you *might* be using the
- wrong sort of data structure, but there are some use cases where
- it's handy.)
-
-* `del(key)`
-
- Deletes a key out of the cache.
-
-* `reset()`
-
- Clear the cache entirely, throwing away all values.
-
-* `has(key)`
-
- Check if a key is in the cache, without updating the recent-ness
- or deleting it for being stale.
-
-* `forEach(function(value,key,cache), [thisp])`
-
- Just like `Array.prototype.forEach`. Iterates over all the keys
- in the cache, in order of recent-ness. (Ie, more recently used
- items are iterated over first.)
-
-* `keys()`
-
- Return an array of the keys in the cache.
-
-* `values()`
-
- Return an array of the values in the cache.
diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/lib/lru-cache.js b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/lib/lru-cache.js
deleted file mode 100644
index d1d13817..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/lib/lru-cache.js
+++ /dev/null
@@ -1,252 +0,0 @@
-;(function () { // closure for web browsers
-
-if (typeof module === 'object' && module.exports) {
- module.exports = LRUCache
-} else {
- // just set the global for non-node platforms.
- this.LRUCache = LRUCache
-}
-
-function hOP (obj, key) {
- return Object.prototype.hasOwnProperty.call(obj, key)
-}
-
-function naiveLength () { return 1 }
-
-function LRUCache (options) {
- if (!(this instanceof LRUCache))
- return new LRUCache(options)
-
- if (typeof options === 'number')
- options = { max: options }
-
- if (!options)
- options = {}
-
- this._max = options.max
- // Kind of weird to have a default max of Infinity, but oh well.
- if (!this._max || !(typeof this._max === "number") || this._max <= 0 )
- this._max = Infinity
-
- this._lengthCalculator = options.length || naiveLength
- if (typeof this._lengthCalculator !== "function")
- this._lengthCalculator = naiveLength
-
- this._allowStale = options.stale || false
- this._maxAge = options.maxAge || null
- this._dispose = options.dispose
- this.reset()
-}
-
-// resize the cache when the max changes.
-Object.defineProperty(LRUCache.prototype, "max",
- { set : function (mL) {
- if (!mL || !(typeof mL === "number") || mL <= 0 ) mL = Infinity
- this._max = mL
- if (this._length > this._max) trim(this)
- }
- , get : function () { return this._max }
- , enumerable : true
- })
-
-// resize the cache when the lengthCalculator changes.
-Object.defineProperty(LRUCache.prototype, "lengthCalculator",
- { set : function (lC) {
- if (typeof lC !== "function") {
- this._lengthCalculator = naiveLength
- this._length = this._itemCount
- for (var key in this._cache) {
- this._cache[key].length = 1
- }
- } else {
- this._lengthCalculator = lC
- this._length = 0
- for (var key in this._cache) {
- this._cache[key].length = this._lengthCalculator(this._cache[key].value)
- this._length += this._cache[key].length
- }
- }
-
- if (this._length > this._max) trim(this)
- }
- , get : function () { return this._lengthCalculator }
- , enumerable : true
- })
-
-Object.defineProperty(LRUCache.prototype, "length",
- { get : function () { return this._length }
- , enumerable : true
- })
-
-
-Object.defineProperty(LRUCache.prototype, "itemCount",
- { get : function () { return this._itemCount }
- , enumerable : true
- })
-
-LRUCache.prototype.forEach = function (fn, thisp) {
- thisp = thisp || this
- var i = 0;
- for (var k = this._mru - 1; k >= 0 && i < this._itemCount; k--) if (this._lruList[k]) {
- i++
- var hit = this._lruList[k]
- if (this._maxAge && (Date.now() - hit.now > this._maxAge)) {
- del(this, hit)
- if (!this._allowStale) hit = undefined
- }
- if (hit) {
- fn.call(thisp, hit.value, hit.key, this)
- }
- }
-}
-
-LRUCache.prototype.keys = function () {
- var keys = new Array(this._itemCount)
- var i = 0
- for (var k = this._mru - 1; k >= 0 && i < this._itemCount; k--) if (this._lruList[k]) {
- var hit = this._lruList[k]
- keys[i++] = hit.key
- }
- return keys
-}
-
-LRUCache.prototype.values = function () {
- var values = new Array(this._itemCount)
- var i = 0
- for (var k = this._mru - 1; k >= 0 && i < this._itemCount; k--) if (this._lruList[k]) {
- var hit = this._lruList[k]
- values[i++] = hit.value
- }
- return values
-}
-
-LRUCache.prototype.reset = function () {
- if (this._dispose && this._cache) {
- for (var k in this._cache) {
- this._dispose(k, this._cache[k].value)
- }
- }
-
- this._cache = Object.create(null) // hash of items by key
- this._lruList = Object.create(null) // list of items in order of use recency
- this._mru = 0 // most recently used
- this._lru = 0 // least recently used
- this._length = 0 // number of items in the list
- this._itemCount = 0
-}
-
-// Provided for debugging/dev purposes only. No promises whatsoever that
-// this API stays stable.
-LRUCache.prototype.dump = function () {
- return this._cache
-}
-
-LRUCache.prototype.dumpLru = function () {
- return this._lruList
-}
-
-LRUCache.prototype.set = function (key, value) {
- if (hOP(this._cache, key)) {
- // dispose of the old one before overwriting
- if (this._dispose) this._dispose(key, this._cache[key].value)
- if (this._maxAge) this._cache[key].now = Date.now()
- this._cache[key].value = value
- this.get(key)
- return true
- }
-
- var len = this._lengthCalculator(value)
- var age = this._maxAge ? Date.now() : 0
- var hit = new Entry(key, value, this._mru++, len, age)
-
- // oversized objects fall out of cache automatically.
- if (hit.length > this._max) {
- if (this._dispose) this._dispose(key, value)
- return false
- }
-
- this._length += hit.length
- this._lruList[hit.lu] = this._cache[key] = hit
- this._itemCount ++
-
- if (this._length > this._max) trim(this)
- return true
-}
-
-LRUCache.prototype.has = function (key) {
- if (!hOP(this._cache, key)) return false
- var hit = this._cache[key]
- if (this._maxAge && (Date.now() - hit.now > this._maxAge)) {
- return false
- }
- return true
-}
-
-LRUCache.prototype.get = function (key) {
- return get(this, key, true)
-}
-
-LRUCache.prototype.peek = function (key) {
- return get(this, key, false)
-}
-
-LRUCache.prototype.pop = function () {
- var hit = this._lruList[this._lru]
- del(this, hit)
- return hit || null
-}
-
-LRUCache.prototype.del = function (key) {
- del(this, this._cache[key])
-}
-
-function get (self, key, doUse) {
- var hit = self._cache[key]
- if (hit) {
- if (self._maxAge && (Date.now() - hit.now > self._maxAge)) {
- del(self, hit)
- if (!self._allowStale) hit = undefined
- } else {
- if (doUse) use(self, hit)
- }
- if (hit) hit = hit.value
- }
- return hit
-}
-
-function use (self, hit) {
- shiftLU(self, hit)
- hit.lu = self._mru ++
- self._lruList[hit.lu] = hit
-}
-
-function trim (self) {
- while (self._lru < self._mru && self._length > self._max)
- del(self, self._lruList[self._lru])
-}
-
-function shiftLU (self, hit) {
- delete self._lruList[ hit.lu ]
- while (self._lru < self._mru && !self._lruList[self._lru]) self._lru ++
-}
-
-function del (self, hit) {
- if (hit) {
- if (self._dispose) self._dispose(hit.key, hit.value)
- self._length -= hit.length
- self._itemCount --
- delete self._cache[ hit.key ]
- shiftLU(self, hit)
- }
-}
-
-// classy, since V8 prefers predictable objects.
-function Entry (key, value, lu, length, now) {
- this.key = key
- this.value = value
- this.lu = lu
- this.length = length
- this.now = now
-}
-
-})()
diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/package.json b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/package.json
deleted file mode 100644
index 2474729b..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/package.json
+++ /dev/null
@@ -1,50 +0,0 @@
-{
- "name": "lru-cache",
- "description": "A cache object that deletes the least-recently-used items.",
- "version": "2.5.0",
- "author": {
- "name": "Isaac Z. Schlueter",
- "email": "i@izs.me"
- },
- "scripts": {
- "test": "tap test --gc"
- },
- "main": "lib/lru-cache.js",
- "repository": {
- "type": "git",
- "url": "git://github.com/isaacs/node-lru-cache.git"
- },
- "devDependencies": {
- "tap": "",
- "weak": ""
- },
- "license": {
- "type": "MIT",
- "url": "http://github.com/isaacs/node-lru-cache/raw/master/LICENSE"
- },
- "bugs": {
- "url": "https://github.com/isaacs/node-lru-cache/issues"
- },
- "homepage": "https://github.com/isaacs/node-lru-cache",
- "_id": "lru-cache@2.5.0",
- "dist": {
- "shasum": "d82388ae9c960becbea0c73bb9eb79b6c6ce9aeb",
- "tarball": "http://registry.npmjs.org/lru-cache/-/lru-cache-2.5.0.tgz"
- },
- "_from": "lru-cache@2",
- "_npmVersion": "1.3.15",
- "_npmUser": {
- "name": "isaacs",
- "email": "i@izs.me"
- },
- "maintainers": [
- {
- "name": "isaacs",
- "email": "i@izs.me"
- }
- ],
- "directories": {},
- "_shasum": "d82388ae9c960becbea0c73bb9eb79b6c6ce9aeb",
- "_resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.5.0.tgz",
- "readme": "ERROR: No README data found!"
-}
diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/test/basic.js b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/test/basic.js
deleted file mode 100644
index f72697c4..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/test/basic.js
+++ /dev/null
@@ -1,369 +0,0 @@
-var test = require("tap").test
- , LRU = require("../")
-
-test("basic", function (t) {
- var cache = new LRU({max: 10})
- cache.set("key", "value")
- t.equal(cache.get("key"), "value")
- t.equal(cache.get("nada"), undefined)
- t.equal(cache.length, 1)
- t.equal(cache.max, 10)
- t.end()
-})
-
-test("least recently set", function (t) {
- var cache = new LRU(2)
- cache.set("a", "A")
- cache.set("b", "B")
- cache.set("c", "C")
- t.equal(cache.get("c"), "C")
- t.equal(cache.get("b"), "B")
- t.equal(cache.get("a"), undefined)
- t.end()
-})
-
-test("lru recently gotten", function (t) {
- var cache = new LRU(2)
- cache.set("a", "A")
- cache.set("b", "B")
- cache.get("a")
- cache.set("c", "C")
- t.equal(cache.get("c"), "C")
- t.equal(cache.get("b"), undefined)
- t.equal(cache.get("a"), "A")
- t.end()
-})
-
-test("del", function (t) {
- var cache = new LRU(2)
- cache.set("a", "A")
- cache.del("a")
- t.equal(cache.get("a"), undefined)
- t.end()
-})
-
-test("max", function (t) {
- var cache = new LRU(3)
-
- // test changing the max, verify that the LRU items get dropped.
- cache.max = 100
- for (var i = 0; i < 100; i ++) cache.set(i, i)
- t.equal(cache.length, 100)
- for (var i = 0; i < 100; i ++) {
- t.equal(cache.get(i), i)
- }
- cache.max = 3
- t.equal(cache.length, 3)
- for (var i = 0; i < 97; i ++) {
- t.equal(cache.get(i), undefined)
- }
- for (var i = 98; i < 100; i ++) {
- t.equal(cache.get(i), i)
- }
-
- // now remove the max restriction, and try again.
- cache.max = "hello"
- for (var i = 0; i < 100; i ++) cache.set(i, i)
- t.equal(cache.length, 100)
- for (var i = 0; i < 100; i ++) {
- t.equal(cache.get(i), i)
- }
- // should trigger an immediate resize
- cache.max = 3
- t.equal(cache.length, 3)
- for (var i = 0; i < 97; i ++) {
- t.equal(cache.get(i), undefined)
- }
- for (var i = 98; i < 100; i ++) {
- t.equal(cache.get(i), i)
- }
- t.end()
-})
-
-test("reset", function (t) {
- var cache = new LRU(10)
- cache.set("a", "A")
- cache.set("b", "B")
- cache.reset()
- t.equal(cache.length, 0)
- t.equal(cache.max, 10)
- t.equal(cache.get("a"), undefined)
- t.equal(cache.get("b"), undefined)
- t.end()
-})
-
-
-// Note: `.dump()` is a debugging tool only. No guarantees are made
-// about the format/layout of the response.
-test("dump", function (t) {
- var cache = new LRU(10)
- var d = cache.dump();
- t.equal(Object.keys(d).length, 0, "nothing in dump for empty cache")
- cache.set("a", "A")
- var d = cache.dump() // { a: { key: "a", value: "A", lu: 0 } }
- t.ok(d.a)
- t.equal(d.a.key, "a")
- t.equal(d.a.value, "A")
- t.equal(d.a.lu, 0)
-
- cache.set("b", "B")
- cache.get("b")
- d = cache.dump()
- t.ok(d.b)
- t.equal(d.b.key, "b")
- t.equal(d.b.value, "B")
- t.equal(d.b.lu, 2)
-
- t.end()
-})
-
-
-test("basic with weighed length", function (t) {
- var cache = new LRU({
- max: 100,
- length: function (item) { return item.size }
- })
- cache.set("key", {val: "value", size: 50})
- t.equal(cache.get("key").val, "value")
- t.equal(cache.get("nada"), undefined)
- t.equal(cache.lengthCalculator(cache.get("key")), 50)
- t.equal(cache.length, 50)
- t.equal(cache.max, 100)
- t.end()
-})
-
-
-test("weighed length item too large", function (t) {
- var cache = new LRU({
- max: 10,
- length: function (item) { return item.size }
- })
- t.equal(cache.max, 10)
-
- // should fall out immediately
- cache.set("key", {val: "value", size: 50})
-
- t.equal(cache.length, 0)
- t.equal(cache.get("key"), undefined)
- t.end()
-})
-
-test("least recently set with weighed length", function (t) {
- var cache = new LRU({
- max:8,
- length: function (item) { return item.length }
- })
- cache.set("a", "A")
- cache.set("b", "BB")
- cache.set("c", "CCC")
- cache.set("d", "DDDD")
- t.equal(cache.get("d"), "DDDD")
- t.equal(cache.get("c"), "CCC")
- t.equal(cache.get("b"), undefined)
- t.equal(cache.get("a"), undefined)
- t.end()
-})
-
-test("lru recently gotten with weighed length", function (t) {
- var cache = new LRU({
- max: 8,
- length: function (item) { return item.length }
- })
- cache.set("a", "A")
- cache.set("b", "BB")
- cache.set("c", "CCC")
- cache.get("a")
- cache.get("b")
- cache.set("d", "DDDD")
- t.equal(cache.get("c"), undefined)
- t.equal(cache.get("d"), "DDDD")
- t.equal(cache.get("b"), "BB")
- t.equal(cache.get("a"), "A")
- t.end()
-})
-
-test("set returns proper booleans", function(t) {
- var cache = new LRU({
- max: 5,
- length: function (item) { return item.length }
- })
-
- t.equal(cache.set("a", "A"), true)
-
- // should return false for max exceeded
- t.equal(cache.set("b", "donuts"), false)
-
- t.equal(cache.set("b", "B"), true)
- t.equal(cache.set("c", "CCCC"), true)
- t.end()
-})
-
-test("drop the old items", function(t) {
- var cache = new LRU({
- max: 5,
- maxAge: 50
- })
-
- cache.set("a", "A")
-
- setTimeout(function () {
- cache.set("b", "b")
- t.equal(cache.get("a"), "A")
- }, 25)
-
- setTimeout(function () {
- cache.set("c", "C")
- // timed out
- t.notOk(cache.get("a"))
- }, 60)
-
- setTimeout(function () {
- t.notOk(cache.get("b"))
- t.equal(cache.get("c"), "C")
- }, 90)
-
- setTimeout(function () {
- t.notOk(cache.get("c"))
- t.end()
- }, 155)
-})
-
-test("disposal function", function(t) {
- var disposed = false
- var cache = new LRU({
- max: 1,
- dispose: function (k, n) {
- disposed = n
- }
- })
-
- cache.set(1, 1)
- cache.set(2, 2)
- t.equal(disposed, 1)
- cache.set(3, 3)
- t.equal(disposed, 2)
- cache.reset()
- t.equal(disposed, 3)
- t.end()
-})
-
-test("disposal function on too big of item", function(t) {
- var disposed = false
- var cache = new LRU({
- max: 1,
- length: function (k) {
- return k.length
- },
- dispose: function (k, n) {
- disposed = n
- }
- })
- var obj = [ 1, 2 ]
-
- t.equal(disposed, false)
- cache.set("obj", obj)
- t.equal(disposed, obj)
- t.end()
-})
-
-test("has()", function(t) {
- var cache = new LRU({
- max: 1,
- maxAge: 10
- })
-
- cache.set('foo', 'bar')
- t.equal(cache.has('foo'), true)
- cache.set('blu', 'baz')
- t.equal(cache.has('foo'), false)
- t.equal(cache.has('blu'), true)
- setTimeout(function() {
- t.equal(cache.has('blu'), false)
- t.end()
- }, 15)
-})
-
-test("stale", function(t) {
- var cache = new LRU({
- maxAge: 10,
- stale: true
- })
-
- cache.set('foo', 'bar')
- t.equal(cache.get('foo'), 'bar')
- t.equal(cache.has('foo'), true)
- setTimeout(function() {
- t.equal(cache.has('foo'), false)
- t.equal(cache.get('foo'), 'bar')
- t.equal(cache.get('foo'), undefined)
- t.end()
- }, 15)
-})
-
-test("lru update via set", function(t) {
- var cache = LRU({ max: 2 });
-
- cache.set('foo', 1);
- cache.set('bar', 2);
- cache.del('bar');
- cache.set('baz', 3);
- cache.set('qux', 4);
-
- t.equal(cache.get('foo'), undefined)
- t.equal(cache.get('bar'), undefined)
- t.equal(cache.get('baz'), 3)
- t.equal(cache.get('qux'), 4)
- t.end()
-})
-
-test("least recently set w/ peek", function (t) {
- var cache = new LRU(2)
- cache.set("a", "A")
- cache.set("b", "B")
- t.equal(cache.peek("a"), "A")
- cache.set("c", "C")
- t.equal(cache.get("c"), "C")
- t.equal(cache.get("b"), "B")
- t.equal(cache.get("a"), undefined)
- t.end()
-})
-
-test("pop the least used item", function (t) {
- var cache = new LRU(3)
- , last
-
- cache.set("a", "A")
- cache.set("b", "B")
- cache.set("c", "C")
-
- t.equal(cache.length, 3)
- t.equal(cache.max, 3)
-
- // Ensure we pop a, c, b
- cache.get("b", "B")
-
- last = cache.pop()
- t.equal(last.key, "a")
- t.equal(last.value, "A")
- t.equal(cache.length, 2)
- t.equal(cache.max, 3)
-
- last = cache.pop()
- t.equal(last.key, "c")
- t.equal(last.value, "C")
- t.equal(cache.length, 1)
- t.equal(cache.max, 3)
-
- last = cache.pop()
- t.equal(last.key, "b")
- t.equal(last.value, "B")
- t.equal(cache.length, 0)
- t.equal(cache.max, 3)
-
- last = cache.pop()
- t.equal(last, null)
- t.equal(cache.length, 0)
- t.equal(cache.max, 3)
-
- t.end()
-})
diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/test/foreach.js b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/test/foreach.js
deleted file mode 100644
index eefb80d9..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/test/foreach.js
+++ /dev/null
@@ -1,52 +0,0 @@
-var test = require('tap').test
-var LRU = require('../')
-
-test('forEach', function (t) {
- var l = new LRU(5)
- for (var i = 0; i < 10; i ++) {
- l.set(i.toString(), i.toString(2))
- }
-
- var i = 9
- l.forEach(function (val, key, cache) {
- t.equal(cache, l)
- t.equal(key, i.toString())
- t.equal(val, i.toString(2))
- i -= 1
- })
-
- // get in order of most recently used
- l.get(6)
- l.get(8)
-
- var order = [ 8, 6, 9, 7, 5 ]
- var i = 0
-
- l.forEach(function (val, key, cache) {
- var j = order[i ++]
- t.equal(cache, l)
- t.equal(key, j.toString())
- t.equal(val, j.toString(2))
- })
-
- t.end()
-})
-
-test('keys() and values()', function (t) {
- var l = new LRU(5)
- for (var i = 0; i < 10; i ++) {
- l.set(i.toString(), i.toString(2))
- }
-
- t.similar(l.keys(), ['9', '8', '7', '6', '5'])
- t.similar(l.values(), ['1001', '1000', '111', '110', '101'])
-
- // get in order of most recently used
- l.get(6)
- l.get(8)
-
- t.similar(l.keys(), ['8', '6', '9', '7', '5'])
- t.similar(l.values(), ['1000', '110', '1001', '111', '101'])
-
- t.end()
-})
diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/test/memory-leak.js b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/test/memory-leak.js
deleted file mode 100644
index 7af45b02..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/test/memory-leak.js
+++ /dev/null
@@ -1,50 +0,0 @@
-#!/usr/bin/env node --expose_gc
-
-var weak = require('weak');
-var test = require('tap').test
-var LRU = require('../')
-var l = new LRU({ max: 10 })
-var refs = 0
-function X() {
- refs ++
- weak(this, deref)
-}
-
-function deref() {
- refs --
-}
-
-test('no leaks', function (t) {
- // fill up the cache
- for (var i = 0; i < 100; i++) {
- l.set(i, new X);
- // throw some gets in there, too.
- if (i % 2 === 0)
- l.get(i / 2)
- }
-
- gc()
-
- var start = process.memoryUsage()
-
- // capture the memory
- var startRefs = refs
-
- // do it again, but more
- for (var i = 0; i < 10000; i++) {
- l.set(i, new X);
- // throw some gets in there, too.
- if (i % 2 === 0)
- l.get(i / 2)
- }
-
- gc()
-
- var end = process.memoryUsage()
- t.equal(refs, startRefs, 'no leaky refs')
-
- console.error('start: %j\n' +
- 'end: %j', start, end);
- t.pass();
- t.end();
-})
diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/LICENSE b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/LICENSE
deleted file mode 100644
index 0c44ae71..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/LICENSE
+++ /dev/null
@@ -1,27 +0,0 @@
-Copyright (c) Isaac Z. Schlueter ("Author")
-All rights reserved.
-
-The BSD License
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
-2. 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.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 THE AUTHOR OR CONTRIBUTORS
-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.
diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/README.md b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/README.md
deleted file mode 100644
index 7e365129..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/README.md
+++ /dev/null
@@ -1,53 +0,0 @@
-# sigmund
-
-Quick and dirty signatures for Objects.
-
-This is like a much faster `deepEquals` comparison, which returns a
-string key suitable for caches and the like.
-
-## Usage
-
-```javascript
-function doSomething (someObj) {
- var key = sigmund(someObj, maxDepth) // max depth defaults to 10
- var cached = cache.get(key)
- if (cached) return cached)
-
- var result = expensiveCalculation(someObj)
- cache.set(key, result)
- return result
-}
-```
-
-The resulting key will be as unique and reproducible as calling
-`JSON.stringify` or `util.inspect` on the object, but is much faster.
-In order to achieve this speed, some differences are glossed over.
-For example, the object `{0:'foo'}` will be treated identically to the
-array `['foo']`.
-
-Also, just as there is no way to summon the soul from the scribblings
-of a cocain-addled psychoanalyst, there is no way to revive the object
-from the signature string that sigmund gives you. In fact, it's
-barely even readable.
-
-As with `sys.inspect` and `JSON.stringify`, larger objects will
-produce larger signature strings.
-
-Because sigmund is a bit less strict than the more thorough
-alternatives, the strings will be shorter, and also there is a
-slightly higher chance for collisions. For example, these objects
-have the same signature:
-
- var obj1 = {a:'b',c:/def/,g:['h','i',{j:'',k:'l'}]}
- var obj2 = {a:'b',c:'/def/',g:['h','i','{jkl']}
-
-Like a good Freudian, sigmund is most effective when you already have
-some understanding of what you're looking for. It can help you help
-yourself, but you must be willing to do some work as well.
-
-Cycles are handled, and cyclical objects are silently omitted (though
-the key is included in the signature output.)
-
-The second argument is the maximum depth, which defaults to 10,
-because that is the maximum object traversal depth covered by most
-insurance carriers.
diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/bench.js b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/bench.js
deleted file mode 100644
index 5acfd6d9..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/bench.js
+++ /dev/null
@@ -1,283 +0,0 @@
-// different ways to id objects
-// use a req/res pair, since it's crazy deep and cyclical
-
-// sparseFE10 and sigmund are usually pretty close, which is to be expected,
-// since they are essentially the same algorithm, except that sigmund handles
-// regular expression objects properly.
-
-
-var http = require('http')
-var util = require('util')
-var sigmund = require('./sigmund.js')
-var sreq, sres, creq, cres, test
-
-http.createServer(function (q, s) {
- sreq = q
- sres = s
- sres.end('ok')
- this.close(function () { setTimeout(function () {
- start()
- }, 200) })
-}).listen(1337, function () {
- creq = http.get({ port: 1337 })
- creq.on('response', function (s) { cres = s })
-})
-
-function start () {
- test = [sreq, sres, creq, cres]
- // test = sreq
- // sreq.sres = sres
- // sreq.creq = creq
- // sreq.cres = cres
-
- for (var i in exports.compare) {
- console.log(i)
- var hash = exports.compare[i]()
- console.log(hash)
- console.log(hash.length)
- console.log('')
- }
-
- require('bench').runMain()
-}
-
-function customWs (obj, md, d) {
- d = d || 0
- var to = typeof obj
- if (to === 'undefined' || to === 'function' || to === null) return ''
- if (d > md || !obj || to !== 'object') return ('' + obj).replace(/[\n ]+/g, '')
-
- if (Array.isArray(obj)) {
- return obj.map(function (i, _, __) {
- return customWs(i, md, d + 1)
- }).reduce(function (a, b) { return a + b }, '')
- }
-
- var keys = Object.keys(obj)
- return keys.map(function (k, _, __) {
- return k + ':' + customWs(obj[k], md, d + 1)
- }).reduce(function (a, b) { return a + b }, '')
-}
-
-function custom (obj, md, d) {
- d = d || 0
- var to = typeof obj
- if (to === 'undefined' || to === 'function' || to === null) return ''
- if (d > md || !obj || to !== 'object') return '' + obj
-
- if (Array.isArray(obj)) {
- return obj.map(function (i, _, __) {
- return custom(i, md, d + 1)
- }).reduce(function (a, b) { return a + b }, '')
- }
-
- var keys = Object.keys(obj)
- return keys.map(function (k, _, __) {
- return k + ':' + custom(obj[k], md, d + 1)
- }).reduce(function (a, b) { return a + b }, '')
-}
-
-function sparseFE2 (obj, maxDepth) {
- var seen = []
- var soFar = ''
- function ch (v, depth) {
- if (depth > maxDepth) return
- if (typeof v === 'function' || typeof v === 'undefined') return
- if (typeof v !== 'object' || !v) {
- soFar += v
- return
- }
- if (seen.indexOf(v) !== -1 || depth === maxDepth) return
- seen.push(v)
- soFar += '{'
- Object.keys(v).forEach(function (k, _, __) {
- // pseudo-private values. skip those.
- if (k.charAt(0) === '_') return
- var to = typeof v[k]
- if (to === 'function' || to === 'undefined') return
- soFar += k + ':'
- ch(v[k], depth + 1)
- })
- soFar += '}'
- }
- ch(obj, 0)
- return soFar
-}
-
-function sparseFE (obj, maxDepth) {
- var seen = []
- var soFar = ''
- function ch (v, depth) {
- if (depth > maxDepth) return
- if (typeof v === 'function' || typeof v === 'undefined') return
- if (typeof v !== 'object' || !v) {
- soFar += v
- return
- }
- if (seen.indexOf(v) !== -1 || depth === maxDepth) return
- seen.push(v)
- soFar += '{'
- Object.keys(v).forEach(function (k, _, __) {
- // pseudo-private values. skip those.
- if (k.charAt(0) === '_') return
- var to = typeof v[k]
- if (to === 'function' || to === 'undefined') return
- soFar += k
- ch(v[k], depth + 1)
- })
- }
- ch(obj, 0)
- return soFar
-}
-
-function sparse (obj, maxDepth) {
- var seen = []
- var soFar = ''
- function ch (v, depth) {
- if (depth > maxDepth) return
- if (typeof v === 'function' || typeof v === 'undefined') return
- if (typeof v !== 'object' || !v) {
- soFar += v
- return
- }
- if (seen.indexOf(v) !== -1 || depth === maxDepth) return
- seen.push(v)
- soFar += '{'
- for (var k in v) {
- // pseudo-private values. skip those.
- if (k.charAt(0) === '_') continue
- var to = typeof v[k]
- if (to === 'function' || to === 'undefined') continue
- soFar += k
- ch(v[k], depth + 1)
- }
- }
- ch(obj, 0)
- return soFar
-}
-
-function noCommas (obj, maxDepth) {
- var seen = []
- var soFar = ''
- function ch (v, depth) {
- if (depth > maxDepth) return
- if (typeof v === 'function' || typeof v === 'undefined') return
- if (typeof v !== 'object' || !v) {
- soFar += v
- return
- }
- if (seen.indexOf(v) !== -1 || depth === maxDepth) return
- seen.push(v)
- soFar += '{'
- for (var k in v) {
- // pseudo-private values. skip those.
- if (k.charAt(0) === '_') continue
- var to = typeof v[k]
- if (to === 'function' || to === 'undefined') continue
- soFar += k + ':'
- ch(v[k], depth + 1)
- }
- soFar += '}'
- }
- ch(obj, 0)
- return soFar
-}
-
-
-function flatten (obj, maxDepth) {
- var seen = []
- var soFar = ''
- function ch (v, depth) {
- if (depth > maxDepth) return
- if (typeof v === 'function' || typeof v === 'undefined') return
- if (typeof v !== 'object' || !v) {
- soFar += v
- return
- }
- if (seen.indexOf(v) !== -1 || depth === maxDepth) return
- seen.push(v)
- soFar += '{'
- for (var k in v) {
- // pseudo-private values. skip those.
- if (k.charAt(0) === '_') continue
- var to = typeof v[k]
- if (to === 'function' || to === 'undefined') continue
- soFar += k + ':'
- ch(v[k], depth + 1)
- soFar += ','
- }
- soFar += '}'
- }
- ch(obj, 0)
- return soFar
-}
-
-exports.compare =
-{
- // 'custom 2': function () {
- // return custom(test, 2, 0)
- // },
- // 'customWs 2': function () {
- // return customWs(test, 2, 0)
- // },
- 'JSON.stringify (guarded)': function () {
- var seen = []
- return JSON.stringify(test, function (k, v) {
- if (typeof v !== 'object' || !v) return v
- if (seen.indexOf(v) !== -1) return undefined
- seen.push(v)
- return v
- })
- },
-
- 'flatten 10': function () {
- return flatten(test, 10)
- },
-
- // 'flattenFE 10': function () {
- // return flattenFE(test, 10)
- // },
-
- 'noCommas 10': function () {
- return noCommas(test, 10)
- },
-
- 'sparse 10': function () {
- return sparse(test, 10)
- },
-
- 'sparseFE 10': function () {
- return sparseFE(test, 10)
- },
-
- 'sparseFE2 10': function () {
- return sparseFE2(test, 10)
- },
-
- sigmund: function() {
- return sigmund(test, 10)
- },
-
-
- // 'util.inspect 1': function () {
- // return util.inspect(test, false, 1, false)
- // },
- // 'util.inspect undefined': function () {
- // util.inspect(test)
- // },
- // 'util.inspect 2': function () {
- // util.inspect(test, false, 2, false)
- // },
- // 'util.inspect 3': function () {
- // util.inspect(test, false, 3, false)
- // },
- // 'util.inspect 4': function () {
- // util.inspect(test, false, 4, false)
- // },
- // 'util.inspect Infinity': function () {
- // util.inspect(test, false, Infinity, false)
- // }
-}
-
-/** results
-**/
diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/package.json b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/package.json
deleted file mode 100644
index a1f755a7..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/package.json
+++ /dev/null
@@ -1,58 +0,0 @@
-{
- "name": "sigmund",
- "version": "1.0.0",
- "description": "Quick and dirty signatures for Objects.",
- "main": "sigmund.js",
- "directories": {
- "test": "test"
- },
- "dependencies": {},
- "devDependencies": {
- "tap": "~0.3.0"
- },
- "scripts": {
- "test": "tap test/*.js",
- "bench": "node bench.js"
- },
- "repository": {
- "type": "git",
- "url": "git://github.com/isaacs/sigmund"
- },
- "keywords": [
- "object",
- "signature",
- "key",
- "data",
- "psychoanalysis"
- ],
- "author": {
- "name": "Isaac Z. Schlueter",
- "email": "i@izs.me",
- "url": "http://blog.izs.me/"
- },
- "license": "BSD",
- "readme": "# sigmund\n\nQuick and dirty signatures for Objects.\n\nThis is like a much faster `deepEquals` comparison, which returns a\nstring key suitable for caches and the like.\n\n## Usage\n\n```javascript\nfunction doSomething (someObj) {\n var key = sigmund(someObj, maxDepth) // max depth defaults to 10\n var cached = cache.get(key)\n if (cached) return cached)\n\n var result = expensiveCalculation(someObj)\n cache.set(key, result)\n return result\n}\n```\n\nThe resulting key will be as unique and reproducible as calling\n`JSON.stringify` or `util.inspect` on the object, but is much faster.\nIn order to achieve this speed, some differences are glossed over.\nFor example, the object `{0:'foo'}` will be treated identically to the\narray `['foo']`.\n\nAlso, just as there is no way to summon the soul from the scribblings\nof a cocain-addled psychoanalyst, there is no way to revive the object\nfrom the signature string that sigmund gives you. In fact, it's\nbarely even readable.\n\nAs with `sys.inspect` and `JSON.stringify`, larger objects will\nproduce larger signature strings.\n\nBecause sigmund is a bit less strict than the more thorough\nalternatives, the strings will be shorter, and also there is a\nslightly higher chance for collisions. For example, these objects\nhave the same signature:\n\n var obj1 = {a:'b',c:/def/,g:['h','i',{j:'',k:'l'}]}\n var obj2 = {a:'b',c:'/def/',g:['h','i','{jkl']}\n\nLike a good Freudian, sigmund is most effective when you already have\nsome understanding of what you're looking for. It can help you help\nyourself, but you must be willing to do some work as well.\n\nCycles are handled, and cyclical objects are silently omitted (though\nthe key is included in the signature output.)\n\nThe second argument is the maximum depth, which defaults to 10,\nbecause that is the maximum object traversal depth covered by most\ninsurance carriers.\n",
- "_id": "sigmund@1.0.0",
- "dist": {
- "shasum": "66a2b3a749ae8b5fb89efd4fcc01dc94fbe02296",
- "tarball": "http://registry.npmjs.org/sigmund/-/sigmund-1.0.0.tgz"
- },
- "_npmVersion": "1.1.48",
- "_npmUser": {
- "name": "isaacs",
- "email": "i@izs.me"
- },
- "maintainers": [
- {
- "name": "isaacs",
- "email": "i@izs.me"
- }
- ],
- "_shasum": "66a2b3a749ae8b5fb89efd4fcc01dc94fbe02296",
- "_from": "sigmund@~1.0.0",
- "_resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.0.tgz",
- "bugs": {
- "url": "https://github.com/isaacs/sigmund/issues"
- },
- "homepage": "https://github.com/isaacs/sigmund"
-}
diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/sigmund.js b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/sigmund.js
deleted file mode 100644
index 82c7ab8c..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/sigmund.js
+++ /dev/null
@@ -1,39 +0,0 @@
-module.exports = sigmund
-function sigmund (subject, maxSessions) {
- maxSessions = maxSessions || 10;
- var notes = [];
- var analysis = '';
- var RE = RegExp;
-
- function psychoAnalyze (subject, session) {
- if (session > maxSessions) return;
-
- if (typeof subject === 'function' ||
- typeof subject === 'undefined') {
- return;
- }
-
- if (typeof subject !== 'object' || !subject ||
- (subject instanceof RE)) {
- analysis += subject;
- return;
- }
-
- if (notes.indexOf(subject) !== -1 || session === maxSessions) return;
-
- notes.push(subject);
- analysis += '{';
- Object.keys(subject).forEach(function (issue, _, __) {
- // pseudo-private values. skip those.
- if (issue.charAt(0) === '_') return;
- var to = typeof subject[issue];
- if (to === 'function' || to === 'undefined') return;
- analysis += issue;
- psychoAnalyze(subject[issue], session + 1);
- });
- }
- psychoAnalyze(subject, 0);
- return analysis;
-}
-
-// vim: set softtabstop=4 shiftwidth=4:
diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/test/basic.js b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/test/basic.js
deleted file mode 100644
index 50c53a13..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/test/basic.js
+++ /dev/null
@@ -1,24 +0,0 @@
-var test = require('tap').test
-var sigmund = require('../sigmund.js')
-
-
-// occasionally there are duplicates
-// that's an acceptable edge-case. JSON.stringify and util.inspect
-// have some collision potential as well, though less, and collision
-// detection is expensive.
-var hash = '{abc/def/g{0h1i2{jkl'
-var obj1 = {a:'b',c:/def/,g:['h','i',{j:'',k:'l'}]}
-var obj2 = {a:'b',c:'/def/',g:['h','i','{jkl']}
-
-var obj3 = JSON.parse(JSON.stringify(obj1))
-obj3.c = /def/
-obj3.g[2].cycle = obj3
-var cycleHash = '{abc/def/g{0h1i2{jklcycle'
-
-test('basic', function (t) {
- t.equal(sigmund(obj1), hash)
- t.equal(sigmund(obj2), hash)
- t.equal(sigmund(obj3), cycleHash)
- t.end()
-})
-
diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/package.json b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/package.json
deleted file mode 100644
index 0fe147d6..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/package.json
+++ /dev/null
@@ -1,57 +0,0 @@
-{
- "author": {
- "name": "Isaac Z. Schlueter",
- "email": "i@izs.me",
- "url": "http://blog.izs.me"
- },
- "name": "minimatch",
- "description": "a glob matcher in javascript",
- "version": "0.3.0",
- "repository": {
- "type": "git",
- "url": "git://github.com/isaacs/minimatch.git"
- },
- "main": "minimatch.js",
- "scripts": {
- "test": "tap test/*.js"
- },
- "engines": {
- "node": "*"
- },
- "dependencies": {
- "lru-cache": "2",
- "sigmund": "~1.0.0"
- },
- "devDependencies": {
- "tap": ""
- },
- "license": {
- "type": "MIT",
- "url": "http://github.com/isaacs/minimatch/raw/master/LICENSE"
- },
- "bugs": {
- "url": "https://github.com/isaacs/minimatch/issues"
- },
- "homepage": "https://github.com/isaacs/minimatch",
- "_id": "minimatch@0.3.0",
- "_shasum": "275d8edaac4f1bb3326472089e7949c8394699dd",
- "_from": "minimatch@0.3",
- "_npmVersion": "1.4.10",
- "_npmUser": {
- "name": "isaacs",
- "email": "i@izs.me"
- },
- "maintainers": [
- {
- "name": "isaacs",
- "email": "i@izs.me"
- }
- ],
- "dist": {
- "shasum": "275d8edaac4f1bb3326472089e7949c8394699dd",
- "tarball": "http://registry.npmjs.org/minimatch/-/minimatch-0.3.0.tgz"
- },
- "directories": {},
- "_resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.3.0.tgz",
- "readme": "ERROR: No README data found!"
-}
diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/basic.js b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/basic.js
deleted file mode 100644
index ae7ac73c..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/basic.js
+++ /dev/null
@@ -1,399 +0,0 @@
-// http://www.bashcookbook.com/bashinfo/source/bash-1.14.7/tests/glob-test
-//
-// TODO: Some of these tests do very bad things with backslashes, and will
-// most likely fail badly on windows. They should probably be skipped.
-
-var tap = require("tap")
- , globalBefore = Object.keys(global)
- , mm = require("../")
- , files = [ "a", "b", "c", "d", "abc"
- , "abd", "abe", "bb", "bcd"
- , "ca", "cb", "dd", "de"
- , "bdir/", "bdir/cfile"]
- , next = files.concat([ "a-b", "aXb"
- , ".x", ".y" ])
-
-
-var patterns =
- [ "http://www.bashcookbook.com/bashinfo/source/bash-1.14.7/tests/glob-test"
- , ["a*", ["a", "abc", "abd", "abe"]]
- , ["X*", ["X*"], {nonull: true}]
-
- // allow null glob expansion
- , ["X*", []]
-
- // isaacs: Slightly different than bash/sh/ksh
- // \\* is not un-escaped to literal "*" in a failed match,
- // but it does make it get treated as a literal star
- , ["\\*", ["\\*"], {nonull: true}]
- , ["\\**", ["\\**"], {nonull: true}]
- , ["\\*\\*", ["\\*\\*"], {nonull: true}]
-
- , ["b*/", ["bdir/"]]
- , ["c*", ["c", "ca", "cb"]]
- , ["**", files]
-
- , ["\\.\\./*/", ["\\.\\./*/"], {nonull: true}]
- , ["s/\\..*//", ["s/\\..*//"], {nonull: true}]
-
- , "legendary larry crashes bashes"
- , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\\1/"
- , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\\1/"], {nonull: true}]
- , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\1/"
- , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\1/"], {nonull: true}]
-
- , "character classes"
- , ["[a-c]b*", ["abc", "abd", "abe", "bb", "cb"]]
- , ["[a-y]*[^c]", ["abd", "abe", "bb", "bcd",
- "bdir/", "ca", "cb", "dd", "de"]]
- , ["a*[^c]", ["abd", "abe"]]
- , function () { files.push("a-b", "aXb") }
- , ["a[X-]b", ["a-b", "aXb"]]
- , function () { files.push(".x", ".y") }
- , ["[^a-c]*", ["d", "dd", "de"]]
- , function () { files.push("a*b/", "a*b/ooo") }
- , ["a\\*b/*", ["a*b/ooo"]]
- , ["a\\*?/*", ["a*b/ooo"]]
- , ["*\\\\!*", [], {null: true}, ["echo !7"]]
- , ["*\\!*", ["echo !7"], null, ["echo !7"]]
- , ["*.\\*", ["r.*"], null, ["r.*"]]
- , ["a[b]c", ["abc"]]
- , ["a[\\b]c", ["abc"]]
- , ["a?c", ["abc"]]
- , ["a\\*c", [], {null: true}, ["abc"]]
- , ["", [""], { null: true }, [""]]
-
- , "http://www.opensource.apple.com/source/bash/bash-23/" +
- "bash/tests/glob-test"
- , function () { files.push("man/", "man/man1/", "man/man1/bash.1") }
- , ["*/man*/bash.*", ["man/man1/bash.1"]]
- , ["man/man1/bash.1", ["man/man1/bash.1"]]
- , ["a***c", ["abc"], null, ["abc"]]
- , ["a*****?c", ["abc"], null, ["abc"]]
- , ["?*****??", ["abc"], null, ["abc"]]
- , ["*****??", ["abc"], null, ["abc"]]
- , ["?*****?c", ["abc"], null, ["abc"]]
- , ["?***?****c", ["abc"], null, ["abc"]]
- , ["?***?****?", ["abc"], null, ["abc"]]
- , ["?***?****", ["abc"], null, ["abc"]]
- , ["*******c", ["abc"], null, ["abc"]]
- , ["*******?", ["abc"], null, ["abc"]]
- , ["a*cd**?**??k", ["abcdecdhjk"], null, ["abcdecdhjk"]]
- , ["a**?**cd**?**??k", ["abcdecdhjk"], null, ["abcdecdhjk"]]
- , ["a**?**cd**?**??k***", ["abcdecdhjk"], null, ["abcdecdhjk"]]
- , ["a**?**cd**?**??***k", ["abcdecdhjk"], null, ["abcdecdhjk"]]
- , ["a**?**cd**?**??***k**", ["abcdecdhjk"], null, ["abcdecdhjk"]]
- , ["a****c**?**??*****", ["abcdecdhjk"], null, ["abcdecdhjk"]]
- , ["[-abc]", ["-"], null, ["-"]]
- , ["[abc-]", ["-"], null, ["-"]]
- , ["\\", ["\\"], null, ["\\"]]
- , ["[\\\\]", ["\\"], null, ["\\"]]
- , ["[[]", ["["], null, ["["]]
- , ["[", ["["], null, ["["]]
- , ["[*", ["[abc"], null, ["[abc"]]
- , "a right bracket shall lose its special meaning and\n" +
- "represent itself in a bracket expression if it occurs\n" +
- "first in the list. -- POSIX.2 2.8.3.2"
- , ["[]]", ["]"], null, ["]"]]
- , ["[]-]", ["]"], null, ["]"]]
- , ["[a-\z]", ["p"], null, ["p"]]
- , ["??**********?****?", [], { null: true }, ["abc"]]
- , ["??**********?****c", [], { null: true }, ["abc"]]
- , ["?************c****?****", [], { null: true }, ["abc"]]
- , ["*c*?**", [], { null: true }, ["abc"]]
- , ["a*****c*?**", [], { null: true }, ["abc"]]
- , ["a********???*******", [], { null: true }, ["abc"]]
- , ["[]", [], { null: true }, ["a"]]
- , ["[abc", [], { null: true }, ["["]]
-
- , "nocase tests"
- , ["XYZ", ["xYz"], { nocase: true, null: true }
- , ["xYz", "ABC", "IjK"]]
- , ["ab*", ["ABC"], { nocase: true, null: true }
- , ["xYz", "ABC", "IjK"]]
- , ["[ia]?[ck]", ["ABC", "IjK"], { nocase: true, null: true }
- , ["xYz", "ABC", "IjK"]]
-
- // [ pattern, [matches], MM opts, files, TAP opts]
- , "onestar/twostar"
- , ["{/*,*}", [], {null: true}, ["/asdf/asdf/asdf"]]
- , ["{/?,*}", ["/a", "bb"], {null: true}
- , ["/a", "/b/b", "/a/b/c", "bb"]]
-
- , "dots should not match unless requested"
- , ["**", ["a/b"], {}, ["a/b", "a/.d", ".a/.d"]]
-
- // .. and . can only match patterns starting with .,
- // even when options.dot is set.
- , function () {
- files = ["a/./b", "a/../b", "a/c/b", "a/.d/b"]
- }
- , ["a/*/b", ["a/c/b", "a/.d/b"], {dot: true}]
- , ["a/.*/b", ["a/./b", "a/../b", "a/.d/b"], {dot: true}]
- , ["a/*/b", ["a/c/b"], {dot:false}]
- , ["a/.*/b", ["a/./b", "a/../b", "a/.d/b"], {dot: false}]
-
-
- // this also tests that changing the options needs
- // to change the cache key, even if the pattern is
- // the same!
- , ["**", ["a/b","a/.d",".a/.d"], { dot: true }
- , [ ".a/.d", "a/.d", "a/b"]]
-
- , "paren sets cannot contain slashes"
- , ["*(a/b)", ["*(a/b)"], {nonull: true}, ["a/b"]]
-
- // brace sets trump all else.
- //
- // invalid glob pattern. fails on bash4 and bsdglob.
- // however, in this implementation, it's easier just
- // to do the intuitive thing, and let brace-expansion
- // actually come before parsing any extglob patterns,
- // like the documentation seems to say.
- //
- // XXX: if anyone complains about this, either fix it
- // or tell them to grow up and stop complaining.
- //
- // bash/bsdglob says this:
- // , ["*(a|{b),c)}", ["*(a|{b),c)}"], {}, ["a", "ab", "ac", "ad"]]
- // but we do this instead:
- , ["*(a|{b),c)}", ["a", "ab", "ac"], {}, ["a", "ab", "ac", "ad"]]
-
- // test partial parsing in the presence of comment/negation chars
- , ["[!a*", ["[!ab"], {}, ["[!ab", "[ab"]]
- , ["[#a*", ["[#ab"], {}, ["[#ab", "[ab"]]
-
- // like: {a,b|c\\,d\\\|e} except it's unclosed, so it has to be escaped.
- , ["+(a|*\\|c\\\\|d\\\\\\|e\\\\\\\\|f\\\\\\\\\\|g"
- , ["+(a|b\\|c\\\\|d\\\\|e\\\\\\\\|f\\\\\\\\|g"]
- , {}
- , ["+(a|b\\|c\\\\|d\\\\|e\\\\\\\\|f\\\\\\\\|g", "a", "b\\c"]]
-
-
- // crazy nested {,,} and *(||) tests.
- , function () {
- files = [ "a", "b", "c", "d"
- , "ab", "ac", "ad"
- , "bc", "cb"
- , "bc,d", "c,db", "c,d"
- , "d)", "(b|c", "*(b|c"
- , "b|c", "b|cc", "cb|c"
- , "x(a|b|c)", "x(a|c)"
- , "(a|b|c)", "(a|c)"]
- }
- , ["*(a|{b,c})", ["a", "b", "c", "ab", "ac"]]
- , ["{a,*(b|c,d)}", ["a","(b|c", "*(b|c", "d)"]]
- // a
- // *(b|c)
- // *(b|d)
- , ["{a,*(b|{c,d})}", ["a","b", "bc", "cb", "c", "d"]]
- , ["*(a|{b|c,c})", ["a", "b", "c", "ab", "ac", "bc", "cb"]]
-
-
- // test various flag settings.
- , [ "*(a|{b|c,c})", ["x(a|b|c)", "x(a|c)", "(a|b|c)", "(a|c)"]
- , { noext: true } ]
- , ["a?b", ["x/y/acb", "acb/"], {matchBase: true}
- , ["x/y/acb", "acb/", "acb/d/e", "x/y/acb/d"] ]
- , ["#*", ["#a", "#b"], {nocomment: true}, ["#a", "#b", "c#d"]]
-
-
- // begin channelling Boole and deMorgan...
- , "negation tests"
- , function () {
- files = ["d", "e", "!ab", "!abc", "a!b", "\\!a"]
- }
-
- // anything that is NOT a* matches.
- , ["!a*", ["\\!a", "d", "e", "!ab", "!abc"]]
-
- // anything that IS !a* matches.
- , ["!a*", ["!ab", "!abc"], {nonegate: true}]
-
- // anything that IS a* matches
- , ["!!a*", ["a!b"]]
-
- // anything that is NOT !a* matches
- , ["!\\!a*", ["a!b", "d", "e", "\\!a"]]
-
- // negation nestled within a pattern
- , function () {
- files = [ "foo.js"
- , "foo.bar"
- // can't match this one without negative lookbehind.
- , "foo.js.js"
- , "blar.js"
- , "foo."
- , "boo.js.boo" ]
- }
- , ["*.!(js)", ["foo.bar", "foo.", "boo.js.boo"] ]
-
- // https://github.com/isaacs/minimatch/issues/5
- , function () {
- files = [ 'a/b/.x/c'
- , 'a/b/.x/c/d'
- , 'a/b/.x/c/d/e'
- , 'a/b/.x'
- , 'a/b/.x/'
- , 'a/.x/b'
- , '.x'
- , '.x/'
- , '.x/a'
- , '.x/a/b'
- , 'a/.x/b/.x/c'
- , '.x/.x' ]
- }
- , ["**/.x/**", [ '.x/'
- , '.x/a'
- , '.x/a/b'
- , 'a/.x/b'
- , 'a/b/.x/'
- , 'a/b/.x/c'
- , 'a/b/.x/c/d'
- , 'a/b/.x/c/d/e' ] ]
-
- ]
-
-var regexps =
- [ '/^(?:(?=.)a[^/]*?)$/',
- '/^(?:(?=.)X[^/]*?)$/',
- '/^(?:(?=.)X[^/]*?)$/',
- '/^(?:\\*)$/',
- '/^(?:(?=.)\\*[^/]*?)$/',
- '/^(?:\\*\\*)$/',
- '/^(?:(?=.)b[^/]*?\\/)$/',
- '/^(?:(?=.)c[^/]*?)$/',
- '/^(?:(?:(?!(?:\\/|^)\\.).)*?)$/',
- '/^(?:\\.\\.\\/(?!\\.)(?=.)[^/]*?\\/)$/',
- '/^(?:s\\/(?=.)\\.\\.[^/]*?\\/)$/',
- '/^(?:\\/\\^root:\\/\\{s\\/(?=.)\\^[^:][^/]*?:[^:][^/]*?:\\([^:]\\)[^/]*?\\.[^/]*?\\$\\/1\\/)$/',
- '/^(?:\\/\\^root:\\/\\{s\\/(?=.)\\^[^:][^/]*?:[^:][^/]*?:\\([^:]\\)[^/]*?\\.[^/]*?\\$\\/\u0001\\/)$/',
- '/^(?:(?!\\.)(?=.)[a-c]b[^/]*?)$/',
- '/^(?:(?!\\.)(?=.)[a-y][^/]*?[^c])$/',
- '/^(?:(?=.)a[^/]*?[^c])$/',
- '/^(?:(?=.)a[X-]b)$/',
- '/^(?:(?!\\.)(?=.)[^a-c][^/]*?)$/',
- '/^(?:a\\*b\\/(?!\\.)(?=.)[^/]*?)$/',
- '/^(?:(?=.)a\\*[^/]\\/(?!\\.)(?=.)[^/]*?)$/',
- '/^(?:(?!\\.)(?=.)[^/]*?\\\\\\![^/]*?)$/',
- '/^(?:(?!\\.)(?=.)[^/]*?\\![^/]*?)$/',
- '/^(?:(?!\\.)(?=.)[^/]*?\\.\\*)$/',
- '/^(?:(?=.)a[b]c)$/',
- '/^(?:(?=.)a[b]c)$/',
- '/^(?:(?=.)a[^/]c)$/',
- '/^(?:a\\*c)$/',
- 'false',
- '/^(?:(?!\\.)(?=.)[^/]*?\\/(?=.)man[^/]*?\\/(?=.)bash\\.[^/]*?)$/',
- '/^(?:man\\/man1\\/bash\\.1)$/',
- '/^(?:(?=.)a[^/]*?[^/]*?[^/]*?c)$/',
- '/^(?:(?=.)a[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]c)$/',
- '/^(?:(?!\\.)(?=.)[^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/][^/])$/',
- '/^(?:(?!\\.)(?=.)[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/][^/])$/',
- '/^(?:(?!\\.)(?=.)[^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]c)$/',
- '/^(?:(?!\\.)(?=.)[^/][^/]*?[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/]*?[^/]*?c)$/',
- '/^(?:(?!\\.)(?=.)[^/][^/]*?[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/]*?[^/]*?[^/])$/',
- '/^(?:(?!\\.)(?=.)[^/][^/]*?[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/]*?[^/]*?)$/',
- '/^(?:(?!\\.)(?=.)[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?c)$/',
- '/^(?:(?!\\.)(?=.)[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/])$/',
- '/^(?:(?=.)a[^/]*?cd[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/][^/]k)$/',
- '/^(?:(?=.)a[^/]*?[^/]*?[^/][^/]*?[^/]*?cd[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/][^/]k)$/',
- '/^(?:(?=.)a[^/]*?[^/]*?[^/][^/]*?[^/]*?cd[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/][^/]k[^/]*?[^/]*?[^/]*?)$/',
- '/^(?:(?=.)a[^/]*?[^/]*?[^/][^/]*?[^/]*?cd[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/][^/][^/]*?[^/]*?[^/]*?k)$/',
- '/^(?:(?=.)a[^/]*?[^/]*?[^/][^/]*?[^/]*?cd[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/][^/][^/]*?[^/]*?[^/]*?k[^/]*?[^/]*?)$/',
- '/^(?:(?=.)a[^/]*?[^/]*?[^/]*?[^/]*?c[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/][^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?)$/',
- '/^(?:(?!\\.)(?=.)[-abc])$/',
- '/^(?:(?!\\.)(?=.)[abc-])$/',
- '/^(?:\\\\)$/',
- '/^(?:(?!\\.)(?=.)[\\\\])$/',
- '/^(?:(?!\\.)(?=.)[\\[])$/',
- '/^(?:\\[)$/',
- '/^(?:(?=.)\\[(?!\\.)(?=.)[^/]*?)$/',
- '/^(?:(?!\\.)(?=.)[\\]])$/',
- '/^(?:(?!\\.)(?=.)[\\]-])$/',
- '/^(?:(?!\\.)(?=.)[a-z])$/',
- '/^(?:(?!\\.)(?=.)[^/][^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/]*?[^/]*?[^/])$/',
- '/^(?:(?!\\.)(?=.)[^/][^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/]*?[^/]*?c)$/',
- '/^(?:(?!\\.)(?=.)[^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?c[^/]*?[^/]*?[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/]*?[^/]*?)$/',
- '/^(?:(?!\\.)(?=.)[^/]*?c[^/]*?[^/][^/]*?[^/]*?)$/',
- '/^(?:(?=.)a[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?c[^/]*?[^/][^/]*?[^/]*?)$/',
- '/^(?:(?=.)a[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/][^/][^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?)$/',
- '/^(?:\\[\\])$/',
- '/^(?:\\[abc)$/',
- '/^(?:(?=.)XYZ)$/i',
- '/^(?:(?=.)ab[^/]*?)$/i',
- '/^(?:(?!\\.)(?=.)[ia][^/][ck])$/i',
- '/^(?:\\/(?!\\.)(?=.)[^/]*?|(?!\\.)(?=.)[^/]*?)$/',
- '/^(?:\\/(?!\\.)(?=.)[^/]|(?!\\.)(?=.)[^/]*?)$/',
- '/^(?:(?:(?!(?:\\/|^)\\.).)*?)$/',
- '/^(?:a\\/(?!(?:^|\\/)\\.{1,2}(?:$|\\/))(?=.)[^/]*?\\/b)$/',
- '/^(?:a\\/(?=.)\\.[^/]*?\\/b)$/',
- '/^(?:a\\/(?!\\.)(?=.)[^/]*?\\/b)$/',
- '/^(?:a\\/(?=.)\\.[^/]*?\\/b)$/',
- '/^(?:(?:(?!(?:\\/|^)(?:\\.{1,2})($|\\/)).)*?)$/',
- '/^(?:(?!\\.)(?=.)[^/]*?\\(a\\/b\\))$/',
- '/^(?:(?!\\.)(?=.)(?:a|b)*|(?!\\.)(?=.)(?:a|c)*)$/',
- '/^(?:(?=.)\\[(?=.)\\!a[^/]*?)$/',
- '/^(?:(?=.)\\[(?=.)#a[^/]*?)$/',
- '/^(?:(?=.)\\+\\(a\\|[^/]*?\\|c\\\\\\\\\\|d\\\\\\\\\\|e\\\\\\\\\\\\\\\\\\|f\\\\\\\\\\\\\\\\\\|g)$/',
- '/^(?:(?!\\.)(?=.)(?:a|b)*|(?!\\.)(?=.)(?:a|c)*)$/',
- '/^(?:a|(?!\\.)(?=.)[^/]*?\\(b\\|c|d\\))$/',
- '/^(?:a|(?!\\.)(?=.)(?:b|c)*|(?!\\.)(?=.)(?:b|d)*)$/',
- '/^(?:(?!\\.)(?=.)(?:a|b|c)*|(?!\\.)(?=.)(?:a|c)*)$/',
- '/^(?:(?!\\.)(?=.)[^/]*?\\(a\\|b\\|c\\)|(?!\\.)(?=.)[^/]*?\\(a\\|c\\))$/',
- '/^(?:(?=.)a[^/]b)$/',
- '/^(?:(?=.)#[^/]*?)$/',
- '/^(?!^(?:(?=.)a[^/]*?)$).*$/',
- '/^(?:(?=.)\\!a[^/]*?)$/',
- '/^(?:(?=.)a[^/]*?)$/',
- '/^(?!^(?:(?=.)\\!a[^/]*?)$).*$/',
- '/^(?:(?!\\.)(?=.)[^/]*?\\.(?:(?!js)[^/]*?))$/',
- '/^(?:(?:(?!(?:\\/|^)\\.).)*?\\/\\.x\\/(?:(?!(?:\\/|^)\\.).)*?)$/' ]
-var re = 0;
-
-tap.test("basic tests", function (t) {
- var start = Date.now()
-
- // [ pattern, [matches], MM opts, files, TAP opts]
- patterns.forEach(function (c) {
- if (typeof c === "function") return c()
- if (typeof c === "string") return t.comment(c)
-
- var pattern = c[0]
- , expect = c[1].sort(alpha)
- , options = c[2] || {}
- , f = c[3] || files
- , tapOpts = c[4] || {}
-
- // options.debug = true
- var m = new mm.Minimatch(pattern, options)
- var r = m.makeRe()
- var expectRe = regexps[re++]
- tapOpts.re = String(r) || JSON.stringify(r)
- tapOpts.files = JSON.stringify(f)
- tapOpts.pattern = pattern
- tapOpts.set = m.set
- tapOpts.negated = m.negate
-
- var actual = mm.match(f, pattern, options)
- actual.sort(alpha)
-
- t.equivalent( actual, expect
- , JSON.stringify(pattern) + " " + JSON.stringify(expect)
- , tapOpts )
-
- t.equal(tapOpts.re, expectRe, tapOpts)
- })
-
- t.comment("time=" + (Date.now() - start) + "ms")
- t.end()
-})
-
-tap.test("global leak test", function (t) {
- var globalAfter = Object.keys(global)
- t.equivalent(globalAfter, globalBefore, "no new globals, please")
- t.end()
-})
-
-function alpha (a, b) {
- return a > b ? 1 : -1
-}
diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/brace-expand.js b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/brace-expand.js
deleted file mode 100644
index 7ee278a2..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/brace-expand.js
+++ /dev/null
@@ -1,33 +0,0 @@
-var tap = require("tap")
- , minimatch = require("../")
-
-tap.test("brace expansion", function (t) {
- // [ pattern, [expanded] ]
- ; [ [ "a{b,c{d,e},{f,g}h}x{y,z}"
- , [ "abxy"
- , "abxz"
- , "acdxy"
- , "acdxz"
- , "acexy"
- , "acexz"
- , "afhxy"
- , "afhxz"
- , "aghxy"
- , "aghxz" ] ]
- , [ "a{1..5}b"
- , [ "a1b"
- , "a2b"
- , "a3b"
- , "a4b"
- , "a5b" ] ]
- , [ "a{b}c", ["a{b}c"] ]
- ].forEach(function (tc) {
- var p = tc[0]
- , expect = tc[1]
- t.equivalent(minimatch.braceExpand(p), expect, p)
- })
- console.error("ending")
- t.end()
-})
-
-
diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/caching.js b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/caching.js
deleted file mode 100644
index 0fec4b0f..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/caching.js
+++ /dev/null
@@ -1,14 +0,0 @@
-var Minimatch = require("../minimatch.js").Minimatch
-var tap = require("tap")
-tap.test("cache test", function (t) {
- var mm1 = new Minimatch("a?b")
- var mm2 = new Minimatch("a?b")
- t.equal(mm1, mm2, "should get the same object")
- // the lru should drop it after 100 entries
- for (var i = 0; i < 100; i ++) {
- new Minimatch("a"+i)
- }
- mm2 = new Minimatch("a?b")
- t.notEqual(mm1, mm2, "cache should have dropped")
- t.end()
-})
diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/defaults.js b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/defaults.js
deleted file mode 100644
index 75e05712..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/defaults.js
+++ /dev/null
@@ -1,274 +0,0 @@
-// http://www.bashcookbook.com/bashinfo/source/bash-1.14.7/tests/glob-test
-//
-// TODO: Some of these tests do very bad things with backslashes, and will
-// most likely fail badly on windows. They should probably be skipped.
-
-var tap = require("tap")
- , globalBefore = Object.keys(global)
- , mm = require("../")
- , files = [ "a", "b", "c", "d", "abc"
- , "abd", "abe", "bb", "bcd"
- , "ca", "cb", "dd", "de"
- , "bdir/", "bdir/cfile"]
- , next = files.concat([ "a-b", "aXb"
- , ".x", ".y" ])
-
-tap.test("basic tests", function (t) {
- var start = Date.now()
-
- // [ pattern, [matches], MM opts, files, TAP opts]
- ; [ "http://www.bashcookbook.com/bashinfo" +
- "/source/bash-1.14.7/tests/glob-test"
- , ["a*", ["a", "abc", "abd", "abe"]]
- , ["X*", ["X*"], {nonull: true}]
-
- // allow null glob expansion
- , ["X*", []]
-
- // isaacs: Slightly different than bash/sh/ksh
- // \\* is not un-escaped to literal "*" in a failed match,
- // but it does make it get treated as a literal star
- , ["\\*", ["\\*"], {nonull: true}]
- , ["\\**", ["\\**"], {nonull: true}]
- , ["\\*\\*", ["\\*\\*"], {nonull: true}]
-
- , ["b*/", ["bdir/"]]
- , ["c*", ["c", "ca", "cb"]]
- , ["**", files]
-
- , ["\\.\\./*/", ["\\.\\./*/"], {nonull: true}]
- , ["s/\\..*//", ["s/\\..*//"], {nonull: true}]
-
- , "legendary larry crashes bashes"
- , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\\1/"
- , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\\1/"], {nonull: true}]
- , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\1/"
- , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\1/"], {nonull: true}]
-
- , "character classes"
- , ["[a-c]b*", ["abc", "abd", "abe", "bb", "cb"]]
- , ["[a-y]*[^c]", ["abd", "abe", "bb", "bcd",
- "bdir/", "ca", "cb", "dd", "de"]]
- , ["a*[^c]", ["abd", "abe"]]
- , function () { files.push("a-b", "aXb") }
- , ["a[X-]b", ["a-b", "aXb"]]
- , function () { files.push(".x", ".y") }
- , ["[^a-c]*", ["d", "dd", "de"]]
- , function () { files.push("a*b/", "a*b/ooo") }
- , ["a\\*b/*", ["a*b/ooo"]]
- , ["a\\*?/*", ["a*b/ooo"]]
- , ["*\\\\!*", [], {null: true}, ["echo !7"]]
- , ["*\\!*", ["echo !7"], null, ["echo !7"]]
- , ["*.\\*", ["r.*"], null, ["r.*"]]
- , ["a[b]c", ["abc"]]
- , ["a[\\b]c", ["abc"]]
- , ["a?c", ["abc"]]
- , ["a\\*c", [], {null: true}, ["abc"]]
- , ["", [""], { null: true }, [""]]
-
- , "http://www.opensource.apple.com/source/bash/bash-23/" +
- "bash/tests/glob-test"
- , function () { files.push("man/", "man/man1/", "man/man1/bash.1") }
- , ["*/man*/bash.*", ["man/man1/bash.1"]]
- , ["man/man1/bash.1", ["man/man1/bash.1"]]
- , ["a***c", ["abc"], null, ["abc"]]
- , ["a*****?c", ["abc"], null, ["abc"]]
- , ["?*****??", ["abc"], null, ["abc"]]
- , ["*****??", ["abc"], null, ["abc"]]
- , ["?*****?c", ["abc"], null, ["abc"]]
- , ["?***?****c", ["abc"], null, ["abc"]]
- , ["?***?****?", ["abc"], null, ["abc"]]
- , ["?***?****", ["abc"], null, ["abc"]]
- , ["*******c", ["abc"], null, ["abc"]]
- , ["*******?", ["abc"], null, ["abc"]]
- , ["a*cd**?**??k", ["abcdecdhjk"], null, ["abcdecdhjk"]]
- , ["a**?**cd**?**??k", ["abcdecdhjk"], null, ["abcdecdhjk"]]
- , ["a**?**cd**?**??k***", ["abcdecdhjk"], null, ["abcdecdhjk"]]
- , ["a**?**cd**?**??***k", ["abcdecdhjk"], null, ["abcdecdhjk"]]
- , ["a**?**cd**?**??***k**", ["abcdecdhjk"], null, ["abcdecdhjk"]]
- , ["a****c**?**??*****", ["abcdecdhjk"], null, ["abcdecdhjk"]]
- , ["[-abc]", ["-"], null, ["-"]]
- , ["[abc-]", ["-"], null, ["-"]]
- , ["\\", ["\\"], null, ["\\"]]
- , ["[\\\\]", ["\\"], null, ["\\"]]
- , ["[[]", ["["], null, ["["]]
- , ["[", ["["], null, ["["]]
- , ["[*", ["[abc"], null, ["[abc"]]
- , "a right bracket shall lose its special meaning and\n" +
- "represent itself in a bracket expression if it occurs\n" +
- "first in the list. -- POSIX.2 2.8.3.2"
- , ["[]]", ["]"], null, ["]"]]
- , ["[]-]", ["]"], null, ["]"]]
- , ["[a-\z]", ["p"], null, ["p"]]
- , ["??**********?****?", [], { null: true }, ["abc"]]
- , ["??**********?****c", [], { null: true }, ["abc"]]
- , ["?************c****?****", [], { null: true }, ["abc"]]
- , ["*c*?**", [], { null: true }, ["abc"]]
- , ["a*****c*?**", [], { null: true }, ["abc"]]
- , ["a********???*******", [], { null: true }, ["abc"]]
- , ["[]", [], { null: true }, ["a"]]
- , ["[abc", [], { null: true }, ["["]]
-
- , "nocase tests"
- , ["XYZ", ["xYz"], { nocase: true, null: true }
- , ["xYz", "ABC", "IjK"]]
- , ["ab*", ["ABC"], { nocase: true, null: true }
- , ["xYz", "ABC", "IjK"]]
- , ["[ia]?[ck]", ["ABC", "IjK"], { nocase: true, null: true }
- , ["xYz", "ABC", "IjK"]]
-
- // [ pattern, [matches], MM opts, files, TAP opts]
- , "onestar/twostar"
- , ["{/*,*}", [], {null: true}, ["/asdf/asdf/asdf"]]
- , ["{/?,*}", ["/a", "bb"], {null: true}
- , ["/a", "/b/b", "/a/b/c", "bb"]]
-
- , "dots should not match unless requested"
- , ["**", ["a/b"], {}, ["a/b", "a/.d", ".a/.d"]]
-
- // .. and . can only match patterns starting with .,
- // even when options.dot is set.
- , function () {
- files = ["a/./b", "a/../b", "a/c/b", "a/.d/b"]
- }
- , ["a/*/b", ["a/c/b", "a/.d/b"], {dot: true}]
- , ["a/.*/b", ["a/./b", "a/../b", "a/.d/b"], {dot: true}]
- , ["a/*/b", ["a/c/b"], {dot:false}]
- , ["a/.*/b", ["a/./b", "a/../b", "a/.d/b"], {dot: false}]
-
-
- // this also tests that changing the options needs
- // to change the cache key, even if the pattern is
- // the same!
- , ["**", ["a/b","a/.d",".a/.d"], { dot: true }
- , [ ".a/.d", "a/.d", "a/b"]]
-
- , "paren sets cannot contain slashes"
- , ["*(a/b)", ["*(a/b)"], {nonull: true}, ["a/b"]]
-
- // brace sets trump all else.
- //
- // invalid glob pattern. fails on bash4 and bsdglob.
- // however, in this implementation, it's easier just
- // to do the intuitive thing, and let brace-expansion
- // actually come before parsing any extglob patterns,
- // like the documentation seems to say.
- //
- // XXX: if anyone complains about this, either fix it
- // or tell them to grow up and stop complaining.
- //
- // bash/bsdglob says this:
- // , ["*(a|{b),c)}", ["*(a|{b),c)}"], {}, ["a", "ab", "ac", "ad"]]
- // but we do this instead:
- , ["*(a|{b),c)}", ["a", "ab", "ac"], {}, ["a", "ab", "ac", "ad"]]
-
- // test partial parsing in the presence of comment/negation chars
- , ["[!a*", ["[!ab"], {}, ["[!ab", "[ab"]]
- , ["[#a*", ["[#ab"], {}, ["[#ab", "[ab"]]
-
- // like: {a,b|c\\,d\\\|e} except it's unclosed, so it has to be escaped.
- , ["+(a|*\\|c\\\\|d\\\\\\|e\\\\\\\\|f\\\\\\\\\\|g"
- , ["+(a|b\\|c\\\\|d\\\\|e\\\\\\\\|f\\\\\\\\|g"]
- , {}
- , ["+(a|b\\|c\\\\|d\\\\|e\\\\\\\\|f\\\\\\\\|g", "a", "b\\c"]]
-
-
- // crazy nested {,,} and *(||) tests.
- , function () {
- files = [ "a", "b", "c", "d"
- , "ab", "ac", "ad"
- , "bc", "cb"
- , "bc,d", "c,db", "c,d"
- , "d)", "(b|c", "*(b|c"
- , "b|c", "b|cc", "cb|c"
- , "x(a|b|c)", "x(a|c)"
- , "(a|b|c)", "(a|c)"]
- }
- , ["*(a|{b,c})", ["a", "b", "c", "ab", "ac"]]
- , ["{a,*(b|c,d)}", ["a","(b|c", "*(b|c", "d)"]]
- // a
- // *(b|c)
- // *(b|d)
- , ["{a,*(b|{c,d})}", ["a","b", "bc", "cb", "c", "d"]]
- , ["*(a|{b|c,c})", ["a", "b", "c", "ab", "ac", "bc", "cb"]]
-
-
- // test various flag settings.
- , [ "*(a|{b|c,c})", ["x(a|b|c)", "x(a|c)", "(a|b|c)", "(a|c)"]
- , { noext: true } ]
- , ["a?b", ["x/y/acb", "acb/"], {matchBase: true}
- , ["x/y/acb", "acb/", "acb/d/e", "x/y/acb/d"] ]
- , ["#*", ["#a", "#b"], {nocomment: true}, ["#a", "#b", "c#d"]]
-
-
- // begin channelling Boole and deMorgan...
- , "negation tests"
- , function () {
- files = ["d", "e", "!ab", "!abc", "a!b", "\\!a"]
- }
-
- // anything that is NOT a* matches.
- , ["!a*", ["\\!a", "d", "e", "!ab", "!abc"]]
-
- // anything that IS !a* matches.
- , ["!a*", ["!ab", "!abc"], {nonegate: true}]
-
- // anything that IS a* matches
- , ["!!a*", ["a!b"]]
-
- // anything that is NOT !a* matches
- , ["!\\!a*", ["a!b", "d", "e", "\\!a"]]
-
- // negation nestled within a pattern
- , function () {
- files = [ "foo.js"
- , "foo.bar"
- // can't match this one without negative lookbehind.
- , "foo.js.js"
- , "blar.js"
- , "foo."
- , "boo.js.boo" ]
- }
- , ["*.!(js)", ["foo.bar", "foo.", "boo.js.boo"] ]
-
- ].forEach(function (c) {
- if (typeof c === "function") return c()
- if (typeof c === "string") return t.comment(c)
-
- var pattern = c[0]
- , expect = c[1].sort(alpha)
- , options = c[2]
- , f = c[3] || files
- , tapOpts = c[4] || {}
-
- // options.debug = true
- var Class = mm.defaults(options).Minimatch
- var m = new Class(pattern, {})
- var r = m.makeRe()
- tapOpts.re = String(r) || JSON.stringify(r)
- tapOpts.files = JSON.stringify(f)
- tapOpts.pattern = pattern
- tapOpts.set = m.set
- tapOpts.negated = m.negate
-
- var actual = mm.match(f, pattern, options)
- actual.sort(alpha)
-
- t.equivalent( actual, expect
- , JSON.stringify(pattern) + " " + JSON.stringify(expect)
- , tapOpts )
- })
-
- t.comment("time=" + (Date.now() - start) + "ms")
- t.end()
-})
-
-tap.test("global leak test", function (t) {
- var globalAfter = Object.keys(global)
- t.equivalent(globalAfter, globalBefore, "no new globals, please")
- t.end()
-})
-
-function alpha (a, b) {
- return a > b ? 1 : -1
-}
diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/extglob-ending-with-state-char.js b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/extglob-ending-with-state-char.js
deleted file mode 100644
index 6676e262..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/extglob-ending-with-state-char.js
+++ /dev/null
@@ -1,8 +0,0 @@
-var test = require('tap').test
-var minimatch = require('../')
-
-test('extglob ending with statechar', function(t) {
- t.notOk(minimatch('ax', 'a?(b*)'))
- t.ok(minimatch('ax', '?(a*|b)'))
- t.end()
-})
diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/package.json b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/package.json
deleted file mode 100644
index e7ec15f3..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/package.json
+++ /dev/null
@@ -1,58 +0,0 @@
-{
- "author": {
- "name": "Isaac Z. Schlueter",
- "email": "i@izs.me",
- "url": "http://blog.izs.me/"
- },
- "name": "glob",
- "description": "a little globber",
- "version": "3.2.11",
- "repository": {
- "type": "git",
- "url": "git://github.com/isaacs/node-glob.git"
- },
- "main": "glob.js",
- "engines": {
- "node": "*"
- },
- "dependencies": {
- "inherits": "2",
- "minimatch": "0.3"
- },
- "devDependencies": {
- "tap": "~0.4.0",
- "mkdirp": "0",
- "rimraf": "1"
- },
- "scripts": {
- "test": "tap test/*.js",
- "test-regen": "TEST_REGEN=1 node test/00-setup.js"
- },
- "license": "BSD",
- "gitHead": "73f57e99510582b2024b762305970ebcf9b70aa2",
- "bugs": {
- "url": "https://github.com/isaacs/node-glob/issues"
- },
- "homepage": "https://github.com/isaacs/node-glob",
- "_id": "glob@3.2.11",
- "_shasum": "4a973f635b9190f715d10987d5c00fd2815ebe3d",
- "_from": "glob@~3.2.9",
- "_npmVersion": "1.4.10",
- "_npmUser": {
- "name": "isaacs",
- "email": "i@izs.me"
- },
- "maintainers": [
- {
- "name": "isaacs",
- "email": "i@izs.me"
- }
- ],
- "dist": {
- "shasum": "4a973f635b9190f715d10987d5c00fd2815ebe3d",
- "tarball": "http://registry.npmjs.org/glob/-/glob-3.2.11.tgz"
- },
- "directories": {},
- "_resolved": "https://registry.npmjs.org/glob/-/glob-3.2.11.tgz",
- "readme": "ERROR: No README data found!"
-}
diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/00-setup.js b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/00-setup.js
deleted file mode 100644
index 245afafd..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/00-setup.js
+++ /dev/null
@@ -1,176 +0,0 @@
-// just a little pre-run script to set up the fixtures.
-// zz-finish cleans it up
-
-var mkdirp = require("mkdirp")
-var path = require("path")
-var i = 0
-var tap = require("tap")
-var fs = require("fs")
-var rimraf = require("rimraf")
-
-var files =
-[ "a/.abcdef/x/y/z/a"
-, "a/abcdef/g/h"
-, "a/abcfed/g/h"
-, "a/b/c/d"
-, "a/bc/e/f"
-, "a/c/d/c/b"
-, "a/cb/e/f"
-]
-
-var symlinkTo = path.resolve(__dirname, "a/symlink/a/b/c")
-var symlinkFrom = "../.."
-
-files = files.map(function (f) {
- return path.resolve(__dirname, f)
-})
-
-tap.test("remove fixtures", function (t) {
- rimraf(path.resolve(__dirname, "a"), function (er) {
- t.ifError(er, "remove fixtures")
- t.end()
- })
-})
-
-files.forEach(function (f) {
- tap.test(f, function (t) {
- var d = path.dirname(f)
- mkdirp(d, 0755, function (er) {
- if (er) {
- t.fail(er)
- return t.bailout()
- }
- fs.writeFile(f, "i like tests", function (er) {
- t.ifError(er, "make file")
- t.end()
- })
- })
- })
-})
-
-if (process.platform !== "win32") {
- tap.test("symlinky", function (t) {
- var d = path.dirname(symlinkTo)
- console.error("mkdirp", d)
- mkdirp(d, 0755, function (er) {
- t.ifError(er)
- fs.symlink(symlinkFrom, symlinkTo, "dir", function (er) {
- t.ifError(er, "make symlink")
- t.end()
- })
- })
- })
-}
-
-;["foo","bar","baz","asdf","quux","qwer","rewq"].forEach(function (w) {
- w = "/tmp/glob-test/" + w
- tap.test("create " + w, function (t) {
- mkdirp(w, function (er) {
- if (er)
- throw er
- t.pass(w)
- t.end()
- })
- })
-})
-
-
-// generate the bash pattern test-fixtures if possible
-if (process.platform === "win32" || !process.env.TEST_REGEN) {
- console.error("Windows, or TEST_REGEN unset. Using cached fixtures.")
- return
-}
-
-var spawn = require("child_process").spawn;
-var globs =
- // put more patterns here.
- // anything that would be directly in / should be in /tmp/glob-test
- ["test/a/*/+(c|g)/./d"
- ,"test/a/**/[cg]/../[cg]"
- ,"test/a/{b,c,d,e,f}/**/g"
- ,"test/a/b/**"
- ,"test/**/g"
- ,"test/a/abc{fed,def}/g/h"
- ,"test/a/abc{fed/g,def}/**/"
- ,"test/a/abc{fed/g,def}/**///**/"
- ,"test/**/a/**/"
- ,"test/+(a|b|c)/a{/,bc*}/**"
- ,"test/*/*/*/f"
- ,"test/**/f"
- ,"test/a/symlink/a/b/c/a/b/c/a/b/c//a/b/c////a/b/c/**/b/c/**"
- ,"{./*/*,/tmp/glob-test/*}"
- ,"{/tmp/glob-test/*,*}" // evil owl face! how you taunt me!
- ,"test/a/!(symlink)/**"
- ]
-var bashOutput = {}
-var fs = require("fs")
-
-globs.forEach(function (pattern) {
- tap.test("generate fixture " + pattern, function (t) {
- var cmd = "shopt -s globstar && " +
- "shopt -s extglob && " +
- "shopt -s nullglob && " +
- // "shopt >&2; " +
- "eval \'for i in " + pattern + "; do echo $i; done\'"
- var cp = spawn("bash", ["-c", cmd], { cwd: path.dirname(__dirname) })
- var out = []
- cp.stdout.on("data", function (c) {
- out.push(c)
- })
- cp.stderr.pipe(process.stderr)
- cp.on("close", function (code) {
- out = flatten(out)
- if (!out)
- out = []
- else
- out = cleanResults(out.split(/\r*\n/))
-
- bashOutput[pattern] = out
- t.notOk(code, "bash test should finish nicely")
- t.end()
- })
- })
-})
-
-tap.test("save fixtures", function (t) {
- var fname = path.resolve(__dirname, "bash-results.json")
- var data = JSON.stringify(bashOutput, null, 2) + "\n"
- fs.writeFile(fname, data, function (er) {
- t.ifError(er)
- t.end()
- })
-})
-
-function cleanResults (m) {
- // normalize discrepancies in ordering, duplication,
- // and ending slashes.
- return m.map(function (m) {
- return m.replace(/\/+/g, "/").replace(/\/$/, "")
- }).sort(alphasort).reduce(function (set, f) {
- if (f !== set[set.length - 1]) set.push(f)
- return set
- }, []).sort(alphasort).map(function (f) {
- // de-windows
- return (process.platform !== 'win32') ? f
- : f.replace(/^[a-zA-Z]:\\\\/, '/').replace(/\\/g, '/')
- })
-}
-
-function flatten (chunks) {
- var s = 0
- chunks.forEach(function (c) { s += c.length })
- var out = new Buffer(s)
- s = 0
- chunks.forEach(function (c) {
- c.copy(out, s)
- s += c.length
- })
-
- return out.toString().trim()
-}
-
-function alphasort (a, b) {
- a = a.toLowerCase()
- b = b.toLowerCase()
- return a > b ? 1 : a < b ? -1 : 0
-}
diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/bash-comparison.js b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/bash-comparison.js
deleted file mode 100644
index 239ed1a9..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/bash-comparison.js
+++ /dev/null
@@ -1,63 +0,0 @@
-// basic test
-// show that it does the same thing by default as the shell.
-var tap = require("tap")
-, child_process = require("child_process")
-, bashResults = require("./bash-results.json")
-, globs = Object.keys(bashResults)
-, glob = require("../")
-, path = require("path")
-
-// run from the root of the project
-// this is usually where you're at anyway, but be sure.
-process.chdir(path.resolve(__dirname, ".."))
-
-function alphasort (a, b) {
- a = a.toLowerCase()
- b = b.toLowerCase()
- return a > b ? 1 : a < b ? -1 : 0
-}
-
-globs.forEach(function (pattern) {
- var expect = bashResults[pattern]
- // anything regarding the symlink thing will fail on windows, so just skip it
- if (process.platform === "win32" &&
- expect.some(function (m) {
- return /\/symlink\//.test(m)
- }))
- return
-
- tap.test(pattern, function (t) {
- glob(pattern, function (er, matches) {
- if (er)
- throw er
-
- // sort and unmark, just to match the shell results
- matches = cleanResults(matches)
-
- t.deepEqual(matches, expect, pattern)
- t.end()
- })
- })
-
- tap.test(pattern + " sync", function (t) {
- var matches = cleanResults(glob.sync(pattern))
-
- t.deepEqual(matches, expect, "should match shell")
- t.end()
- })
-})
-
-function cleanResults (m) {
- // normalize discrepancies in ordering, duplication,
- // and ending slashes.
- return m.map(function (m) {
- return m.replace(/\/+/g, "/").replace(/\/$/, "")
- }).sort(alphasort).reduce(function (set, f) {
- if (f !== set[set.length - 1]) set.push(f)
- return set
- }, []).sort(alphasort).map(function (f) {
- // de-windows
- return (process.platform !== 'win32') ? f
- : f.replace(/^[a-zA-Z]:[\/\\]+/, '/').replace(/[\\\/]+/g, '/')
- })
-}
diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/bash-results.json b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/bash-results.json
deleted file mode 100644
index 8051c723..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/bash-results.json
+++ /dev/null
@@ -1,351 +0,0 @@
-{
- "test/a/*/+(c|g)/./d": [
- "test/a/b/c/./d"
- ],
- "test/a/**/[cg]/../[cg]": [
- "test/a/abcdef/g/../g",
- "test/a/abcfed/g/../g",
- "test/a/b/c/../c",
- "test/a/c/../c",
- "test/a/c/d/c/../c",
- "test/a/symlink/a/b/c/../c",
- "test/a/symlink/a/b/c/a/b/c/../c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/../c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/../c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c"
- ],
- "test/a/{b,c,d,e,f}/**/g": [],
- "test/a/b/**": [
- "test/a/b",
- "test/a/b/c",
- "test/a/b/c/d"
- ],
- "test/**/g": [
- "test/a/abcdef/g",
- "test/a/abcfed/g"
- ],
- "test/a/abc{fed,def}/g/h": [
- "test/a/abcdef/g/h",
- "test/a/abcfed/g/h"
- ],
- "test/a/abc{fed/g,def}/**/": [
- "test/a/abcdef",
- "test/a/abcdef/g",
- "test/a/abcfed/g"
- ],
- "test/a/abc{fed/g,def}/**///**/": [
- "test/a/abcdef",
- "test/a/abcdef/g",
- "test/a/abcfed/g"
- ],
- "test/**/a/**/": [
- "test/a",
- "test/a/abcdef",
- "test/a/abcdef/g",
- "test/a/abcfed",
- "test/a/abcfed/g",
- "test/a/b",
- "test/a/b/c",
- "test/a/bc",
- "test/a/bc/e",
- "test/a/c",
- "test/a/c/d",
- "test/a/c/d/c",
- "test/a/cb",
- "test/a/cb/e",
- "test/a/symlink",
- "test/a/symlink/a",
- "test/a/symlink/a/b",
- "test/a/symlink/a/b/c",
- "test/a/symlink/a/b/c/a",
- "test/a/symlink/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b"
- ],
- "test/+(a|b|c)/a{/,bc*}/**": [
- "test/a/abcdef",
- "test/a/abcdef/g",
- "test/a/abcdef/g/h",
- "test/a/abcfed",
- "test/a/abcfed/g",
- "test/a/abcfed/g/h"
- ],
- "test/*/*/*/f": [
- "test/a/bc/e/f",
- "test/a/cb/e/f"
- ],
- "test/**/f": [
- "test/a/bc/e/f",
- "test/a/cb/e/f"
- ],
- "test/a/symlink/a/b/c/a/b/c/a/b/c//a/b/c////a/b/c/**/b/c/**": [
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
- "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c"
- ],
- "{./*/*,/tmp/glob-test/*}": [
- "./examples/g.js",
- "./examples/usr-local.js",
- "./node_modules/inherits",
- "./node_modules/minimatch",
- "./node_modules/mkdirp",
- "./node_modules/rimraf",
- "./node_modules/tap",
- "./test/00-setup.js",
- "./test/a",
- "./test/bash-comparison.js",
- "./test/bash-results.json",
- "./test/cwd-test.js",
- "./test/globstar-match.js",
- "./test/mark.js",
- "./test/new-glob-optional-options.js",
- "./test/nocase-nomagic.js",
- "./test/pause-resume.js",
- "./test/readme-issue.js",
- "./test/root-nomount.js",
- "./test/root.js",
- "./test/stat.js",
- "./test/zz-cleanup.js",
- "/tmp/glob-test/asdf",
- "/tmp/glob-test/bar",
- "/tmp/glob-test/baz",
- "/tmp/glob-test/foo",
- "/tmp/glob-test/quux",
- "/tmp/glob-test/qwer",
- "/tmp/glob-test/rewq"
- ],
- "{/tmp/glob-test/*,*}": [
- "/tmp/glob-test/asdf",
- "/tmp/glob-test/bar",
- "/tmp/glob-test/baz",
- "/tmp/glob-test/foo",
- "/tmp/glob-test/quux",
- "/tmp/glob-test/qwer",
- "/tmp/glob-test/rewq",
- "examples",
- "glob.js",
- "LICENSE",
- "node_modules",
- "package.json",
- "README.md",
- "test"
- ],
- "test/a/!(symlink)/**": [
- "test/a/abcdef",
- "test/a/abcdef/g",
- "test/a/abcdef/g/h",
- "test/a/abcfed",
- "test/a/abcfed/g",
- "test/a/abcfed/g/h",
- "test/a/b",
- "test/a/b/c",
- "test/a/b/c/d",
- "test/a/bc",
- "test/a/bc/e",
- "test/a/bc/e/f",
- "test/a/c",
- "test/a/c/d",
- "test/a/c/d/c",
- "test/a/c/d/c/b",
- "test/a/cb",
- "test/a/cb/e",
- "test/a/cb/e/f"
- ]
-}
diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/cwd-test.js b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/cwd-test.js
deleted file mode 100644
index 352c27ef..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/cwd-test.js
+++ /dev/null
@@ -1,55 +0,0 @@
-var tap = require("tap")
-
-var origCwd = process.cwd()
-process.chdir(__dirname)
-
-tap.test("changing cwd and searching for **/d", function (t) {
- var glob = require('../')
- var path = require('path')
- t.test('.', function (t) {
- glob('**/d', function (er, matches) {
- t.ifError(er)
- t.like(matches, [ 'a/b/c/d', 'a/c/d' ])
- t.end()
- })
- })
-
- t.test('a', function (t) {
- glob('**/d', {cwd:path.resolve('a')}, function (er, matches) {
- t.ifError(er)
- t.like(matches, [ 'b/c/d', 'c/d' ])
- t.end()
- })
- })
-
- t.test('a/b', function (t) {
- glob('**/d', {cwd:path.resolve('a/b')}, function (er, matches) {
- t.ifError(er)
- t.like(matches, [ 'c/d' ])
- t.end()
- })
- })
-
- t.test('a/b/', function (t) {
- glob('**/d', {cwd:path.resolve('a/b/')}, function (er, matches) {
- t.ifError(er)
- t.like(matches, [ 'c/d' ])
- t.end()
- })
- })
-
- t.test('.', function (t) {
- glob('**/d', {cwd: process.cwd()}, function (er, matches) {
- t.ifError(er)
- t.like(matches, [ 'a/b/c/d', 'a/c/d' ])
- t.end()
- })
- })
-
- t.test('cd -', function (t) {
- process.chdir(origCwd)
- t.end()
- })
-
- t.end()
-})
diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/globstar-match.js b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/globstar-match.js
deleted file mode 100644
index 9b234fa2..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/globstar-match.js
+++ /dev/null
@@ -1,19 +0,0 @@
-var Glob = require("../glob.js").Glob
-var test = require('tap').test
-
-test('globstar should not have dupe matches', function(t) {
- var pattern = 'a/**/[gh]'
- var g = new Glob(pattern, { cwd: __dirname })
- var matches = []
- g.on('match', function(m) {
- console.error('match %j', m)
- matches.push(m)
- })
- g.on('end', function(set) {
- console.error('set', set)
- matches = matches.sort()
- set = set.sort()
- t.same(matches, set, 'should have same set of matches')
- t.end()
- })
-})
diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/mark.js b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/mark.js
deleted file mode 100644
index bf411c0e..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/mark.js
+++ /dev/null
@@ -1,118 +0,0 @@
-var test = require("tap").test
-var glob = require('../')
-process.chdir(__dirname)
-
-// expose timing issues
-var lag = 5
-glob.Glob.prototype._stat = function(o) { return function(f, cb) {
- var args = arguments
- setTimeout(function() {
- o.call(this, f, cb)
- }.bind(this), lag += 5)
-}}(glob.Glob.prototype._stat)
-
-
-test("mark, with **", function (t) {
- glob("a/*b*/**", {mark: true}, function (er, results) {
- if (er)
- throw er
- var expect =
- [ 'a/abcdef/',
- 'a/abcdef/g/',
- 'a/abcdef/g/h',
- 'a/abcfed/',
- 'a/abcfed/g/',
- 'a/abcfed/g/h',
- 'a/b/',
- 'a/b/c/',
- 'a/b/c/d',
- 'a/bc/',
- 'a/bc/e/',
- 'a/bc/e/f',
- 'a/cb/',
- 'a/cb/e/',
- 'a/cb/e/f' ]
-
- t.same(results, expect)
- t.end()
- })
-})
-
-test("mark, no / on pattern", function (t) {
- glob("a/*", {mark: true}, function (er, results) {
- if (er)
- throw er
- var expect = [ 'a/abcdef/',
- 'a/abcfed/',
- 'a/b/',
- 'a/bc/',
- 'a/c/',
- 'a/cb/' ]
-
- if (process.platform !== "win32")
- expect.push('a/symlink/')
-
- t.same(results, expect)
- t.end()
- }).on('match', function(m) {
- t.similar(m, /\/$/)
- })
-})
-
-test("mark=false, no / on pattern", function (t) {
- glob("a/*", function (er, results) {
- if (er)
- throw er
- var expect = [ 'a/abcdef',
- 'a/abcfed',
- 'a/b',
- 'a/bc',
- 'a/c',
- 'a/cb' ]
-
- if (process.platform !== "win32")
- expect.push('a/symlink')
- t.same(results, expect)
- t.end()
- }).on('match', function(m) {
- t.similar(m, /[^\/]$/)
- })
-})
-
-test("mark=true, / on pattern", function (t) {
- glob("a/*/", {mark: true}, function (er, results) {
- if (er)
- throw er
- var expect = [ 'a/abcdef/',
- 'a/abcfed/',
- 'a/b/',
- 'a/bc/',
- 'a/c/',
- 'a/cb/' ]
- if (process.platform !== "win32")
- expect.push('a/symlink/')
- t.same(results, expect)
- t.end()
- }).on('match', function(m) {
- t.similar(m, /\/$/)
- })
-})
-
-test("mark=false, / on pattern", function (t) {
- glob("a/*/", function (er, results) {
- if (er)
- throw er
- var expect = [ 'a/abcdef/',
- 'a/abcfed/',
- 'a/b/',
- 'a/bc/',
- 'a/c/',
- 'a/cb/' ]
- if (process.platform !== "win32")
- expect.push('a/symlink/')
- t.same(results, expect)
- t.end()
- }).on('match', function(m) {
- t.similar(m, /\/$/)
- })
-})
diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/new-glob-optional-options.js b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/new-glob-optional-options.js
deleted file mode 100644
index 3e7dc5ac..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/new-glob-optional-options.js
+++ /dev/null
@@ -1,10 +0,0 @@
-var Glob = require('../glob.js').Glob;
-var test = require('tap').test;
-
-test('new glob, with cb, and no options', function (t) {
- new Glob(__filename, function(er, results) {
- if (er) throw er;
- t.same(results, [__filename]);
- t.end();
- });
-});
diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/nocase-nomagic.js b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/nocase-nomagic.js
deleted file mode 100644
index 2503f231..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/nocase-nomagic.js
+++ /dev/null
@@ -1,113 +0,0 @@
-var fs = require('fs');
-var test = require('tap').test;
-var glob = require('../');
-
-test('mock fs', function(t) {
- var stat = fs.stat
- var statSync = fs.statSync
- var readdir = fs.readdir
- var readdirSync = fs.readdirSync
-
- function fakeStat(path) {
- var ret
- switch (path.toLowerCase()) {
- case '/tmp': case '/tmp/':
- ret = { isDirectory: function() { return true } }
- break
- case '/tmp/a':
- ret = { isDirectory: function() { return false } }
- break
- }
- return ret
- }
-
- fs.stat = function(path, cb) {
- var f = fakeStat(path);
- if (f) {
- process.nextTick(function() {
- cb(null, f)
- })
- } else {
- stat.call(fs, path, cb)
- }
- }
-
- fs.statSync = function(path) {
- return fakeStat(path) || statSync.call(fs, path)
- }
-
- function fakeReaddir(path) {
- var ret
- switch (path.toLowerCase()) {
- case '/tmp': case '/tmp/':
- ret = [ 'a', 'A' ]
- break
- case '/':
- ret = ['tmp', 'tMp', 'tMP', 'TMP']
- }
- return ret
- }
-
- fs.readdir = function(path, cb) {
- var f = fakeReaddir(path)
- if (f)
- process.nextTick(function() {
- cb(null, f)
- })
- else
- readdir.call(fs, path, cb)
- }
-
- fs.readdirSync = function(path) {
- return fakeReaddir(path) || readdirSync.call(fs, path)
- }
-
- t.pass('mocked')
- t.end()
-})
-
-test('nocase, nomagic', function(t) {
- var n = 2
- var want = [ '/TMP/A',
- '/TMP/a',
- '/tMP/A',
- '/tMP/a',
- '/tMp/A',
- '/tMp/a',
- '/tmp/A',
- '/tmp/a' ]
- glob('/tmp/a', { nocase: true }, function(er, res) {
- if (er)
- throw er
- t.same(res.sort(), want)
- if (--n === 0) t.end()
- })
- glob('/tmp/A', { nocase: true }, function(er, res) {
- if (er)
- throw er
- t.same(res.sort(), want)
- if (--n === 0) t.end()
- })
-})
-
-test('nocase, with some magic', function(t) {
- t.plan(2)
- var want = [ '/TMP/A',
- '/TMP/a',
- '/tMP/A',
- '/tMP/a',
- '/tMp/A',
- '/tMp/a',
- '/tmp/A',
- '/tmp/a' ]
- glob('/tmp/*', { nocase: true }, function(er, res) {
- if (er)
- throw er
- t.same(res.sort(), want)
- })
- glob('/tmp/*', { nocase: true }, function(er, res) {
- if (er)
- throw er
- t.same(res.sort(), want)
- })
-})
diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/pause-resume.js b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/pause-resume.js
deleted file mode 100644
index e1ffbab1..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/pause-resume.js
+++ /dev/null
@@ -1,73 +0,0 @@
-// show that no match events happen while paused.
-var tap = require("tap")
-, child_process = require("child_process")
-// just some gnarly pattern with lots of matches
-, pattern = "test/a/!(symlink)/**"
-, bashResults = require("./bash-results.json")
-, patterns = Object.keys(bashResults)
-, glob = require("../")
-, Glob = glob.Glob
-, path = require("path")
-
-// run from the root of the project
-// this is usually where you're at anyway, but be sure.
-process.chdir(path.resolve(__dirname, ".."))
-
-function alphasort (a, b) {
- a = a.toLowerCase()
- b = b.toLowerCase()
- return a > b ? 1 : a < b ? -1 : 0
-}
-
-function cleanResults (m) {
- // normalize discrepancies in ordering, duplication,
- // and ending slashes.
- return m.map(function (m) {
- return m.replace(/\/+/g, "/").replace(/\/$/, "")
- }).sort(alphasort).reduce(function (set, f) {
- if (f !== set[set.length - 1]) set.push(f)
- return set
- }, []).sort(alphasort).map(function (f) {
- // de-windows
- return (process.platform !== 'win32') ? f
- : f.replace(/^[a-zA-Z]:\\\\/, '/').replace(/\\/g, '/')
- })
-}
-
-var globResults = []
-tap.test("use a Glob object, and pause/resume it", function (t) {
- var g = new Glob(pattern)
- , paused = false
- , res = []
- , expect = bashResults[pattern]
-
- g.on("pause", function () {
- console.error("pause")
- })
-
- g.on("resume", function () {
- console.error("resume")
- })
-
- g.on("match", function (m) {
- t.notOk(g.paused, "must not be paused")
- globResults.push(m)
- g.pause()
- t.ok(g.paused, "must be paused")
- setTimeout(g.resume.bind(g), 10)
- })
-
- g.on("end", function (matches) {
- t.pass("reached glob end")
- globResults = cleanResults(globResults)
- matches = cleanResults(matches)
- t.deepEqual(matches, globResults,
- "end event matches should be the same as match events")
-
- t.deepEqual(matches, expect,
- "glob matches should be the same as bash results")
-
- t.end()
- })
-})
-
diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/readme-issue.js b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/readme-issue.js
deleted file mode 100644
index 0b4e0be2..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/readme-issue.js
+++ /dev/null
@@ -1,36 +0,0 @@
-var test = require("tap").test
-var glob = require("../")
-
-var mkdirp = require("mkdirp")
-var fs = require("fs")
-var rimraf = require("rimraf")
-var dir = __dirname + "/package"
-
-test("setup", function (t) {
- mkdirp.sync(dir)
- fs.writeFileSync(dir + "/package.json", "{}", "ascii")
- fs.writeFileSync(dir + "/README", "x", "ascii")
- t.pass("setup done")
- t.end()
-})
-
-test("glob", function (t) {
- var opt = {
- cwd: dir,
- nocase: true,
- mark: true
- }
-
- glob("README?(.*)", opt, function (er, files) {
- if (er)
- throw er
- t.same(files, ["README"])
- t.end()
- })
-})
-
-test("cleanup", function (t) {
- rimraf.sync(dir)
- t.pass("clean")
- t.end()
-})
diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/root-nomount.js b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/root-nomount.js
deleted file mode 100644
index 3ac5979b..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/root-nomount.js
+++ /dev/null
@@ -1,39 +0,0 @@
-var tap = require("tap")
-
-var origCwd = process.cwd()
-process.chdir(__dirname)
-
-tap.test("changing root and searching for /b*/**", function (t) {
- var glob = require('../')
- var path = require('path')
- t.test('.', function (t) {
- glob('/b*/**', { globDebug: true, root: '.', nomount: true }, function (er, matches) {
- t.ifError(er)
- t.like(matches, [])
- t.end()
- })
- })
-
- t.test('a', function (t) {
- glob('/b*/**', { globDebug: true, root: path.resolve('a'), nomount: true }, function (er, matches) {
- t.ifError(er)
- t.like(matches, [ '/b', '/b/c', '/b/c/d', '/bc', '/bc/e', '/bc/e/f' ])
- t.end()
- })
- })
-
- t.test('root=a, cwd=a/b', function (t) {
- glob('/b*/**', { globDebug: true, root: 'a', cwd: path.resolve('a/b'), nomount: true }, function (er, matches) {
- t.ifError(er)
- t.like(matches, [ '/b', '/b/c', '/b/c/d', '/bc', '/bc/e', '/bc/e/f' ])
- t.end()
- })
- })
-
- t.test('cd -', function (t) {
- process.chdir(origCwd)
- t.end()
- })
-
- t.end()
-})
diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/root.js b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/root.js
deleted file mode 100644
index 95c23f99..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/root.js
+++ /dev/null
@@ -1,46 +0,0 @@
-var t = require("tap")
-
-var origCwd = process.cwd()
-process.chdir(__dirname)
-
-var glob = require('../')
-var path = require('path')
-
-t.test('.', function (t) {
- glob('/b*/**', { globDebug: true, root: '.' }, function (er, matches) {
- t.ifError(er)
- t.like(matches, [])
- t.end()
- })
-})
-
-
-t.test('a', function (t) {
- console.error("root=" + path.resolve('a'))
- glob('/b*/**', { globDebug: true, root: path.resolve('a') }, function (er, matches) {
- t.ifError(er)
- var wanted = [
- '/b', '/b/c', '/b/c/d', '/bc', '/bc/e', '/bc/e/f'
- ].map(function (m) {
- return path.join(path.resolve('a'), m).replace(/\\/g, '/')
- })
-
- t.like(matches, wanted)
- t.end()
- })
-})
-
-t.test('root=a, cwd=a/b', function (t) {
- glob('/b*/**', { globDebug: true, root: 'a', cwd: path.resolve('a/b') }, function (er, matches) {
- t.ifError(er)
- t.like(matches, [ '/b', '/b/c', '/b/c/d', '/bc', '/bc/e', '/bc/e/f' ].map(function (m) {
- return path.join(path.resolve('a'), m).replace(/\\/g, '/')
- }))
- t.end()
- })
-})
-
-t.test('cd -', function (t) {
- process.chdir(origCwd)
- t.end()
-})
diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/stat.js b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/stat.js
deleted file mode 100644
index 62917114..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/stat.js
+++ /dev/null
@@ -1,32 +0,0 @@
-var glob = require('../')
-var test = require('tap').test
-var path = require('path')
-
-test('stat all the things', function(t) {
- var g = new glob.Glob('a/*abc*/**', { stat: true, cwd: __dirname })
- var matches = []
- g.on('match', function(m) {
- matches.push(m)
- })
- var stats = []
- g.on('stat', function(m) {
- stats.push(m)
- })
- g.on('end', function(eof) {
- stats = stats.sort()
- matches = matches.sort()
- eof = eof.sort()
- t.same(stats, matches)
- t.same(eof, matches)
- var cache = Object.keys(this.statCache)
- t.same(cache.map(function (f) {
- return path.relative(__dirname, f)
- }).sort(), matches)
-
- cache.forEach(function(c) {
- t.equal(typeof this.statCache[c], 'object')
- }, this)
-
- t.end()
- })
-})
diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/zz-cleanup.js b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/zz-cleanup.js
deleted file mode 100644
index e085f0fa..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/zz-cleanup.js
+++ /dev/null
@@ -1,11 +0,0 @@
-// remove the fixtures
-var tap = require("tap")
-, rimraf = require("rimraf")
-, path = require("path")
-
-tap.test("cleanup fixtures", function (t) {
- rimraf(path.resolve(__dirname, "a"), function (er) {
- t.ifError(er, "removed")
- t.end()
- })
-})
diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/lodash/LICENSE.txt b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/lodash/LICENSE.txt
deleted file mode 100644
index 49869bba..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/lodash/LICENSE.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-Copyright 2012-2013 The Dojo Foundation
-Based on Underscore.js 1.5.2, copyright 2009-2013 Jeremy Ashkenas,
-DocumentCloud and Investigative Reporters & Editors
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\ No newline at end of file
diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/lodash/README.md b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/lodash/README.md
deleted file mode 100644
index 6f9598e8..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/lodash/README.md
+++ /dev/null
@@ -1,163 +0,0 @@
-# Lo-Dash v2.4.1
-A utility library delivering consistency, [customization](http://lodash.com/custom-builds), [performance](http://lodash.com/benchmarks), & [extras](http://lodash.com/#features).
-
-## Download
-
-Check out our [wiki]([https://github.com/lodash/lodash/wiki/build-differences]) for details over the differences between builds.
-
-* Modern builds perfect for newer browsers/environments:
-[Development](https://raw.github.com/lodash/lodash/2.4.1/dist/lodash.js) &
-[Production](https://raw.github.com/lodash/lodash/2.4.1/dist/lodash.min.js)
-
-* Compatibility builds for older environment support too:
-[Development](https://raw.github.com/lodash/lodash/2.4.1/dist/lodash.compat.js) &
-[Production](https://raw.github.com/lodash/lodash/2.4.1/dist/lodash.compat.min.js)
-
-* Underscore builds to use as a drop-in replacement:
-[Development](https://raw.github.com/lodash/lodash/2.4.1/dist/lodash.underscore.js) &
-[Production](https://raw.github.com/lodash/lodash/2.4.1/dist/lodash.underscore.min.js)
-
-CDN copies are available on [cdnjs](http://cdnjs.com/libraries/lodash.js/) & [jsDelivr](http://www.jsdelivr.com/#!lodash). For smaller file sizes, create [custom builds](http://lodash.com/custom-builds) with only the features needed.
-
-Love modules? We’ve got you covered with [lodash-amd](https://npmjs.org/package/lodash-amd), [lodash-es6](https://github.com/lodash/lodash-es6), [lodash-node](https://npmjs.org/package/lodash-node), & [npm packages](https://npmjs.org/browse/keyword/lodash-modularized) per method.
-
-## Dive in
-
-There’s plenty of **[documentation](http://lodash.com/docs)**, [unit tests](http://lodash.com/tests), & [benchmarks](http://lodash.com/benchmarks).
-Check out DevDocs as a fast, organized, & searchable interface for our documentation.
-
-The full changelog for this release is available on our [wiki](https://github.com/lodash/lodash/wiki/Changelog).
-A list of upcoming features is available on our [roadmap](https://github.com/lodash/lodash/wiki/Roadmap).
-
-## Features *not* in Underscore
-
- * AMD loader support ([curl](https://github.com/cujojs/curl), [dojo](http://dojotoolkit.org/), [requirejs](http://requirejs.org/), etc.)
- * [_(…)](http://lodash.com/docs#_) supports intuitive chaining
- * [_.at](http://lodash.com/docs#at) for cherry-picking collection values
- * [_.bindKey](http://lodash.com/docs#bindKey) for binding [*“lazy”*](http://michaux.ca/articles/lazy-function-definition-pattern) defined methods
- * [_.clone](http://lodash.com/docs#clone) supports shallow cloning of `Date` & `RegExp` objects
- * [_.cloneDeep](http://lodash.com/docs#cloneDeep) for deep cloning arrays & objects
- * [_.constant](http://lodash.com/docs#constant) & [_.property](http://lodash.com/docs#property) function generators for composing functions
- * [_.contains](http://lodash.com/docs#contains) accepts a `fromIndex`
- * [_.create](http://lodash.com/docs#create) for easier object inheritance
- * [_.createCallback](http://lodash.com/docs#createCallback) for extending callbacks in methods & mixins
- * [_.curry](http://lodash.com/docs#curry) for creating [curried](http://hughfdjackson.com/javascript/2013/07/06/why-curry-helps/) functions
- * [_.debounce](http://lodash.com/docs#debounce) & [_.throttle](http://lodash.com/docs#throttle) accept additional `options` for more control
- * [_.findIndex](http://lodash.com/docs#findIndex) & [_.findKey](http://lodash.com/docs#findKey) for finding indexes & keys
- * [_.forEach](http://lodash.com/docs#forEach) is chainable & supports exiting early
- * [_.forIn](http://lodash.com/docs#forIn) for iterating own & inherited properties
- * [_.forOwn](http://lodash.com/docs#forOwn) for iterating own properties
- * [_.isPlainObject](http://lodash.com/docs#isPlainObject) for checking if values are created by `Object`
- * [_.mapValues](http://lodash.com/docs#mapValues) for [mapping](http://lodash.com/docs#map) values to an object
- * [_.memoize](http://lodash.com/docs#memoize) exposes the `cache` of memoized functions
- * [_.merge](http://lodash.com/docs#merge) for a deep [_.extend](http://lodash.com/docs#extend)
- * [_.noop](http://lodash.com/docs#noop) for function placeholders
- * [_.now](http://lodash.com/docs#now) as a cross-browser `Date.now` alternative
- * [_.parseInt](http://lodash.com/docs#parseInt) for consistent behavior
- * [_.pull](http://lodash.com/docs#pull) & [_.remove](http://lodash.com/docs#remove) for mutating arrays
- * [_.random](http://lodash.com/docs#random) supports returning floating-point numbers
- * [_.runInContext](http://lodash.com/docs#runInContext) for easier mocking
- * [_.sortBy](http://lodash.com/docs#sortBy) supports sorting by multiple properties
- * [_.support](http://lodash.com/docs#support) for flagging environment features
- * [_.template](http://lodash.com/docs#template) supports [*“imports”*](http://lodash.com/docs#templateSettings_imports) options & [ES6 template delimiters](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-literals-string-literals)
- * [_.transform](http://lodash.com/docs#transform) as a powerful alternative to [_.reduce](http://lodash.com/docs#reduce) for transforming objects
- * [_.where](http://lodash.com/docs#where) supports deep object comparisons
- * [_.xor](http://lodash.com/docs#xor) as a companion to [_.difference](http://lodash.com/docs#difference), [_.intersection](http://lodash.com/docs#intersection), & [_.union](http://lodash.com/docs#union)
- * [_.zip](http://lodash.com/docs#zip) is capable of unzipping values
- * [_.omit](http://lodash.com/docs#omit), [_.pick](http://lodash.com/docs#pick), &
- [more](http://lodash.com/docs "_.assign, _.clone, _.cloneDeep, _.first, _.initial, _.isEqual, _.last, _.merge, _.rest") accept callbacks
- * [_.contains](http://lodash.com/docs#contains), [_.toArray](http://lodash.com/docs#toArray), &
- [more](http://lodash.com/docs "_.at, _.countBy, _.every, _.filter, _.find, _.forEach, _.forEachRight, _.groupBy, _.invoke, _.map, _.max, _.min, _.pluck, _.reduce, _.reduceRight, _.reject, _.shuffle, _.size, _.some, _.sortBy, _.where") accept strings
- * [_.filter](http://lodash.com/docs#filter), [_.map](http://lodash.com/docs#map), &
- [more](http://lodash.com/docs "_.countBy, _.every, _.find, _.findKey, _.findLast, _.findLastIndex, _.findLastKey, _.first, _.groupBy, _.initial, _.last, _.max, _.min, _.reject, _.rest, _.some, _.sortBy, _.sortedIndex, _.uniq") support *“_.pluck”* & *“_.where”* shorthands
- * [_.findLast](http://lodash.com/docs#findLast), [_.findLastIndex](http://lodash.com/docs#findLastIndex), &
- [more](http://lodash.com/docs "_.findLastKey, _.forEachRight, _.forInRight, _.forOwnRight, _.partialRight") right-associative methods
-
-## Resources
-
- * Podcasts
- - [JavaScript Jabber](http://javascriptjabber.com/079-jsj-lo-dash-with-john-david-dalton/)
-
- * Posts
- - [Say “Hello” to Lo-Dash](http://kitcambridge.be/blog/say-hello-to-lo-dash/)
- - [Custom builds in Lo-Dash 2.0](http://kitcambridge.be/blog/custom-builds-in-lo-dash-2-dot-0/)
-
- * Videos
- - [Introduction](https://vimeo.com/44154599)
- - [Origins](https://vimeo.com/44154600)
- - [Optimizations & builds](https://vimeo.com/44154601)
- - [Native method use](https://vimeo.com/48576012)
- - [Testing](https://vimeo.com/45865290)
- - [CascadiaJS ’12](http://www.youtube.com/watch?v=dpPy4f_SeEk)
-
- A list of other community created podcasts, posts, & videos is available on our [wiki](https://github.com/lodash/lodash/wiki/Resources).
-
-## Support
-
-Tested in Chrome 5~31, Firefox 2~25, IE 6-11, Opera 9.25~17, Safari 3-7, Node.js 0.6.21~0.10.22, Narwhal 0.3.2, PhantomJS 1.9.2, RingoJS 0.9, & Rhino 1.7RC5.
-Automated browser test results [are available](https://saucelabs.com/u/lodash) as well as [Travis CI](https://travis-ci.org/) builds for [lodash](https://travis-ci.org/lodash/lodash/), [lodash-cli](https://travis-ci.org/lodash/lodash-cli/), [lodash-amd](https://travis-ci.org/lodash/lodash-amd/), [lodash-node](https://travis-ci.org/lodash/lodash-node/), & [grunt-lodash](https://travis-ci.org/lodash/grunt-lodash).
-
-Special thanks to [Sauce Labs](https://saucelabs.com/) for providing automated browser testing.
-[](https://saucelabs.com/ "Sauce Labs: Selenium Testing & More")
-
-## Installation & usage
-
-In browsers:
-
-```html
-
-```
-
-Using [`npm`](http://npmjs.org/):
-
-```bash
-npm i --save lodash
-
-{sudo} npm i -g lodash
-npm ln lodash
-```
-
-In [Node.js](http://nodejs.org/) & [Ringo](http://ringojs.org/):
-
-```js
-var _ = require('lodash');
-// or as Underscore
-var _ = require('lodash/dist/lodash.underscore');
-```
-
-**Notes:**
- * Don’t assign values to [special variable](http://nodejs.org/api/repl.html#repl_repl_features) `_` when in the REPL
- * If Lo-Dash is installed globally, run [`npm ln lodash`](http://blog.nodejs.org/2011/03/23/npm-1-0-global-vs-local-installation/) in your project’s root directory *before* requiring it
-
-In [Rhino](http://www.mozilla.org/rhino/):
-
-```js
-load('lodash.js');
-```
-
-In an AMD loader:
-
-```js
-require({
- 'packages': [
- { 'name': 'lodash', 'location': 'path/to/lodash', 'main': 'lodash' }
- ]
-},
-['lodash'], function(_) {
- console.log(_.VERSION);
-});
-```
-
-## Author
-
-| [](https://twitter.com/jdalton "Follow @jdalton on Twitter") |
-|---|
-| [John-David Dalton](http://allyoucanleet.com/) |
-
-## Contributors
-
-| [](https://twitter.com/blainebublitz "Follow @BlaineBublitz on Twitter") | [](https://twitter.com/kitcambridge "Follow @kitcambridge on Twitter") | [](https://twitter.com/mathias "Follow @mathias on Twitter") |
-|---|---|---|
-| [Blaine Bublitz](http://www.iceddev.com/) | [Kit Cambridge](http://kitcambridge.be/) | [Mathias Bynens](http://mathiasbynens.be/) |
-
-[](https://bitdeli.com/free "Bitdeli Badge")
diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/lodash/dist/lodash.compat.js b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/lodash/dist/lodash.compat.js
deleted file mode 100644
index 23798ba8..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/lodash/dist/lodash.compat.js
+++ /dev/null
@@ -1,7157 +0,0 @@
-/**
- * @license
- * Lo-Dash 2.4.1 (Custom Build)
- * Build: `lodash -o ./dist/lodash.compat.js`
- * Copyright 2012-2013 The Dojo Foundation
- * Based on Underscore.js 1.5.2
- * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
- * Available under MIT license
- */
-;(function() {
-
- /** Used as a safe reference for `undefined` in pre ES5 environments */
- var undefined;
-
- /** Used to pool arrays and objects used internally */
- var arrayPool = [],
- objectPool = [];
-
- /** Used to generate unique IDs */
- var idCounter = 0;
-
- /** Used internally to indicate various things */
- var indicatorObject = {};
-
- /** Used to prefix keys to avoid issues with `__proto__` and properties on `Object.prototype` */
- var keyPrefix = +new Date + '';
-
- /** Used as the size when optimizations are enabled for large arrays */
- var largeArraySize = 75;
-
- /** Used as the max size of the `arrayPool` and `objectPool` */
- var maxPoolSize = 40;
-
- /** Used to detect and test whitespace */
- var whitespace = (
- // whitespace
- ' \t\x0B\f\xA0\ufeff' +
-
- // line terminators
- '\n\r\u2028\u2029' +
-
- // unicode category "Zs" space separators
- '\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000'
- );
-
- /** Used to match empty string literals in compiled template source */
- var reEmptyStringLeading = /\b__p \+= '';/g,
- reEmptyStringMiddle = /\b(__p \+=) '' \+/g,
- reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g;
-
- /**
- * Used to match ES6 template delimiters
- * http://people.mozilla.org/~jorendorff/es6-draft.html#sec-literals-string-literals
- */
- var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g;
-
- /** Used to match regexp flags from their coerced string values */
- var reFlags = /\w*$/;
-
- /** Used to detected named functions */
- var reFuncName = /^\s*function[ \n\r\t]+\w/;
-
- /** Used to match "interpolate" template delimiters */
- var reInterpolate = /<%=([\s\S]+?)%>/g;
-
- /** Used to match leading whitespace and zeros to be removed */
- var reLeadingSpacesAndZeros = RegExp('^[' + whitespace + ']*0+(?=.$)');
-
- /** Used to ensure capturing order of template delimiters */
- var reNoMatch = /($^)/;
-
- /** Used to detect functions containing a `this` reference */
- var reThis = /\bthis\b/;
-
- /** Used to match unescaped characters in compiled string literals */
- var reUnescapedString = /['\n\r\t\u2028\u2029\\]/g;
-
- /** Used to assign default `context` object properties */
- var contextProps = [
- 'Array', 'Boolean', 'Date', 'Error', 'Function', 'Math', 'Number', 'Object',
- 'RegExp', 'String', '_', 'attachEvent', 'clearTimeout', 'isFinite', 'isNaN',
- 'parseInt', 'setTimeout'
- ];
-
- /** Used to fix the JScript [[DontEnum]] bug */
- var shadowedProps = [
- 'constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable',
- 'toLocaleString', 'toString', 'valueOf'
- ];
-
- /** Used to make template sourceURLs easier to identify */
- var templateCounter = 0;
-
- /** `Object#toString` result shortcuts */
- var argsClass = '[object Arguments]',
- arrayClass = '[object Array]',
- boolClass = '[object Boolean]',
- dateClass = '[object Date]',
- errorClass = '[object Error]',
- funcClass = '[object Function]',
- numberClass = '[object Number]',
- objectClass = '[object Object]',
- regexpClass = '[object RegExp]',
- stringClass = '[object String]';
-
- /** Used to identify object classifications that `_.clone` supports */
- var cloneableClasses = {};
- cloneableClasses[funcClass] = false;
- cloneableClasses[argsClass] = cloneableClasses[arrayClass] =
- cloneableClasses[boolClass] = cloneableClasses[dateClass] =
- cloneableClasses[numberClass] = cloneableClasses[objectClass] =
- cloneableClasses[regexpClass] = cloneableClasses[stringClass] = true;
-
- /** Used as an internal `_.debounce` options object */
- var debounceOptions = {
- 'leading': false,
- 'maxWait': 0,
- 'trailing': false
- };
-
- /** Used as the property descriptor for `__bindData__` */
- var descriptor = {
- 'configurable': false,
- 'enumerable': false,
- 'value': null,
- 'writable': false
- };
-
- /** Used as the data object for `iteratorTemplate` */
- var iteratorData = {
- 'args': '',
- 'array': null,
- 'bottom': '',
- 'firstArg': '',
- 'init': '',
- 'keys': null,
- 'loop': '',
- 'shadowedProps': null,
- 'support': null,
- 'top': '',
- 'useHas': false
- };
-
- /** Used to determine if values are of the language type Object */
- var objectTypes = {
- 'boolean': false,
- 'function': true,
- 'object': true,
- 'number': false,
- 'string': false,
- 'undefined': false
- };
-
- /** Used to escape characters for inclusion in compiled string literals */
- var stringEscapes = {
- '\\': '\\',
- "'": "'",
- '\n': 'n',
- '\r': 'r',
- '\t': 't',
- '\u2028': 'u2028',
- '\u2029': 'u2029'
- };
-
- /** Used as a reference to the global object */
- var root = (objectTypes[typeof window] && window) || this;
-
- /** Detect free variable `exports` */
- var freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports;
-
- /** Detect free variable `module` */
- var freeModule = objectTypes[typeof module] && module && !module.nodeType && module;
-
- /** Detect the popular CommonJS extension `module.exports` */
- var moduleExports = freeModule && freeModule.exports === freeExports && freeExports;
-
- /** Detect free variable `global` from Node.js or Browserified code and use it as `root` */
- var freeGlobal = objectTypes[typeof global] && global;
- if (freeGlobal && (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal)) {
- root = freeGlobal;
- }
-
- /*--------------------------------------------------------------------------*/
-
- /**
- * The base implementation of `_.indexOf` without support for binary searches
- * or `fromIndex` constraints.
- *
- * @private
- * @param {Array} array The array to search.
- * @param {*} value The value to search for.
- * @param {number} [fromIndex=0] The index to search from.
- * @returns {number} Returns the index of the matched value or `-1`.
- */
- function baseIndexOf(array, value, fromIndex) {
- var index = (fromIndex || 0) - 1,
- length = array ? array.length : 0;
-
- while (++index < length) {
- if (array[index] === value) {
- return index;
- }
- }
- return -1;
- }
-
- /**
- * An implementation of `_.contains` for cache objects that mimics the return
- * signature of `_.indexOf` by returning `0` if the value is found, else `-1`.
- *
- * @private
- * @param {Object} cache The cache object to inspect.
- * @param {*} value The value to search for.
- * @returns {number} Returns `0` if `value` is found, else `-1`.
- */
- function cacheIndexOf(cache, value) {
- var type = typeof value;
- cache = cache.cache;
-
- if (type == 'boolean' || value == null) {
- return cache[value] ? 0 : -1;
- }
- if (type != 'number' && type != 'string') {
- type = 'object';
- }
- var key = type == 'number' ? value : keyPrefix + value;
- cache = (cache = cache[type]) && cache[key];
-
- return type == 'object'
- ? (cache && baseIndexOf(cache, value) > -1 ? 0 : -1)
- : (cache ? 0 : -1);
- }
-
- /**
- * Adds a given value to the corresponding cache object.
- *
- * @private
- * @param {*} value The value to add to the cache.
- */
- function cachePush(value) {
- var cache = this.cache,
- type = typeof value;
-
- if (type == 'boolean' || value == null) {
- cache[value] = true;
- } else {
- if (type != 'number' && type != 'string') {
- type = 'object';
- }
- var key = type == 'number' ? value : keyPrefix + value,
- typeCache = cache[type] || (cache[type] = {});
-
- if (type == 'object') {
- (typeCache[key] || (typeCache[key] = [])).push(value);
- } else {
- typeCache[key] = true;
- }
- }
- }
-
- /**
- * Used by `_.max` and `_.min` as the default callback when a given
- * collection is a string value.
- *
- * @private
- * @param {string} value The character to inspect.
- * @returns {number} Returns the code unit of given character.
- */
- function charAtCallback(value) {
- return value.charCodeAt(0);
- }
-
- /**
- * Used by `sortBy` to compare transformed `collection` elements, stable sorting
- * them in ascending order.
- *
- * @private
- * @param {Object} a The object to compare to `b`.
- * @param {Object} b The object to compare to `a`.
- * @returns {number} Returns the sort order indicator of `1` or `-1`.
- */
- function compareAscending(a, b) {
- var ac = a.criteria,
- bc = b.criteria,
- index = -1,
- length = ac.length;
-
- while (++index < length) {
- var value = ac[index],
- other = bc[index];
-
- if (value !== other) {
- if (value > other || typeof value == 'undefined') {
- return 1;
- }
- if (value < other || typeof other == 'undefined') {
- return -1;
- }
- }
- }
- // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications
- // that causes it, under certain circumstances, to return the same value for
- // `a` and `b`. See https://github.com/jashkenas/underscore/pull/1247
- //
- // This also ensures a stable sort in V8 and other engines.
- // See http://code.google.com/p/v8/issues/detail?id=90
- return a.index - b.index;
- }
-
- /**
- * Creates a cache object to optimize linear searches of large arrays.
- *
- * @private
- * @param {Array} [array=[]] The array to search.
- * @returns {null|Object} Returns the cache object or `null` if caching should not be used.
- */
- function createCache(array) {
- var index = -1,
- length = array.length,
- first = array[0],
- mid = array[(length / 2) | 0],
- last = array[length - 1];
-
- if (first && typeof first == 'object' &&
- mid && typeof mid == 'object' && last && typeof last == 'object') {
- return false;
- }
- var cache = getObject();
- cache['false'] = cache['null'] = cache['true'] = cache['undefined'] = false;
-
- var result = getObject();
- result.array = array;
- result.cache = cache;
- result.push = cachePush;
-
- while (++index < length) {
- result.push(array[index]);
- }
- return result;
- }
-
- /**
- * Used by `template` to escape characters for inclusion in compiled
- * string literals.
- *
- * @private
- * @param {string} match The matched character to escape.
- * @returns {string} Returns the escaped character.
- */
- function escapeStringChar(match) {
- return '\\' + stringEscapes[match];
- }
-
- /**
- * Gets an array from the array pool or creates a new one if the pool is empty.
- *
- * @private
- * @returns {Array} The array from the pool.
- */
- function getArray() {
- return arrayPool.pop() || [];
- }
-
- /**
- * Gets an object from the object pool or creates a new one if the pool is empty.
- *
- * @private
- * @returns {Object} The object from the pool.
- */
- function getObject() {
- return objectPool.pop() || {
- 'array': null,
- 'cache': null,
- 'criteria': null,
- 'false': false,
- 'index': 0,
- 'null': false,
- 'number': null,
- 'object': null,
- 'push': null,
- 'string': null,
- 'true': false,
- 'undefined': false,
- 'value': null
- };
- }
-
- /**
- * Checks if `value` is a DOM node in IE < 9.
- *
- * @private
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if the `value` is a DOM node, else `false`.
- */
- function isNode(value) {
- // IE < 9 presents DOM nodes as `Object` objects except they have `toString`
- // methods that are `typeof` "string" and still can coerce nodes to strings
- return typeof value.toString != 'function' && typeof (value + '') == 'string';
- }
-
- /**
- * Releases the given array back to the array pool.
- *
- * @private
- * @param {Array} [array] The array to release.
- */
- function releaseArray(array) {
- array.length = 0;
- if (arrayPool.length < maxPoolSize) {
- arrayPool.push(array);
- }
- }
-
- /**
- * Releases the given object back to the object pool.
- *
- * @private
- * @param {Object} [object] The object to release.
- */
- function releaseObject(object) {
- var cache = object.cache;
- if (cache) {
- releaseObject(cache);
- }
- object.array = object.cache = object.criteria = object.object = object.number = object.string = object.value = null;
- if (objectPool.length < maxPoolSize) {
- objectPool.push(object);
- }
- }
-
- /**
- * Slices the `collection` from the `start` index up to, but not including,
- * the `end` index.
- *
- * Note: This function is used instead of `Array#slice` to support node lists
- * in IE < 9 and to ensure dense arrays are returned.
- *
- * @private
- * @param {Array|Object|string} collection The collection to slice.
- * @param {number} start The start index.
- * @param {number} end The end index.
- * @returns {Array} Returns the new array.
- */
- function slice(array, start, end) {
- start || (start = 0);
- if (typeof end == 'undefined') {
- end = array ? array.length : 0;
- }
- var index = -1,
- length = end - start || 0,
- result = Array(length < 0 ? 0 : length);
-
- while (++index < length) {
- result[index] = array[start + index];
- }
- return result;
- }
-
- /*--------------------------------------------------------------------------*/
-
- /**
- * Create a new `lodash` function using the given context object.
- *
- * @static
- * @memberOf _
- * @category Utilities
- * @param {Object} [context=root] The context object.
- * @returns {Function} Returns the `lodash` function.
- */
- function runInContext(context) {
- // Avoid issues with some ES3 environments that attempt to use values, named
- // after built-in constructors like `Object`, for the creation of literals.
- // ES5 clears this up by stating that literals must use built-in constructors.
- // See http://es5.github.io/#x11.1.5.
- context = context ? _.defaults(root.Object(), context, _.pick(root, contextProps)) : root;
-
- /** Native constructor references */
- var Array = context.Array,
- Boolean = context.Boolean,
- Date = context.Date,
- Error = context.Error,
- Function = context.Function,
- Math = context.Math,
- Number = context.Number,
- Object = context.Object,
- RegExp = context.RegExp,
- String = context.String,
- TypeError = context.TypeError;
-
- /**
- * Used for `Array` method references.
- *
- * Normally `Array.prototype` would suffice, however, using an array literal
- * avoids issues in Narwhal.
- */
- var arrayRef = [];
-
- /** Used for native method references */
- var errorProto = Error.prototype,
- objectProto = Object.prototype,
- stringProto = String.prototype;
-
- /** Used to restore the original `_` reference in `noConflict` */
- var oldDash = context._;
-
- /** Used to resolve the internal [[Class]] of values */
- var toString = objectProto.toString;
-
- /** Used to detect if a method is native */
- var reNative = RegExp('^' +
- String(toString)
- .replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
- .replace(/toString| for [^\]]+/g, '.*?') + '$'
- );
-
- /** Native method shortcuts */
- var ceil = Math.ceil,
- clearTimeout = context.clearTimeout,
- floor = Math.floor,
- fnToString = Function.prototype.toString,
- getPrototypeOf = isNative(getPrototypeOf = Object.getPrototypeOf) && getPrototypeOf,
- hasOwnProperty = objectProto.hasOwnProperty,
- push = arrayRef.push,
- propertyIsEnumerable = objectProto.propertyIsEnumerable,
- setTimeout = context.setTimeout,
- splice = arrayRef.splice,
- unshift = arrayRef.unshift;
-
- /** Used to set meta data on functions */
- var defineProperty = (function() {
- // IE 8 only accepts DOM elements
- try {
- var o = {},
- func = isNative(func = Object.defineProperty) && func,
- result = func(o, o, o) && func;
- } catch(e) { }
- return result;
- }());
-
- /* Native method shortcuts for methods with the same name as other `lodash` methods */
- var nativeCreate = isNative(nativeCreate = Object.create) && nativeCreate,
- nativeIsArray = isNative(nativeIsArray = Array.isArray) && nativeIsArray,
- nativeIsFinite = context.isFinite,
- nativeIsNaN = context.isNaN,
- nativeKeys = isNative(nativeKeys = Object.keys) && nativeKeys,
- nativeMax = Math.max,
- nativeMin = Math.min,
- nativeParseInt = context.parseInt,
- nativeRandom = Math.random;
-
- /** Used to lookup a built-in constructor by [[Class]] */
- var ctorByClass = {};
- ctorByClass[arrayClass] = Array;
- ctorByClass[boolClass] = Boolean;
- ctorByClass[dateClass] = Date;
- ctorByClass[funcClass] = Function;
- ctorByClass[objectClass] = Object;
- ctorByClass[numberClass] = Number;
- ctorByClass[regexpClass] = RegExp;
- ctorByClass[stringClass] = String;
-
- /** Used to avoid iterating non-enumerable properties in IE < 9 */
- var nonEnumProps = {};
- nonEnumProps[arrayClass] = nonEnumProps[dateClass] = nonEnumProps[numberClass] = { 'constructor': true, 'toLocaleString': true, 'toString': true, 'valueOf': true };
- nonEnumProps[boolClass] = nonEnumProps[stringClass] = { 'constructor': true, 'toString': true, 'valueOf': true };
- nonEnumProps[errorClass] = nonEnumProps[funcClass] = nonEnumProps[regexpClass] = { 'constructor': true, 'toString': true };
- nonEnumProps[objectClass] = { 'constructor': true };
-
- (function() {
- var length = shadowedProps.length;
- while (length--) {
- var key = shadowedProps[length];
- for (var className in nonEnumProps) {
- if (hasOwnProperty.call(nonEnumProps, className) && !hasOwnProperty.call(nonEnumProps[className], key)) {
- nonEnumProps[className][key] = false;
- }
- }
- }
- }());
-
- /*--------------------------------------------------------------------------*/
-
- /**
- * Creates a `lodash` object which wraps the given value to enable intuitive
- * method chaining.
- *
- * In addition to Lo-Dash methods, wrappers also have the following `Array` methods:
- * `concat`, `join`, `pop`, `push`, `reverse`, `shift`, `slice`, `sort`, `splice`,
- * and `unshift`
- *
- * Chaining is supported in custom builds as long as the `value` method is
- * implicitly or explicitly included in the build.
- *
- * The chainable wrapper functions are:
- * `after`, `assign`, `bind`, `bindAll`, `bindKey`, `chain`, `compact`,
- * `compose`, `concat`, `countBy`, `create`, `createCallback`, `curry`,
- * `debounce`, `defaults`, `defer`, `delay`, `difference`, `filter`, `flatten`,
- * `forEach`, `forEachRight`, `forIn`, `forInRight`, `forOwn`, `forOwnRight`,
- * `functions`, `groupBy`, `indexBy`, `initial`, `intersection`, `invert`,
- * `invoke`, `keys`, `map`, `max`, `memoize`, `merge`, `min`, `object`, `omit`,
- * `once`, `pairs`, `partial`, `partialRight`, `pick`, `pluck`, `pull`, `push`,
- * `range`, `reject`, `remove`, `rest`, `reverse`, `shuffle`, `slice`, `sort`,
- * `sortBy`, `splice`, `tap`, `throttle`, `times`, `toArray`, `transform`,
- * `union`, `uniq`, `unshift`, `unzip`, `values`, `where`, `without`, `wrap`,
- * and `zip`
- *
- * The non-chainable wrapper functions are:
- * `clone`, `cloneDeep`, `contains`, `escape`, `every`, `find`, `findIndex`,
- * `findKey`, `findLast`, `findLastIndex`, `findLastKey`, `has`, `identity`,
- * `indexOf`, `isArguments`, `isArray`, `isBoolean`, `isDate`, `isElement`,
- * `isEmpty`, `isEqual`, `isFinite`, `isFunction`, `isNaN`, `isNull`, `isNumber`,
- * `isObject`, `isPlainObject`, `isRegExp`, `isString`, `isUndefined`, `join`,
- * `lastIndexOf`, `mixin`, `noConflict`, `parseInt`, `pop`, `random`, `reduce`,
- * `reduceRight`, `result`, `shift`, `size`, `some`, `sortedIndex`, `runInContext`,
- * `template`, `unescape`, `uniqueId`, and `value`
- *
- * The wrapper functions `first` and `last` return wrapped values when `n` is
- * provided, otherwise they return unwrapped values.
- *
- * Explicit chaining can be enabled by using the `_.chain` method.
- *
- * @name _
- * @constructor
- * @category Chaining
- * @param {*} value The value to wrap in a `lodash` instance.
- * @returns {Object} Returns a `lodash` instance.
- * @example
- *
- * var wrapped = _([1, 2, 3]);
- *
- * // returns an unwrapped value
- * wrapped.reduce(function(sum, num) {
- * return sum + num;
- * });
- * // => 6
- *
- * // returns a wrapped value
- * var squares = wrapped.map(function(num) {
- * return num * num;
- * });
- *
- * _.isArray(squares);
- * // => false
- *
- * _.isArray(squares.value());
- * // => true
- */
- function lodash(value) {
- // don't wrap if already wrapped, even if wrapped by a different `lodash` constructor
- return (value && typeof value == 'object' && !isArray(value) && hasOwnProperty.call(value, '__wrapped__'))
- ? value
- : new lodashWrapper(value);
- }
-
- /**
- * A fast path for creating `lodash` wrapper objects.
- *
- * @private
- * @param {*} value The value to wrap in a `lodash` instance.
- * @param {boolean} chainAll A flag to enable chaining for all methods
- * @returns {Object} Returns a `lodash` instance.
- */
- function lodashWrapper(value, chainAll) {
- this.__chain__ = !!chainAll;
- this.__wrapped__ = value;
- }
- // ensure `new lodashWrapper` is an instance of `lodash`
- lodashWrapper.prototype = lodash.prototype;
-
- /**
- * An object used to flag environments features.
- *
- * @static
- * @memberOf _
- * @type Object
- */
- var support = lodash.support = {};
-
- (function() {
- var ctor = function() { this.x = 1; },
- object = { '0': 1, 'length': 1 },
- props = [];
-
- ctor.prototype = { 'valueOf': 1, 'y': 1 };
- for (var key in new ctor) { props.push(key); }
- for (key in arguments) { }
-
- /**
- * Detect if an `arguments` object's [[Class]] is resolvable (all but Firefox < 4, IE < 9).
- *
- * @memberOf _.support
- * @type boolean
- */
- support.argsClass = toString.call(arguments) == argsClass;
-
- /**
- * Detect if `arguments` objects are `Object` objects (all but Narwhal and Opera < 10.5).
- *
- * @memberOf _.support
- * @type boolean
- */
- support.argsObject = arguments.constructor == Object && !(arguments instanceof Array);
-
- /**
- * Detect if `name` or `message` properties of `Error.prototype` are
- * enumerable by default. (IE < 9, Safari < 5.1)
- *
- * @memberOf _.support
- * @type boolean
- */
- support.enumErrorProps = propertyIsEnumerable.call(errorProto, 'message') || propertyIsEnumerable.call(errorProto, 'name');
-
- /**
- * Detect if `prototype` properties are enumerable by default.
- *
- * Firefox < 3.6, Opera > 9.50 - Opera < 11.60, and Safari < 5.1
- * (if the prototype or a property on the prototype has been set)
- * incorrectly sets a function's `prototype` property [[Enumerable]]
- * value to `true`.
- *
- * @memberOf _.support
- * @type boolean
- */
- support.enumPrototypes = propertyIsEnumerable.call(ctor, 'prototype');
-
- /**
- * Detect if functions can be decompiled by `Function#toString`
- * (all but PS3 and older Opera mobile browsers & avoided in Windows 8 apps).
- *
- * @memberOf _.support
- * @type boolean
- */
- support.funcDecomp = !isNative(context.WinRTError) && reThis.test(runInContext);
-
- /**
- * Detect if `Function#name` is supported (all but IE).
- *
- * @memberOf _.support
- * @type boolean
- */
- support.funcNames = typeof Function.name == 'string';
-
- /**
- * Detect if `arguments` object indexes are non-enumerable
- * (Firefox < 4, IE < 9, PhantomJS, Safari < 5.1).
- *
- * @memberOf _.support
- * @type boolean
- */
- support.nonEnumArgs = key != 0;
-
- /**
- * Detect if properties shadowing those on `Object.prototype` are non-enumerable.
- *
- * In IE < 9 an objects own properties, shadowing non-enumerable ones, are
- * made non-enumerable as well (a.k.a the JScript [[DontEnum]] bug).
- *
- * @memberOf _.support
- * @type boolean
- */
- support.nonEnumShadows = !/valueOf/.test(props);
-
- /**
- * Detect if own properties are iterated after inherited properties (all but IE < 9).
- *
- * @memberOf _.support
- * @type boolean
- */
- support.ownLast = props[0] != 'x';
-
- /**
- * Detect if `Array#shift` and `Array#splice` augment array-like objects correctly.
- *
- * Firefox < 10, IE compatibility mode, and IE < 9 have buggy Array `shift()`
- * and `splice()` functions that fail to remove the last element, `value[0]`,
- * of array-like objects even though the `length` property is set to `0`.
- * The `shift()` method is buggy in IE 8 compatibility mode, while `splice()`
- * is buggy regardless of mode in IE < 9 and buggy in compatibility mode in IE 9.
- *
- * @memberOf _.support
- * @type boolean
- */
- support.spliceObjects = (arrayRef.splice.call(object, 0, 1), !object[0]);
-
- /**
- * Detect lack of support for accessing string characters by index.
- *
- * IE < 8 can't access characters by index and IE 8 can only access
- * characters by index on string literals.
- *
- * @memberOf _.support
- * @type boolean
- */
- support.unindexedChars = ('x'[0] + Object('x')[0]) != 'xx';
-
- /**
- * Detect if a DOM node's [[Class]] is resolvable (all but IE < 9)
- * and that the JS engine errors when attempting to coerce an object to
- * a string without a `toString` function.
- *
- * @memberOf _.support
- * @type boolean
- */
- try {
- support.nodeClass = !(toString.call(document) == objectClass && !({ 'toString': 0 } + ''));
- } catch(e) {
- support.nodeClass = true;
- }
- }(1));
-
- /**
- * By default, the template delimiters used by Lo-Dash are similar to those in
- * embedded Ruby (ERB). Change the following template settings to use alternative
- * delimiters.
- *
- * @static
- * @memberOf _
- * @type Object
- */
- lodash.templateSettings = {
-
- /**
- * Used to detect `data` property values to be HTML-escaped.
- *
- * @memberOf _.templateSettings
- * @type RegExp
- */
- 'escape': /<%-([\s\S]+?)%>/g,
-
- /**
- * Used to detect code to be evaluated.
- *
- * @memberOf _.templateSettings
- * @type RegExp
- */
- 'evaluate': /<%([\s\S]+?)%>/g,
-
- /**
- * Used to detect `data` property values to inject.
- *
- * @memberOf _.templateSettings
- * @type RegExp
- */
- 'interpolate': reInterpolate,
-
- /**
- * Used to reference the data object in the template text.
- *
- * @memberOf _.templateSettings
- * @type string
- */
- 'variable': '',
-
- /**
- * Used to import variables into the compiled template.
- *
- * @memberOf _.templateSettings
- * @type Object
- */
- 'imports': {
-
- /**
- * A reference to the `lodash` function.
- *
- * @memberOf _.templateSettings.imports
- * @type Function
- */
- '_': lodash
- }
- };
-
- /*--------------------------------------------------------------------------*/
-
- /**
- * The template used to create iterator functions.
- *
- * @private
- * @param {Object} data The data object used to populate the text.
- * @returns {string} Returns the interpolated text.
- */
- var iteratorTemplate = function(obj) {
-
- var __p = 'var index, iterable = ' +
- (obj.firstArg) +
- ', result = ' +
- (obj.init) +
- ';\nif (!iterable) return result;\n' +
- (obj.top) +
- ';';
- if (obj.array) {
- __p += '\nvar length = iterable.length; index = -1;\nif (' +
- (obj.array) +
- ') { ';
- if (support.unindexedChars) {
- __p += '\n if (isString(iterable)) {\n iterable = iterable.split(\'\')\n } ';
- }
- __p += '\n while (++index < length) {\n ' +
- (obj.loop) +
- ';\n }\n}\nelse { ';
- } else if (support.nonEnumArgs) {
- __p += '\n var length = iterable.length; index = -1;\n if (length && isArguments(iterable)) {\n while (++index < length) {\n index += \'\';\n ' +
- (obj.loop) +
- ';\n }\n } else { ';
- }
-
- if (support.enumPrototypes) {
- __p += '\n var skipProto = typeof iterable == \'function\';\n ';
- }
-
- if (support.enumErrorProps) {
- __p += '\n var skipErrorProps = iterable === errorProto || iterable instanceof Error;\n ';
- }
-
- var conditions = []; if (support.enumPrototypes) { conditions.push('!(skipProto && index == "prototype")'); } if (support.enumErrorProps) { conditions.push('!(skipErrorProps && (index == "message" || index == "name"))'); }
-
- if (obj.useHas && obj.keys) {
- __p += '\n var ownIndex = -1,\n ownProps = objectTypes[typeof iterable] && keys(iterable),\n length = ownProps ? ownProps.length : 0;\n\n while (++ownIndex < length) {\n index = ownProps[ownIndex];\n';
- if (conditions.length) {
- __p += ' if (' +
- (conditions.join(' && ')) +
- ') {\n ';
- }
- __p +=
- (obj.loop) +
- '; ';
- if (conditions.length) {
- __p += '\n }';
- }
- __p += '\n } ';
- } else {
- __p += '\n for (index in iterable) {\n';
- if (obj.useHas) { conditions.push("hasOwnProperty.call(iterable, index)"); } if (conditions.length) {
- __p += ' if (' +
- (conditions.join(' && ')) +
- ') {\n ';
- }
- __p +=
- (obj.loop) +
- '; ';
- if (conditions.length) {
- __p += '\n }';
- }
- __p += '\n } ';
- if (support.nonEnumShadows) {
- __p += '\n\n if (iterable !== objectProto) {\n var ctor = iterable.constructor,\n isProto = iterable === (ctor && ctor.prototype),\n className = iterable === stringProto ? stringClass : iterable === errorProto ? errorClass : toString.call(iterable),\n nonEnum = nonEnumProps[className];\n ';
- for (k = 0; k < 7; k++) {
- __p += '\n index = \'' +
- (obj.shadowedProps[k]) +
- '\';\n if ((!(isProto && nonEnum[index]) && hasOwnProperty.call(iterable, index))';
- if (!obj.useHas) {
- __p += ' || (!nonEnum[index] && iterable[index] !== objectProto[index])';
- }
- __p += ') {\n ' +
- (obj.loop) +
- ';\n } ';
- }
- __p += '\n } ';
- }
-
- }
-
- if (obj.array || support.nonEnumArgs) {
- __p += '\n}';
- }
- __p +=
- (obj.bottom) +
- ';\nreturn result';
-
- return __p
- };
-
- /*--------------------------------------------------------------------------*/
-
- /**
- * The base implementation of `_.bind` that creates the bound function and
- * sets its meta data.
- *
- * @private
- * @param {Array} bindData The bind data array.
- * @returns {Function} Returns the new bound function.
- */
- function baseBind(bindData) {
- var func = bindData[0],
- partialArgs = bindData[2],
- thisArg = bindData[4];
-
- function bound() {
- // `Function#bind` spec
- // http://es5.github.io/#x15.3.4.5
- if (partialArgs) {
- // avoid `arguments` object deoptimizations by using `slice` instead
- // of `Array.prototype.slice.call` and not assigning `arguments` to a
- // variable as a ternary expression
- var args = slice(partialArgs);
- push.apply(args, arguments);
- }
- // mimic the constructor's `return` behavior
- // http://es5.github.io/#x13.2.2
- if (this instanceof bound) {
- // ensure `new bound` is an instance of `func`
- var thisBinding = baseCreate(func.prototype),
- result = func.apply(thisBinding, args || arguments);
- return isObject(result) ? result : thisBinding;
- }
- return func.apply(thisArg, args || arguments);
- }
- setBindData(bound, bindData);
- return bound;
- }
-
- /**
- * The base implementation of `_.clone` without argument juggling or support
- * for `thisArg` binding.
- *
- * @private
- * @param {*} value The value to clone.
- * @param {boolean} [isDeep=false] Specify a deep clone.
- * @param {Function} [callback] The function to customize cloning values.
- * @param {Array} [stackA=[]] Tracks traversed source objects.
- * @param {Array} [stackB=[]] Associates clones with source counterparts.
- * @returns {*} Returns the cloned value.
- */
- function baseClone(value, isDeep, callback, stackA, stackB) {
- if (callback) {
- var result = callback(value);
- if (typeof result != 'undefined') {
- return result;
- }
- }
- // inspect [[Class]]
- var isObj = isObject(value);
- if (isObj) {
- var className = toString.call(value);
- if (!cloneableClasses[className] || (!support.nodeClass && isNode(value))) {
- return value;
- }
- var ctor = ctorByClass[className];
- switch (className) {
- case boolClass:
- case dateClass:
- return new ctor(+value);
-
- case numberClass:
- case stringClass:
- return new ctor(value);
-
- case regexpClass:
- result = ctor(value.source, reFlags.exec(value));
- result.lastIndex = value.lastIndex;
- return result;
- }
- } else {
- return value;
- }
- var isArr = isArray(value);
- if (isDeep) {
- // check for circular references and return corresponding clone
- var initedStack = !stackA;
- stackA || (stackA = getArray());
- stackB || (stackB = getArray());
-
- var length = stackA.length;
- while (length--) {
- if (stackA[length] == value) {
- return stackB[length];
- }
- }
- result = isArr ? ctor(value.length) : {};
- }
- else {
- result = isArr ? slice(value) : assign({}, value);
- }
- // add array properties assigned by `RegExp#exec`
- if (isArr) {
- if (hasOwnProperty.call(value, 'index')) {
- result.index = value.index;
- }
- if (hasOwnProperty.call(value, 'input')) {
- result.input = value.input;
- }
- }
- // exit for shallow clone
- if (!isDeep) {
- return result;
- }
- // add the source value to the stack of traversed objects
- // and associate it with its clone
- stackA.push(value);
- stackB.push(result);
-
- // recursively populate clone (susceptible to call stack limits)
- (isArr ? baseEach : forOwn)(value, function(objValue, key) {
- result[key] = baseClone(objValue, isDeep, callback, stackA, stackB);
- });
-
- if (initedStack) {
- releaseArray(stackA);
- releaseArray(stackB);
- }
- return result;
- }
-
- /**
- * The base implementation of `_.create` without support for assigning
- * properties to the created object.
- *
- * @private
- * @param {Object} prototype The object to inherit from.
- * @returns {Object} Returns the new object.
- */
- function baseCreate(prototype, properties) {
- return isObject(prototype) ? nativeCreate(prototype) : {};
- }
- // fallback for browsers without `Object.create`
- if (!nativeCreate) {
- baseCreate = (function() {
- function Object() {}
- return function(prototype) {
- if (isObject(prototype)) {
- Object.prototype = prototype;
- var result = new Object;
- Object.prototype = null;
- }
- return result || context.Object();
- };
- }());
- }
-
- /**
- * The base implementation of `_.createCallback` without support for creating
- * "_.pluck" or "_.where" style callbacks.
- *
- * @private
- * @param {*} [func=identity] The value to convert to a callback.
- * @param {*} [thisArg] The `this` binding of the created callback.
- * @param {number} [argCount] The number of arguments the callback accepts.
- * @returns {Function} Returns a callback function.
- */
- function baseCreateCallback(func, thisArg, argCount) {
- if (typeof func != 'function') {
- return identity;
- }
- // exit early for no `thisArg` or already bound by `Function#bind`
- if (typeof thisArg == 'undefined' || !('prototype' in func)) {
- return func;
- }
- var bindData = func.__bindData__;
- if (typeof bindData == 'undefined') {
- if (support.funcNames) {
- bindData = !func.name;
- }
- bindData = bindData || !support.funcDecomp;
- if (!bindData) {
- var source = fnToString.call(func);
- if (!support.funcNames) {
- bindData = !reFuncName.test(source);
- }
- if (!bindData) {
- // checks if `func` references the `this` keyword and stores the result
- bindData = reThis.test(source);
- setBindData(func, bindData);
- }
- }
- }
- // exit early if there are no `this` references or `func` is bound
- if (bindData === false || (bindData !== true && bindData[1] & 1)) {
- return func;
- }
- switch (argCount) {
- case 1: return function(value) {
- return func.call(thisArg, value);
- };
- case 2: return function(a, b) {
- return func.call(thisArg, a, b);
- };
- case 3: return function(value, index, collection) {
- return func.call(thisArg, value, index, collection);
- };
- case 4: return function(accumulator, value, index, collection) {
- return func.call(thisArg, accumulator, value, index, collection);
- };
- }
- return bind(func, thisArg);
- }
-
- /**
- * The base implementation of `createWrapper` that creates the wrapper and
- * sets its meta data.
- *
- * @private
- * @param {Array} bindData The bind data array.
- * @returns {Function} Returns the new function.
- */
- function baseCreateWrapper(bindData) {
- var func = bindData[0],
- bitmask = bindData[1],
- partialArgs = bindData[2],
- partialRightArgs = bindData[3],
- thisArg = bindData[4],
- arity = bindData[5];
-
- var isBind = bitmask & 1,
- isBindKey = bitmask & 2,
- isCurry = bitmask & 4,
- isCurryBound = bitmask & 8,
- key = func;
-
- function bound() {
- var thisBinding = isBind ? thisArg : this;
- if (partialArgs) {
- var args = slice(partialArgs);
- push.apply(args, arguments);
- }
- if (partialRightArgs || isCurry) {
- args || (args = slice(arguments));
- if (partialRightArgs) {
- push.apply(args, partialRightArgs);
- }
- if (isCurry && args.length < arity) {
- bitmask |= 16 & ~32;
- return baseCreateWrapper([func, (isCurryBound ? bitmask : bitmask & ~3), args, null, thisArg, arity]);
- }
- }
- args || (args = arguments);
- if (isBindKey) {
- func = thisBinding[key];
- }
- if (this instanceof bound) {
- thisBinding = baseCreate(func.prototype);
- var result = func.apply(thisBinding, args);
- return isObject(result) ? result : thisBinding;
- }
- return func.apply(thisBinding, args);
- }
- setBindData(bound, bindData);
- return bound;
- }
-
- /**
- * The base implementation of `_.difference` that accepts a single array
- * of values to exclude.
- *
- * @private
- * @param {Array} array The array to process.
- * @param {Array} [values] The array of values to exclude.
- * @returns {Array} Returns a new array of filtered values.
- */
- function baseDifference(array, values) {
- var index = -1,
- indexOf = getIndexOf(),
- length = array ? array.length : 0,
- isLarge = length >= largeArraySize && indexOf === baseIndexOf,
- result = [];
-
- if (isLarge) {
- var cache = createCache(values);
- if (cache) {
- indexOf = cacheIndexOf;
- values = cache;
- } else {
- isLarge = false;
- }
- }
- while (++index < length) {
- var value = array[index];
- if (indexOf(values, value) < 0) {
- result.push(value);
- }
- }
- if (isLarge) {
- releaseObject(values);
- }
- return result;
- }
-
- /**
- * The base implementation of `_.flatten` without support for callback
- * shorthands or `thisArg` binding.
- *
- * @private
- * @param {Array} array The array to flatten.
- * @param {boolean} [isShallow=false] A flag to restrict flattening to a single level.
- * @param {boolean} [isStrict=false] A flag to restrict flattening to arrays and `arguments` objects.
- * @param {number} [fromIndex=0] The index to start from.
- * @returns {Array} Returns a new flattened array.
- */
- function baseFlatten(array, isShallow, isStrict, fromIndex) {
- var index = (fromIndex || 0) - 1,
- length = array ? array.length : 0,
- result = [];
-
- while (++index < length) {
- var value = array[index];
-
- if (value && typeof value == 'object' && typeof value.length == 'number'
- && (isArray(value) || isArguments(value))) {
- // recursively flatten arrays (susceptible to call stack limits)
- if (!isShallow) {
- value = baseFlatten(value, isShallow, isStrict);
- }
- var valIndex = -1,
- valLength = value.length,
- resIndex = result.length;
-
- result.length += valLength;
- while (++valIndex < valLength) {
- result[resIndex++] = value[valIndex];
- }
- } else if (!isStrict) {
- result.push(value);
- }
- }
- return result;
- }
-
- /**
- * The base implementation of `_.isEqual`, without support for `thisArg` binding,
- * that allows partial "_.where" style comparisons.
- *
- * @private
- * @param {*} a The value to compare.
- * @param {*} b The other value to compare.
- * @param {Function} [callback] The function to customize comparing values.
- * @param {Function} [isWhere=false] A flag to indicate performing partial comparisons.
- * @param {Array} [stackA=[]] Tracks traversed `a` objects.
- * @param {Array} [stackB=[]] Tracks traversed `b` objects.
- * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
- */
- function baseIsEqual(a, b, callback, isWhere, stackA, stackB) {
- // used to indicate that when comparing objects, `a` has at least the properties of `b`
- if (callback) {
- var result = callback(a, b);
- if (typeof result != 'undefined') {
- return !!result;
- }
- }
- // exit early for identical values
- if (a === b) {
- // treat `+0` vs. `-0` as not equal
- return a !== 0 || (1 / a == 1 / b);
- }
- var type = typeof a,
- otherType = typeof b;
-
- // exit early for unlike primitive values
- if (a === a &&
- !(a && objectTypes[type]) &&
- !(b && objectTypes[otherType])) {
- return false;
- }
- // exit early for `null` and `undefined` avoiding ES3's Function#call behavior
- // http://es5.github.io/#x15.3.4.4
- if (a == null || b == null) {
- return a === b;
- }
- // compare [[Class]] names
- var className = toString.call(a),
- otherClass = toString.call(b);
-
- if (className == argsClass) {
- className = objectClass;
- }
- if (otherClass == argsClass) {
- otherClass = objectClass;
- }
- if (className != otherClass) {
- return false;
- }
- switch (className) {
- case boolClass:
- case dateClass:
- // coerce dates and booleans to numbers, dates to milliseconds and booleans
- // to `1` or `0` treating invalid dates coerced to `NaN` as not equal
- return +a == +b;
-
- case numberClass:
- // treat `NaN` vs. `NaN` as equal
- return (a != +a)
- ? b != +b
- // but treat `+0` vs. `-0` as not equal
- : (a == 0 ? (1 / a == 1 / b) : a == +b);
-
- case regexpClass:
- case stringClass:
- // coerce regexes to strings (http://es5.github.io/#x15.10.6.4)
- // treat string primitives and their corresponding object instances as equal
- return a == String(b);
- }
- var isArr = className == arrayClass;
- if (!isArr) {
- // unwrap any `lodash` wrapped values
- var aWrapped = hasOwnProperty.call(a, '__wrapped__'),
- bWrapped = hasOwnProperty.call(b, '__wrapped__');
-
- if (aWrapped || bWrapped) {
- return baseIsEqual(aWrapped ? a.__wrapped__ : a, bWrapped ? b.__wrapped__ : b, callback, isWhere, stackA, stackB);
- }
- // exit for functions and DOM nodes
- if (className != objectClass || (!support.nodeClass && (isNode(a) || isNode(b)))) {
- return false;
- }
- // in older versions of Opera, `arguments` objects have `Array` constructors
- var ctorA = !support.argsObject && isArguments(a) ? Object : a.constructor,
- ctorB = !support.argsObject && isArguments(b) ? Object : b.constructor;
-
- // non `Object` object instances with different constructors are not equal
- if (ctorA != ctorB &&
- !(isFunction(ctorA) && ctorA instanceof ctorA && isFunction(ctorB) && ctorB instanceof ctorB) &&
- ('constructor' in a && 'constructor' in b)
- ) {
- return false;
- }
- }
- // assume cyclic structures are equal
- // the algorithm for detecting cyclic structures is adapted from ES 5.1
- // section 15.12.3, abstract operation `JO` (http://es5.github.io/#x15.12.3)
- var initedStack = !stackA;
- stackA || (stackA = getArray());
- stackB || (stackB = getArray());
-
- var length = stackA.length;
- while (length--) {
- if (stackA[length] == a) {
- return stackB[length] == b;
- }
- }
- var size = 0;
- result = true;
-
- // add `a` and `b` to the stack of traversed objects
- stackA.push(a);
- stackB.push(b);
-
- // recursively compare objects and arrays (susceptible to call stack limits)
- if (isArr) {
- // compare lengths to determine if a deep comparison is necessary
- length = a.length;
- size = b.length;
- result = size == length;
-
- if (result || isWhere) {
- // deep compare the contents, ignoring non-numeric properties
- while (size--) {
- var index = length,
- value = b[size];
-
- if (isWhere) {
- while (index--) {
- if ((result = baseIsEqual(a[index], value, callback, isWhere, stackA, stackB))) {
- break;
- }
- }
- } else if (!(result = baseIsEqual(a[size], value, callback, isWhere, stackA, stackB))) {
- break;
- }
- }
- }
- }
- else {
- // deep compare objects using `forIn`, instead of `forOwn`, to avoid `Object.keys`
- // which, in this case, is more costly
- forIn(b, function(value, key, b) {
- if (hasOwnProperty.call(b, key)) {
- // count the number of properties.
- size++;
- // deep compare each property value.
- return (result = hasOwnProperty.call(a, key) && baseIsEqual(a[key], value, callback, isWhere, stackA, stackB));
- }
- });
-
- if (result && !isWhere) {
- // ensure both objects have the same number of properties
- forIn(a, function(value, key, a) {
- if (hasOwnProperty.call(a, key)) {
- // `size` will be `-1` if `a` has more properties than `b`
- return (result = --size > -1);
- }
- });
- }
- }
- stackA.pop();
- stackB.pop();
-
- if (initedStack) {
- releaseArray(stackA);
- releaseArray(stackB);
- }
- return result;
- }
-
- /**
- * The base implementation of `_.merge` without argument juggling or support
- * for `thisArg` binding.
- *
- * @private
- * @param {Object} object The destination object.
- * @param {Object} source The source object.
- * @param {Function} [callback] The function to customize merging properties.
- * @param {Array} [stackA=[]] Tracks traversed source objects.
- * @param {Array} [stackB=[]] Associates values with source counterparts.
- */
- function baseMerge(object, source, callback, stackA, stackB) {
- (isArray(source) ? forEach : forOwn)(source, function(source, key) {
- var found,
- isArr,
- result = source,
- value = object[key];
-
- if (source && ((isArr = isArray(source)) || isPlainObject(source))) {
- // avoid merging previously merged cyclic sources
- var stackLength = stackA.length;
- while (stackLength--) {
- if ((found = stackA[stackLength] == source)) {
- value = stackB[stackLength];
- break;
- }
- }
- if (!found) {
- var isShallow;
- if (callback) {
- result = callback(value, source);
- if ((isShallow = typeof result != 'undefined')) {
- value = result;
- }
- }
- if (!isShallow) {
- value = isArr
- ? (isArray(value) ? value : [])
- : (isPlainObject(value) ? value : {});
- }
- // add `source` and associated `value` to the stack of traversed objects
- stackA.push(source);
- stackB.push(value);
-
- // recursively merge objects and arrays (susceptible to call stack limits)
- if (!isShallow) {
- baseMerge(value, source, callback, stackA, stackB);
- }
- }
- }
- else {
- if (callback) {
- result = callback(value, source);
- if (typeof result == 'undefined') {
- result = source;
- }
- }
- if (typeof result != 'undefined') {
- value = result;
- }
- }
- object[key] = value;
- });
- }
-
- /**
- * The base implementation of `_.random` without argument juggling or support
- * for returning floating-point numbers.
- *
- * @private
- * @param {number} min The minimum possible value.
- * @param {number} max The maximum possible value.
- * @returns {number} Returns a random number.
- */
- function baseRandom(min, max) {
- return min + floor(nativeRandom() * (max - min + 1));
- }
-
- /**
- * The base implementation of `_.uniq` without support for callback shorthands
- * or `thisArg` binding.
- *
- * @private
- * @param {Array} array The array to process.
- * @param {boolean} [isSorted=false] A flag to indicate that `array` is sorted.
- * @param {Function} [callback] The function called per iteration.
- * @returns {Array} Returns a duplicate-value-free array.
- */
- function baseUniq(array, isSorted, callback) {
- var index = -1,
- indexOf = getIndexOf(),
- length = array ? array.length : 0,
- result = [];
-
- var isLarge = !isSorted && length >= largeArraySize && indexOf === baseIndexOf,
- seen = (callback || isLarge) ? getArray() : result;
-
- if (isLarge) {
- var cache = createCache(seen);
- indexOf = cacheIndexOf;
- seen = cache;
- }
- while (++index < length) {
- var value = array[index],
- computed = callback ? callback(value, index, array) : value;
-
- if (isSorted
- ? !index || seen[seen.length - 1] !== computed
- : indexOf(seen, computed) < 0
- ) {
- if (callback || isLarge) {
- seen.push(computed);
- }
- result.push(value);
- }
- }
- if (isLarge) {
- releaseArray(seen.array);
- releaseObject(seen);
- } else if (callback) {
- releaseArray(seen);
- }
- return result;
- }
-
- /**
- * Creates a function that aggregates a collection, creating an object composed
- * of keys generated from the results of running each element of the collection
- * through a callback. The given `setter` function sets the keys and values
- * of the composed object.
- *
- * @private
- * @param {Function} setter The setter function.
- * @returns {Function} Returns the new aggregator function.
- */
- function createAggregator(setter) {
- return function(collection, callback, thisArg) {
- var result = {};
- callback = lodash.createCallback(callback, thisArg, 3);
-
- if (isArray(collection)) {
- var index = -1,
- length = collection.length;
-
- while (++index < length) {
- var value = collection[index];
- setter(result, value, callback(value, index, collection), collection);
- }
- } else {
- baseEach(collection, function(value, key, collection) {
- setter(result, value, callback(value, key, collection), collection);
- });
- }
- return result;
- };
- }
-
- /**
- * Creates a function that, when called, either curries or invokes `func`
- * with an optional `this` binding and partially applied arguments.
- *
- * @private
- * @param {Function|string} func The function or method name to reference.
- * @param {number} bitmask The bitmask of method flags to compose.
- * The bitmask may be composed of the following flags:
- * 1 - `_.bind`
- * 2 - `_.bindKey`
- * 4 - `_.curry`
- * 8 - `_.curry` (bound)
- * 16 - `_.partial`
- * 32 - `_.partialRight`
- * @param {Array} [partialArgs] An array of arguments to prepend to those
- * provided to the new function.
- * @param {Array} [partialRightArgs] An array of arguments to append to those
- * provided to the new function.
- * @param {*} [thisArg] The `this` binding of `func`.
- * @param {number} [arity] The arity of `func`.
- * @returns {Function} Returns the new function.
- */
- function createWrapper(func, bitmask, partialArgs, partialRightArgs, thisArg, arity) {
- var isBind = bitmask & 1,
- isBindKey = bitmask & 2,
- isCurry = bitmask & 4,
- isCurryBound = bitmask & 8,
- isPartial = bitmask & 16,
- isPartialRight = bitmask & 32;
-
- if (!isBindKey && !isFunction(func)) {
- throw new TypeError;
- }
- if (isPartial && !partialArgs.length) {
- bitmask &= ~16;
- isPartial = partialArgs = false;
- }
- if (isPartialRight && !partialRightArgs.length) {
- bitmask &= ~32;
- isPartialRight = partialRightArgs = false;
- }
- var bindData = func && func.__bindData__;
- if (bindData && bindData !== true) {
- // clone `bindData`
- bindData = slice(bindData);
- if (bindData[2]) {
- bindData[2] = slice(bindData[2]);
- }
- if (bindData[3]) {
- bindData[3] = slice(bindData[3]);
- }
- // set `thisBinding` is not previously bound
- if (isBind && !(bindData[1] & 1)) {
- bindData[4] = thisArg;
- }
- // set if previously bound but not currently (subsequent curried functions)
- if (!isBind && bindData[1] & 1) {
- bitmask |= 8;
- }
- // set curried arity if not yet set
- if (isCurry && !(bindData[1] & 4)) {
- bindData[5] = arity;
- }
- // append partial left arguments
- if (isPartial) {
- push.apply(bindData[2] || (bindData[2] = []), partialArgs);
- }
- // append partial right arguments
- if (isPartialRight) {
- unshift.apply(bindData[3] || (bindData[3] = []), partialRightArgs);
- }
- // merge flags
- bindData[1] |= bitmask;
- return createWrapper.apply(null, bindData);
- }
- // fast path for `_.bind`
- var creater = (bitmask == 1 || bitmask === 17) ? baseBind : baseCreateWrapper;
- return creater([func, bitmask, partialArgs, partialRightArgs, thisArg, arity]);
- }
-
- /**
- * Creates compiled iteration functions.
- *
- * @private
- * @param {...Object} [options] The compile options object(s).
- * @param {string} [options.array] Code to determine if the iterable is an array or array-like.
- * @param {boolean} [options.useHas] Specify using `hasOwnProperty` checks in the object loop.
- * @param {Function} [options.keys] A reference to `_.keys` for use in own property iteration.
- * @param {string} [options.args] A comma separated string of iteration function arguments.
- * @param {string} [options.top] Code to execute before the iteration branches.
- * @param {string} [options.loop] Code to execute in the object loop.
- * @param {string} [options.bottom] Code to execute after the iteration branches.
- * @returns {Function} Returns the compiled function.
- */
- function createIterator() {
- // data properties
- iteratorData.shadowedProps = shadowedProps;
-
- // iterator options
- iteratorData.array = iteratorData.bottom = iteratorData.loop = iteratorData.top = '';
- iteratorData.init = 'iterable';
- iteratorData.useHas = true;
-
- // merge options into a template data object
- for (var object, index = 0; object = arguments[index]; index++) {
- for (var key in object) {
- iteratorData[key] = object[key];
- }
- }
- var args = iteratorData.args;
- iteratorData.firstArg = /^[^,]+/.exec(args)[0];
-
- // create the function factory
- var factory = Function(
- 'baseCreateCallback, errorClass, errorProto, hasOwnProperty, ' +
- 'indicatorObject, isArguments, isArray, isString, keys, objectProto, ' +
- 'objectTypes, nonEnumProps, stringClass, stringProto, toString',
- 'return function(' + args + ') {\n' + iteratorTemplate(iteratorData) + '\n}'
- );
-
- // return the compiled function
- return factory(
- baseCreateCallback, errorClass, errorProto, hasOwnProperty,
- indicatorObject, isArguments, isArray, isString, iteratorData.keys, objectProto,
- objectTypes, nonEnumProps, stringClass, stringProto, toString
- );
- }
-
- /**
- * Used by `escape` to convert characters to HTML entities.
- *
- * @private
- * @param {string} match The matched character to escape.
- * @returns {string} Returns the escaped character.
- */
- function escapeHtmlChar(match) {
- return htmlEscapes[match];
- }
-
- /**
- * Gets the appropriate "indexOf" function. If the `_.indexOf` method is
- * customized, this method returns the custom method, otherwise it returns
- * the `baseIndexOf` function.
- *
- * @private
- * @returns {Function} Returns the "indexOf" function.
- */
- function getIndexOf() {
- var result = (result = lodash.indexOf) === indexOf ? baseIndexOf : result;
- return result;
- }
-
- /**
- * Checks if `value` is a native function.
- *
- * @private
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if the `value` is a native function, else `false`.
- */
- function isNative(value) {
- return typeof value == 'function' && reNative.test(value);
- }
-
- /**
- * Sets `this` binding data on a given function.
- *
- * @private
- * @param {Function} func The function to set data on.
- * @param {Array} value The data array to set.
- */
- var setBindData = !defineProperty ? noop : function(func, value) {
- descriptor.value = value;
- defineProperty(func, '__bindData__', descriptor);
- };
-
- /**
- * A fallback implementation of `isPlainObject` which checks if a given value
- * is an object created by the `Object` constructor, assuming objects created
- * by the `Object` constructor have no inherited enumerable properties and that
- * there are no `Object.prototype` extensions.
- *
- * @private
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
- */
- function shimIsPlainObject(value) {
- var ctor,
- result;
-
- // avoid non Object objects, `arguments` objects, and DOM elements
- if (!(value && toString.call(value) == objectClass) ||
- (ctor = value.constructor, isFunction(ctor) && !(ctor instanceof ctor)) ||
- (!support.argsClass && isArguments(value)) ||
- (!support.nodeClass && isNode(value))) {
- return false;
- }
- // IE < 9 iterates inherited properties before own properties. If the first
- // iterated property is an object's own property then there are no inherited
- // enumerable properties.
- if (support.ownLast) {
- forIn(value, function(value, key, object) {
- result = hasOwnProperty.call(object, key);
- return false;
- });
- return result !== false;
- }
- // In most environments an object's own properties are iterated before
- // its inherited properties. If the last iterated property is an object's
- // own property then there are no inherited enumerable properties.
- forIn(value, function(value, key) {
- result = key;
- });
- return typeof result == 'undefined' || hasOwnProperty.call(value, result);
- }
-
- /**
- * Used by `unescape` to convert HTML entities to characters.
- *
- * @private
- * @param {string} match The matched character to unescape.
- * @returns {string} Returns the unescaped character.
- */
- function unescapeHtmlChar(match) {
- return htmlUnescapes[match];
- }
-
- /*--------------------------------------------------------------------------*/
-
- /**
- * Checks if `value` is an `arguments` object.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if the `value` is an `arguments` object, else `false`.
- * @example
- *
- * (function() { return _.isArguments(arguments); })(1, 2, 3);
- * // => true
- *
- * _.isArguments([1, 2, 3]);
- * // => false
- */
- function isArguments(value) {
- return value && typeof value == 'object' && typeof value.length == 'number' &&
- toString.call(value) == argsClass || false;
- }
- // fallback for browsers that can't detect `arguments` objects by [[Class]]
- if (!support.argsClass) {
- isArguments = function(value) {
- return value && typeof value == 'object' && typeof value.length == 'number' &&
- hasOwnProperty.call(value, 'callee') && !propertyIsEnumerable.call(value, 'callee') || false;
- };
- }
-
- /**
- * Checks if `value` is an array.
- *
- * @static
- * @memberOf _
- * @type Function
- * @category Objects
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if the `value` is an array, else `false`.
- * @example
- *
- * (function() { return _.isArray(arguments); })();
- * // => false
- *
- * _.isArray([1, 2, 3]);
- * // => true
- */
- var isArray = nativeIsArray || function(value) {
- return value && typeof value == 'object' && typeof value.length == 'number' &&
- toString.call(value) == arrayClass || false;
- };
-
- /**
- * A fallback implementation of `Object.keys` which produces an array of the
- * given object's own enumerable property names.
- *
- * @private
- * @type Function
- * @param {Object} object The object to inspect.
- * @returns {Array} Returns an array of property names.
- */
- var shimKeys = createIterator({
- 'args': 'object',
- 'init': '[]',
- 'top': 'if (!(objectTypes[typeof object])) return result',
- 'loop': 'result.push(index)'
- });
-
- /**
- * Creates an array composed of the own enumerable property names of an object.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {Object} object The object to inspect.
- * @returns {Array} Returns an array of property names.
- * @example
- *
- * _.keys({ 'one': 1, 'two': 2, 'three': 3 });
- * // => ['one', 'two', 'three'] (property order is not guaranteed across environments)
- */
- var keys = !nativeKeys ? shimKeys : function(object) {
- if (!isObject(object)) {
- return [];
- }
- if ((support.enumPrototypes && typeof object == 'function') ||
- (support.nonEnumArgs && object.length && isArguments(object))) {
- return shimKeys(object);
- }
- return nativeKeys(object);
- };
-
- /** Reusable iterator options shared by `each`, `forIn`, and `forOwn` */
- var eachIteratorOptions = {
- 'args': 'collection, callback, thisArg',
- 'top': "callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3)",
- 'array': "typeof length == 'number'",
- 'keys': keys,
- 'loop': 'if (callback(iterable[index], index, collection) === false) return result'
- };
-
- /** Reusable iterator options for `assign` and `defaults` */
- var defaultsIteratorOptions = {
- 'args': 'object, source, guard',
- 'top':
- 'var args = arguments,\n' +
- ' argsIndex = 0,\n' +
- " argsLength = typeof guard == 'number' ? 2 : args.length;\n" +
- 'while (++argsIndex < argsLength) {\n' +
- ' iterable = args[argsIndex];\n' +
- ' if (iterable && objectTypes[typeof iterable]) {',
- 'keys': keys,
- 'loop': "if (typeof result[index] == 'undefined') result[index] = iterable[index]",
- 'bottom': ' }\n}'
- };
-
- /** Reusable iterator options for `forIn` and `forOwn` */
- var forOwnIteratorOptions = {
- 'top': 'if (!objectTypes[typeof iterable]) return result;\n' + eachIteratorOptions.top,
- 'array': false
- };
-
- /**
- * Used to convert characters to HTML entities:
- *
- * Though the `>` character is escaped for symmetry, characters like `>` and `/`
- * don't require escaping in HTML and have no special meaning unless they're part
- * of a tag or an unquoted attribute value.
- * http://mathiasbynens.be/notes/ambiguous-ampersands (under "semi-related fun fact")
- */
- var htmlEscapes = {
- '&': '&',
- '<': '<',
- '>': '>',
- '"': '"',
- "'": '''
- };
-
- /** Used to convert HTML entities to characters */
- var htmlUnescapes = invert(htmlEscapes);
-
- /** Used to match HTML entities and HTML characters */
- var reEscapedHtml = RegExp('(' + keys(htmlUnescapes).join('|') + ')', 'g'),
- reUnescapedHtml = RegExp('[' + keys(htmlEscapes).join('') + ']', 'g');
-
- /**
- * A function compiled to iterate `arguments` objects, arrays, objects, and
- * strings consistenly across environments, executing the callback for each
- * element in the collection. The callback is bound to `thisArg` and invoked
- * with three arguments; (value, index|key, collection). Callbacks may exit
- * iteration early by explicitly returning `false`.
- *
- * @private
- * @type Function
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function} [callback=identity] The function called per iteration.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Array|Object|string} Returns `collection`.
- */
- var baseEach = createIterator(eachIteratorOptions);
-
- /*--------------------------------------------------------------------------*/
-
- /**
- * Assigns own enumerable properties of source object(s) to the destination
- * object. Subsequent sources will overwrite property assignments of previous
- * sources. If a callback is provided it will be executed to produce the
- * assigned values. The callback is bound to `thisArg` and invoked with two
- * arguments; (objectValue, sourceValue).
- *
- * @static
- * @memberOf _
- * @type Function
- * @alias extend
- * @category Objects
- * @param {Object} object The destination object.
- * @param {...Object} [source] The source objects.
- * @param {Function} [callback] The function to customize assigning values.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Object} Returns the destination object.
- * @example
- *
- * _.assign({ 'name': 'fred' }, { 'employer': 'slate' });
- * // => { 'name': 'fred', 'employer': 'slate' }
- *
- * var defaults = _.partialRight(_.assign, function(a, b) {
- * return typeof a == 'undefined' ? b : a;
- * });
- *
- * var object = { 'name': 'barney' };
- * defaults(object, { 'name': 'fred', 'employer': 'slate' });
- * // => { 'name': 'barney', 'employer': 'slate' }
- */
- var assign = createIterator(defaultsIteratorOptions, {
- 'top':
- defaultsIteratorOptions.top.replace(';',
- ';\n' +
- "if (argsLength > 3 && typeof args[argsLength - 2] == 'function') {\n" +
- ' var callback = baseCreateCallback(args[--argsLength - 1], args[argsLength--], 2);\n' +
- "} else if (argsLength > 2 && typeof args[argsLength - 1] == 'function') {\n" +
- ' callback = args[--argsLength];\n' +
- '}'
- ),
- 'loop': 'result[index] = callback ? callback(result[index], iterable[index]) : iterable[index]'
- });
-
- /**
- * Creates a clone of `value`. If `isDeep` is `true` nested objects will also
- * be cloned, otherwise they will be assigned by reference. If a callback
- * is provided it will be executed to produce the cloned values. If the
- * callback returns `undefined` cloning will be handled by the method instead.
- * The callback is bound to `thisArg` and invoked with one argument; (value).
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {*} value The value to clone.
- * @param {boolean} [isDeep=false] Specify a deep clone.
- * @param {Function} [callback] The function to customize cloning values.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {*} Returns the cloned value.
- * @example
- *
- * var characters = [
- * { 'name': 'barney', 'age': 36 },
- * { 'name': 'fred', 'age': 40 }
- * ];
- *
- * var shallow = _.clone(characters);
- * shallow[0] === characters[0];
- * // => true
- *
- * var deep = _.clone(characters, true);
- * deep[0] === characters[0];
- * // => false
- *
- * _.mixin({
- * 'clone': _.partialRight(_.clone, function(value) {
- * return _.isElement(value) ? value.cloneNode(false) : undefined;
- * })
- * });
- *
- * var clone = _.clone(document.body);
- * clone.childNodes.length;
- * // => 0
- */
- function clone(value, isDeep, callback, thisArg) {
- // allows working with "Collections" methods without using their `index`
- // and `collection` arguments for `isDeep` and `callback`
- if (typeof isDeep != 'boolean' && isDeep != null) {
- thisArg = callback;
- callback = isDeep;
- isDeep = false;
- }
- return baseClone(value, isDeep, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 1));
- }
-
- /**
- * Creates a deep clone of `value`. If a callback is provided it will be
- * executed to produce the cloned values. If the callback returns `undefined`
- * cloning will be handled by the method instead. The callback is bound to
- * `thisArg` and invoked with one argument; (value).
- *
- * Note: This method is loosely based on the structured clone algorithm. Functions
- * and DOM nodes are **not** cloned. The enumerable properties of `arguments` objects and
- * objects created by constructors other than `Object` are cloned to plain `Object` objects.
- * See http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {*} value The value to deep clone.
- * @param {Function} [callback] The function to customize cloning values.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {*} Returns the deep cloned value.
- * @example
- *
- * var characters = [
- * { 'name': 'barney', 'age': 36 },
- * { 'name': 'fred', 'age': 40 }
- * ];
- *
- * var deep = _.cloneDeep(characters);
- * deep[0] === characters[0];
- * // => false
- *
- * var view = {
- * 'label': 'docs',
- * 'node': element
- * };
- *
- * var clone = _.cloneDeep(view, function(value) {
- * return _.isElement(value) ? value.cloneNode(true) : undefined;
- * });
- *
- * clone.node == view.node;
- * // => false
- */
- function cloneDeep(value, callback, thisArg) {
- return baseClone(value, true, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 1));
- }
-
- /**
- * Creates an object that inherits from the given `prototype` object. If a
- * `properties` object is provided its own enumerable properties are assigned
- * to the created object.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {Object} prototype The object to inherit from.
- * @param {Object} [properties] The properties to assign to the object.
- * @returns {Object} Returns the new object.
- * @example
- *
- * function Shape() {
- * this.x = 0;
- * this.y = 0;
- * }
- *
- * function Circle() {
- * Shape.call(this);
- * }
- *
- * Circle.prototype = _.create(Shape.prototype, { 'constructor': Circle });
- *
- * var circle = new Circle;
- * circle instanceof Circle;
- * // => true
- *
- * circle instanceof Shape;
- * // => true
- */
- function create(prototype, properties) {
- var result = baseCreate(prototype);
- return properties ? assign(result, properties) : result;
- }
-
- /**
- * Assigns own enumerable properties of source object(s) to the destination
- * object for all destination properties that resolve to `undefined`. Once a
- * property is set, additional defaults of the same property will be ignored.
- *
- * @static
- * @memberOf _
- * @type Function
- * @category Objects
- * @param {Object} object The destination object.
- * @param {...Object} [source] The source objects.
- * @param- {Object} [guard] Allows working with `_.reduce` without using its
- * `key` and `object` arguments as sources.
- * @returns {Object} Returns the destination object.
- * @example
- *
- * var object = { 'name': 'barney' };
- * _.defaults(object, { 'name': 'fred', 'employer': 'slate' });
- * // => { 'name': 'barney', 'employer': 'slate' }
- */
- var defaults = createIterator(defaultsIteratorOptions);
-
- /**
- * This method is like `_.findIndex` except that it returns the key of the
- * first element that passes the callback check, instead of the element itself.
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {Object} object The object to search.
- * @param {Function|Object|string} [callback=identity] The function called per
- * iteration. If a property name or object is provided it will be used to
- * create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {string|undefined} Returns the key of the found element, else `undefined`.
- * @example
- *
- * var characters = {
- * 'barney': { 'age': 36, 'blocked': false },
- * 'fred': { 'age': 40, 'blocked': true },
- * 'pebbles': { 'age': 1, 'blocked': false }
- * };
- *
- * _.findKey(characters, function(chr) {
- * return chr.age < 40;
- * });
- * // => 'barney' (property order is not guaranteed across environments)
- *
- * // using "_.where" callback shorthand
- * _.findKey(characters, { 'age': 1 });
- * // => 'pebbles'
- *
- * // using "_.pluck" callback shorthand
- * _.findKey(characters, 'blocked');
- * // => 'fred'
- */
- function findKey(object, callback, thisArg) {
- var result;
- callback = lodash.createCallback(callback, thisArg, 3);
- forOwn(object, function(value, key, object) {
- if (callback(value, key, object)) {
- result = key;
- return false;
- }
- });
- return result;
- }
-
- /**
- * This method is like `_.findKey` except that it iterates over elements
- * of a `collection` in the opposite order.
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {Object} object The object to search.
- * @param {Function|Object|string} [callback=identity] The function called per
- * iteration. If a property name or object is provided it will be used to
- * create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {string|undefined} Returns the key of the found element, else `undefined`.
- * @example
- *
- * var characters = {
- * 'barney': { 'age': 36, 'blocked': true },
- * 'fred': { 'age': 40, 'blocked': false },
- * 'pebbles': { 'age': 1, 'blocked': true }
- * };
- *
- * _.findLastKey(characters, function(chr) {
- * return chr.age < 40;
- * });
- * // => returns `pebbles`, assuming `_.findKey` returns `barney`
- *
- * // using "_.where" callback shorthand
- * _.findLastKey(characters, { 'age': 40 });
- * // => 'fred'
- *
- * // using "_.pluck" callback shorthand
- * _.findLastKey(characters, 'blocked');
- * // => 'pebbles'
- */
- function findLastKey(object, callback, thisArg) {
- var result;
- callback = lodash.createCallback(callback, thisArg, 3);
- forOwnRight(object, function(value, key, object) {
- if (callback(value, key, object)) {
- result = key;
- return false;
- }
- });
- return result;
- }
-
- /**
- * Iterates over own and inherited enumerable properties of an object,
- * executing the callback for each property. The callback is bound to `thisArg`
- * and invoked with three arguments; (value, key, object). Callbacks may exit
- * iteration early by explicitly returning `false`.
- *
- * @static
- * @memberOf _
- * @type Function
- * @category Objects
- * @param {Object} object The object to iterate over.
- * @param {Function} [callback=identity] The function called per iteration.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Object} Returns `object`.
- * @example
- *
- * function Shape() {
- * this.x = 0;
- * this.y = 0;
- * }
- *
- * Shape.prototype.move = function(x, y) {
- * this.x += x;
- * this.y += y;
- * };
- *
- * _.forIn(new Shape, function(value, key) {
- * console.log(key);
- * });
- * // => logs 'x', 'y', and 'move' (property order is not guaranteed across environments)
- */
- var forIn = createIterator(eachIteratorOptions, forOwnIteratorOptions, {
- 'useHas': false
- });
-
- /**
- * This method is like `_.forIn` except that it iterates over elements
- * of a `collection` in the opposite order.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {Object} object The object to iterate over.
- * @param {Function} [callback=identity] The function called per iteration.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Object} Returns `object`.
- * @example
- *
- * function Shape() {
- * this.x = 0;
- * this.y = 0;
- * }
- *
- * Shape.prototype.move = function(x, y) {
- * this.x += x;
- * this.y += y;
- * };
- *
- * _.forInRight(new Shape, function(value, key) {
- * console.log(key);
- * });
- * // => logs 'move', 'y', and 'x' assuming `_.forIn ` logs 'x', 'y', and 'move'
- */
- function forInRight(object, callback, thisArg) {
- var pairs = [];
-
- forIn(object, function(value, key) {
- pairs.push(key, value);
- });
-
- var length = pairs.length;
- callback = baseCreateCallback(callback, thisArg, 3);
- while (length--) {
- if (callback(pairs[length--], pairs[length], object) === false) {
- break;
- }
- }
- return object;
- }
-
- /**
- * Iterates over own enumerable properties of an object, executing the callback
- * for each property. The callback is bound to `thisArg` and invoked with three
- * arguments; (value, key, object). Callbacks may exit iteration early by
- * explicitly returning `false`.
- *
- * @static
- * @memberOf _
- * @type Function
- * @category Objects
- * @param {Object} object The object to iterate over.
- * @param {Function} [callback=identity] The function called per iteration.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Object} Returns `object`.
- * @example
- *
- * _.forOwn({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) {
- * console.log(key);
- * });
- * // => logs '0', '1', and 'length' (property order is not guaranteed across environments)
- */
- var forOwn = createIterator(eachIteratorOptions, forOwnIteratorOptions);
-
- /**
- * This method is like `_.forOwn` except that it iterates over elements
- * of a `collection` in the opposite order.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {Object} object The object to iterate over.
- * @param {Function} [callback=identity] The function called per iteration.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Object} Returns `object`.
- * @example
- *
- * _.forOwnRight({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) {
- * console.log(key);
- * });
- * // => logs 'length', '1', and '0' assuming `_.forOwn` logs '0', '1', and 'length'
- */
- function forOwnRight(object, callback, thisArg) {
- var props = keys(object),
- length = props.length;
-
- callback = baseCreateCallback(callback, thisArg, 3);
- while (length--) {
- var key = props[length];
- if (callback(object[key], key, object) === false) {
- break;
- }
- }
- return object;
- }
-
- /**
- * Creates a sorted array of property names of all enumerable properties,
- * own and inherited, of `object` that have function values.
- *
- * @static
- * @memberOf _
- * @alias methods
- * @category Objects
- * @param {Object} object The object to inspect.
- * @returns {Array} Returns an array of property names that have function values.
- * @example
- *
- * _.functions(_);
- * // => ['all', 'any', 'bind', 'bindAll', 'clone', 'compact', 'compose', ...]
- */
- function functions(object) {
- var result = [];
- forIn(object, function(value, key) {
- if (isFunction(value)) {
- result.push(key);
- }
- });
- return result.sort();
- }
-
- /**
- * Checks if the specified property name exists as a direct property of `object`,
- * instead of an inherited property.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {Object} object The object to inspect.
- * @param {string} key The name of the property to check.
- * @returns {boolean} Returns `true` if key is a direct property, else `false`.
- * @example
- *
- * _.has({ 'a': 1, 'b': 2, 'c': 3 }, 'b');
- * // => true
- */
- function has(object, key) {
- return object ? hasOwnProperty.call(object, key) : false;
- }
-
- /**
- * Creates an object composed of the inverted keys and values of the given object.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {Object} object The object to invert.
- * @returns {Object} Returns the created inverted object.
- * @example
- *
- * _.invert({ 'first': 'fred', 'second': 'barney' });
- * // => { 'fred': 'first', 'barney': 'second' }
- */
- function invert(object) {
- var index = -1,
- props = keys(object),
- length = props.length,
- result = {};
-
- while (++index < length) {
- var key = props[index];
- result[object[key]] = key;
- }
- return result;
- }
-
- /**
- * Checks if `value` is a boolean value.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if the `value` is a boolean value, else `false`.
- * @example
- *
- * _.isBoolean(null);
- * // => false
- */
- function isBoolean(value) {
- return value === true || value === false ||
- value && typeof value == 'object' && toString.call(value) == boolClass || false;
- }
-
- /**
- * Checks if `value` is a date.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if the `value` is a date, else `false`.
- * @example
- *
- * _.isDate(new Date);
- * // => true
- */
- function isDate(value) {
- return value && typeof value == 'object' && toString.call(value) == dateClass || false;
- }
-
- /**
- * Checks if `value` is a DOM element.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if the `value` is a DOM element, else `false`.
- * @example
- *
- * _.isElement(document.body);
- * // => true
- */
- function isElement(value) {
- return value && value.nodeType === 1 || false;
- }
-
- /**
- * Checks if `value` is empty. Arrays, strings, or `arguments` objects with a
- * length of `0` and objects with no own enumerable properties are considered
- * "empty".
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {Array|Object|string} value The value to inspect.
- * @returns {boolean} Returns `true` if the `value` is empty, else `false`.
- * @example
- *
- * _.isEmpty([1, 2, 3]);
- * // => false
- *
- * _.isEmpty({});
- * // => true
- *
- * _.isEmpty('');
- * // => true
- */
- function isEmpty(value) {
- var result = true;
- if (!value) {
- return result;
- }
- var className = toString.call(value),
- length = value.length;
-
- if ((className == arrayClass || className == stringClass ||
- (support.argsClass ? className == argsClass : isArguments(value))) ||
- (className == objectClass && typeof length == 'number' && isFunction(value.splice))) {
- return !length;
- }
- forOwn(value, function() {
- return (result = false);
- });
- return result;
- }
-
- /**
- * Performs a deep comparison between two values to determine if they are
- * equivalent to each other. If a callback is provided it will be executed
- * to compare values. If the callback returns `undefined` comparisons will
- * be handled by the method instead. The callback is bound to `thisArg` and
- * invoked with two arguments; (a, b).
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {*} a The value to compare.
- * @param {*} b The other value to compare.
- * @param {Function} [callback] The function to customize comparing values.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
- * @example
- *
- * var object = { 'name': 'fred' };
- * var copy = { 'name': 'fred' };
- *
- * object == copy;
- * // => false
- *
- * _.isEqual(object, copy);
- * // => true
- *
- * var words = ['hello', 'goodbye'];
- * var otherWords = ['hi', 'goodbye'];
- *
- * _.isEqual(words, otherWords, function(a, b) {
- * var reGreet = /^(?:hello|hi)$/i,
- * aGreet = _.isString(a) && reGreet.test(a),
- * bGreet = _.isString(b) && reGreet.test(b);
- *
- * return (aGreet || bGreet) ? (aGreet == bGreet) : undefined;
- * });
- * // => true
- */
- function isEqual(a, b, callback, thisArg) {
- return baseIsEqual(a, b, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 2));
- }
-
- /**
- * Checks if `value` is, or can be coerced to, a finite number.
- *
- * Note: This is not the same as native `isFinite` which will return true for
- * booleans and empty strings. See http://es5.github.io/#x15.1.2.5.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if the `value` is finite, else `false`.
- * @example
- *
- * _.isFinite(-101);
- * // => true
- *
- * _.isFinite('10');
- * // => true
- *
- * _.isFinite(true);
- * // => false
- *
- * _.isFinite('');
- * // => false
- *
- * _.isFinite(Infinity);
- * // => false
- */
- function isFinite(value) {
- return nativeIsFinite(value) && !nativeIsNaN(parseFloat(value));
- }
-
- /**
- * Checks if `value` is a function.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if the `value` is a function, else `false`.
- * @example
- *
- * _.isFunction(_);
- * // => true
- */
- function isFunction(value) {
- return typeof value == 'function';
- }
- // fallback for older versions of Chrome and Safari
- if (isFunction(/x/)) {
- isFunction = function(value) {
- return typeof value == 'function' && toString.call(value) == funcClass;
- };
- }
-
- /**
- * Checks if `value` is the language type of Object.
- * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if the `value` is an object, else `false`.
- * @example
- *
- * _.isObject({});
- * // => true
- *
- * _.isObject([1, 2, 3]);
- * // => true
- *
- * _.isObject(1);
- * // => false
- */
- function isObject(value) {
- // check if the value is the ECMAScript language type of Object
- // http://es5.github.io/#x8
- // and avoid a V8 bug
- // http://code.google.com/p/v8/issues/detail?id=2291
- return !!(value && objectTypes[typeof value]);
- }
-
- /**
- * Checks if `value` is `NaN`.
- *
- * Note: This is not the same as native `isNaN` which will return `true` for
- * `undefined` and other non-numeric values. See http://es5.github.io/#x15.1.2.4.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if the `value` is `NaN`, else `false`.
- * @example
- *
- * _.isNaN(NaN);
- * // => true
- *
- * _.isNaN(new Number(NaN));
- * // => true
- *
- * isNaN(undefined);
- * // => true
- *
- * _.isNaN(undefined);
- * // => false
- */
- function isNaN(value) {
- // `NaN` as a primitive is the only value that is not equal to itself
- // (perform the [[Class]] check first to avoid errors with some host objects in IE)
- return isNumber(value) && value != +value;
- }
-
- /**
- * Checks if `value` is `null`.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if the `value` is `null`, else `false`.
- * @example
- *
- * _.isNull(null);
- * // => true
- *
- * _.isNull(undefined);
- * // => false
- */
- function isNull(value) {
- return value === null;
- }
-
- /**
- * Checks if `value` is a number.
- *
- * Note: `NaN` is considered a number. See http://es5.github.io/#x8.5.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if the `value` is a number, else `false`.
- * @example
- *
- * _.isNumber(8.4 * 5);
- * // => true
- */
- function isNumber(value) {
- return typeof value == 'number' ||
- value && typeof value == 'object' && toString.call(value) == numberClass || false;
- }
-
- /**
- * Checks if `value` is an object created by the `Object` constructor.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
- * @example
- *
- * function Shape() {
- * this.x = 0;
- * this.y = 0;
- * }
- *
- * _.isPlainObject(new Shape);
- * // => false
- *
- * _.isPlainObject([1, 2, 3]);
- * // => false
- *
- * _.isPlainObject({ 'x': 0, 'y': 0 });
- * // => true
- */
- var isPlainObject = !getPrototypeOf ? shimIsPlainObject : function(value) {
- if (!(value && toString.call(value) == objectClass) || (!support.argsClass && isArguments(value))) {
- return false;
- }
- var valueOf = value.valueOf,
- objProto = isNative(valueOf) && (objProto = getPrototypeOf(valueOf)) && getPrototypeOf(objProto);
-
- return objProto
- ? (value == objProto || getPrototypeOf(value) == objProto)
- : shimIsPlainObject(value);
- };
-
- /**
- * Checks if `value` is a regular expression.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if the `value` is a regular expression, else `false`.
- * @example
- *
- * _.isRegExp(/fred/);
- * // => true
- */
- function isRegExp(value) {
- return value && objectTypes[typeof value] && toString.call(value) == regexpClass || false;
- }
-
- /**
- * Checks if `value` is a string.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if the `value` is a string, else `false`.
- * @example
- *
- * _.isString('fred');
- * // => true
- */
- function isString(value) {
- return typeof value == 'string' ||
- value && typeof value == 'object' && toString.call(value) == stringClass || false;
- }
-
- /**
- * Checks if `value` is `undefined`.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if the `value` is `undefined`, else `false`.
- * @example
- *
- * _.isUndefined(void 0);
- * // => true
- */
- function isUndefined(value) {
- return typeof value == 'undefined';
- }
-
- /**
- * Creates an object with the same keys as `object` and values generated by
- * running each own enumerable property of `object` through the callback.
- * The callback is bound to `thisArg` and invoked with three arguments;
- * (value, key, object).
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {Object} object The object to iterate over.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Array} Returns a new object with values of the results of each `callback` execution.
- * @example
- *
- * _.mapValues({ 'a': 1, 'b': 2, 'c': 3} , function(num) { return num * 3; });
- * // => { 'a': 3, 'b': 6, 'c': 9 }
- *
- * var characters = {
- * 'fred': { 'name': 'fred', 'age': 40 },
- * 'pebbles': { 'name': 'pebbles', 'age': 1 }
- * };
- *
- * // using "_.pluck" callback shorthand
- * _.mapValues(characters, 'age');
- * // => { 'fred': 40, 'pebbles': 1 }
- */
- function mapValues(object, callback, thisArg) {
- var result = {};
- callback = lodash.createCallback(callback, thisArg, 3);
-
- forOwn(object, function(value, key, object) {
- result[key] = callback(value, key, object);
- });
- return result;
- }
-
- /**
- * Recursively merges own enumerable properties of the source object(s), that
- * don't resolve to `undefined` into the destination object. Subsequent sources
- * will overwrite property assignments of previous sources. If a callback is
- * provided it will be executed to produce the merged values of the destination
- * and source properties. If the callback returns `undefined` merging will
- * be handled by the method instead. The callback is bound to `thisArg` and
- * invoked with two arguments; (objectValue, sourceValue).
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {Object} object The destination object.
- * @param {...Object} [source] The source objects.
- * @param {Function} [callback] The function to customize merging properties.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Object} Returns the destination object.
- * @example
- *
- * var names = {
- * 'characters': [
- * { 'name': 'barney' },
- * { 'name': 'fred' }
- * ]
- * };
- *
- * var ages = {
- * 'characters': [
- * { 'age': 36 },
- * { 'age': 40 }
- * ]
- * };
- *
- * _.merge(names, ages);
- * // => { 'characters': [{ 'name': 'barney', 'age': 36 }, { 'name': 'fred', 'age': 40 }] }
- *
- * var food = {
- * 'fruits': ['apple'],
- * 'vegetables': ['beet']
- * };
- *
- * var otherFood = {
- * 'fruits': ['banana'],
- * 'vegetables': ['carrot']
- * };
- *
- * _.merge(food, otherFood, function(a, b) {
- * return _.isArray(a) ? a.concat(b) : undefined;
- * });
- * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot] }
- */
- function merge(object) {
- var args = arguments,
- length = 2;
-
- if (!isObject(object)) {
- return object;
- }
- // allows working with `_.reduce` and `_.reduceRight` without using
- // their `index` and `collection` arguments
- if (typeof args[2] != 'number') {
- length = args.length;
- }
- if (length > 3 && typeof args[length - 2] == 'function') {
- var callback = baseCreateCallback(args[--length - 1], args[length--], 2);
- } else if (length > 2 && typeof args[length - 1] == 'function') {
- callback = args[--length];
- }
- var sources = slice(arguments, 1, length),
- index = -1,
- stackA = getArray(),
- stackB = getArray();
-
- while (++index < length) {
- baseMerge(object, sources[index], callback, stackA, stackB);
- }
- releaseArray(stackA);
- releaseArray(stackB);
- return object;
- }
-
- /**
- * Creates a shallow clone of `object` excluding the specified properties.
- * Property names may be specified as individual arguments or as arrays of
- * property names. If a callback is provided it will be executed for each
- * property of `object` omitting the properties the callback returns truey
- * for. The callback is bound to `thisArg` and invoked with three arguments;
- * (value, key, object).
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {Object} object The source object.
- * @param {Function|...string|string[]} [callback] The properties to omit or the
- * function called per iteration.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Object} Returns an object without the omitted properties.
- * @example
- *
- * _.omit({ 'name': 'fred', 'age': 40 }, 'age');
- * // => { 'name': 'fred' }
- *
- * _.omit({ 'name': 'fred', 'age': 40 }, function(value) {
- * return typeof value == 'number';
- * });
- * // => { 'name': 'fred' }
- */
- function omit(object, callback, thisArg) {
- var result = {};
- if (typeof callback != 'function') {
- var props = [];
- forIn(object, function(value, key) {
- props.push(key);
- });
- props = baseDifference(props, baseFlatten(arguments, true, false, 1));
-
- var index = -1,
- length = props.length;
-
- while (++index < length) {
- var key = props[index];
- result[key] = object[key];
- }
- } else {
- callback = lodash.createCallback(callback, thisArg, 3);
- forIn(object, function(value, key, object) {
- if (!callback(value, key, object)) {
- result[key] = value;
- }
- });
- }
- return result;
- }
-
- /**
- * Creates a two dimensional array of an object's key-value pairs,
- * i.e. `[[key1, value1], [key2, value2]]`.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {Object} object The object to inspect.
- * @returns {Array} Returns new array of key-value pairs.
- * @example
- *
- * _.pairs({ 'barney': 36, 'fred': 40 });
- * // => [['barney', 36], ['fred', 40]] (property order is not guaranteed across environments)
- */
- function pairs(object) {
- var index = -1,
- props = keys(object),
- length = props.length,
- result = Array(length);
-
- while (++index < length) {
- var key = props[index];
- result[index] = [key, object[key]];
- }
- return result;
- }
-
- /**
- * Creates a shallow clone of `object` composed of the specified properties.
- * Property names may be specified as individual arguments or as arrays of
- * property names. If a callback is provided it will be executed for each
- * property of `object` picking the properties the callback returns truey
- * for. The callback is bound to `thisArg` and invoked with three arguments;
- * (value, key, object).
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {Object} object The source object.
- * @param {Function|...string|string[]} [callback] The function called per
- * iteration or property names to pick, specified as individual property
- * names or arrays of property names.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Object} Returns an object composed of the picked properties.
- * @example
- *
- * _.pick({ 'name': 'fred', '_userid': 'fred1' }, 'name');
- * // => { 'name': 'fred' }
- *
- * _.pick({ 'name': 'fred', '_userid': 'fred1' }, function(value, key) {
- * return key.charAt(0) != '_';
- * });
- * // => { 'name': 'fred' }
- */
- function pick(object, callback, thisArg) {
- var result = {};
- if (typeof callback != 'function') {
- var index = -1,
- props = baseFlatten(arguments, true, false, 1),
- length = isObject(object) ? props.length : 0;
-
- while (++index < length) {
- var key = props[index];
- if (key in object) {
- result[key] = object[key];
- }
- }
- } else {
- callback = lodash.createCallback(callback, thisArg, 3);
- forIn(object, function(value, key, object) {
- if (callback(value, key, object)) {
- result[key] = value;
- }
- });
- }
- return result;
- }
-
- /**
- * An alternative to `_.reduce` this method transforms `object` to a new
- * `accumulator` object which is the result of running each of its own
- * enumerable properties through a callback, with each callback execution
- * potentially mutating the `accumulator` object. The callback is bound to
- * `thisArg` and invoked with four arguments; (accumulator, value, key, object).
- * Callbacks may exit iteration early by explicitly returning `false`.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {Array|Object} object The object to iterate over.
- * @param {Function} [callback=identity] The function called per iteration.
- * @param {*} [accumulator] The custom accumulator value.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {*} Returns the accumulated value.
- * @example
- *
- * var squares = _.transform([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], function(result, num) {
- * num *= num;
- * if (num % 2) {
- * return result.push(num) < 3;
- * }
- * });
- * // => [1, 9, 25]
- *
- * var mapped = _.transform({ 'a': 1, 'b': 2, 'c': 3 }, function(result, num, key) {
- * result[key] = num * 3;
- * });
- * // => { 'a': 3, 'b': 6, 'c': 9 }
- */
- function transform(object, callback, accumulator, thisArg) {
- var isArr = isArray(object);
- if (accumulator == null) {
- if (isArr) {
- accumulator = [];
- } else {
- var ctor = object && object.constructor,
- proto = ctor && ctor.prototype;
-
- accumulator = baseCreate(proto);
- }
- }
- if (callback) {
- callback = lodash.createCallback(callback, thisArg, 4);
- (isArr ? baseEach : forOwn)(object, function(value, index, object) {
- return callback(accumulator, value, index, object);
- });
- }
- return accumulator;
- }
-
- /**
- * Creates an array composed of the own enumerable property values of `object`.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {Object} object The object to inspect.
- * @returns {Array} Returns an array of property values.
- * @example
- *
- * _.values({ 'one': 1, 'two': 2, 'three': 3 });
- * // => [1, 2, 3] (property order is not guaranteed across environments)
- */
- function values(object) {
- var index = -1,
- props = keys(object),
- length = props.length,
- result = Array(length);
-
- while (++index < length) {
- result[index] = object[props[index]];
- }
- return result;
- }
-
- /*--------------------------------------------------------------------------*/
-
- /**
- * Creates an array of elements from the specified indexes, or keys, of the
- * `collection`. Indexes may be specified as individual arguments or as arrays
- * of indexes.
- *
- * @static
- * @memberOf _
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {...(number|number[]|string|string[])} [index] The indexes of `collection`
- * to retrieve, specified as individual indexes or arrays of indexes.
- * @returns {Array} Returns a new array of elements corresponding to the
- * provided indexes.
- * @example
- *
- * _.at(['a', 'b', 'c', 'd', 'e'], [0, 2, 4]);
- * // => ['a', 'c', 'e']
- *
- * _.at(['fred', 'barney', 'pebbles'], 0, 2);
- * // => ['fred', 'pebbles']
- */
- function at(collection) {
- var args = arguments,
- index = -1,
- props = baseFlatten(args, true, false, 1),
- length = (args[2] && args[2][args[1]] === collection) ? 1 : props.length,
- result = Array(length);
-
- if (support.unindexedChars && isString(collection)) {
- collection = collection.split('');
- }
- while(++index < length) {
- result[index] = collection[props[index]];
- }
- return result;
- }
-
- /**
- * Checks if a given value is present in a collection using strict equality
- * for comparisons, i.e. `===`. If `fromIndex` is negative, it is used as the
- * offset from the end of the collection.
- *
- * @static
- * @memberOf _
- * @alias include
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {*} target The value to check for.
- * @param {number} [fromIndex=0] The index to search from.
- * @returns {boolean} Returns `true` if the `target` element is found, else `false`.
- * @example
- *
- * _.contains([1, 2, 3], 1);
- * // => true
- *
- * _.contains([1, 2, 3], 1, 2);
- * // => false
- *
- * _.contains({ 'name': 'fred', 'age': 40 }, 'fred');
- * // => true
- *
- * _.contains('pebbles', 'eb');
- * // => true
- */
- function contains(collection, target, fromIndex) {
- var index = -1,
- indexOf = getIndexOf(),
- length = collection ? collection.length : 0,
- result = false;
-
- fromIndex = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex) || 0;
- if (isArray(collection)) {
- result = indexOf(collection, target, fromIndex) > -1;
- } else if (typeof length == 'number') {
- result = (isString(collection) ? collection.indexOf(target, fromIndex) : indexOf(collection, target, fromIndex)) > -1;
- } else {
- baseEach(collection, function(value) {
- if (++index >= fromIndex) {
- return !(result = value === target);
- }
- });
- }
- return result;
- }
-
- /**
- * Creates an object composed of keys generated from the results of running
- * each element of `collection` through the callback. The corresponding value
- * of each key is the number of times the key was returned by the callback.
- * The callback is bound to `thisArg` and invoked with three arguments;
- * (value, index|key, collection).
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Object} Returns the composed aggregate object.
- * @example
- *
- * _.countBy([4.3, 6.1, 6.4], function(num) { return Math.floor(num); });
- * // => { '4': 1, '6': 2 }
- *
- * _.countBy([4.3, 6.1, 6.4], function(num) { return this.floor(num); }, Math);
- * // => { '4': 1, '6': 2 }
- *
- * _.countBy(['one', 'two', 'three'], 'length');
- * // => { '3': 2, '5': 1 }
- */
- var countBy = createAggregator(function(result, value, key) {
- (hasOwnProperty.call(result, key) ? result[key]++ : result[key] = 1);
- });
-
- /**
- * Checks if the given callback returns truey value for **all** elements of
- * a collection. The callback is bound to `thisArg` and invoked with three
- * arguments; (value, index|key, collection).
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @alias all
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {boolean} Returns `true` if all elements passed the callback check,
- * else `false`.
- * @example
- *
- * _.every([true, 1, null, 'yes']);
- * // => false
- *
- * var characters = [
- * { 'name': 'barney', 'age': 36 },
- * { 'name': 'fred', 'age': 40 }
- * ];
- *
- * // using "_.pluck" callback shorthand
- * _.every(characters, 'age');
- * // => true
- *
- * // using "_.where" callback shorthand
- * _.every(characters, { 'age': 36 });
- * // => false
- */
- function every(collection, callback, thisArg) {
- var result = true;
- callback = lodash.createCallback(callback, thisArg, 3);
-
- if (isArray(collection)) {
- var index = -1,
- length = collection.length;
-
- while (++index < length) {
- if (!(result = !!callback(collection[index], index, collection))) {
- break;
- }
- }
- } else {
- baseEach(collection, function(value, index, collection) {
- return (result = !!callback(value, index, collection));
- });
- }
- return result;
- }
-
- /**
- * Iterates over elements of a collection, returning an array of all elements
- * the callback returns truey for. The callback is bound to `thisArg` and
- * invoked with three arguments; (value, index|key, collection).
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @alias select
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Array} Returns a new array of elements that passed the callback check.
- * @example
- *
- * var evens = _.filter([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; });
- * // => [2, 4, 6]
- *
- * var characters = [
- * { 'name': 'barney', 'age': 36, 'blocked': false },
- * { 'name': 'fred', 'age': 40, 'blocked': true }
- * ];
- *
- * // using "_.pluck" callback shorthand
- * _.filter(characters, 'blocked');
- * // => [{ 'name': 'fred', 'age': 40, 'blocked': true }]
- *
- * // using "_.where" callback shorthand
- * _.filter(characters, { 'age': 36 });
- * // => [{ 'name': 'barney', 'age': 36, 'blocked': false }]
- */
- function filter(collection, callback, thisArg) {
- var result = [];
- callback = lodash.createCallback(callback, thisArg, 3);
-
- if (isArray(collection)) {
- var index = -1,
- length = collection.length;
-
- while (++index < length) {
- var value = collection[index];
- if (callback(value, index, collection)) {
- result.push(value);
- }
- }
- } else {
- baseEach(collection, function(value, index, collection) {
- if (callback(value, index, collection)) {
- result.push(value);
- }
- });
- }
- return result;
- }
-
- /**
- * Iterates over elements of a collection, returning the first element that
- * the callback returns truey for. The callback is bound to `thisArg` and
- * invoked with three arguments; (value, index|key, collection).
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @alias detect, findWhere
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {*} Returns the found element, else `undefined`.
- * @example
- *
- * var characters = [
- * { 'name': 'barney', 'age': 36, 'blocked': false },
- * { 'name': 'fred', 'age': 40, 'blocked': true },
- * { 'name': 'pebbles', 'age': 1, 'blocked': false }
- * ];
- *
- * _.find(characters, function(chr) {
- * return chr.age < 40;
- * });
- * // => { 'name': 'barney', 'age': 36, 'blocked': false }
- *
- * // using "_.where" callback shorthand
- * _.find(characters, { 'age': 1 });
- * // => { 'name': 'pebbles', 'age': 1, 'blocked': false }
- *
- * // using "_.pluck" callback shorthand
- * _.find(characters, 'blocked');
- * // => { 'name': 'fred', 'age': 40, 'blocked': true }
- */
- function find(collection, callback, thisArg) {
- callback = lodash.createCallback(callback, thisArg, 3);
-
- if (isArray(collection)) {
- var index = -1,
- length = collection.length;
-
- while (++index < length) {
- var value = collection[index];
- if (callback(value, index, collection)) {
- return value;
- }
- }
- } else {
- var result;
- baseEach(collection, function(value, index, collection) {
- if (callback(value, index, collection)) {
- result = value;
- return false;
- }
- });
- return result;
- }
- }
-
- /**
- * This method is like `_.find` except that it iterates over elements
- * of a `collection` from right to left.
- *
- * @static
- * @memberOf _
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {*} Returns the found element, else `undefined`.
- * @example
- *
- * _.findLast([1, 2, 3, 4], function(num) {
- * return num % 2 == 1;
- * });
- * // => 3
- */
- function findLast(collection, callback, thisArg) {
- var result;
- callback = lodash.createCallback(callback, thisArg, 3);
- forEachRight(collection, function(value, index, collection) {
- if (callback(value, index, collection)) {
- result = value;
- return false;
- }
- });
- return result;
- }
-
- /**
- * Iterates over elements of a collection, executing the callback for each
- * element. The callback is bound to `thisArg` and invoked with three arguments;
- * (value, index|key, collection). Callbacks may exit iteration early by
- * explicitly returning `false`.
- *
- * Note: As with other "Collections" methods, objects with a `length` property
- * are iterated like arrays. To avoid this behavior `_.forIn` or `_.forOwn`
- * may be used for object iteration.
- *
- * @static
- * @memberOf _
- * @alias each
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function} [callback=identity] The function called per iteration.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Array|Object|string} Returns `collection`.
- * @example
- *
- * _([1, 2, 3]).forEach(function(num) { console.log(num); }).join(',');
- * // => logs each number and returns '1,2,3'
- *
- * _.forEach({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { console.log(num); });
- * // => logs each number and returns the object (property order is not guaranteed across environments)
- */
- function forEach(collection, callback, thisArg) {
- if (callback && typeof thisArg == 'undefined' && isArray(collection)) {
- var index = -1,
- length = collection.length;
-
- while (++index < length) {
- if (callback(collection[index], index, collection) === false) {
- break;
- }
- }
- } else {
- baseEach(collection, callback, thisArg);
- }
- return collection;
- }
-
- /**
- * This method is like `_.forEach` except that it iterates over elements
- * of a `collection` from right to left.
- *
- * @static
- * @memberOf _
- * @alias eachRight
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function} [callback=identity] The function called per iteration.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Array|Object|string} Returns `collection`.
- * @example
- *
- * _([1, 2, 3]).forEachRight(function(num) { console.log(num); }).join(',');
- * // => logs each number from right to left and returns '3,2,1'
- */
- function forEachRight(collection, callback, thisArg) {
- var iterable = collection,
- length = collection ? collection.length : 0;
-
- callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3);
- if (isArray(collection)) {
- while (length--) {
- if (callback(collection[length], length, collection) === false) {
- break;
- }
- }
- } else {
- if (typeof length != 'number') {
- var props = keys(collection);
- length = props.length;
- } else if (support.unindexedChars && isString(collection)) {
- iterable = collection.split('');
- }
- baseEach(collection, function(value, key, collection) {
- key = props ? props[--length] : --length;
- return callback(iterable[key], key, collection);
- });
- }
- return collection;
- }
-
- /**
- * Creates an object composed of keys generated from the results of running
- * each element of a collection through the callback. The corresponding value
- * of each key is an array of the elements responsible for generating the key.
- * The callback is bound to `thisArg` and invoked with three arguments;
- * (value, index|key, collection).
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`
- *
- * @static
- * @memberOf _
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Object} Returns the composed aggregate object.
- * @example
- *
- * _.groupBy([4.2, 6.1, 6.4], function(num) { return Math.floor(num); });
- * // => { '4': [4.2], '6': [6.1, 6.4] }
- *
- * _.groupBy([4.2, 6.1, 6.4], function(num) { return this.floor(num); }, Math);
- * // => { '4': [4.2], '6': [6.1, 6.4] }
- *
- * // using "_.pluck" callback shorthand
- * _.groupBy(['one', 'two', 'three'], 'length');
- * // => { '3': ['one', 'two'], '5': ['three'] }
- */
- var groupBy = createAggregator(function(result, value, key) {
- (hasOwnProperty.call(result, key) ? result[key] : result[key] = []).push(value);
- });
-
- /**
- * Creates an object composed of keys generated from the results of running
- * each element of the collection through the given callback. The corresponding
- * value of each key is the last element responsible for generating the key.
- * The callback is bound to `thisArg` and invoked with three arguments;
- * (value, index|key, collection).
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Object} Returns the composed aggregate object.
- * @example
- *
- * var keys = [
- * { 'dir': 'left', 'code': 97 },
- * { 'dir': 'right', 'code': 100 }
- * ];
- *
- * _.indexBy(keys, 'dir');
- * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } }
- *
- * _.indexBy(keys, function(key) { return String.fromCharCode(key.code); });
- * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
- *
- * _.indexBy(characters, function(key) { this.fromCharCode(key.code); }, String);
- * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
- */
- var indexBy = createAggregator(function(result, value, key) {
- result[key] = value;
- });
-
- /**
- * Invokes the method named by `methodName` on each element in the `collection`
- * returning an array of the results of each invoked method. Additional arguments
- * will be provided to each invoked method. If `methodName` is a function it
- * will be invoked for, and `this` bound to, each element in the `collection`.
- *
- * @static
- * @memberOf _
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|string} methodName The name of the method to invoke or
- * the function invoked per iteration.
- * @param {...*} [arg] Arguments to invoke the method with.
- * @returns {Array} Returns a new array of the results of each invoked method.
- * @example
- *
- * _.invoke([[5, 1, 7], [3, 2, 1]], 'sort');
- * // => [[1, 5, 7], [1, 2, 3]]
- *
- * _.invoke([123, 456], String.prototype.split, '');
- * // => [['1', '2', '3'], ['4', '5', '6']]
- */
- function invoke(collection, methodName) {
- var args = slice(arguments, 2),
- index = -1,
- isFunc = typeof methodName == 'function',
- length = collection ? collection.length : 0,
- result = Array(typeof length == 'number' ? length : 0);
-
- forEach(collection, function(value) {
- result[++index] = (isFunc ? methodName : value[methodName]).apply(value, args);
- });
- return result;
- }
-
- /**
- * Creates an array of values by running each element in the collection
- * through the callback. The callback is bound to `thisArg` and invoked with
- * three arguments; (value, index|key, collection).
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @alias collect
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Array} Returns a new array of the results of each `callback` execution.
- * @example
- *
- * _.map([1, 2, 3], function(num) { return num * 3; });
- * // => [3, 6, 9]
- *
- * _.map({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { return num * 3; });
- * // => [3, 6, 9] (property order is not guaranteed across environments)
- *
- * var characters = [
- * { 'name': 'barney', 'age': 36 },
- * { 'name': 'fred', 'age': 40 }
- * ];
- *
- * // using "_.pluck" callback shorthand
- * _.map(characters, 'name');
- * // => ['barney', 'fred']
- */
- function map(collection, callback, thisArg) {
- var index = -1,
- length = collection ? collection.length : 0,
- result = Array(typeof length == 'number' ? length : 0);
-
- callback = lodash.createCallback(callback, thisArg, 3);
- if (isArray(collection)) {
- while (++index < length) {
- result[index] = callback(collection[index], index, collection);
- }
- } else {
- baseEach(collection, function(value, key, collection) {
- result[++index] = callback(value, key, collection);
- });
- }
- return result;
- }
-
- /**
- * Retrieves the maximum value of a collection. If the collection is empty or
- * falsey `-Infinity` is returned. If a callback is provided it will be executed
- * for each value in the collection to generate the criterion by which the value
- * is ranked. The callback is bound to `thisArg` and invoked with three
- * arguments; (value, index, collection).
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {*} Returns the maximum value.
- * @example
- *
- * _.max([4, 2, 8, 6]);
- * // => 8
- *
- * var characters = [
- * { 'name': 'barney', 'age': 36 },
- * { 'name': 'fred', 'age': 40 }
- * ];
- *
- * _.max(characters, function(chr) { return chr.age; });
- * // => { 'name': 'fred', 'age': 40 };
- *
- * // using "_.pluck" callback shorthand
- * _.max(characters, 'age');
- * // => { 'name': 'fred', 'age': 40 };
- */
- function max(collection, callback, thisArg) {
- var computed = -Infinity,
- result = computed;
-
- // allows working with functions like `_.map` without using
- // their `index` argument as a callback
- if (typeof callback != 'function' && thisArg && thisArg[callback] === collection) {
- callback = null;
- }
- if (callback == null && isArray(collection)) {
- var index = -1,
- length = collection.length;
-
- while (++index < length) {
- var value = collection[index];
- if (value > result) {
- result = value;
- }
- }
- } else {
- callback = (callback == null && isString(collection))
- ? charAtCallback
- : lodash.createCallback(callback, thisArg, 3);
-
- baseEach(collection, function(value, index, collection) {
- var current = callback(value, index, collection);
- if (current > computed) {
- computed = current;
- result = value;
- }
- });
- }
- return result;
- }
-
- /**
- * Retrieves the minimum value of a collection. If the collection is empty or
- * falsey `Infinity` is returned. If a callback is provided it will be executed
- * for each value in the collection to generate the criterion by which the value
- * is ranked. The callback is bound to `thisArg` and invoked with three
- * arguments; (value, index, collection).
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {*} Returns the minimum value.
- * @example
- *
- * _.min([4, 2, 8, 6]);
- * // => 2
- *
- * var characters = [
- * { 'name': 'barney', 'age': 36 },
- * { 'name': 'fred', 'age': 40 }
- * ];
- *
- * _.min(characters, function(chr) { return chr.age; });
- * // => { 'name': 'barney', 'age': 36 };
- *
- * // using "_.pluck" callback shorthand
- * _.min(characters, 'age');
- * // => { 'name': 'barney', 'age': 36 };
- */
- function min(collection, callback, thisArg) {
- var computed = Infinity,
- result = computed;
-
- // allows working with functions like `_.map` without using
- // their `index` argument as a callback
- if (typeof callback != 'function' && thisArg && thisArg[callback] === collection) {
- callback = null;
- }
- if (callback == null && isArray(collection)) {
- var index = -1,
- length = collection.length;
-
- while (++index < length) {
- var value = collection[index];
- if (value < result) {
- result = value;
- }
- }
- } else {
- callback = (callback == null && isString(collection))
- ? charAtCallback
- : lodash.createCallback(callback, thisArg, 3);
-
- baseEach(collection, function(value, index, collection) {
- var current = callback(value, index, collection);
- if (current < computed) {
- computed = current;
- result = value;
- }
- });
- }
- return result;
- }
-
- /**
- * Retrieves the value of a specified property from all elements in the collection.
- *
- * @static
- * @memberOf _
- * @type Function
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {string} property The name of the property to pluck.
- * @returns {Array} Returns a new array of property values.
- * @example
- *
- * var characters = [
- * { 'name': 'barney', 'age': 36 },
- * { 'name': 'fred', 'age': 40 }
- * ];
- *
- * _.pluck(characters, 'name');
- * // => ['barney', 'fred']
- */
- var pluck = map;
-
- /**
- * Reduces a collection to a value which is the accumulated result of running
- * each element in the collection through the callback, where each successive
- * callback execution consumes the return value of the previous execution. If
- * `accumulator` is not provided the first element of the collection will be
- * used as the initial `accumulator` value. The callback is bound to `thisArg`
- * and invoked with four arguments; (accumulator, value, index|key, collection).
- *
- * @static
- * @memberOf _
- * @alias foldl, inject
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function} [callback=identity] The function called per iteration.
- * @param {*} [accumulator] Initial value of the accumulator.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {*} Returns the accumulated value.
- * @example
- *
- * var sum = _.reduce([1, 2, 3], function(sum, num) {
- * return sum + num;
- * });
- * // => 6
- *
- * var mapped = _.reduce({ 'a': 1, 'b': 2, 'c': 3 }, function(result, num, key) {
- * result[key] = num * 3;
- * return result;
- * }, {});
- * // => { 'a': 3, 'b': 6, 'c': 9 }
- */
- function reduce(collection, callback, accumulator, thisArg) {
- var noaccum = arguments.length < 3;
- callback = lodash.createCallback(callback, thisArg, 4);
-
- if (isArray(collection)) {
- var index = -1,
- length = collection.length;
-
- if (noaccum) {
- accumulator = collection[++index];
- }
- while (++index < length) {
- accumulator = callback(accumulator, collection[index], index, collection);
- }
- } else {
- baseEach(collection, function(value, index, collection) {
- accumulator = noaccum
- ? (noaccum = false, value)
- : callback(accumulator, value, index, collection)
- });
- }
- return accumulator;
- }
-
- /**
- * This method is like `_.reduce` except that it iterates over elements
- * of a `collection` from right to left.
- *
- * @static
- * @memberOf _
- * @alias foldr
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function} [callback=identity] The function called per iteration.
- * @param {*} [accumulator] Initial value of the accumulator.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {*} Returns the accumulated value.
- * @example
- *
- * var list = [[0, 1], [2, 3], [4, 5]];
- * var flat = _.reduceRight(list, function(a, b) { return a.concat(b); }, []);
- * // => [4, 5, 2, 3, 0, 1]
- */
- function reduceRight(collection, callback, accumulator, thisArg) {
- var noaccum = arguments.length < 3;
- callback = lodash.createCallback(callback, thisArg, 4);
- forEachRight(collection, function(value, index, collection) {
- accumulator = noaccum
- ? (noaccum = false, value)
- : callback(accumulator, value, index, collection);
- });
- return accumulator;
- }
-
- /**
- * The opposite of `_.filter` this method returns the elements of a
- * collection that the callback does **not** return truey for.
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Array} Returns a new array of elements that failed the callback check.
- * @example
- *
- * var odds = _.reject([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; });
- * // => [1, 3, 5]
- *
- * var characters = [
- * { 'name': 'barney', 'age': 36, 'blocked': false },
- * { 'name': 'fred', 'age': 40, 'blocked': true }
- * ];
- *
- * // using "_.pluck" callback shorthand
- * _.reject(characters, 'blocked');
- * // => [{ 'name': 'barney', 'age': 36, 'blocked': false }]
- *
- * // using "_.where" callback shorthand
- * _.reject(characters, { 'age': 36 });
- * // => [{ 'name': 'fred', 'age': 40, 'blocked': true }]
- */
- function reject(collection, callback, thisArg) {
- callback = lodash.createCallback(callback, thisArg, 3);
- return filter(collection, function(value, index, collection) {
- return !callback(value, index, collection);
- });
- }
-
- /**
- * Retrieves a random element or `n` random elements from a collection.
- *
- * @static
- * @memberOf _
- * @category Collections
- * @param {Array|Object|string} collection The collection to sample.
- * @param {number} [n] The number of elements to sample.
- * @param- {Object} [guard] Allows working with functions like `_.map`
- * without using their `index` arguments as `n`.
- * @returns {Array} Returns the random sample(s) of `collection`.
- * @example
- *
- * _.sample([1, 2, 3, 4]);
- * // => 2
- *
- * _.sample([1, 2, 3, 4], 2);
- * // => [3, 1]
- */
- function sample(collection, n, guard) {
- if (collection && typeof collection.length != 'number') {
- collection = values(collection);
- } else if (support.unindexedChars && isString(collection)) {
- collection = collection.split('');
- }
- if (n == null || guard) {
- return collection ? collection[baseRandom(0, collection.length - 1)] : undefined;
- }
- var result = shuffle(collection);
- result.length = nativeMin(nativeMax(0, n), result.length);
- return result;
- }
-
- /**
- * Creates an array of shuffled values, using a version of the Fisher-Yates
- * shuffle. See http://en.wikipedia.org/wiki/Fisher-Yates_shuffle.
- *
- * @static
- * @memberOf _
- * @category Collections
- * @param {Array|Object|string} collection The collection to shuffle.
- * @returns {Array} Returns a new shuffled collection.
- * @example
- *
- * _.shuffle([1, 2, 3, 4, 5, 6]);
- * // => [4, 1, 6, 3, 5, 2]
- */
- function shuffle(collection) {
- var index = -1,
- length = collection ? collection.length : 0,
- result = Array(typeof length == 'number' ? length : 0);
-
- forEach(collection, function(value) {
- var rand = baseRandom(0, ++index);
- result[index] = result[rand];
- result[rand] = value;
- });
- return result;
- }
-
- /**
- * Gets the size of the `collection` by returning `collection.length` for arrays
- * and array-like objects or the number of own enumerable properties for objects.
- *
- * @static
- * @memberOf _
- * @category Collections
- * @param {Array|Object|string} collection The collection to inspect.
- * @returns {number} Returns `collection.length` or number of own enumerable properties.
- * @example
- *
- * _.size([1, 2]);
- * // => 2
- *
- * _.size({ 'one': 1, 'two': 2, 'three': 3 });
- * // => 3
- *
- * _.size('pebbles');
- * // => 7
- */
- function size(collection) {
- var length = collection ? collection.length : 0;
- return typeof length == 'number' ? length : keys(collection).length;
- }
-
- /**
- * Checks if the callback returns a truey value for **any** element of a
- * collection. The function returns as soon as it finds a passing value and
- * does not iterate over the entire collection. The callback is bound to
- * `thisArg` and invoked with three arguments; (value, index|key, collection).
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @alias any
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {boolean} Returns `true` if any element passed the callback check,
- * else `false`.
- * @example
- *
- * _.some([null, 0, 'yes', false], Boolean);
- * // => true
- *
- * var characters = [
- * { 'name': 'barney', 'age': 36, 'blocked': false },
- * { 'name': 'fred', 'age': 40, 'blocked': true }
- * ];
- *
- * // using "_.pluck" callback shorthand
- * _.some(characters, 'blocked');
- * // => true
- *
- * // using "_.where" callback shorthand
- * _.some(characters, { 'age': 1 });
- * // => false
- */
- function some(collection, callback, thisArg) {
- var result;
- callback = lodash.createCallback(callback, thisArg, 3);
-
- if (isArray(collection)) {
- var index = -1,
- length = collection.length;
-
- while (++index < length) {
- if ((result = callback(collection[index], index, collection))) {
- break;
- }
- }
- } else {
- baseEach(collection, function(value, index, collection) {
- return !(result = callback(value, index, collection));
- });
- }
- return !!result;
- }
-
- /**
- * Creates an array of elements, sorted in ascending order by the results of
- * running each element in a collection through the callback. This method
- * performs a stable sort, that is, it will preserve the original sort order
- * of equal elements. The callback is bound to `thisArg` and invoked with
- * three arguments; (value, index|key, collection).
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an array of property names is provided for `callback` the collection
- * will be sorted by each property value.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Array|Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Array} Returns a new array of sorted elements.
- * @example
- *
- * _.sortBy([1, 2, 3], function(num) { return Math.sin(num); });
- * // => [3, 1, 2]
- *
- * _.sortBy([1, 2, 3], function(num) { return this.sin(num); }, Math);
- * // => [3, 1, 2]
- *
- * var characters = [
- * { 'name': 'barney', 'age': 36 },
- * { 'name': 'fred', 'age': 40 },
- * { 'name': 'barney', 'age': 26 },
- * { 'name': 'fred', 'age': 30 }
- * ];
- *
- * // using "_.pluck" callback shorthand
- * _.map(_.sortBy(characters, 'age'), _.values);
- * // => [['barney', 26], ['fred', 30], ['barney', 36], ['fred', 40]]
- *
- * // sorting by multiple properties
- * _.map(_.sortBy(characters, ['name', 'age']), _.values);
- * // = > [['barney', 26], ['barney', 36], ['fred', 30], ['fred', 40]]
- */
- function sortBy(collection, callback, thisArg) {
- var index = -1,
- isArr = isArray(callback),
- length = collection ? collection.length : 0,
- result = Array(typeof length == 'number' ? length : 0);
-
- if (!isArr) {
- callback = lodash.createCallback(callback, thisArg, 3);
- }
- forEach(collection, function(value, key, collection) {
- var object = result[++index] = getObject();
- if (isArr) {
- object.criteria = map(callback, function(key) { return value[key]; });
- } else {
- (object.criteria = getArray())[0] = callback(value, key, collection);
- }
- object.index = index;
- object.value = value;
- });
-
- length = result.length;
- result.sort(compareAscending);
- while (length--) {
- var object = result[length];
- result[length] = object.value;
- if (!isArr) {
- releaseArray(object.criteria);
- }
- releaseObject(object);
- }
- return result;
- }
-
- /**
- * Converts the `collection` to an array.
- *
- * @static
- * @memberOf _
- * @category Collections
- * @param {Array|Object|string} collection The collection to convert.
- * @returns {Array} Returns the new converted array.
- * @example
- *
- * (function() { return _.toArray(arguments).slice(1); })(1, 2, 3, 4);
- * // => [2, 3, 4]
- */
- function toArray(collection) {
- if (collection && typeof collection.length == 'number') {
- return (support.unindexedChars && isString(collection))
- ? collection.split('')
- : slice(collection);
- }
- return values(collection);
- }
-
- /**
- * Performs a deep comparison of each element in a `collection` to the given
- * `properties` object, returning an array of all elements that have equivalent
- * property values.
- *
- * @static
- * @memberOf _
- * @type Function
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Object} props The object of property values to filter by.
- * @returns {Array} Returns a new array of elements that have the given properties.
- * @example
- *
- * var characters = [
- * { 'name': 'barney', 'age': 36, 'pets': ['hoppy'] },
- * { 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] }
- * ];
- *
- * _.where(characters, { 'age': 36 });
- * // => [{ 'name': 'barney', 'age': 36, 'pets': ['hoppy'] }]
- *
- * _.where(characters, { 'pets': ['dino'] });
- * // => [{ 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] }]
- */
- var where = filter;
-
- /*--------------------------------------------------------------------------*/
-
- /**
- * Creates an array with all falsey values removed. The values `false`, `null`,
- * `0`, `""`, `undefined`, and `NaN` are all falsey.
- *
- * @static
- * @memberOf _
- * @category Arrays
- * @param {Array} array The array to compact.
- * @returns {Array} Returns a new array of filtered values.
- * @example
- *
- * _.compact([0, 1, false, 2, '', 3]);
- * // => [1, 2, 3]
- */
- function compact(array) {
- var index = -1,
- length = array ? array.length : 0,
- result = [];
-
- while (++index < length) {
- var value = array[index];
- if (value) {
- result.push(value);
- }
- }
- return result;
- }
-
- /**
- * Creates an array excluding all values of the provided arrays using strict
- * equality for comparisons, i.e. `===`.
- *
- * @static
- * @memberOf _
- * @category Arrays
- * @param {Array} array The array to process.
- * @param {...Array} [values] The arrays of values to exclude.
- * @returns {Array} Returns a new array of filtered values.
- * @example
- *
- * _.difference([1, 2, 3, 4, 5], [5, 2, 10]);
- * // => [1, 3, 4]
- */
- function difference(array) {
- return baseDifference(array, baseFlatten(arguments, true, true, 1));
- }
-
- /**
- * This method is like `_.find` except that it returns the index of the first
- * element that passes the callback check, instead of the element itself.
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @category Arrays
- * @param {Array} array The array to search.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {number} Returns the index of the found element, else `-1`.
- * @example
- *
- * var characters = [
- * { 'name': 'barney', 'age': 36, 'blocked': false },
- * { 'name': 'fred', 'age': 40, 'blocked': true },
- * { 'name': 'pebbles', 'age': 1, 'blocked': false }
- * ];
- *
- * _.findIndex(characters, function(chr) {
- * return chr.age < 20;
- * });
- * // => 2
- *
- * // using "_.where" callback shorthand
- * _.findIndex(characters, { 'age': 36 });
- * // => 0
- *
- * // using "_.pluck" callback shorthand
- * _.findIndex(characters, 'blocked');
- * // => 1
- */
- function findIndex(array, callback, thisArg) {
- var index = -1,
- length = array ? array.length : 0;
-
- callback = lodash.createCallback(callback, thisArg, 3);
- while (++index < length) {
- if (callback(array[index], index, array)) {
- return index;
- }
- }
- return -1;
- }
-
- /**
- * This method is like `_.findIndex` except that it iterates over elements
- * of a `collection` from right to left.
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @category Arrays
- * @param {Array} array The array to search.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {number} Returns the index of the found element, else `-1`.
- * @example
- *
- * var characters = [
- * { 'name': 'barney', 'age': 36, 'blocked': true },
- * { 'name': 'fred', 'age': 40, 'blocked': false },
- * { 'name': 'pebbles', 'age': 1, 'blocked': true }
- * ];
- *
- * _.findLastIndex(characters, function(chr) {
- * return chr.age > 30;
- * });
- * // => 1
- *
- * // using "_.where" callback shorthand
- * _.findLastIndex(characters, { 'age': 36 });
- * // => 0
- *
- * // using "_.pluck" callback shorthand
- * _.findLastIndex(characters, 'blocked');
- * // => 2
- */
- function findLastIndex(array, callback, thisArg) {
- var length = array ? array.length : 0;
- callback = lodash.createCallback(callback, thisArg, 3);
- while (length--) {
- if (callback(array[length], length, array)) {
- return length;
- }
- }
- return -1;
- }
-
- /**
- * Gets the first element or first `n` elements of an array. If a callback
- * is provided elements at the beginning of the array are returned as long
- * as the callback returns truey. The callback is bound to `thisArg` and
- * invoked with three arguments; (value, index, array).
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @alias head, take
- * @category Arrays
- * @param {Array} array The array to query.
- * @param {Function|Object|number|string} [callback] The function called
- * per element or the number of elements to return. If a property name or
- * object is provided it will be used to create a "_.pluck" or "_.where"
- * style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {*} Returns the first element(s) of `array`.
- * @example
- *
- * _.first([1, 2, 3]);
- * // => 1
- *
- * _.first([1, 2, 3], 2);
- * // => [1, 2]
- *
- * _.first([1, 2, 3], function(num) {
- * return num < 3;
- * });
- * // => [1, 2]
- *
- * var characters = [
- * { 'name': 'barney', 'blocked': true, 'employer': 'slate' },
- * { 'name': 'fred', 'blocked': false, 'employer': 'slate' },
- * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' }
- * ];
- *
- * // using "_.pluck" callback shorthand
- * _.first(characters, 'blocked');
- * // => [{ 'name': 'barney', 'blocked': true, 'employer': 'slate' }]
- *
- * // using "_.where" callback shorthand
- * _.pluck(_.first(characters, { 'employer': 'slate' }), 'name');
- * // => ['barney', 'fred']
- */
- function first(array, callback, thisArg) {
- var n = 0,
- length = array ? array.length : 0;
-
- if (typeof callback != 'number' && callback != null) {
- var index = -1;
- callback = lodash.createCallback(callback, thisArg, 3);
- while (++index < length && callback(array[index], index, array)) {
- n++;
- }
- } else {
- n = callback;
- if (n == null || thisArg) {
- return array ? array[0] : undefined;
- }
- }
- return slice(array, 0, nativeMin(nativeMax(0, n), length));
- }
-
- /**
- * Flattens a nested array (the nesting can be to any depth). If `isShallow`
- * is truey, the array will only be flattened a single level. If a callback
- * is provided each element of the array is passed through the callback before
- * flattening. The callback is bound to `thisArg` and invoked with three
- * arguments; (value, index, array).
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @category Arrays
- * @param {Array} array The array to flatten.
- * @param {boolean} [isShallow=false] A flag to restrict flattening to a single level.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Array} Returns a new flattened array.
- * @example
- *
- * _.flatten([1, [2], [3, [[4]]]]);
- * // => [1, 2, 3, 4];
- *
- * _.flatten([1, [2], [3, [[4]]]], true);
- * // => [1, 2, 3, [[4]]];
- *
- * var characters = [
- * { 'name': 'barney', 'age': 30, 'pets': ['hoppy'] },
- * { 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] }
- * ];
- *
- * // using "_.pluck" callback shorthand
- * _.flatten(characters, 'pets');
- * // => ['hoppy', 'baby puss', 'dino']
- */
- function flatten(array, isShallow, callback, thisArg) {
- // juggle arguments
- if (typeof isShallow != 'boolean' && isShallow != null) {
- thisArg = callback;
- callback = (typeof isShallow != 'function' && thisArg && thisArg[isShallow] === array) ? null : isShallow;
- isShallow = false;
- }
- if (callback != null) {
- array = map(array, callback, thisArg);
- }
- return baseFlatten(array, isShallow);
- }
-
- /**
- * Gets the index at which the first occurrence of `value` is found using
- * strict equality for comparisons, i.e. `===`. If the array is already sorted
- * providing `true` for `fromIndex` will run a faster binary search.
- *
- * @static
- * @memberOf _
- * @category Arrays
- * @param {Array} array The array to search.
- * @param {*} value The value to search for.
- * @param {boolean|number} [fromIndex=0] The index to search from or `true`
- * to perform a binary search on a sorted array.
- * @returns {number} Returns the index of the matched value or `-1`.
- * @example
- *
- * _.indexOf([1, 2, 3, 1, 2, 3], 2);
- * // => 1
- *
- * _.indexOf([1, 2, 3, 1, 2, 3], 2, 3);
- * // => 4
- *
- * _.indexOf([1, 1, 2, 2, 3, 3], 2, true);
- * // => 2
- */
- function indexOf(array, value, fromIndex) {
- if (typeof fromIndex == 'number') {
- var length = array ? array.length : 0;
- fromIndex = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex || 0);
- } else if (fromIndex) {
- var index = sortedIndex(array, value);
- return array[index] === value ? index : -1;
- }
- return baseIndexOf(array, value, fromIndex);
- }
-
- /**
- * Gets all but the last element or last `n` elements of an array. If a
- * callback is provided elements at the end of the array are excluded from
- * the result as long as the callback returns truey. The callback is bound
- * to `thisArg` and invoked with three arguments; (value, index, array).
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @category Arrays
- * @param {Array} array The array to query.
- * @param {Function|Object|number|string} [callback=1] The function called
- * per element or the number of elements to exclude. If a property name or
- * object is provided it will be used to create a "_.pluck" or "_.where"
- * style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Array} Returns a slice of `array`.
- * @example
- *
- * _.initial([1, 2, 3]);
- * // => [1, 2]
- *
- * _.initial([1, 2, 3], 2);
- * // => [1]
- *
- * _.initial([1, 2, 3], function(num) {
- * return num > 1;
- * });
- * // => [1]
- *
- * var characters = [
- * { 'name': 'barney', 'blocked': false, 'employer': 'slate' },
- * { 'name': 'fred', 'blocked': true, 'employer': 'slate' },
- * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' }
- * ];
- *
- * // using "_.pluck" callback shorthand
- * _.initial(characters, 'blocked');
- * // => [{ 'name': 'barney', 'blocked': false, 'employer': 'slate' }]
- *
- * // using "_.where" callback shorthand
- * _.pluck(_.initial(characters, { 'employer': 'na' }), 'name');
- * // => ['barney', 'fred']
- */
- function initial(array, callback, thisArg) {
- var n = 0,
- length = array ? array.length : 0;
-
- if (typeof callback != 'number' && callback != null) {
- var index = length;
- callback = lodash.createCallback(callback, thisArg, 3);
- while (index-- && callback(array[index], index, array)) {
- n++;
- }
- } else {
- n = (callback == null || thisArg) ? 1 : callback || n;
- }
- return slice(array, 0, nativeMin(nativeMax(0, length - n), length));
- }
-
- /**
- * Creates an array of unique values present in all provided arrays using
- * strict equality for comparisons, i.e. `===`.
- *
- * @static
- * @memberOf _
- * @category Arrays
- * @param {...Array} [array] The arrays to inspect.
- * @returns {Array} Returns an array of shared values.
- * @example
- *
- * _.intersection([1, 2, 3], [5, 2, 1, 4], [2, 1]);
- * // => [1, 2]
- */
- function intersection() {
- var args = [],
- argsIndex = -1,
- argsLength = arguments.length,
- caches = getArray(),
- indexOf = getIndexOf(),
- trustIndexOf = indexOf === baseIndexOf,
- seen = getArray();
-
- while (++argsIndex < argsLength) {
- var value = arguments[argsIndex];
- if (isArray(value) || isArguments(value)) {
- args.push(value);
- caches.push(trustIndexOf && value.length >= largeArraySize &&
- createCache(argsIndex ? args[argsIndex] : seen));
- }
- }
- var array = args[0],
- index = -1,
- length = array ? array.length : 0,
- result = [];
-
- outer:
- while (++index < length) {
- var cache = caches[0];
- value = array[index];
-
- if ((cache ? cacheIndexOf(cache, value) : indexOf(seen, value)) < 0) {
- argsIndex = argsLength;
- (cache || seen).push(value);
- while (--argsIndex) {
- cache = caches[argsIndex];
- if ((cache ? cacheIndexOf(cache, value) : indexOf(args[argsIndex], value)) < 0) {
- continue outer;
- }
- }
- result.push(value);
- }
- }
- while (argsLength--) {
- cache = caches[argsLength];
- if (cache) {
- releaseObject(cache);
- }
- }
- releaseArray(caches);
- releaseArray(seen);
- return result;
- }
-
- /**
- * Gets the last element or last `n` elements of an array. If a callback is
- * provided elements at the end of the array are returned as long as the
- * callback returns truey. The callback is bound to `thisArg` and invoked
- * with three arguments; (value, index, array).
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @category Arrays
- * @param {Array} array The array to query.
- * @param {Function|Object|number|string} [callback] The function called
- * per element or the number of elements to return. If a property name or
- * object is provided it will be used to create a "_.pluck" or "_.where"
- * style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {*} Returns the last element(s) of `array`.
- * @example
- *
- * _.last([1, 2, 3]);
- * // => 3
- *
- * _.last([1, 2, 3], 2);
- * // => [2, 3]
- *
- * _.last([1, 2, 3], function(num) {
- * return num > 1;
- * });
- * // => [2, 3]
- *
- * var characters = [
- * { 'name': 'barney', 'blocked': false, 'employer': 'slate' },
- * { 'name': 'fred', 'blocked': true, 'employer': 'slate' },
- * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' }
- * ];
- *
- * // using "_.pluck" callback shorthand
- * _.pluck(_.last(characters, 'blocked'), 'name');
- * // => ['fred', 'pebbles']
- *
- * // using "_.where" callback shorthand
- * _.last(characters, { 'employer': 'na' });
- * // => [{ 'name': 'pebbles', 'blocked': true, 'employer': 'na' }]
- */
- function last(array, callback, thisArg) {
- var n = 0,
- length = array ? array.length : 0;
-
- if (typeof callback != 'number' && callback != null) {
- var index = length;
- callback = lodash.createCallback(callback, thisArg, 3);
- while (index-- && callback(array[index], index, array)) {
- n++;
- }
- } else {
- n = callback;
- if (n == null || thisArg) {
- return array ? array[length - 1] : undefined;
- }
- }
- return slice(array, nativeMax(0, length - n));
- }
-
- /**
- * Gets the index at which the last occurrence of `value` is found using strict
- * equality for comparisons, i.e. `===`. If `fromIndex` is negative, it is used
- * as the offset from the end of the collection.
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @category Arrays
- * @param {Array} array The array to search.
- * @param {*} value The value to search for.
- * @param {number} [fromIndex=array.length-1] The index to search from.
- * @returns {number} Returns the index of the matched value or `-1`.
- * @example
- *
- * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2);
- * // => 4
- *
- * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2, 3);
- * // => 1
- */
- function lastIndexOf(array, value, fromIndex) {
- var index = array ? array.length : 0;
- if (typeof fromIndex == 'number') {
- index = (fromIndex < 0 ? nativeMax(0, index + fromIndex) : nativeMin(fromIndex, index - 1)) + 1;
- }
- while (index--) {
- if (array[index] === value) {
- return index;
- }
- }
- return -1;
- }
-
- /**
- * Removes all provided values from the given array using strict equality for
- * comparisons, i.e. `===`.
- *
- * @static
- * @memberOf _
- * @category Arrays
- * @param {Array} array The array to modify.
- * @param {...*} [value] The values to remove.
- * @returns {Array} Returns `array`.
- * @example
- *
- * var array = [1, 2, 3, 1, 2, 3];
- * _.pull(array, 2, 3);
- * console.log(array);
- * // => [1, 1]
- */
- function pull(array) {
- var args = arguments,
- argsIndex = 0,
- argsLength = args.length,
- length = array ? array.length : 0;
-
- while (++argsIndex < argsLength) {
- var index = -1,
- value = args[argsIndex];
- while (++index < length) {
- if (array[index] === value) {
- splice.call(array, index--, 1);
- length--;
- }
- }
- }
- return array;
- }
-
- /**
- * Creates an array of numbers (positive and/or negative) progressing from
- * `start` up to but not including `end`. If `start` is less than `stop` a
- * zero-length range is created unless a negative `step` is specified.
- *
- * @static
- * @memberOf _
- * @category Arrays
- * @param {number} [start=0] The start of the range.
- * @param {number} end The end of the range.
- * @param {number} [step=1] The value to increment or decrement by.
- * @returns {Array} Returns a new range array.
- * @example
- *
- * _.range(4);
- * // => [0, 1, 2, 3]
- *
- * _.range(1, 5);
- * // => [1, 2, 3, 4]
- *
- * _.range(0, 20, 5);
- * // => [0, 5, 10, 15]
- *
- * _.range(0, -4, -1);
- * // => [0, -1, -2, -3]
- *
- * _.range(1, 4, 0);
- * // => [1, 1, 1]
- *
- * _.range(0);
- * // => []
- */
- function range(start, end, step) {
- start = +start || 0;
- step = typeof step == 'number' ? step : (+step || 1);
-
- if (end == null) {
- end = start;
- start = 0;
- }
- // use `Array(length)` so engines like Chakra and V8 avoid slower modes
- // http://youtu.be/XAqIpGU8ZZk#t=17m25s
- var index = -1,
- length = nativeMax(0, ceil((end - start) / (step || 1))),
- result = Array(length);
-
- while (++index < length) {
- result[index] = start;
- start += step;
- }
- return result;
- }
-
- /**
- * Removes all elements from an array that the callback returns truey for
- * and returns an array of removed elements. The callback is bound to `thisArg`
- * and invoked with three arguments; (value, index, array).
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @category Arrays
- * @param {Array} array The array to modify.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Array} Returns a new array of removed elements.
- * @example
- *
- * var array = [1, 2, 3, 4, 5, 6];
- * var evens = _.remove(array, function(num) { return num % 2 == 0; });
- *
- * console.log(array);
- * // => [1, 3, 5]
- *
- * console.log(evens);
- * // => [2, 4, 6]
- */
- function remove(array, callback, thisArg) {
- var index = -1,
- length = array ? array.length : 0,
- result = [];
-
- callback = lodash.createCallback(callback, thisArg, 3);
- while (++index < length) {
- var value = array[index];
- if (callback(value, index, array)) {
- result.push(value);
- splice.call(array, index--, 1);
- length--;
- }
- }
- return result;
- }
-
- /**
- * The opposite of `_.initial` this method gets all but the first element or
- * first `n` elements of an array. If a callback function is provided elements
- * at the beginning of the array are excluded from the result as long as the
- * callback returns truey. The callback is bound to `thisArg` and invoked
- * with three arguments; (value, index, array).
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @alias drop, tail
- * @category Arrays
- * @param {Array} array The array to query.
- * @param {Function|Object|number|string} [callback=1] The function called
- * per element or the number of elements to exclude. If a property name or
- * object is provided it will be used to create a "_.pluck" or "_.where"
- * style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Array} Returns a slice of `array`.
- * @example
- *
- * _.rest([1, 2, 3]);
- * // => [2, 3]
- *
- * _.rest([1, 2, 3], 2);
- * // => [3]
- *
- * _.rest([1, 2, 3], function(num) {
- * return num < 3;
- * });
- * // => [3]
- *
- * var characters = [
- * { 'name': 'barney', 'blocked': true, 'employer': 'slate' },
- * { 'name': 'fred', 'blocked': false, 'employer': 'slate' },
- * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' }
- * ];
- *
- * // using "_.pluck" callback shorthand
- * _.pluck(_.rest(characters, 'blocked'), 'name');
- * // => ['fred', 'pebbles']
- *
- * // using "_.where" callback shorthand
- * _.rest(characters, { 'employer': 'slate' });
- * // => [{ 'name': 'pebbles', 'blocked': true, 'employer': 'na' }]
- */
- function rest(array, callback, thisArg) {
- if (typeof callback != 'number' && callback != null) {
- var n = 0,
- index = -1,
- length = array ? array.length : 0;
-
- callback = lodash.createCallback(callback, thisArg, 3);
- while (++index < length && callback(array[index], index, array)) {
- n++;
- }
- } else {
- n = (callback == null || thisArg) ? 1 : nativeMax(0, callback);
- }
- return slice(array, n);
- }
-
- /**
- * Uses a binary search to determine the smallest index at which a value
- * should be inserted into a given sorted array in order to maintain the sort
- * order of the array. If a callback is provided it will be executed for
- * `value` and each element of `array` to compute their sort ranking. The
- * callback is bound to `thisArg` and invoked with one argument; (value).
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @category Arrays
- * @param {Array} array The array to inspect.
- * @param {*} value The value to evaluate.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {number} Returns the index at which `value` should be inserted
- * into `array`.
- * @example
- *
- * _.sortedIndex([20, 30, 50], 40);
- * // => 2
- *
- * // using "_.pluck" callback shorthand
- * _.sortedIndex([{ 'x': 20 }, { 'x': 30 }, { 'x': 50 }], { 'x': 40 }, 'x');
- * // => 2
- *
- * var dict = {
- * 'wordToNumber': { 'twenty': 20, 'thirty': 30, 'fourty': 40, 'fifty': 50 }
- * };
- *
- * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) {
- * return dict.wordToNumber[word];
- * });
- * // => 2
- *
- * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) {
- * return this.wordToNumber[word];
- * }, dict);
- * // => 2
- */
- function sortedIndex(array, value, callback, thisArg) {
- var low = 0,
- high = array ? array.length : low;
-
- // explicitly reference `identity` for better inlining in Firefox
- callback = callback ? lodash.createCallback(callback, thisArg, 1) : identity;
- value = callback(value);
-
- while (low < high) {
- var mid = (low + high) >>> 1;
- (callback(array[mid]) < value)
- ? low = mid + 1
- : high = mid;
- }
- return low;
- }
-
- /**
- * Creates an array of unique values, in order, of the provided arrays using
- * strict equality for comparisons, i.e. `===`.
- *
- * @static
- * @memberOf _
- * @category Arrays
- * @param {...Array} [array] The arrays to inspect.
- * @returns {Array} Returns an array of combined values.
- * @example
- *
- * _.union([1, 2, 3], [5, 2, 1, 4], [2, 1]);
- * // => [1, 2, 3, 5, 4]
- */
- function union() {
- return baseUniq(baseFlatten(arguments, true, true));
- }
-
- /**
- * Creates a duplicate-value-free version of an array using strict equality
- * for comparisons, i.e. `===`. If the array is sorted, providing
- * `true` for `isSorted` will use a faster algorithm. If a callback is provided
- * each element of `array` is passed through the callback before uniqueness
- * is computed. The callback is bound to `thisArg` and invoked with three
- * arguments; (value, index, array).
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @alias unique
- * @category Arrays
- * @param {Array} array The array to process.
- * @param {boolean} [isSorted=false] A flag to indicate that `array` is sorted.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Array} Returns a duplicate-value-free array.
- * @example
- *
- * _.uniq([1, 2, 1, 3, 1]);
- * // => [1, 2, 3]
- *
- * _.uniq([1, 1, 2, 2, 3], true);
- * // => [1, 2, 3]
- *
- * _.uniq(['A', 'b', 'C', 'a', 'B', 'c'], function(letter) { return letter.toLowerCase(); });
- * // => ['A', 'b', 'C']
- *
- * _.uniq([1, 2.5, 3, 1.5, 2, 3.5], function(num) { return this.floor(num); }, Math);
- * // => [1, 2.5, 3]
- *
- * // using "_.pluck" callback shorthand
- * _.uniq([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');
- * // => [{ 'x': 1 }, { 'x': 2 }]
- */
- function uniq(array, isSorted, callback, thisArg) {
- // juggle arguments
- if (typeof isSorted != 'boolean' && isSorted != null) {
- thisArg = callback;
- callback = (typeof isSorted != 'function' && thisArg && thisArg[isSorted] === array) ? null : isSorted;
- isSorted = false;
- }
- if (callback != null) {
- callback = lodash.createCallback(callback, thisArg, 3);
- }
- return baseUniq(array, isSorted, callback);
- }
-
- /**
- * Creates an array excluding all provided values using strict equality for
- * comparisons, i.e. `===`.
- *
- * @static
- * @memberOf _
- * @category Arrays
- * @param {Array} array The array to filter.
- * @param {...*} [value] The values to exclude.
- * @returns {Array} Returns a new array of filtered values.
- * @example
- *
- * _.without([1, 2, 1, 0, 3, 1, 4], 0, 1);
- * // => [2, 3, 4]
- */
- function without(array) {
- return baseDifference(array, slice(arguments, 1));
- }
-
- /**
- * Creates an array that is the symmetric difference of the provided arrays.
- * See http://en.wikipedia.org/wiki/Symmetric_difference.
- *
- * @static
- * @memberOf _
- * @category Arrays
- * @param {...Array} [array] The arrays to inspect.
- * @returns {Array} Returns an array of values.
- * @example
- *
- * _.xor([1, 2, 3], [5, 2, 1, 4]);
- * // => [3, 5, 4]
- *
- * _.xor([1, 2, 5], [2, 3, 5], [3, 4, 5]);
- * // => [1, 4, 5]
- */
- function xor() {
- var index = -1,
- length = arguments.length;
-
- while (++index < length) {
- var array = arguments[index];
- if (isArray(array) || isArguments(array)) {
- var result = result
- ? baseUniq(baseDifference(result, array).concat(baseDifference(array, result)))
- : array;
- }
- }
- return result || [];
- }
-
- /**
- * Creates an array of grouped elements, the first of which contains the first
- * elements of the given arrays, the second of which contains the second
- * elements of the given arrays, and so on.
- *
- * @static
- * @memberOf _
- * @alias unzip
- * @category Arrays
- * @param {...Array} [array] Arrays to process.
- * @returns {Array} Returns a new array of grouped elements.
- * @example
- *
- * _.zip(['fred', 'barney'], [30, 40], [true, false]);
- * // => [['fred', 30, true], ['barney', 40, false]]
- */
- function zip() {
- var array = arguments.length > 1 ? arguments : arguments[0],
- index = -1,
- length = array ? max(pluck(array, 'length')) : 0,
- result = Array(length < 0 ? 0 : length);
-
- while (++index < length) {
- result[index] = pluck(array, index);
- }
- return result;
- }
-
- /**
- * Creates an object composed from arrays of `keys` and `values`. Provide
- * either a single two dimensional array, i.e. `[[key1, value1], [key2, value2]]`
- * or two arrays, one of `keys` and one of corresponding `values`.
- *
- * @static
- * @memberOf _
- * @alias object
- * @category Arrays
- * @param {Array} keys The array of keys.
- * @param {Array} [values=[]] The array of values.
- * @returns {Object} Returns an object composed of the given keys and
- * corresponding values.
- * @example
- *
- * _.zipObject(['fred', 'barney'], [30, 40]);
- * // => { 'fred': 30, 'barney': 40 }
- */
- function zipObject(keys, values) {
- var index = -1,
- length = keys ? keys.length : 0,
- result = {};
-
- if (!values && length && !isArray(keys[0])) {
- values = [];
- }
- while (++index < length) {
- var key = keys[index];
- if (values) {
- result[key] = values[index];
- } else if (key) {
- result[key[0]] = key[1];
- }
- }
- return result;
- }
-
- /*--------------------------------------------------------------------------*/
-
- /**
- * Creates a function that executes `func`, with the `this` binding and
- * arguments of the created function, only after being called `n` times.
- *
- * @static
- * @memberOf _
- * @category Functions
- * @param {number} n The number of times the function must be called before
- * `func` is executed.
- * @param {Function} func The function to restrict.
- * @returns {Function} Returns the new restricted function.
- * @example
- *
- * var saves = ['profile', 'settings'];
- *
- * var done = _.after(saves.length, function() {
- * console.log('Done saving!');
- * });
- *
- * _.forEach(saves, function(type) {
- * asyncSave({ 'type': type, 'complete': done });
- * });
- * // => logs 'Done saving!', after all saves have completed
- */
- function after(n, func) {
- if (!isFunction(func)) {
- throw new TypeError;
- }
- return function() {
- if (--n < 1) {
- return func.apply(this, arguments);
- }
- };
- }
-
- /**
- * Creates a function that, when called, invokes `func` with the `this`
- * binding of `thisArg` and prepends any additional `bind` arguments to those
- * provided to the bound function.
- *
- * @static
- * @memberOf _
- * @category Functions
- * @param {Function} func The function to bind.
- * @param {*} [thisArg] The `this` binding of `func`.
- * @param {...*} [arg] Arguments to be partially applied.
- * @returns {Function} Returns the new bound function.
- * @example
- *
- * var func = function(greeting) {
- * return greeting + ' ' + this.name;
- * };
- *
- * func = _.bind(func, { 'name': 'fred' }, 'hi');
- * func();
- * // => 'hi fred'
- */
- function bind(func, thisArg) {
- return arguments.length > 2
- ? createWrapper(func, 17, slice(arguments, 2), null, thisArg)
- : createWrapper(func, 1, null, null, thisArg);
- }
-
- /**
- * Binds methods of an object to the object itself, overwriting the existing
- * method. Method names may be specified as individual arguments or as arrays
- * of method names. If no method names are provided all the function properties
- * of `object` will be bound.
- *
- * @static
- * @memberOf _
- * @category Functions
- * @param {Object} object The object to bind and assign the bound methods to.
- * @param {...string} [methodName] The object method names to
- * bind, specified as individual method names or arrays of method names.
- * @returns {Object} Returns `object`.
- * @example
- *
- * var view = {
- * 'label': 'docs',
- * 'onClick': function() { console.log('clicked ' + this.label); }
- * };
- *
- * _.bindAll(view);
- * jQuery('#docs').on('click', view.onClick);
- * // => logs 'clicked docs', when the button is clicked
- */
- function bindAll(object) {
- var funcs = arguments.length > 1 ? baseFlatten(arguments, true, false, 1) : functions(object),
- index = -1,
- length = funcs.length;
-
- while (++index < length) {
- var key = funcs[index];
- object[key] = createWrapper(object[key], 1, null, null, object);
- }
- return object;
- }
-
- /**
- * Creates a function that, when called, invokes the method at `object[key]`
- * and prepends any additional `bindKey` arguments to those provided to the bound
- * function. This method differs from `_.bind` by allowing bound functions to
- * reference methods that will be redefined or don't yet exist.
- * See http://michaux.ca/articles/lazy-function-definition-pattern.
- *
- * @static
- * @memberOf _
- * @category Functions
- * @param {Object} object The object the method belongs to.
- * @param {string} key The key of the method.
- * @param {...*} [arg] Arguments to be partially applied.
- * @returns {Function} Returns the new bound function.
- * @example
- *
- * var object = {
- * 'name': 'fred',
- * 'greet': function(greeting) {
- * return greeting + ' ' + this.name;
- * }
- * };
- *
- * var func = _.bindKey(object, 'greet', 'hi');
- * func();
- * // => 'hi fred'
- *
- * object.greet = function(greeting) {
- * return greeting + 'ya ' + this.name + '!';
- * };
- *
- * func();
- * // => 'hiya fred!'
- */
- function bindKey(object, key) {
- return arguments.length > 2
- ? createWrapper(key, 19, slice(arguments, 2), null, object)
- : createWrapper(key, 3, null, null, object);
- }
-
- /**
- * Creates a function that is the composition of the provided functions,
- * where each function consumes the return value of the function that follows.
- * For example, composing the functions `f()`, `g()`, and `h()` produces `f(g(h()))`.
- * Each function is executed with the `this` binding of the composed function.
- *
- * @static
- * @memberOf _
- * @category Functions
- * @param {...Function} [func] Functions to compose.
- * @returns {Function} Returns the new composed function.
- * @example
- *
- * var realNameMap = {
- * 'pebbles': 'penelope'
- * };
- *
- * var format = function(name) {
- * name = realNameMap[name.toLowerCase()] || name;
- * return name.charAt(0).toUpperCase() + name.slice(1).toLowerCase();
- * };
- *
- * var greet = function(formatted) {
- * return 'Hiya ' + formatted + '!';
- * };
- *
- * var welcome = _.compose(greet, format);
- * welcome('pebbles');
- * // => 'Hiya Penelope!'
- */
- function compose() {
- var funcs = arguments,
- length = funcs.length;
-
- while (length--) {
- if (!isFunction(funcs[length])) {
- throw new TypeError;
- }
- }
- return function() {
- var args = arguments,
- length = funcs.length;
-
- while (length--) {
- args = [funcs[length].apply(this, args)];
- }
- return args[0];
- };
- }
-
- /**
- * Creates a function which accepts one or more arguments of `func` that when
- * invoked either executes `func` returning its result, if all `func` arguments
- * have been provided, or returns a function that accepts one or more of the
- * remaining `func` arguments, and so on. The arity of `func` can be specified
- * if `func.length` is not sufficient.
- *
- * @static
- * @memberOf _
- * @category Functions
- * @param {Function} func The function to curry.
- * @param {number} [arity=func.length] The arity of `func`.
- * @returns {Function} Returns the new curried function.
- * @example
- *
- * var curried = _.curry(function(a, b, c) {
- * console.log(a + b + c);
- * });
- *
- * curried(1)(2)(3);
- * // => 6
- *
- * curried(1, 2)(3);
- * // => 6
- *
- * curried(1, 2, 3);
- * // => 6
- */
- function curry(func, arity) {
- arity = typeof arity == 'number' ? arity : (+arity || func.length);
- return createWrapper(func, 4, null, null, null, arity);
- }
-
- /**
- * Creates a function that will delay the execution of `func` until after
- * `wait` milliseconds have elapsed since the last time it was invoked.
- * Provide an options object to indicate that `func` should be invoked on
- * the leading and/or trailing edge of the `wait` timeout. Subsequent calls
- * to the debounced function will return the result of the last `func` call.
- *
- * Note: If `leading` and `trailing` options are `true` `func` will be called
- * on the trailing edge of the timeout only if the the debounced function is
- * invoked more than once during the `wait` timeout.
- *
- * @static
- * @memberOf _
- * @category Functions
- * @param {Function} func The function to debounce.
- * @param {number} wait The number of milliseconds to delay.
- * @param {Object} [options] The options object.
- * @param {boolean} [options.leading=false] Specify execution on the leading edge of the timeout.
- * @param {number} [options.maxWait] The maximum time `func` is allowed to be delayed before it's called.
- * @param {boolean} [options.trailing=true] Specify execution on the trailing edge of the timeout.
- * @returns {Function} Returns the new debounced function.
- * @example
- *
- * // avoid costly calculations while the window size is in flux
- * var lazyLayout = _.debounce(calculateLayout, 150);
- * jQuery(window).on('resize', lazyLayout);
- *
- * // execute `sendMail` when the click event is fired, debouncing subsequent calls
- * jQuery('#postbox').on('click', _.debounce(sendMail, 300, {
- * 'leading': true,
- * 'trailing': false
- * });
- *
- * // ensure `batchLog` is executed once after 1 second of debounced calls
- * var source = new EventSource('/stream');
- * source.addEventListener('message', _.debounce(batchLog, 250, {
- * 'maxWait': 1000
- * }, false);
- */
- function debounce(func, wait, options) {
- var args,
- maxTimeoutId,
- result,
- stamp,
- thisArg,
- timeoutId,
- trailingCall,
- lastCalled = 0,
- maxWait = false,
- trailing = true;
-
- if (!isFunction(func)) {
- throw new TypeError;
- }
- wait = nativeMax(0, wait) || 0;
- if (options === true) {
- var leading = true;
- trailing = false;
- } else if (isObject(options)) {
- leading = options.leading;
- maxWait = 'maxWait' in options && (nativeMax(wait, options.maxWait) || 0);
- trailing = 'trailing' in options ? options.trailing : trailing;
- }
- var delayed = function() {
- var remaining = wait - (now() - stamp);
- if (remaining <= 0) {
- if (maxTimeoutId) {
- clearTimeout(maxTimeoutId);
- }
- var isCalled = trailingCall;
- maxTimeoutId = timeoutId = trailingCall = undefined;
- if (isCalled) {
- lastCalled = now();
- result = func.apply(thisArg, args);
- if (!timeoutId && !maxTimeoutId) {
- args = thisArg = null;
- }
- }
- } else {
- timeoutId = setTimeout(delayed, remaining);
- }
- };
-
- var maxDelayed = function() {
- if (timeoutId) {
- clearTimeout(timeoutId);
- }
- maxTimeoutId = timeoutId = trailingCall = undefined;
- if (trailing || (maxWait !== wait)) {
- lastCalled = now();
- result = func.apply(thisArg, args);
- if (!timeoutId && !maxTimeoutId) {
- args = thisArg = null;
- }
- }
- };
-
- return function() {
- args = arguments;
- stamp = now();
- thisArg = this;
- trailingCall = trailing && (timeoutId || !leading);
-
- if (maxWait === false) {
- var leadingCall = leading && !timeoutId;
- } else {
- if (!maxTimeoutId && !leading) {
- lastCalled = stamp;
- }
- var remaining = maxWait - (stamp - lastCalled),
- isCalled = remaining <= 0;
-
- if (isCalled) {
- if (maxTimeoutId) {
- maxTimeoutId = clearTimeout(maxTimeoutId);
- }
- lastCalled = stamp;
- result = func.apply(thisArg, args);
- }
- else if (!maxTimeoutId) {
- maxTimeoutId = setTimeout(maxDelayed, remaining);
- }
- }
- if (isCalled && timeoutId) {
- timeoutId = clearTimeout(timeoutId);
- }
- else if (!timeoutId && wait !== maxWait) {
- timeoutId = setTimeout(delayed, wait);
- }
- if (leadingCall) {
- isCalled = true;
- result = func.apply(thisArg, args);
- }
- if (isCalled && !timeoutId && !maxTimeoutId) {
- args = thisArg = null;
- }
- return result;
- };
- }
-
- /**
- * Defers executing the `func` function until the current call stack has cleared.
- * Additional arguments will be provided to `func` when it is invoked.
- *
- * @static
- * @memberOf _
- * @category Functions
- * @param {Function} func The function to defer.
- * @param {...*} [arg] Arguments to invoke the function with.
- * @returns {number} Returns the timer id.
- * @example
- *
- * _.defer(function(text) { console.log(text); }, 'deferred');
- * // logs 'deferred' after one or more milliseconds
- */
- function defer(func) {
- if (!isFunction(func)) {
- throw new TypeError;
- }
- var args = slice(arguments, 1);
- return setTimeout(function() { func.apply(undefined, args); }, 1);
- }
-
- /**
- * Executes the `func` function after `wait` milliseconds. Additional arguments
- * will be provided to `func` when it is invoked.
- *
- * @static
- * @memberOf _
- * @category Functions
- * @param {Function} func The function to delay.
- * @param {number} wait The number of milliseconds to delay execution.
- * @param {...*} [arg] Arguments to invoke the function with.
- * @returns {number} Returns the timer id.
- * @example
- *
- * _.delay(function(text) { console.log(text); }, 1000, 'later');
- * // => logs 'later' after one second
- */
- function delay(func, wait) {
- if (!isFunction(func)) {
- throw new TypeError;
- }
- var args = slice(arguments, 2);
- return setTimeout(function() { func.apply(undefined, args); }, wait);
- }
-
- /**
- * Creates a function that memoizes the result of `func`. If `resolver` is
- * provided it will be used to determine the cache key for storing the result
- * based on the arguments provided to the memoized function. By default, the
- * first argument provided to the memoized function is used as the cache key.
- * The `func` is executed with the `this` binding of the memoized function.
- * The result cache is exposed as the `cache` property on the memoized function.
- *
- * @static
- * @memberOf _
- * @category Functions
- * @param {Function} func The function to have its output memoized.
- * @param {Function} [resolver] A function used to resolve the cache key.
- * @returns {Function} Returns the new memoizing function.
- * @example
- *
- * var fibonacci = _.memoize(function(n) {
- * return n < 2 ? n : fibonacci(n - 1) + fibonacci(n - 2);
- * });
- *
- * fibonacci(9)
- * // => 34
- *
- * var data = {
- * 'fred': { 'name': 'fred', 'age': 40 },
- * 'pebbles': { 'name': 'pebbles', 'age': 1 }
- * };
- *
- * // modifying the result cache
- * var get = _.memoize(function(name) { return data[name]; }, _.identity);
- * get('pebbles');
- * // => { 'name': 'pebbles', 'age': 1 }
- *
- * get.cache.pebbles.name = 'penelope';
- * get('pebbles');
- * // => { 'name': 'penelope', 'age': 1 }
- */
- function memoize(func, resolver) {
- if (!isFunction(func)) {
- throw new TypeError;
- }
- var memoized = function() {
- var cache = memoized.cache,
- key = resolver ? resolver.apply(this, arguments) : keyPrefix + arguments[0];
-
- return hasOwnProperty.call(cache, key)
- ? cache[key]
- : (cache[key] = func.apply(this, arguments));
- }
- memoized.cache = {};
- return memoized;
- }
-
- /**
- * Creates a function that is restricted to execute `func` once. Repeat calls to
- * the function will return the value of the first call. The `func` is executed
- * with the `this` binding of the created function.
- *
- * @static
- * @memberOf _
- * @category Functions
- * @param {Function} func The function to restrict.
- * @returns {Function} Returns the new restricted function.
- * @example
- *
- * var initialize = _.once(createApplication);
- * initialize();
- * initialize();
- * // `initialize` executes `createApplication` once
- */
- function once(func) {
- var ran,
- result;
-
- if (!isFunction(func)) {
- throw new TypeError;
- }
- return function() {
- if (ran) {
- return result;
- }
- ran = true;
- result = func.apply(this, arguments);
-
- // clear the `func` variable so the function may be garbage collected
- func = null;
- return result;
- };
- }
-
- /**
- * Creates a function that, when called, invokes `func` with any additional
- * `partial` arguments prepended to those provided to the new function. This
- * method is similar to `_.bind` except it does **not** alter the `this` binding.
- *
- * @static
- * @memberOf _
- * @category Functions
- * @param {Function} func The function to partially apply arguments to.
- * @param {...*} [arg] Arguments to be partially applied.
- * @returns {Function} Returns the new partially applied function.
- * @example
- *
- * var greet = function(greeting, name) { return greeting + ' ' + name; };
- * var hi = _.partial(greet, 'hi');
- * hi('fred');
- * // => 'hi fred'
- */
- function partial(func) {
- return createWrapper(func, 16, slice(arguments, 1));
- }
-
- /**
- * This method is like `_.partial` except that `partial` arguments are
- * appended to those provided to the new function.
- *
- * @static
- * @memberOf _
- * @category Functions
- * @param {Function} func The function to partially apply arguments to.
- * @param {...*} [arg] Arguments to be partially applied.
- * @returns {Function} Returns the new partially applied function.
- * @example
- *
- * var defaultsDeep = _.partialRight(_.merge, _.defaults);
- *
- * var options = {
- * 'variable': 'data',
- * 'imports': { 'jq': $ }
- * };
- *
- * defaultsDeep(options, _.templateSettings);
- *
- * options.variable
- * // => 'data'
- *
- * options.imports
- * // => { '_': _, 'jq': $ }
- */
- function partialRight(func) {
- return createWrapper(func, 32, null, slice(arguments, 1));
- }
-
- /**
- * Creates a function that, when executed, will only call the `func` function
- * at most once per every `wait` milliseconds. Provide an options object to
- * indicate that `func` should be invoked on the leading and/or trailing edge
- * of the `wait` timeout. Subsequent calls to the throttled function will
- * return the result of the last `func` call.
- *
- * Note: If `leading` and `trailing` options are `true` `func` will be called
- * on the trailing edge of the timeout only if the the throttled function is
- * invoked more than once during the `wait` timeout.
- *
- * @static
- * @memberOf _
- * @category Functions
- * @param {Function} func The function to throttle.
- * @param {number} wait The number of milliseconds to throttle executions to.
- * @param {Object} [options] The options object.
- * @param {boolean} [options.leading=true] Specify execution on the leading edge of the timeout.
- * @param {boolean} [options.trailing=true] Specify execution on the trailing edge of the timeout.
- * @returns {Function} Returns the new throttled function.
- * @example
- *
- * // avoid excessively updating the position while scrolling
- * var throttled = _.throttle(updatePosition, 100);
- * jQuery(window).on('scroll', throttled);
- *
- * // execute `renewToken` when the click event is fired, but not more than once every 5 minutes
- * jQuery('.interactive').on('click', _.throttle(renewToken, 300000, {
- * 'trailing': false
- * }));
- */
- function throttle(func, wait, options) {
- var leading = true,
- trailing = true;
-
- if (!isFunction(func)) {
- throw new TypeError;
- }
- if (options === false) {
- leading = false;
- } else if (isObject(options)) {
- leading = 'leading' in options ? options.leading : leading;
- trailing = 'trailing' in options ? options.trailing : trailing;
- }
- debounceOptions.leading = leading;
- debounceOptions.maxWait = wait;
- debounceOptions.trailing = trailing;
-
- return debounce(func, wait, debounceOptions);
- }
-
- /**
- * Creates a function that provides `value` to the wrapper function as its
- * first argument. Additional arguments provided to the function are appended
- * to those provided to the wrapper function. The wrapper is executed with
- * the `this` binding of the created function.
- *
- * @static
- * @memberOf _
- * @category Functions
- * @param {*} value The value to wrap.
- * @param {Function} wrapper The wrapper function.
- * @returns {Function} Returns the new function.
- * @example
- *
- * var p = _.wrap(_.escape, function(func, text) {
- * return '' + func(text) + '
';
- * });
- *
- * p('Fred, Wilma, & Pebbles');
- * // => 'Fred, Wilma, & Pebbles
'
- */
- function wrap(value, wrapper) {
- return createWrapper(wrapper, 16, [value]);
- }
-
- /*--------------------------------------------------------------------------*/
-
- /**
- * Creates a function that returns `value`.
- *
- * @static
- * @memberOf _
- * @category Utilities
- * @param {*} value The value to return from the new function.
- * @returns {Function} Returns the new function.
- * @example
- *
- * var object = { 'name': 'fred' };
- * var getter = _.constant(object);
- * getter() === object;
- * // => true
- */
- function constant(value) {
- return function() {
- return value;
- };
- }
-
- /**
- * Produces a callback bound to an optional `thisArg`. If `func` is a property
- * name the created callback will return the property value for a given element.
- * If `func` is an object the created callback will return `true` for elements
- * that contain the equivalent object properties, otherwise it will return `false`.
- *
- * @static
- * @memberOf _
- * @category Utilities
- * @param {*} [func=identity] The value to convert to a callback.
- * @param {*} [thisArg] The `this` binding of the created callback.
- * @param {number} [argCount] The number of arguments the callback accepts.
- * @returns {Function} Returns a callback function.
- * @example
- *
- * var characters = [
- * { 'name': 'barney', 'age': 36 },
- * { 'name': 'fred', 'age': 40 }
- * ];
- *
- * // wrap to create custom callback shorthands
- * _.createCallback = _.wrap(_.createCallback, function(func, callback, thisArg) {
- * var match = /^(.+?)__([gl]t)(.+)$/.exec(callback);
- * return !match ? func(callback, thisArg) : function(object) {
- * return match[2] == 'gt' ? object[match[1]] > match[3] : object[match[1]] < match[3];
- * };
- * });
- *
- * _.filter(characters, 'age__gt38');
- * // => [{ 'name': 'fred', 'age': 40 }]
- */
- function createCallback(func, thisArg, argCount) {
- var type = typeof func;
- if (func == null || type == 'function') {
- return baseCreateCallback(func, thisArg, argCount);
- }
- // handle "_.pluck" style callback shorthands
- if (type != 'object') {
- return property(func);
- }
- var props = keys(func),
- key = props[0],
- a = func[key];
-
- // handle "_.where" style callback shorthands
- if (props.length == 1 && a === a && !isObject(a)) {
- // fast path the common case of providing an object with a single
- // property containing a primitive value
- return function(object) {
- var b = object[key];
- return a === b && (a !== 0 || (1 / a == 1 / b));
- };
- }
- return function(object) {
- var length = props.length,
- result = false;
-
- while (length--) {
- if (!(result = baseIsEqual(object[props[length]], func[props[length]], null, true))) {
- break;
- }
- }
- return result;
- };
- }
-
- /**
- * Converts the characters `&`, `<`, `>`, `"`, and `'` in `string` to their
- * corresponding HTML entities.
- *
- * @static
- * @memberOf _
- * @category Utilities
- * @param {string} string The string to escape.
- * @returns {string} Returns the escaped string.
- * @example
- *
- * _.escape('Fred, Wilma, & Pebbles');
- * // => 'Fred, Wilma, & Pebbles'
- */
- function escape(string) {
- return string == null ? '' : String(string).replace(reUnescapedHtml, escapeHtmlChar);
- }
-
- /**
- * This method returns the first argument provided to it.
- *
- * @static
- * @memberOf _
- * @category Utilities
- * @param {*} value Any value.
- * @returns {*} Returns `value`.
- * @example
- *
- * var object = { 'name': 'fred' };
- * _.identity(object) === object;
- * // => true
- */
- function identity(value) {
- return value;
- }
-
- /**
- * Adds function properties of a source object to the destination object.
- * If `object` is a function methods will be added to its prototype as well.
- *
- * @static
- * @memberOf _
- * @category Utilities
- * @param {Function|Object} [object=lodash] object The destination object.
- * @param {Object} source The object of functions to add.
- * @param {Object} [options] The options object.
- * @param {boolean} [options.chain=true] Specify whether the functions added are chainable.
- * @example
- *
- * function capitalize(string) {
- * return string.charAt(0).toUpperCase() + string.slice(1).toLowerCase();
- * }
- *
- * _.mixin({ 'capitalize': capitalize });
- * _.capitalize('fred');
- * // => 'Fred'
- *
- * _('fred').capitalize().value();
- * // => 'Fred'
- *
- * _.mixin({ 'capitalize': capitalize }, { 'chain': false });
- * _('fred').capitalize();
- * // => 'Fred'
- */
- function mixin(object, source, options) {
- var chain = true,
- methodNames = source && functions(source);
-
- if (!source || (!options && !methodNames.length)) {
- if (options == null) {
- options = source;
- }
- ctor = lodashWrapper;
- source = object;
- object = lodash;
- methodNames = functions(source);
- }
- if (options === false) {
- chain = false;
- } else if (isObject(options) && 'chain' in options) {
- chain = options.chain;
- }
- var ctor = object,
- isFunc = isFunction(ctor);
-
- forEach(methodNames, function(methodName) {
- var func = object[methodName] = source[methodName];
- if (isFunc) {
- ctor.prototype[methodName] = function() {
- var chainAll = this.__chain__,
- value = this.__wrapped__,
- args = [value];
-
- push.apply(args, arguments);
- var result = func.apply(object, args);
- if (chain || chainAll) {
- if (value === result && isObject(result)) {
- return this;
- }
- result = new ctor(result);
- result.__chain__ = chainAll;
- }
- return result;
- };
- }
- });
- }
-
- /**
- * Reverts the '_' variable to its previous value and returns a reference to
- * the `lodash` function.
- *
- * @static
- * @memberOf _
- * @category Utilities
- * @returns {Function} Returns the `lodash` function.
- * @example
- *
- * var lodash = _.noConflict();
- */
- function noConflict() {
- context._ = oldDash;
- return this;
- }
-
- /**
- * A no-operation function.
- *
- * @static
- * @memberOf _
- * @category Utilities
- * @example
- *
- * var object = { 'name': 'fred' };
- * _.noop(object) === undefined;
- * // => true
- */
- function noop() {
- // no operation performed
- }
-
- /**
- * Gets the number of milliseconds that have elapsed since the Unix epoch
- * (1 January 1970 00:00:00 UTC).
- *
- * @static
- * @memberOf _
- * @category Utilities
- * @example
- *
- * var stamp = _.now();
- * _.defer(function() { console.log(_.now() - stamp); });
- * // => logs the number of milliseconds it took for the deferred function to be called
- */
- var now = isNative(now = Date.now) && now || function() {
- return new Date().getTime();
- };
-
- /**
- * Converts the given value into an integer of the specified radix.
- * If `radix` is `undefined` or `0` a `radix` of `10` is used unless the
- * `value` is a hexadecimal, in which case a `radix` of `16` is used.
- *
- * Note: This method avoids differences in native ES3 and ES5 `parseInt`
- * implementations. See http://es5.github.io/#E.
- *
- * @static
- * @memberOf _
- * @category Utilities
- * @param {string} value The value to parse.
- * @param {number} [radix] The radix used to interpret the value to parse.
- * @returns {number} Returns the new integer value.
- * @example
- *
- * _.parseInt('08');
- * // => 8
- */
- var parseInt = nativeParseInt(whitespace + '08') == 8 ? nativeParseInt : function(value, radix) {
- // Firefox < 21 and Opera < 15 follow the ES3 specified implementation of `parseInt`
- return nativeParseInt(isString(value) ? value.replace(reLeadingSpacesAndZeros, '') : value, radix || 0);
- };
-
- /**
- * Creates a "_.pluck" style function, which returns the `key` value of a
- * given object.
- *
- * @static
- * @memberOf _
- * @category Utilities
- * @param {string} key The name of the property to retrieve.
- * @returns {Function} Returns the new function.
- * @example
- *
- * var characters = [
- * { 'name': 'fred', 'age': 40 },
- * { 'name': 'barney', 'age': 36 }
- * ];
- *
- * var getName = _.property('name');
- *
- * _.map(characters, getName);
- * // => ['barney', 'fred']
- *
- * _.sortBy(characters, getName);
- * // => [{ 'name': 'barney', 'age': 36 }, { 'name': 'fred', 'age': 40 }]
- */
- function property(key) {
- return function(object) {
- return object[key];
- };
- }
-
- /**
- * Produces a random number between `min` and `max` (inclusive). If only one
- * argument is provided a number between `0` and the given number will be
- * returned. If `floating` is truey or either `min` or `max` are floats a
- * floating-point number will be returned instead of an integer.
- *
- * @static
- * @memberOf _
- * @category Utilities
- * @param {number} [min=0] The minimum possible value.
- * @param {number} [max=1] The maximum possible value.
- * @param {boolean} [floating=false] Specify returning a floating-point number.
- * @returns {number} Returns a random number.
- * @example
- *
- * _.random(0, 5);
- * // => an integer between 0 and 5
- *
- * _.random(5);
- * // => also an integer between 0 and 5
- *
- * _.random(5, true);
- * // => a floating-point number between 0 and 5
- *
- * _.random(1.2, 5.2);
- * // => a floating-point number between 1.2 and 5.2
- */
- function random(min, max, floating) {
- var noMin = min == null,
- noMax = max == null;
-
- if (floating == null) {
- if (typeof min == 'boolean' && noMax) {
- floating = min;
- min = 1;
- }
- else if (!noMax && typeof max == 'boolean') {
- floating = max;
- noMax = true;
- }
- }
- if (noMin && noMax) {
- max = 1;
- }
- min = +min || 0;
- if (noMax) {
- max = min;
- min = 0;
- } else {
- max = +max || 0;
- }
- if (floating || min % 1 || max % 1) {
- var rand = nativeRandom();
- return nativeMin(min + (rand * (max - min + parseFloat('1e-' + ((rand +'').length - 1)))), max);
- }
- return baseRandom(min, max);
- }
-
- /**
- * Resolves the value of property `key` on `object`. If `key` is a function
- * it will be invoked with the `this` binding of `object` and its result returned,
- * else the property value is returned. If `object` is falsey then `undefined`
- * is returned.
- *
- * @static
- * @memberOf _
- * @category Utilities
- * @param {Object} object The object to inspect.
- * @param {string} key The name of the property to resolve.
- * @returns {*} Returns the resolved value.
- * @example
- *
- * var object = {
- * 'cheese': 'crumpets',
- * 'stuff': function() {
- * return 'nonsense';
- * }
- * };
- *
- * _.result(object, 'cheese');
- * // => 'crumpets'
- *
- * _.result(object, 'stuff');
- * // => 'nonsense'
- */
- function result(object, key) {
- if (object) {
- var value = object[key];
- return isFunction(value) ? object[key]() : value;
- }
- }
-
- /**
- * A micro-templating method that handles arbitrary delimiters, preserves
- * whitespace, and correctly escapes quotes within interpolated code.
- *
- * Note: In the development build, `_.template` utilizes sourceURLs for easier
- * debugging. See http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl
- *
- * For more information on precompiling templates see:
- * http://lodash.com/custom-builds
- *
- * For more information on Chrome extension sandboxes see:
- * http://developer.chrome.com/stable/extensions/sandboxingEval.html
- *
- * @static
- * @memberOf _
- * @category Utilities
- * @param {string} text The template text.
- * @param {Object} data The data object used to populate the text.
- * @param {Object} [options] The options object.
- * @param {RegExp} [options.escape] The "escape" delimiter.
- * @param {RegExp} [options.evaluate] The "evaluate" delimiter.
- * @param {Object} [options.imports] An object to import into the template as local variables.
- * @param {RegExp} [options.interpolate] The "interpolate" delimiter.
- * @param {string} [sourceURL] The sourceURL of the template's compiled source.
- * @param {string} [variable] The data object variable name.
- * @returns {Function|string} Returns a compiled function when no `data` object
- * is given, else it returns the interpolated text.
- * @example
- *
- * // using the "interpolate" delimiter to create a compiled template
- * var compiled = _.template('hello <%= name %>');
- * compiled({ 'name': 'fred' });
- * // => 'hello fred'
- *
- * // using the "escape" delimiter to escape HTML in data property values
- * _.template('<%- value %>', { 'value': '
-```
-
-Using [`npm`](http://npmjs.org/):
-
-```bash
-npm i --save lodash
-
-{sudo} npm i -g lodash
-npm ln lodash
-```
-
-In [Node.js](http://nodejs.org/) & [Ringo](http://ringojs.org/):
-
-```js
-var _ = require('lodash');
-// or as Underscore
-var _ = require('lodash/dist/lodash.underscore');
-```
-
-**Notes:**
- * Don’t assign values to [special variable](http://nodejs.org/api/repl.html#repl_repl_features) `_` when in the REPL
- * If Lo-Dash is installed globally, run [`npm ln lodash`](http://blog.nodejs.org/2011/03/23/npm-1-0-global-vs-local-installation/) in your project’s root directory *before* requiring it
-
-In [Rhino](http://www.mozilla.org/rhino/):
-
-```js
-load('lodash.js');
-```
-
-In an AMD loader:
-
-```js
-require({
- 'packages': [
- { 'name': 'lodash', 'location': 'path/to/lodash', 'main': 'lodash' }
- ]
-},
-['lodash'], function(_) {
- console.log(_.VERSION);
-});
-```
-
-## Author
-
-| [](https://twitter.com/jdalton "Follow @jdalton on Twitter") |
-|---|
-| [John-David Dalton](http://allyoucanleet.com/) |
-
-## Contributors
-
-| [](https://twitter.com/blainebublitz "Follow @BlaineBublitz on Twitter") | [](https://twitter.com/kitcambridge "Follow @kitcambridge on Twitter") | [](https://twitter.com/mathias "Follow @mathias on Twitter") |
-|---|---|---|
-| [Blaine Bublitz](http://www.iceddev.com/) | [Kit Cambridge](http://kitcambridge.be/) | [Mathias Bynens](http://mathiasbynens.be/) |
-
-[](https://bitdeli.com/free "Bitdeli Badge")
diff --git a/spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/lodash/dist/lodash.compat.js b/spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/lodash/dist/lodash.compat.js
deleted file mode 100644
index 23798ba8..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/lodash/dist/lodash.compat.js
+++ /dev/null
@@ -1,7157 +0,0 @@
-/**
- * @license
- * Lo-Dash 2.4.1 (Custom Build)
- * Build: `lodash -o ./dist/lodash.compat.js`
- * Copyright 2012-2013 The Dojo Foundation
- * Based on Underscore.js 1.5.2
- * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
- * Available under MIT license
- */
-;(function() {
-
- /** Used as a safe reference for `undefined` in pre ES5 environments */
- var undefined;
-
- /** Used to pool arrays and objects used internally */
- var arrayPool = [],
- objectPool = [];
-
- /** Used to generate unique IDs */
- var idCounter = 0;
-
- /** Used internally to indicate various things */
- var indicatorObject = {};
-
- /** Used to prefix keys to avoid issues with `__proto__` and properties on `Object.prototype` */
- var keyPrefix = +new Date + '';
-
- /** Used as the size when optimizations are enabled for large arrays */
- var largeArraySize = 75;
-
- /** Used as the max size of the `arrayPool` and `objectPool` */
- var maxPoolSize = 40;
-
- /** Used to detect and test whitespace */
- var whitespace = (
- // whitespace
- ' \t\x0B\f\xA0\ufeff' +
-
- // line terminators
- '\n\r\u2028\u2029' +
-
- // unicode category "Zs" space separators
- '\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000'
- );
-
- /** Used to match empty string literals in compiled template source */
- var reEmptyStringLeading = /\b__p \+= '';/g,
- reEmptyStringMiddle = /\b(__p \+=) '' \+/g,
- reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g;
-
- /**
- * Used to match ES6 template delimiters
- * http://people.mozilla.org/~jorendorff/es6-draft.html#sec-literals-string-literals
- */
- var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g;
-
- /** Used to match regexp flags from their coerced string values */
- var reFlags = /\w*$/;
-
- /** Used to detected named functions */
- var reFuncName = /^\s*function[ \n\r\t]+\w/;
-
- /** Used to match "interpolate" template delimiters */
- var reInterpolate = /<%=([\s\S]+?)%>/g;
-
- /** Used to match leading whitespace and zeros to be removed */
- var reLeadingSpacesAndZeros = RegExp('^[' + whitespace + ']*0+(?=.$)');
-
- /** Used to ensure capturing order of template delimiters */
- var reNoMatch = /($^)/;
-
- /** Used to detect functions containing a `this` reference */
- var reThis = /\bthis\b/;
-
- /** Used to match unescaped characters in compiled string literals */
- var reUnescapedString = /['\n\r\t\u2028\u2029\\]/g;
-
- /** Used to assign default `context` object properties */
- var contextProps = [
- 'Array', 'Boolean', 'Date', 'Error', 'Function', 'Math', 'Number', 'Object',
- 'RegExp', 'String', '_', 'attachEvent', 'clearTimeout', 'isFinite', 'isNaN',
- 'parseInt', 'setTimeout'
- ];
-
- /** Used to fix the JScript [[DontEnum]] bug */
- var shadowedProps = [
- 'constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable',
- 'toLocaleString', 'toString', 'valueOf'
- ];
-
- /** Used to make template sourceURLs easier to identify */
- var templateCounter = 0;
-
- /** `Object#toString` result shortcuts */
- var argsClass = '[object Arguments]',
- arrayClass = '[object Array]',
- boolClass = '[object Boolean]',
- dateClass = '[object Date]',
- errorClass = '[object Error]',
- funcClass = '[object Function]',
- numberClass = '[object Number]',
- objectClass = '[object Object]',
- regexpClass = '[object RegExp]',
- stringClass = '[object String]';
-
- /** Used to identify object classifications that `_.clone` supports */
- var cloneableClasses = {};
- cloneableClasses[funcClass] = false;
- cloneableClasses[argsClass] = cloneableClasses[arrayClass] =
- cloneableClasses[boolClass] = cloneableClasses[dateClass] =
- cloneableClasses[numberClass] = cloneableClasses[objectClass] =
- cloneableClasses[regexpClass] = cloneableClasses[stringClass] = true;
-
- /** Used as an internal `_.debounce` options object */
- var debounceOptions = {
- 'leading': false,
- 'maxWait': 0,
- 'trailing': false
- };
-
- /** Used as the property descriptor for `__bindData__` */
- var descriptor = {
- 'configurable': false,
- 'enumerable': false,
- 'value': null,
- 'writable': false
- };
-
- /** Used as the data object for `iteratorTemplate` */
- var iteratorData = {
- 'args': '',
- 'array': null,
- 'bottom': '',
- 'firstArg': '',
- 'init': '',
- 'keys': null,
- 'loop': '',
- 'shadowedProps': null,
- 'support': null,
- 'top': '',
- 'useHas': false
- };
-
- /** Used to determine if values are of the language type Object */
- var objectTypes = {
- 'boolean': false,
- 'function': true,
- 'object': true,
- 'number': false,
- 'string': false,
- 'undefined': false
- };
-
- /** Used to escape characters for inclusion in compiled string literals */
- var stringEscapes = {
- '\\': '\\',
- "'": "'",
- '\n': 'n',
- '\r': 'r',
- '\t': 't',
- '\u2028': 'u2028',
- '\u2029': 'u2029'
- };
-
- /** Used as a reference to the global object */
- var root = (objectTypes[typeof window] && window) || this;
-
- /** Detect free variable `exports` */
- var freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports;
-
- /** Detect free variable `module` */
- var freeModule = objectTypes[typeof module] && module && !module.nodeType && module;
-
- /** Detect the popular CommonJS extension `module.exports` */
- var moduleExports = freeModule && freeModule.exports === freeExports && freeExports;
-
- /** Detect free variable `global` from Node.js or Browserified code and use it as `root` */
- var freeGlobal = objectTypes[typeof global] && global;
- if (freeGlobal && (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal)) {
- root = freeGlobal;
- }
-
- /*--------------------------------------------------------------------------*/
-
- /**
- * The base implementation of `_.indexOf` without support for binary searches
- * or `fromIndex` constraints.
- *
- * @private
- * @param {Array} array The array to search.
- * @param {*} value The value to search for.
- * @param {number} [fromIndex=0] The index to search from.
- * @returns {number} Returns the index of the matched value or `-1`.
- */
- function baseIndexOf(array, value, fromIndex) {
- var index = (fromIndex || 0) - 1,
- length = array ? array.length : 0;
-
- while (++index < length) {
- if (array[index] === value) {
- return index;
- }
- }
- return -1;
- }
-
- /**
- * An implementation of `_.contains` for cache objects that mimics the return
- * signature of `_.indexOf` by returning `0` if the value is found, else `-1`.
- *
- * @private
- * @param {Object} cache The cache object to inspect.
- * @param {*} value The value to search for.
- * @returns {number} Returns `0` if `value` is found, else `-1`.
- */
- function cacheIndexOf(cache, value) {
- var type = typeof value;
- cache = cache.cache;
-
- if (type == 'boolean' || value == null) {
- return cache[value] ? 0 : -1;
- }
- if (type != 'number' && type != 'string') {
- type = 'object';
- }
- var key = type == 'number' ? value : keyPrefix + value;
- cache = (cache = cache[type]) && cache[key];
-
- return type == 'object'
- ? (cache && baseIndexOf(cache, value) > -1 ? 0 : -1)
- : (cache ? 0 : -1);
- }
-
- /**
- * Adds a given value to the corresponding cache object.
- *
- * @private
- * @param {*} value The value to add to the cache.
- */
- function cachePush(value) {
- var cache = this.cache,
- type = typeof value;
-
- if (type == 'boolean' || value == null) {
- cache[value] = true;
- } else {
- if (type != 'number' && type != 'string') {
- type = 'object';
- }
- var key = type == 'number' ? value : keyPrefix + value,
- typeCache = cache[type] || (cache[type] = {});
-
- if (type == 'object') {
- (typeCache[key] || (typeCache[key] = [])).push(value);
- } else {
- typeCache[key] = true;
- }
- }
- }
-
- /**
- * Used by `_.max` and `_.min` as the default callback when a given
- * collection is a string value.
- *
- * @private
- * @param {string} value The character to inspect.
- * @returns {number} Returns the code unit of given character.
- */
- function charAtCallback(value) {
- return value.charCodeAt(0);
- }
-
- /**
- * Used by `sortBy` to compare transformed `collection` elements, stable sorting
- * them in ascending order.
- *
- * @private
- * @param {Object} a The object to compare to `b`.
- * @param {Object} b The object to compare to `a`.
- * @returns {number} Returns the sort order indicator of `1` or `-1`.
- */
- function compareAscending(a, b) {
- var ac = a.criteria,
- bc = b.criteria,
- index = -1,
- length = ac.length;
-
- while (++index < length) {
- var value = ac[index],
- other = bc[index];
-
- if (value !== other) {
- if (value > other || typeof value == 'undefined') {
- return 1;
- }
- if (value < other || typeof other == 'undefined') {
- return -1;
- }
- }
- }
- // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications
- // that causes it, under certain circumstances, to return the same value for
- // `a` and `b`. See https://github.com/jashkenas/underscore/pull/1247
- //
- // This also ensures a stable sort in V8 and other engines.
- // See http://code.google.com/p/v8/issues/detail?id=90
- return a.index - b.index;
- }
-
- /**
- * Creates a cache object to optimize linear searches of large arrays.
- *
- * @private
- * @param {Array} [array=[]] The array to search.
- * @returns {null|Object} Returns the cache object or `null` if caching should not be used.
- */
- function createCache(array) {
- var index = -1,
- length = array.length,
- first = array[0],
- mid = array[(length / 2) | 0],
- last = array[length - 1];
-
- if (first && typeof first == 'object' &&
- mid && typeof mid == 'object' && last && typeof last == 'object') {
- return false;
- }
- var cache = getObject();
- cache['false'] = cache['null'] = cache['true'] = cache['undefined'] = false;
-
- var result = getObject();
- result.array = array;
- result.cache = cache;
- result.push = cachePush;
-
- while (++index < length) {
- result.push(array[index]);
- }
- return result;
- }
-
- /**
- * Used by `template` to escape characters for inclusion in compiled
- * string literals.
- *
- * @private
- * @param {string} match The matched character to escape.
- * @returns {string} Returns the escaped character.
- */
- function escapeStringChar(match) {
- return '\\' + stringEscapes[match];
- }
-
- /**
- * Gets an array from the array pool or creates a new one if the pool is empty.
- *
- * @private
- * @returns {Array} The array from the pool.
- */
- function getArray() {
- return arrayPool.pop() || [];
- }
-
- /**
- * Gets an object from the object pool or creates a new one if the pool is empty.
- *
- * @private
- * @returns {Object} The object from the pool.
- */
- function getObject() {
- return objectPool.pop() || {
- 'array': null,
- 'cache': null,
- 'criteria': null,
- 'false': false,
- 'index': 0,
- 'null': false,
- 'number': null,
- 'object': null,
- 'push': null,
- 'string': null,
- 'true': false,
- 'undefined': false,
- 'value': null
- };
- }
-
- /**
- * Checks if `value` is a DOM node in IE < 9.
- *
- * @private
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if the `value` is a DOM node, else `false`.
- */
- function isNode(value) {
- // IE < 9 presents DOM nodes as `Object` objects except they have `toString`
- // methods that are `typeof` "string" and still can coerce nodes to strings
- return typeof value.toString != 'function' && typeof (value + '') == 'string';
- }
-
- /**
- * Releases the given array back to the array pool.
- *
- * @private
- * @param {Array} [array] The array to release.
- */
- function releaseArray(array) {
- array.length = 0;
- if (arrayPool.length < maxPoolSize) {
- arrayPool.push(array);
- }
- }
-
- /**
- * Releases the given object back to the object pool.
- *
- * @private
- * @param {Object} [object] The object to release.
- */
- function releaseObject(object) {
- var cache = object.cache;
- if (cache) {
- releaseObject(cache);
- }
- object.array = object.cache = object.criteria = object.object = object.number = object.string = object.value = null;
- if (objectPool.length < maxPoolSize) {
- objectPool.push(object);
- }
- }
-
- /**
- * Slices the `collection` from the `start` index up to, but not including,
- * the `end` index.
- *
- * Note: This function is used instead of `Array#slice` to support node lists
- * in IE < 9 and to ensure dense arrays are returned.
- *
- * @private
- * @param {Array|Object|string} collection The collection to slice.
- * @param {number} start The start index.
- * @param {number} end The end index.
- * @returns {Array} Returns the new array.
- */
- function slice(array, start, end) {
- start || (start = 0);
- if (typeof end == 'undefined') {
- end = array ? array.length : 0;
- }
- var index = -1,
- length = end - start || 0,
- result = Array(length < 0 ? 0 : length);
-
- while (++index < length) {
- result[index] = array[start + index];
- }
- return result;
- }
-
- /*--------------------------------------------------------------------------*/
-
- /**
- * Create a new `lodash` function using the given context object.
- *
- * @static
- * @memberOf _
- * @category Utilities
- * @param {Object} [context=root] The context object.
- * @returns {Function} Returns the `lodash` function.
- */
- function runInContext(context) {
- // Avoid issues with some ES3 environments that attempt to use values, named
- // after built-in constructors like `Object`, for the creation of literals.
- // ES5 clears this up by stating that literals must use built-in constructors.
- // See http://es5.github.io/#x11.1.5.
- context = context ? _.defaults(root.Object(), context, _.pick(root, contextProps)) : root;
-
- /** Native constructor references */
- var Array = context.Array,
- Boolean = context.Boolean,
- Date = context.Date,
- Error = context.Error,
- Function = context.Function,
- Math = context.Math,
- Number = context.Number,
- Object = context.Object,
- RegExp = context.RegExp,
- String = context.String,
- TypeError = context.TypeError;
-
- /**
- * Used for `Array` method references.
- *
- * Normally `Array.prototype` would suffice, however, using an array literal
- * avoids issues in Narwhal.
- */
- var arrayRef = [];
-
- /** Used for native method references */
- var errorProto = Error.prototype,
- objectProto = Object.prototype,
- stringProto = String.prototype;
-
- /** Used to restore the original `_` reference in `noConflict` */
- var oldDash = context._;
-
- /** Used to resolve the internal [[Class]] of values */
- var toString = objectProto.toString;
-
- /** Used to detect if a method is native */
- var reNative = RegExp('^' +
- String(toString)
- .replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
- .replace(/toString| for [^\]]+/g, '.*?') + '$'
- );
-
- /** Native method shortcuts */
- var ceil = Math.ceil,
- clearTimeout = context.clearTimeout,
- floor = Math.floor,
- fnToString = Function.prototype.toString,
- getPrototypeOf = isNative(getPrototypeOf = Object.getPrototypeOf) && getPrototypeOf,
- hasOwnProperty = objectProto.hasOwnProperty,
- push = arrayRef.push,
- propertyIsEnumerable = objectProto.propertyIsEnumerable,
- setTimeout = context.setTimeout,
- splice = arrayRef.splice,
- unshift = arrayRef.unshift;
-
- /** Used to set meta data on functions */
- var defineProperty = (function() {
- // IE 8 only accepts DOM elements
- try {
- var o = {},
- func = isNative(func = Object.defineProperty) && func,
- result = func(o, o, o) && func;
- } catch(e) { }
- return result;
- }());
-
- /* Native method shortcuts for methods with the same name as other `lodash` methods */
- var nativeCreate = isNative(nativeCreate = Object.create) && nativeCreate,
- nativeIsArray = isNative(nativeIsArray = Array.isArray) && nativeIsArray,
- nativeIsFinite = context.isFinite,
- nativeIsNaN = context.isNaN,
- nativeKeys = isNative(nativeKeys = Object.keys) && nativeKeys,
- nativeMax = Math.max,
- nativeMin = Math.min,
- nativeParseInt = context.parseInt,
- nativeRandom = Math.random;
-
- /** Used to lookup a built-in constructor by [[Class]] */
- var ctorByClass = {};
- ctorByClass[arrayClass] = Array;
- ctorByClass[boolClass] = Boolean;
- ctorByClass[dateClass] = Date;
- ctorByClass[funcClass] = Function;
- ctorByClass[objectClass] = Object;
- ctorByClass[numberClass] = Number;
- ctorByClass[regexpClass] = RegExp;
- ctorByClass[stringClass] = String;
-
- /** Used to avoid iterating non-enumerable properties in IE < 9 */
- var nonEnumProps = {};
- nonEnumProps[arrayClass] = nonEnumProps[dateClass] = nonEnumProps[numberClass] = { 'constructor': true, 'toLocaleString': true, 'toString': true, 'valueOf': true };
- nonEnumProps[boolClass] = nonEnumProps[stringClass] = { 'constructor': true, 'toString': true, 'valueOf': true };
- nonEnumProps[errorClass] = nonEnumProps[funcClass] = nonEnumProps[regexpClass] = { 'constructor': true, 'toString': true };
- nonEnumProps[objectClass] = { 'constructor': true };
-
- (function() {
- var length = shadowedProps.length;
- while (length--) {
- var key = shadowedProps[length];
- for (var className in nonEnumProps) {
- if (hasOwnProperty.call(nonEnumProps, className) && !hasOwnProperty.call(nonEnumProps[className], key)) {
- nonEnumProps[className][key] = false;
- }
- }
- }
- }());
-
- /*--------------------------------------------------------------------------*/
-
- /**
- * Creates a `lodash` object which wraps the given value to enable intuitive
- * method chaining.
- *
- * In addition to Lo-Dash methods, wrappers also have the following `Array` methods:
- * `concat`, `join`, `pop`, `push`, `reverse`, `shift`, `slice`, `sort`, `splice`,
- * and `unshift`
- *
- * Chaining is supported in custom builds as long as the `value` method is
- * implicitly or explicitly included in the build.
- *
- * The chainable wrapper functions are:
- * `after`, `assign`, `bind`, `bindAll`, `bindKey`, `chain`, `compact`,
- * `compose`, `concat`, `countBy`, `create`, `createCallback`, `curry`,
- * `debounce`, `defaults`, `defer`, `delay`, `difference`, `filter`, `flatten`,
- * `forEach`, `forEachRight`, `forIn`, `forInRight`, `forOwn`, `forOwnRight`,
- * `functions`, `groupBy`, `indexBy`, `initial`, `intersection`, `invert`,
- * `invoke`, `keys`, `map`, `max`, `memoize`, `merge`, `min`, `object`, `omit`,
- * `once`, `pairs`, `partial`, `partialRight`, `pick`, `pluck`, `pull`, `push`,
- * `range`, `reject`, `remove`, `rest`, `reverse`, `shuffle`, `slice`, `sort`,
- * `sortBy`, `splice`, `tap`, `throttle`, `times`, `toArray`, `transform`,
- * `union`, `uniq`, `unshift`, `unzip`, `values`, `where`, `without`, `wrap`,
- * and `zip`
- *
- * The non-chainable wrapper functions are:
- * `clone`, `cloneDeep`, `contains`, `escape`, `every`, `find`, `findIndex`,
- * `findKey`, `findLast`, `findLastIndex`, `findLastKey`, `has`, `identity`,
- * `indexOf`, `isArguments`, `isArray`, `isBoolean`, `isDate`, `isElement`,
- * `isEmpty`, `isEqual`, `isFinite`, `isFunction`, `isNaN`, `isNull`, `isNumber`,
- * `isObject`, `isPlainObject`, `isRegExp`, `isString`, `isUndefined`, `join`,
- * `lastIndexOf`, `mixin`, `noConflict`, `parseInt`, `pop`, `random`, `reduce`,
- * `reduceRight`, `result`, `shift`, `size`, `some`, `sortedIndex`, `runInContext`,
- * `template`, `unescape`, `uniqueId`, and `value`
- *
- * The wrapper functions `first` and `last` return wrapped values when `n` is
- * provided, otherwise they return unwrapped values.
- *
- * Explicit chaining can be enabled by using the `_.chain` method.
- *
- * @name _
- * @constructor
- * @category Chaining
- * @param {*} value The value to wrap in a `lodash` instance.
- * @returns {Object} Returns a `lodash` instance.
- * @example
- *
- * var wrapped = _([1, 2, 3]);
- *
- * // returns an unwrapped value
- * wrapped.reduce(function(sum, num) {
- * return sum + num;
- * });
- * // => 6
- *
- * // returns a wrapped value
- * var squares = wrapped.map(function(num) {
- * return num * num;
- * });
- *
- * _.isArray(squares);
- * // => false
- *
- * _.isArray(squares.value());
- * // => true
- */
- function lodash(value) {
- // don't wrap if already wrapped, even if wrapped by a different `lodash` constructor
- return (value && typeof value == 'object' && !isArray(value) && hasOwnProperty.call(value, '__wrapped__'))
- ? value
- : new lodashWrapper(value);
- }
-
- /**
- * A fast path for creating `lodash` wrapper objects.
- *
- * @private
- * @param {*} value The value to wrap in a `lodash` instance.
- * @param {boolean} chainAll A flag to enable chaining for all methods
- * @returns {Object} Returns a `lodash` instance.
- */
- function lodashWrapper(value, chainAll) {
- this.__chain__ = !!chainAll;
- this.__wrapped__ = value;
- }
- // ensure `new lodashWrapper` is an instance of `lodash`
- lodashWrapper.prototype = lodash.prototype;
-
- /**
- * An object used to flag environments features.
- *
- * @static
- * @memberOf _
- * @type Object
- */
- var support = lodash.support = {};
-
- (function() {
- var ctor = function() { this.x = 1; },
- object = { '0': 1, 'length': 1 },
- props = [];
-
- ctor.prototype = { 'valueOf': 1, 'y': 1 };
- for (var key in new ctor) { props.push(key); }
- for (key in arguments) { }
-
- /**
- * Detect if an `arguments` object's [[Class]] is resolvable (all but Firefox < 4, IE < 9).
- *
- * @memberOf _.support
- * @type boolean
- */
- support.argsClass = toString.call(arguments) == argsClass;
-
- /**
- * Detect if `arguments` objects are `Object` objects (all but Narwhal and Opera < 10.5).
- *
- * @memberOf _.support
- * @type boolean
- */
- support.argsObject = arguments.constructor == Object && !(arguments instanceof Array);
-
- /**
- * Detect if `name` or `message` properties of `Error.prototype` are
- * enumerable by default. (IE < 9, Safari < 5.1)
- *
- * @memberOf _.support
- * @type boolean
- */
- support.enumErrorProps = propertyIsEnumerable.call(errorProto, 'message') || propertyIsEnumerable.call(errorProto, 'name');
-
- /**
- * Detect if `prototype` properties are enumerable by default.
- *
- * Firefox < 3.6, Opera > 9.50 - Opera < 11.60, and Safari < 5.1
- * (if the prototype or a property on the prototype has been set)
- * incorrectly sets a function's `prototype` property [[Enumerable]]
- * value to `true`.
- *
- * @memberOf _.support
- * @type boolean
- */
- support.enumPrototypes = propertyIsEnumerable.call(ctor, 'prototype');
-
- /**
- * Detect if functions can be decompiled by `Function#toString`
- * (all but PS3 and older Opera mobile browsers & avoided in Windows 8 apps).
- *
- * @memberOf _.support
- * @type boolean
- */
- support.funcDecomp = !isNative(context.WinRTError) && reThis.test(runInContext);
-
- /**
- * Detect if `Function#name` is supported (all but IE).
- *
- * @memberOf _.support
- * @type boolean
- */
- support.funcNames = typeof Function.name == 'string';
-
- /**
- * Detect if `arguments` object indexes are non-enumerable
- * (Firefox < 4, IE < 9, PhantomJS, Safari < 5.1).
- *
- * @memberOf _.support
- * @type boolean
- */
- support.nonEnumArgs = key != 0;
-
- /**
- * Detect if properties shadowing those on `Object.prototype` are non-enumerable.
- *
- * In IE < 9 an objects own properties, shadowing non-enumerable ones, are
- * made non-enumerable as well (a.k.a the JScript [[DontEnum]] bug).
- *
- * @memberOf _.support
- * @type boolean
- */
- support.nonEnumShadows = !/valueOf/.test(props);
-
- /**
- * Detect if own properties are iterated after inherited properties (all but IE < 9).
- *
- * @memberOf _.support
- * @type boolean
- */
- support.ownLast = props[0] != 'x';
-
- /**
- * Detect if `Array#shift` and `Array#splice` augment array-like objects correctly.
- *
- * Firefox < 10, IE compatibility mode, and IE < 9 have buggy Array `shift()`
- * and `splice()` functions that fail to remove the last element, `value[0]`,
- * of array-like objects even though the `length` property is set to `0`.
- * The `shift()` method is buggy in IE 8 compatibility mode, while `splice()`
- * is buggy regardless of mode in IE < 9 and buggy in compatibility mode in IE 9.
- *
- * @memberOf _.support
- * @type boolean
- */
- support.spliceObjects = (arrayRef.splice.call(object, 0, 1), !object[0]);
-
- /**
- * Detect lack of support for accessing string characters by index.
- *
- * IE < 8 can't access characters by index and IE 8 can only access
- * characters by index on string literals.
- *
- * @memberOf _.support
- * @type boolean
- */
- support.unindexedChars = ('x'[0] + Object('x')[0]) != 'xx';
-
- /**
- * Detect if a DOM node's [[Class]] is resolvable (all but IE < 9)
- * and that the JS engine errors when attempting to coerce an object to
- * a string without a `toString` function.
- *
- * @memberOf _.support
- * @type boolean
- */
- try {
- support.nodeClass = !(toString.call(document) == objectClass && !({ 'toString': 0 } + ''));
- } catch(e) {
- support.nodeClass = true;
- }
- }(1));
-
- /**
- * By default, the template delimiters used by Lo-Dash are similar to those in
- * embedded Ruby (ERB). Change the following template settings to use alternative
- * delimiters.
- *
- * @static
- * @memberOf _
- * @type Object
- */
- lodash.templateSettings = {
-
- /**
- * Used to detect `data` property values to be HTML-escaped.
- *
- * @memberOf _.templateSettings
- * @type RegExp
- */
- 'escape': /<%-([\s\S]+?)%>/g,
-
- /**
- * Used to detect code to be evaluated.
- *
- * @memberOf _.templateSettings
- * @type RegExp
- */
- 'evaluate': /<%([\s\S]+?)%>/g,
-
- /**
- * Used to detect `data` property values to inject.
- *
- * @memberOf _.templateSettings
- * @type RegExp
- */
- 'interpolate': reInterpolate,
-
- /**
- * Used to reference the data object in the template text.
- *
- * @memberOf _.templateSettings
- * @type string
- */
- 'variable': '',
-
- /**
- * Used to import variables into the compiled template.
- *
- * @memberOf _.templateSettings
- * @type Object
- */
- 'imports': {
-
- /**
- * A reference to the `lodash` function.
- *
- * @memberOf _.templateSettings.imports
- * @type Function
- */
- '_': lodash
- }
- };
-
- /*--------------------------------------------------------------------------*/
-
- /**
- * The template used to create iterator functions.
- *
- * @private
- * @param {Object} data The data object used to populate the text.
- * @returns {string} Returns the interpolated text.
- */
- var iteratorTemplate = function(obj) {
-
- var __p = 'var index, iterable = ' +
- (obj.firstArg) +
- ', result = ' +
- (obj.init) +
- ';\nif (!iterable) return result;\n' +
- (obj.top) +
- ';';
- if (obj.array) {
- __p += '\nvar length = iterable.length; index = -1;\nif (' +
- (obj.array) +
- ') { ';
- if (support.unindexedChars) {
- __p += '\n if (isString(iterable)) {\n iterable = iterable.split(\'\')\n } ';
- }
- __p += '\n while (++index < length) {\n ' +
- (obj.loop) +
- ';\n }\n}\nelse { ';
- } else if (support.nonEnumArgs) {
- __p += '\n var length = iterable.length; index = -1;\n if (length && isArguments(iterable)) {\n while (++index < length) {\n index += \'\';\n ' +
- (obj.loop) +
- ';\n }\n } else { ';
- }
-
- if (support.enumPrototypes) {
- __p += '\n var skipProto = typeof iterable == \'function\';\n ';
- }
-
- if (support.enumErrorProps) {
- __p += '\n var skipErrorProps = iterable === errorProto || iterable instanceof Error;\n ';
- }
-
- var conditions = []; if (support.enumPrototypes) { conditions.push('!(skipProto && index == "prototype")'); } if (support.enumErrorProps) { conditions.push('!(skipErrorProps && (index == "message" || index == "name"))'); }
-
- if (obj.useHas && obj.keys) {
- __p += '\n var ownIndex = -1,\n ownProps = objectTypes[typeof iterable] && keys(iterable),\n length = ownProps ? ownProps.length : 0;\n\n while (++ownIndex < length) {\n index = ownProps[ownIndex];\n';
- if (conditions.length) {
- __p += ' if (' +
- (conditions.join(' && ')) +
- ') {\n ';
- }
- __p +=
- (obj.loop) +
- '; ';
- if (conditions.length) {
- __p += '\n }';
- }
- __p += '\n } ';
- } else {
- __p += '\n for (index in iterable) {\n';
- if (obj.useHas) { conditions.push("hasOwnProperty.call(iterable, index)"); } if (conditions.length) {
- __p += ' if (' +
- (conditions.join(' && ')) +
- ') {\n ';
- }
- __p +=
- (obj.loop) +
- '; ';
- if (conditions.length) {
- __p += '\n }';
- }
- __p += '\n } ';
- if (support.nonEnumShadows) {
- __p += '\n\n if (iterable !== objectProto) {\n var ctor = iterable.constructor,\n isProto = iterable === (ctor && ctor.prototype),\n className = iterable === stringProto ? stringClass : iterable === errorProto ? errorClass : toString.call(iterable),\n nonEnum = nonEnumProps[className];\n ';
- for (k = 0; k < 7; k++) {
- __p += '\n index = \'' +
- (obj.shadowedProps[k]) +
- '\';\n if ((!(isProto && nonEnum[index]) && hasOwnProperty.call(iterable, index))';
- if (!obj.useHas) {
- __p += ' || (!nonEnum[index] && iterable[index] !== objectProto[index])';
- }
- __p += ') {\n ' +
- (obj.loop) +
- ';\n } ';
- }
- __p += '\n } ';
- }
-
- }
-
- if (obj.array || support.nonEnumArgs) {
- __p += '\n}';
- }
- __p +=
- (obj.bottom) +
- ';\nreturn result';
-
- return __p
- };
-
- /*--------------------------------------------------------------------------*/
-
- /**
- * The base implementation of `_.bind` that creates the bound function and
- * sets its meta data.
- *
- * @private
- * @param {Array} bindData The bind data array.
- * @returns {Function} Returns the new bound function.
- */
- function baseBind(bindData) {
- var func = bindData[0],
- partialArgs = bindData[2],
- thisArg = bindData[4];
-
- function bound() {
- // `Function#bind` spec
- // http://es5.github.io/#x15.3.4.5
- if (partialArgs) {
- // avoid `arguments` object deoptimizations by using `slice` instead
- // of `Array.prototype.slice.call` and not assigning `arguments` to a
- // variable as a ternary expression
- var args = slice(partialArgs);
- push.apply(args, arguments);
- }
- // mimic the constructor's `return` behavior
- // http://es5.github.io/#x13.2.2
- if (this instanceof bound) {
- // ensure `new bound` is an instance of `func`
- var thisBinding = baseCreate(func.prototype),
- result = func.apply(thisBinding, args || arguments);
- return isObject(result) ? result : thisBinding;
- }
- return func.apply(thisArg, args || arguments);
- }
- setBindData(bound, bindData);
- return bound;
- }
-
- /**
- * The base implementation of `_.clone` without argument juggling or support
- * for `thisArg` binding.
- *
- * @private
- * @param {*} value The value to clone.
- * @param {boolean} [isDeep=false] Specify a deep clone.
- * @param {Function} [callback] The function to customize cloning values.
- * @param {Array} [stackA=[]] Tracks traversed source objects.
- * @param {Array} [stackB=[]] Associates clones with source counterparts.
- * @returns {*} Returns the cloned value.
- */
- function baseClone(value, isDeep, callback, stackA, stackB) {
- if (callback) {
- var result = callback(value);
- if (typeof result != 'undefined') {
- return result;
- }
- }
- // inspect [[Class]]
- var isObj = isObject(value);
- if (isObj) {
- var className = toString.call(value);
- if (!cloneableClasses[className] || (!support.nodeClass && isNode(value))) {
- return value;
- }
- var ctor = ctorByClass[className];
- switch (className) {
- case boolClass:
- case dateClass:
- return new ctor(+value);
-
- case numberClass:
- case stringClass:
- return new ctor(value);
-
- case regexpClass:
- result = ctor(value.source, reFlags.exec(value));
- result.lastIndex = value.lastIndex;
- return result;
- }
- } else {
- return value;
- }
- var isArr = isArray(value);
- if (isDeep) {
- // check for circular references and return corresponding clone
- var initedStack = !stackA;
- stackA || (stackA = getArray());
- stackB || (stackB = getArray());
-
- var length = stackA.length;
- while (length--) {
- if (stackA[length] == value) {
- return stackB[length];
- }
- }
- result = isArr ? ctor(value.length) : {};
- }
- else {
- result = isArr ? slice(value) : assign({}, value);
- }
- // add array properties assigned by `RegExp#exec`
- if (isArr) {
- if (hasOwnProperty.call(value, 'index')) {
- result.index = value.index;
- }
- if (hasOwnProperty.call(value, 'input')) {
- result.input = value.input;
- }
- }
- // exit for shallow clone
- if (!isDeep) {
- return result;
- }
- // add the source value to the stack of traversed objects
- // and associate it with its clone
- stackA.push(value);
- stackB.push(result);
-
- // recursively populate clone (susceptible to call stack limits)
- (isArr ? baseEach : forOwn)(value, function(objValue, key) {
- result[key] = baseClone(objValue, isDeep, callback, stackA, stackB);
- });
-
- if (initedStack) {
- releaseArray(stackA);
- releaseArray(stackB);
- }
- return result;
- }
-
- /**
- * The base implementation of `_.create` without support for assigning
- * properties to the created object.
- *
- * @private
- * @param {Object} prototype The object to inherit from.
- * @returns {Object} Returns the new object.
- */
- function baseCreate(prototype, properties) {
- return isObject(prototype) ? nativeCreate(prototype) : {};
- }
- // fallback for browsers without `Object.create`
- if (!nativeCreate) {
- baseCreate = (function() {
- function Object() {}
- return function(prototype) {
- if (isObject(prototype)) {
- Object.prototype = prototype;
- var result = new Object;
- Object.prototype = null;
- }
- return result || context.Object();
- };
- }());
- }
-
- /**
- * The base implementation of `_.createCallback` without support for creating
- * "_.pluck" or "_.where" style callbacks.
- *
- * @private
- * @param {*} [func=identity] The value to convert to a callback.
- * @param {*} [thisArg] The `this` binding of the created callback.
- * @param {number} [argCount] The number of arguments the callback accepts.
- * @returns {Function} Returns a callback function.
- */
- function baseCreateCallback(func, thisArg, argCount) {
- if (typeof func != 'function') {
- return identity;
- }
- // exit early for no `thisArg` or already bound by `Function#bind`
- if (typeof thisArg == 'undefined' || !('prototype' in func)) {
- return func;
- }
- var bindData = func.__bindData__;
- if (typeof bindData == 'undefined') {
- if (support.funcNames) {
- bindData = !func.name;
- }
- bindData = bindData || !support.funcDecomp;
- if (!bindData) {
- var source = fnToString.call(func);
- if (!support.funcNames) {
- bindData = !reFuncName.test(source);
- }
- if (!bindData) {
- // checks if `func` references the `this` keyword and stores the result
- bindData = reThis.test(source);
- setBindData(func, bindData);
- }
- }
- }
- // exit early if there are no `this` references or `func` is bound
- if (bindData === false || (bindData !== true && bindData[1] & 1)) {
- return func;
- }
- switch (argCount) {
- case 1: return function(value) {
- return func.call(thisArg, value);
- };
- case 2: return function(a, b) {
- return func.call(thisArg, a, b);
- };
- case 3: return function(value, index, collection) {
- return func.call(thisArg, value, index, collection);
- };
- case 4: return function(accumulator, value, index, collection) {
- return func.call(thisArg, accumulator, value, index, collection);
- };
- }
- return bind(func, thisArg);
- }
-
- /**
- * The base implementation of `createWrapper` that creates the wrapper and
- * sets its meta data.
- *
- * @private
- * @param {Array} bindData The bind data array.
- * @returns {Function} Returns the new function.
- */
- function baseCreateWrapper(bindData) {
- var func = bindData[0],
- bitmask = bindData[1],
- partialArgs = bindData[2],
- partialRightArgs = bindData[3],
- thisArg = bindData[4],
- arity = bindData[5];
-
- var isBind = bitmask & 1,
- isBindKey = bitmask & 2,
- isCurry = bitmask & 4,
- isCurryBound = bitmask & 8,
- key = func;
-
- function bound() {
- var thisBinding = isBind ? thisArg : this;
- if (partialArgs) {
- var args = slice(partialArgs);
- push.apply(args, arguments);
- }
- if (partialRightArgs || isCurry) {
- args || (args = slice(arguments));
- if (partialRightArgs) {
- push.apply(args, partialRightArgs);
- }
- if (isCurry && args.length < arity) {
- bitmask |= 16 & ~32;
- return baseCreateWrapper([func, (isCurryBound ? bitmask : bitmask & ~3), args, null, thisArg, arity]);
- }
- }
- args || (args = arguments);
- if (isBindKey) {
- func = thisBinding[key];
- }
- if (this instanceof bound) {
- thisBinding = baseCreate(func.prototype);
- var result = func.apply(thisBinding, args);
- return isObject(result) ? result : thisBinding;
- }
- return func.apply(thisBinding, args);
- }
- setBindData(bound, bindData);
- return bound;
- }
-
- /**
- * The base implementation of `_.difference` that accepts a single array
- * of values to exclude.
- *
- * @private
- * @param {Array} array The array to process.
- * @param {Array} [values] The array of values to exclude.
- * @returns {Array} Returns a new array of filtered values.
- */
- function baseDifference(array, values) {
- var index = -1,
- indexOf = getIndexOf(),
- length = array ? array.length : 0,
- isLarge = length >= largeArraySize && indexOf === baseIndexOf,
- result = [];
-
- if (isLarge) {
- var cache = createCache(values);
- if (cache) {
- indexOf = cacheIndexOf;
- values = cache;
- } else {
- isLarge = false;
- }
- }
- while (++index < length) {
- var value = array[index];
- if (indexOf(values, value) < 0) {
- result.push(value);
- }
- }
- if (isLarge) {
- releaseObject(values);
- }
- return result;
- }
-
- /**
- * The base implementation of `_.flatten` without support for callback
- * shorthands or `thisArg` binding.
- *
- * @private
- * @param {Array} array The array to flatten.
- * @param {boolean} [isShallow=false] A flag to restrict flattening to a single level.
- * @param {boolean} [isStrict=false] A flag to restrict flattening to arrays and `arguments` objects.
- * @param {number} [fromIndex=0] The index to start from.
- * @returns {Array} Returns a new flattened array.
- */
- function baseFlatten(array, isShallow, isStrict, fromIndex) {
- var index = (fromIndex || 0) - 1,
- length = array ? array.length : 0,
- result = [];
-
- while (++index < length) {
- var value = array[index];
-
- if (value && typeof value == 'object' && typeof value.length == 'number'
- && (isArray(value) || isArguments(value))) {
- // recursively flatten arrays (susceptible to call stack limits)
- if (!isShallow) {
- value = baseFlatten(value, isShallow, isStrict);
- }
- var valIndex = -1,
- valLength = value.length,
- resIndex = result.length;
-
- result.length += valLength;
- while (++valIndex < valLength) {
- result[resIndex++] = value[valIndex];
- }
- } else if (!isStrict) {
- result.push(value);
- }
- }
- return result;
- }
-
- /**
- * The base implementation of `_.isEqual`, without support for `thisArg` binding,
- * that allows partial "_.where" style comparisons.
- *
- * @private
- * @param {*} a The value to compare.
- * @param {*} b The other value to compare.
- * @param {Function} [callback] The function to customize comparing values.
- * @param {Function} [isWhere=false] A flag to indicate performing partial comparisons.
- * @param {Array} [stackA=[]] Tracks traversed `a` objects.
- * @param {Array} [stackB=[]] Tracks traversed `b` objects.
- * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
- */
- function baseIsEqual(a, b, callback, isWhere, stackA, stackB) {
- // used to indicate that when comparing objects, `a` has at least the properties of `b`
- if (callback) {
- var result = callback(a, b);
- if (typeof result != 'undefined') {
- return !!result;
- }
- }
- // exit early for identical values
- if (a === b) {
- // treat `+0` vs. `-0` as not equal
- return a !== 0 || (1 / a == 1 / b);
- }
- var type = typeof a,
- otherType = typeof b;
-
- // exit early for unlike primitive values
- if (a === a &&
- !(a && objectTypes[type]) &&
- !(b && objectTypes[otherType])) {
- return false;
- }
- // exit early for `null` and `undefined` avoiding ES3's Function#call behavior
- // http://es5.github.io/#x15.3.4.4
- if (a == null || b == null) {
- return a === b;
- }
- // compare [[Class]] names
- var className = toString.call(a),
- otherClass = toString.call(b);
-
- if (className == argsClass) {
- className = objectClass;
- }
- if (otherClass == argsClass) {
- otherClass = objectClass;
- }
- if (className != otherClass) {
- return false;
- }
- switch (className) {
- case boolClass:
- case dateClass:
- // coerce dates and booleans to numbers, dates to milliseconds and booleans
- // to `1` or `0` treating invalid dates coerced to `NaN` as not equal
- return +a == +b;
-
- case numberClass:
- // treat `NaN` vs. `NaN` as equal
- return (a != +a)
- ? b != +b
- // but treat `+0` vs. `-0` as not equal
- : (a == 0 ? (1 / a == 1 / b) : a == +b);
-
- case regexpClass:
- case stringClass:
- // coerce regexes to strings (http://es5.github.io/#x15.10.6.4)
- // treat string primitives and their corresponding object instances as equal
- return a == String(b);
- }
- var isArr = className == arrayClass;
- if (!isArr) {
- // unwrap any `lodash` wrapped values
- var aWrapped = hasOwnProperty.call(a, '__wrapped__'),
- bWrapped = hasOwnProperty.call(b, '__wrapped__');
-
- if (aWrapped || bWrapped) {
- return baseIsEqual(aWrapped ? a.__wrapped__ : a, bWrapped ? b.__wrapped__ : b, callback, isWhere, stackA, stackB);
- }
- // exit for functions and DOM nodes
- if (className != objectClass || (!support.nodeClass && (isNode(a) || isNode(b)))) {
- return false;
- }
- // in older versions of Opera, `arguments` objects have `Array` constructors
- var ctorA = !support.argsObject && isArguments(a) ? Object : a.constructor,
- ctorB = !support.argsObject && isArguments(b) ? Object : b.constructor;
-
- // non `Object` object instances with different constructors are not equal
- if (ctorA != ctorB &&
- !(isFunction(ctorA) && ctorA instanceof ctorA && isFunction(ctorB) && ctorB instanceof ctorB) &&
- ('constructor' in a && 'constructor' in b)
- ) {
- return false;
- }
- }
- // assume cyclic structures are equal
- // the algorithm for detecting cyclic structures is adapted from ES 5.1
- // section 15.12.3, abstract operation `JO` (http://es5.github.io/#x15.12.3)
- var initedStack = !stackA;
- stackA || (stackA = getArray());
- stackB || (stackB = getArray());
-
- var length = stackA.length;
- while (length--) {
- if (stackA[length] == a) {
- return stackB[length] == b;
- }
- }
- var size = 0;
- result = true;
-
- // add `a` and `b` to the stack of traversed objects
- stackA.push(a);
- stackB.push(b);
-
- // recursively compare objects and arrays (susceptible to call stack limits)
- if (isArr) {
- // compare lengths to determine if a deep comparison is necessary
- length = a.length;
- size = b.length;
- result = size == length;
-
- if (result || isWhere) {
- // deep compare the contents, ignoring non-numeric properties
- while (size--) {
- var index = length,
- value = b[size];
-
- if (isWhere) {
- while (index--) {
- if ((result = baseIsEqual(a[index], value, callback, isWhere, stackA, stackB))) {
- break;
- }
- }
- } else if (!(result = baseIsEqual(a[size], value, callback, isWhere, stackA, stackB))) {
- break;
- }
- }
- }
- }
- else {
- // deep compare objects using `forIn`, instead of `forOwn`, to avoid `Object.keys`
- // which, in this case, is more costly
- forIn(b, function(value, key, b) {
- if (hasOwnProperty.call(b, key)) {
- // count the number of properties.
- size++;
- // deep compare each property value.
- return (result = hasOwnProperty.call(a, key) && baseIsEqual(a[key], value, callback, isWhere, stackA, stackB));
- }
- });
-
- if (result && !isWhere) {
- // ensure both objects have the same number of properties
- forIn(a, function(value, key, a) {
- if (hasOwnProperty.call(a, key)) {
- // `size` will be `-1` if `a` has more properties than `b`
- return (result = --size > -1);
- }
- });
- }
- }
- stackA.pop();
- stackB.pop();
-
- if (initedStack) {
- releaseArray(stackA);
- releaseArray(stackB);
- }
- return result;
- }
-
- /**
- * The base implementation of `_.merge` without argument juggling or support
- * for `thisArg` binding.
- *
- * @private
- * @param {Object} object The destination object.
- * @param {Object} source The source object.
- * @param {Function} [callback] The function to customize merging properties.
- * @param {Array} [stackA=[]] Tracks traversed source objects.
- * @param {Array} [stackB=[]] Associates values with source counterparts.
- */
- function baseMerge(object, source, callback, stackA, stackB) {
- (isArray(source) ? forEach : forOwn)(source, function(source, key) {
- var found,
- isArr,
- result = source,
- value = object[key];
-
- if (source && ((isArr = isArray(source)) || isPlainObject(source))) {
- // avoid merging previously merged cyclic sources
- var stackLength = stackA.length;
- while (stackLength--) {
- if ((found = stackA[stackLength] == source)) {
- value = stackB[stackLength];
- break;
- }
- }
- if (!found) {
- var isShallow;
- if (callback) {
- result = callback(value, source);
- if ((isShallow = typeof result != 'undefined')) {
- value = result;
- }
- }
- if (!isShallow) {
- value = isArr
- ? (isArray(value) ? value : [])
- : (isPlainObject(value) ? value : {});
- }
- // add `source` and associated `value` to the stack of traversed objects
- stackA.push(source);
- stackB.push(value);
-
- // recursively merge objects and arrays (susceptible to call stack limits)
- if (!isShallow) {
- baseMerge(value, source, callback, stackA, stackB);
- }
- }
- }
- else {
- if (callback) {
- result = callback(value, source);
- if (typeof result == 'undefined') {
- result = source;
- }
- }
- if (typeof result != 'undefined') {
- value = result;
- }
- }
- object[key] = value;
- });
- }
-
- /**
- * The base implementation of `_.random` without argument juggling or support
- * for returning floating-point numbers.
- *
- * @private
- * @param {number} min The minimum possible value.
- * @param {number} max The maximum possible value.
- * @returns {number} Returns a random number.
- */
- function baseRandom(min, max) {
- return min + floor(nativeRandom() * (max - min + 1));
- }
-
- /**
- * The base implementation of `_.uniq` without support for callback shorthands
- * or `thisArg` binding.
- *
- * @private
- * @param {Array} array The array to process.
- * @param {boolean} [isSorted=false] A flag to indicate that `array` is sorted.
- * @param {Function} [callback] The function called per iteration.
- * @returns {Array} Returns a duplicate-value-free array.
- */
- function baseUniq(array, isSorted, callback) {
- var index = -1,
- indexOf = getIndexOf(),
- length = array ? array.length : 0,
- result = [];
-
- var isLarge = !isSorted && length >= largeArraySize && indexOf === baseIndexOf,
- seen = (callback || isLarge) ? getArray() : result;
-
- if (isLarge) {
- var cache = createCache(seen);
- indexOf = cacheIndexOf;
- seen = cache;
- }
- while (++index < length) {
- var value = array[index],
- computed = callback ? callback(value, index, array) : value;
-
- if (isSorted
- ? !index || seen[seen.length - 1] !== computed
- : indexOf(seen, computed) < 0
- ) {
- if (callback || isLarge) {
- seen.push(computed);
- }
- result.push(value);
- }
- }
- if (isLarge) {
- releaseArray(seen.array);
- releaseObject(seen);
- } else if (callback) {
- releaseArray(seen);
- }
- return result;
- }
-
- /**
- * Creates a function that aggregates a collection, creating an object composed
- * of keys generated from the results of running each element of the collection
- * through a callback. The given `setter` function sets the keys and values
- * of the composed object.
- *
- * @private
- * @param {Function} setter The setter function.
- * @returns {Function} Returns the new aggregator function.
- */
- function createAggregator(setter) {
- return function(collection, callback, thisArg) {
- var result = {};
- callback = lodash.createCallback(callback, thisArg, 3);
-
- if (isArray(collection)) {
- var index = -1,
- length = collection.length;
-
- while (++index < length) {
- var value = collection[index];
- setter(result, value, callback(value, index, collection), collection);
- }
- } else {
- baseEach(collection, function(value, key, collection) {
- setter(result, value, callback(value, key, collection), collection);
- });
- }
- return result;
- };
- }
-
- /**
- * Creates a function that, when called, either curries or invokes `func`
- * with an optional `this` binding and partially applied arguments.
- *
- * @private
- * @param {Function|string} func The function or method name to reference.
- * @param {number} bitmask The bitmask of method flags to compose.
- * The bitmask may be composed of the following flags:
- * 1 - `_.bind`
- * 2 - `_.bindKey`
- * 4 - `_.curry`
- * 8 - `_.curry` (bound)
- * 16 - `_.partial`
- * 32 - `_.partialRight`
- * @param {Array} [partialArgs] An array of arguments to prepend to those
- * provided to the new function.
- * @param {Array} [partialRightArgs] An array of arguments to append to those
- * provided to the new function.
- * @param {*} [thisArg] The `this` binding of `func`.
- * @param {number} [arity] The arity of `func`.
- * @returns {Function} Returns the new function.
- */
- function createWrapper(func, bitmask, partialArgs, partialRightArgs, thisArg, arity) {
- var isBind = bitmask & 1,
- isBindKey = bitmask & 2,
- isCurry = bitmask & 4,
- isCurryBound = bitmask & 8,
- isPartial = bitmask & 16,
- isPartialRight = bitmask & 32;
-
- if (!isBindKey && !isFunction(func)) {
- throw new TypeError;
- }
- if (isPartial && !partialArgs.length) {
- bitmask &= ~16;
- isPartial = partialArgs = false;
- }
- if (isPartialRight && !partialRightArgs.length) {
- bitmask &= ~32;
- isPartialRight = partialRightArgs = false;
- }
- var bindData = func && func.__bindData__;
- if (bindData && bindData !== true) {
- // clone `bindData`
- bindData = slice(bindData);
- if (bindData[2]) {
- bindData[2] = slice(bindData[2]);
- }
- if (bindData[3]) {
- bindData[3] = slice(bindData[3]);
- }
- // set `thisBinding` is not previously bound
- if (isBind && !(bindData[1] & 1)) {
- bindData[4] = thisArg;
- }
- // set if previously bound but not currently (subsequent curried functions)
- if (!isBind && bindData[1] & 1) {
- bitmask |= 8;
- }
- // set curried arity if not yet set
- if (isCurry && !(bindData[1] & 4)) {
- bindData[5] = arity;
- }
- // append partial left arguments
- if (isPartial) {
- push.apply(bindData[2] || (bindData[2] = []), partialArgs);
- }
- // append partial right arguments
- if (isPartialRight) {
- unshift.apply(bindData[3] || (bindData[3] = []), partialRightArgs);
- }
- // merge flags
- bindData[1] |= bitmask;
- return createWrapper.apply(null, bindData);
- }
- // fast path for `_.bind`
- var creater = (bitmask == 1 || bitmask === 17) ? baseBind : baseCreateWrapper;
- return creater([func, bitmask, partialArgs, partialRightArgs, thisArg, arity]);
- }
-
- /**
- * Creates compiled iteration functions.
- *
- * @private
- * @param {...Object} [options] The compile options object(s).
- * @param {string} [options.array] Code to determine if the iterable is an array or array-like.
- * @param {boolean} [options.useHas] Specify using `hasOwnProperty` checks in the object loop.
- * @param {Function} [options.keys] A reference to `_.keys` for use in own property iteration.
- * @param {string} [options.args] A comma separated string of iteration function arguments.
- * @param {string} [options.top] Code to execute before the iteration branches.
- * @param {string} [options.loop] Code to execute in the object loop.
- * @param {string} [options.bottom] Code to execute after the iteration branches.
- * @returns {Function} Returns the compiled function.
- */
- function createIterator() {
- // data properties
- iteratorData.shadowedProps = shadowedProps;
-
- // iterator options
- iteratorData.array = iteratorData.bottom = iteratorData.loop = iteratorData.top = '';
- iteratorData.init = 'iterable';
- iteratorData.useHas = true;
-
- // merge options into a template data object
- for (var object, index = 0; object = arguments[index]; index++) {
- for (var key in object) {
- iteratorData[key] = object[key];
- }
- }
- var args = iteratorData.args;
- iteratorData.firstArg = /^[^,]+/.exec(args)[0];
-
- // create the function factory
- var factory = Function(
- 'baseCreateCallback, errorClass, errorProto, hasOwnProperty, ' +
- 'indicatorObject, isArguments, isArray, isString, keys, objectProto, ' +
- 'objectTypes, nonEnumProps, stringClass, stringProto, toString',
- 'return function(' + args + ') {\n' + iteratorTemplate(iteratorData) + '\n}'
- );
-
- // return the compiled function
- return factory(
- baseCreateCallback, errorClass, errorProto, hasOwnProperty,
- indicatorObject, isArguments, isArray, isString, iteratorData.keys, objectProto,
- objectTypes, nonEnumProps, stringClass, stringProto, toString
- );
- }
-
- /**
- * Used by `escape` to convert characters to HTML entities.
- *
- * @private
- * @param {string} match The matched character to escape.
- * @returns {string} Returns the escaped character.
- */
- function escapeHtmlChar(match) {
- return htmlEscapes[match];
- }
-
- /**
- * Gets the appropriate "indexOf" function. If the `_.indexOf` method is
- * customized, this method returns the custom method, otherwise it returns
- * the `baseIndexOf` function.
- *
- * @private
- * @returns {Function} Returns the "indexOf" function.
- */
- function getIndexOf() {
- var result = (result = lodash.indexOf) === indexOf ? baseIndexOf : result;
- return result;
- }
-
- /**
- * Checks if `value` is a native function.
- *
- * @private
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if the `value` is a native function, else `false`.
- */
- function isNative(value) {
- return typeof value == 'function' && reNative.test(value);
- }
-
- /**
- * Sets `this` binding data on a given function.
- *
- * @private
- * @param {Function} func The function to set data on.
- * @param {Array} value The data array to set.
- */
- var setBindData = !defineProperty ? noop : function(func, value) {
- descriptor.value = value;
- defineProperty(func, '__bindData__', descriptor);
- };
-
- /**
- * A fallback implementation of `isPlainObject` which checks if a given value
- * is an object created by the `Object` constructor, assuming objects created
- * by the `Object` constructor have no inherited enumerable properties and that
- * there are no `Object.prototype` extensions.
- *
- * @private
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
- */
- function shimIsPlainObject(value) {
- var ctor,
- result;
-
- // avoid non Object objects, `arguments` objects, and DOM elements
- if (!(value && toString.call(value) == objectClass) ||
- (ctor = value.constructor, isFunction(ctor) && !(ctor instanceof ctor)) ||
- (!support.argsClass && isArguments(value)) ||
- (!support.nodeClass && isNode(value))) {
- return false;
- }
- // IE < 9 iterates inherited properties before own properties. If the first
- // iterated property is an object's own property then there are no inherited
- // enumerable properties.
- if (support.ownLast) {
- forIn(value, function(value, key, object) {
- result = hasOwnProperty.call(object, key);
- return false;
- });
- return result !== false;
- }
- // In most environments an object's own properties are iterated before
- // its inherited properties. If the last iterated property is an object's
- // own property then there are no inherited enumerable properties.
- forIn(value, function(value, key) {
- result = key;
- });
- return typeof result == 'undefined' || hasOwnProperty.call(value, result);
- }
-
- /**
- * Used by `unescape` to convert HTML entities to characters.
- *
- * @private
- * @param {string} match The matched character to unescape.
- * @returns {string} Returns the unescaped character.
- */
- function unescapeHtmlChar(match) {
- return htmlUnescapes[match];
- }
-
- /*--------------------------------------------------------------------------*/
-
- /**
- * Checks if `value` is an `arguments` object.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if the `value` is an `arguments` object, else `false`.
- * @example
- *
- * (function() { return _.isArguments(arguments); })(1, 2, 3);
- * // => true
- *
- * _.isArguments([1, 2, 3]);
- * // => false
- */
- function isArguments(value) {
- return value && typeof value == 'object' && typeof value.length == 'number' &&
- toString.call(value) == argsClass || false;
- }
- // fallback for browsers that can't detect `arguments` objects by [[Class]]
- if (!support.argsClass) {
- isArguments = function(value) {
- return value && typeof value == 'object' && typeof value.length == 'number' &&
- hasOwnProperty.call(value, 'callee') && !propertyIsEnumerable.call(value, 'callee') || false;
- };
- }
-
- /**
- * Checks if `value` is an array.
- *
- * @static
- * @memberOf _
- * @type Function
- * @category Objects
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if the `value` is an array, else `false`.
- * @example
- *
- * (function() { return _.isArray(arguments); })();
- * // => false
- *
- * _.isArray([1, 2, 3]);
- * // => true
- */
- var isArray = nativeIsArray || function(value) {
- return value && typeof value == 'object' && typeof value.length == 'number' &&
- toString.call(value) == arrayClass || false;
- };
-
- /**
- * A fallback implementation of `Object.keys` which produces an array of the
- * given object's own enumerable property names.
- *
- * @private
- * @type Function
- * @param {Object} object The object to inspect.
- * @returns {Array} Returns an array of property names.
- */
- var shimKeys = createIterator({
- 'args': 'object',
- 'init': '[]',
- 'top': 'if (!(objectTypes[typeof object])) return result',
- 'loop': 'result.push(index)'
- });
-
- /**
- * Creates an array composed of the own enumerable property names of an object.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {Object} object The object to inspect.
- * @returns {Array} Returns an array of property names.
- * @example
- *
- * _.keys({ 'one': 1, 'two': 2, 'three': 3 });
- * // => ['one', 'two', 'three'] (property order is not guaranteed across environments)
- */
- var keys = !nativeKeys ? shimKeys : function(object) {
- if (!isObject(object)) {
- return [];
- }
- if ((support.enumPrototypes && typeof object == 'function') ||
- (support.nonEnumArgs && object.length && isArguments(object))) {
- return shimKeys(object);
- }
- return nativeKeys(object);
- };
-
- /** Reusable iterator options shared by `each`, `forIn`, and `forOwn` */
- var eachIteratorOptions = {
- 'args': 'collection, callback, thisArg',
- 'top': "callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3)",
- 'array': "typeof length == 'number'",
- 'keys': keys,
- 'loop': 'if (callback(iterable[index], index, collection) === false) return result'
- };
-
- /** Reusable iterator options for `assign` and `defaults` */
- var defaultsIteratorOptions = {
- 'args': 'object, source, guard',
- 'top':
- 'var args = arguments,\n' +
- ' argsIndex = 0,\n' +
- " argsLength = typeof guard == 'number' ? 2 : args.length;\n" +
- 'while (++argsIndex < argsLength) {\n' +
- ' iterable = args[argsIndex];\n' +
- ' if (iterable && objectTypes[typeof iterable]) {',
- 'keys': keys,
- 'loop': "if (typeof result[index] == 'undefined') result[index] = iterable[index]",
- 'bottom': ' }\n}'
- };
-
- /** Reusable iterator options for `forIn` and `forOwn` */
- var forOwnIteratorOptions = {
- 'top': 'if (!objectTypes[typeof iterable]) return result;\n' + eachIteratorOptions.top,
- 'array': false
- };
-
- /**
- * Used to convert characters to HTML entities:
- *
- * Though the `>` character is escaped for symmetry, characters like `>` and `/`
- * don't require escaping in HTML and have no special meaning unless they're part
- * of a tag or an unquoted attribute value.
- * http://mathiasbynens.be/notes/ambiguous-ampersands (under "semi-related fun fact")
- */
- var htmlEscapes = {
- '&': '&',
- '<': '<',
- '>': '>',
- '"': '"',
- "'": '''
- };
-
- /** Used to convert HTML entities to characters */
- var htmlUnescapes = invert(htmlEscapes);
-
- /** Used to match HTML entities and HTML characters */
- var reEscapedHtml = RegExp('(' + keys(htmlUnescapes).join('|') + ')', 'g'),
- reUnescapedHtml = RegExp('[' + keys(htmlEscapes).join('') + ']', 'g');
-
- /**
- * A function compiled to iterate `arguments` objects, arrays, objects, and
- * strings consistenly across environments, executing the callback for each
- * element in the collection. The callback is bound to `thisArg` and invoked
- * with three arguments; (value, index|key, collection). Callbacks may exit
- * iteration early by explicitly returning `false`.
- *
- * @private
- * @type Function
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function} [callback=identity] The function called per iteration.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Array|Object|string} Returns `collection`.
- */
- var baseEach = createIterator(eachIteratorOptions);
-
- /*--------------------------------------------------------------------------*/
-
- /**
- * Assigns own enumerable properties of source object(s) to the destination
- * object. Subsequent sources will overwrite property assignments of previous
- * sources. If a callback is provided it will be executed to produce the
- * assigned values. The callback is bound to `thisArg` and invoked with two
- * arguments; (objectValue, sourceValue).
- *
- * @static
- * @memberOf _
- * @type Function
- * @alias extend
- * @category Objects
- * @param {Object} object The destination object.
- * @param {...Object} [source] The source objects.
- * @param {Function} [callback] The function to customize assigning values.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Object} Returns the destination object.
- * @example
- *
- * _.assign({ 'name': 'fred' }, { 'employer': 'slate' });
- * // => { 'name': 'fred', 'employer': 'slate' }
- *
- * var defaults = _.partialRight(_.assign, function(a, b) {
- * return typeof a == 'undefined' ? b : a;
- * });
- *
- * var object = { 'name': 'barney' };
- * defaults(object, { 'name': 'fred', 'employer': 'slate' });
- * // => { 'name': 'barney', 'employer': 'slate' }
- */
- var assign = createIterator(defaultsIteratorOptions, {
- 'top':
- defaultsIteratorOptions.top.replace(';',
- ';\n' +
- "if (argsLength > 3 && typeof args[argsLength - 2] == 'function') {\n" +
- ' var callback = baseCreateCallback(args[--argsLength - 1], args[argsLength--], 2);\n' +
- "} else if (argsLength > 2 && typeof args[argsLength - 1] == 'function') {\n" +
- ' callback = args[--argsLength];\n' +
- '}'
- ),
- 'loop': 'result[index] = callback ? callback(result[index], iterable[index]) : iterable[index]'
- });
-
- /**
- * Creates a clone of `value`. If `isDeep` is `true` nested objects will also
- * be cloned, otherwise they will be assigned by reference. If a callback
- * is provided it will be executed to produce the cloned values. If the
- * callback returns `undefined` cloning will be handled by the method instead.
- * The callback is bound to `thisArg` and invoked with one argument; (value).
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {*} value The value to clone.
- * @param {boolean} [isDeep=false] Specify a deep clone.
- * @param {Function} [callback] The function to customize cloning values.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {*} Returns the cloned value.
- * @example
- *
- * var characters = [
- * { 'name': 'barney', 'age': 36 },
- * { 'name': 'fred', 'age': 40 }
- * ];
- *
- * var shallow = _.clone(characters);
- * shallow[0] === characters[0];
- * // => true
- *
- * var deep = _.clone(characters, true);
- * deep[0] === characters[0];
- * // => false
- *
- * _.mixin({
- * 'clone': _.partialRight(_.clone, function(value) {
- * return _.isElement(value) ? value.cloneNode(false) : undefined;
- * })
- * });
- *
- * var clone = _.clone(document.body);
- * clone.childNodes.length;
- * // => 0
- */
- function clone(value, isDeep, callback, thisArg) {
- // allows working with "Collections" methods without using their `index`
- // and `collection` arguments for `isDeep` and `callback`
- if (typeof isDeep != 'boolean' && isDeep != null) {
- thisArg = callback;
- callback = isDeep;
- isDeep = false;
- }
- return baseClone(value, isDeep, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 1));
- }
-
- /**
- * Creates a deep clone of `value`. If a callback is provided it will be
- * executed to produce the cloned values. If the callback returns `undefined`
- * cloning will be handled by the method instead. The callback is bound to
- * `thisArg` and invoked with one argument; (value).
- *
- * Note: This method is loosely based on the structured clone algorithm. Functions
- * and DOM nodes are **not** cloned. The enumerable properties of `arguments` objects and
- * objects created by constructors other than `Object` are cloned to plain `Object` objects.
- * See http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {*} value The value to deep clone.
- * @param {Function} [callback] The function to customize cloning values.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {*} Returns the deep cloned value.
- * @example
- *
- * var characters = [
- * { 'name': 'barney', 'age': 36 },
- * { 'name': 'fred', 'age': 40 }
- * ];
- *
- * var deep = _.cloneDeep(characters);
- * deep[0] === characters[0];
- * // => false
- *
- * var view = {
- * 'label': 'docs',
- * 'node': element
- * };
- *
- * var clone = _.cloneDeep(view, function(value) {
- * return _.isElement(value) ? value.cloneNode(true) : undefined;
- * });
- *
- * clone.node == view.node;
- * // => false
- */
- function cloneDeep(value, callback, thisArg) {
- return baseClone(value, true, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 1));
- }
-
- /**
- * Creates an object that inherits from the given `prototype` object. If a
- * `properties` object is provided its own enumerable properties are assigned
- * to the created object.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {Object} prototype The object to inherit from.
- * @param {Object} [properties] The properties to assign to the object.
- * @returns {Object} Returns the new object.
- * @example
- *
- * function Shape() {
- * this.x = 0;
- * this.y = 0;
- * }
- *
- * function Circle() {
- * Shape.call(this);
- * }
- *
- * Circle.prototype = _.create(Shape.prototype, { 'constructor': Circle });
- *
- * var circle = new Circle;
- * circle instanceof Circle;
- * // => true
- *
- * circle instanceof Shape;
- * // => true
- */
- function create(prototype, properties) {
- var result = baseCreate(prototype);
- return properties ? assign(result, properties) : result;
- }
-
- /**
- * Assigns own enumerable properties of source object(s) to the destination
- * object for all destination properties that resolve to `undefined`. Once a
- * property is set, additional defaults of the same property will be ignored.
- *
- * @static
- * @memberOf _
- * @type Function
- * @category Objects
- * @param {Object} object The destination object.
- * @param {...Object} [source] The source objects.
- * @param- {Object} [guard] Allows working with `_.reduce` without using its
- * `key` and `object` arguments as sources.
- * @returns {Object} Returns the destination object.
- * @example
- *
- * var object = { 'name': 'barney' };
- * _.defaults(object, { 'name': 'fred', 'employer': 'slate' });
- * // => { 'name': 'barney', 'employer': 'slate' }
- */
- var defaults = createIterator(defaultsIteratorOptions);
-
- /**
- * This method is like `_.findIndex` except that it returns the key of the
- * first element that passes the callback check, instead of the element itself.
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {Object} object The object to search.
- * @param {Function|Object|string} [callback=identity] The function called per
- * iteration. If a property name or object is provided it will be used to
- * create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {string|undefined} Returns the key of the found element, else `undefined`.
- * @example
- *
- * var characters = {
- * 'barney': { 'age': 36, 'blocked': false },
- * 'fred': { 'age': 40, 'blocked': true },
- * 'pebbles': { 'age': 1, 'blocked': false }
- * };
- *
- * _.findKey(characters, function(chr) {
- * return chr.age < 40;
- * });
- * // => 'barney' (property order is not guaranteed across environments)
- *
- * // using "_.where" callback shorthand
- * _.findKey(characters, { 'age': 1 });
- * // => 'pebbles'
- *
- * // using "_.pluck" callback shorthand
- * _.findKey(characters, 'blocked');
- * // => 'fred'
- */
- function findKey(object, callback, thisArg) {
- var result;
- callback = lodash.createCallback(callback, thisArg, 3);
- forOwn(object, function(value, key, object) {
- if (callback(value, key, object)) {
- result = key;
- return false;
- }
- });
- return result;
- }
-
- /**
- * This method is like `_.findKey` except that it iterates over elements
- * of a `collection` in the opposite order.
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {Object} object The object to search.
- * @param {Function|Object|string} [callback=identity] The function called per
- * iteration. If a property name or object is provided it will be used to
- * create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {string|undefined} Returns the key of the found element, else `undefined`.
- * @example
- *
- * var characters = {
- * 'barney': { 'age': 36, 'blocked': true },
- * 'fred': { 'age': 40, 'blocked': false },
- * 'pebbles': { 'age': 1, 'blocked': true }
- * };
- *
- * _.findLastKey(characters, function(chr) {
- * return chr.age < 40;
- * });
- * // => returns `pebbles`, assuming `_.findKey` returns `barney`
- *
- * // using "_.where" callback shorthand
- * _.findLastKey(characters, { 'age': 40 });
- * // => 'fred'
- *
- * // using "_.pluck" callback shorthand
- * _.findLastKey(characters, 'blocked');
- * // => 'pebbles'
- */
- function findLastKey(object, callback, thisArg) {
- var result;
- callback = lodash.createCallback(callback, thisArg, 3);
- forOwnRight(object, function(value, key, object) {
- if (callback(value, key, object)) {
- result = key;
- return false;
- }
- });
- return result;
- }
-
- /**
- * Iterates over own and inherited enumerable properties of an object,
- * executing the callback for each property. The callback is bound to `thisArg`
- * and invoked with three arguments; (value, key, object). Callbacks may exit
- * iteration early by explicitly returning `false`.
- *
- * @static
- * @memberOf _
- * @type Function
- * @category Objects
- * @param {Object} object The object to iterate over.
- * @param {Function} [callback=identity] The function called per iteration.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Object} Returns `object`.
- * @example
- *
- * function Shape() {
- * this.x = 0;
- * this.y = 0;
- * }
- *
- * Shape.prototype.move = function(x, y) {
- * this.x += x;
- * this.y += y;
- * };
- *
- * _.forIn(new Shape, function(value, key) {
- * console.log(key);
- * });
- * // => logs 'x', 'y', and 'move' (property order is not guaranteed across environments)
- */
- var forIn = createIterator(eachIteratorOptions, forOwnIteratorOptions, {
- 'useHas': false
- });
-
- /**
- * This method is like `_.forIn` except that it iterates over elements
- * of a `collection` in the opposite order.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {Object} object The object to iterate over.
- * @param {Function} [callback=identity] The function called per iteration.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Object} Returns `object`.
- * @example
- *
- * function Shape() {
- * this.x = 0;
- * this.y = 0;
- * }
- *
- * Shape.prototype.move = function(x, y) {
- * this.x += x;
- * this.y += y;
- * };
- *
- * _.forInRight(new Shape, function(value, key) {
- * console.log(key);
- * });
- * // => logs 'move', 'y', and 'x' assuming `_.forIn ` logs 'x', 'y', and 'move'
- */
- function forInRight(object, callback, thisArg) {
- var pairs = [];
-
- forIn(object, function(value, key) {
- pairs.push(key, value);
- });
-
- var length = pairs.length;
- callback = baseCreateCallback(callback, thisArg, 3);
- while (length--) {
- if (callback(pairs[length--], pairs[length], object) === false) {
- break;
- }
- }
- return object;
- }
-
- /**
- * Iterates over own enumerable properties of an object, executing the callback
- * for each property. The callback is bound to `thisArg` and invoked with three
- * arguments; (value, key, object). Callbacks may exit iteration early by
- * explicitly returning `false`.
- *
- * @static
- * @memberOf _
- * @type Function
- * @category Objects
- * @param {Object} object The object to iterate over.
- * @param {Function} [callback=identity] The function called per iteration.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Object} Returns `object`.
- * @example
- *
- * _.forOwn({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) {
- * console.log(key);
- * });
- * // => logs '0', '1', and 'length' (property order is not guaranteed across environments)
- */
- var forOwn = createIterator(eachIteratorOptions, forOwnIteratorOptions);
-
- /**
- * This method is like `_.forOwn` except that it iterates over elements
- * of a `collection` in the opposite order.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {Object} object The object to iterate over.
- * @param {Function} [callback=identity] The function called per iteration.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Object} Returns `object`.
- * @example
- *
- * _.forOwnRight({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) {
- * console.log(key);
- * });
- * // => logs 'length', '1', and '0' assuming `_.forOwn` logs '0', '1', and 'length'
- */
- function forOwnRight(object, callback, thisArg) {
- var props = keys(object),
- length = props.length;
-
- callback = baseCreateCallback(callback, thisArg, 3);
- while (length--) {
- var key = props[length];
- if (callback(object[key], key, object) === false) {
- break;
- }
- }
- return object;
- }
-
- /**
- * Creates a sorted array of property names of all enumerable properties,
- * own and inherited, of `object` that have function values.
- *
- * @static
- * @memberOf _
- * @alias methods
- * @category Objects
- * @param {Object} object The object to inspect.
- * @returns {Array} Returns an array of property names that have function values.
- * @example
- *
- * _.functions(_);
- * // => ['all', 'any', 'bind', 'bindAll', 'clone', 'compact', 'compose', ...]
- */
- function functions(object) {
- var result = [];
- forIn(object, function(value, key) {
- if (isFunction(value)) {
- result.push(key);
- }
- });
- return result.sort();
- }
-
- /**
- * Checks if the specified property name exists as a direct property of `object`,
- * instead of an inherited property.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {Object} object The object to inspect.
- * @param {string} key The name of the property to check.
- * @returns {boolean} Returns `true` if key is a direct property, else `false`.
- * @example
- *
- * _.has({ 'a': 1, 'b': 2, 'c': 3 }, 'b');
- * // => true
- */
- function has(object, key) {
- return object ? hasOwnProperty.call(object, key) : false;
- }
-
- /**
- * Creates an object composed of the inverted keys and values of the given object.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {Object} object The object to invert.
- * @returns {Object} Returns the created inverted object.
- * @example
- *
- * _.invert({ 'first': 'fred', 'second': 'barney' });
- * // => { 'fred': 'first', 'barney': 'second' }
- */
- function invert(object) {
- var index = -1,
- props = keys(object),
- length = props.length,
- result = {};
-
- while (++index < length) {
- var key = props[index];
- result[object[key]] = key;
- }
- return result;
- }
-
- /**
- * Checks if `value` is a boolean value.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if the `value` is a boolean value, else `false`.
- * @example
- *
- * _.isBoolean(null);
- * // => false
- */
- function isBoolean(value) {
- return value === true || value === false ||
- value && typeof value == 'object' && toString.call(value) == boolClass || false;
- }
-
- /**
- * Checks if `value` is a date.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if the `value` is a date, else `false`.
- * @example
- *
- * _.isDate(new Date);
- * // => true
- */
- function isDate(value) {
- return value && typeof value == 'object' && toString.call(value) == dateClass || false;
- }
-
- /**
- * Checks if `value` is a DOM element.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if the `value` is a DOM element, else `false`.
- * @example
- *
- * _.isElement(document.body);
- * // => true
- */
- function isElement(value) {
- return value && value.nodeType === 1 || false;
- }
-
- /**
- * Checks if `value` is empty. Arrays, strings, or `arguments` objects with a
- * length of `0` and objects with no own enumerable properties are considered
- * "empty".
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {Array|Object|string} value The value to inspect.
- * @returns {boolean} Returns `true` if the `value` is empty, else `false`.
- * @example
- *
- * _.isEmpty([1, 2, 3]);
- * // => false
- *
- * _.isEmpty({});
- * // => true
- *
- * _.isEmpty('');
- * // => true
- */
- function isEmpty(value) {
- var result = true;
- if (!value) {
- return result;
- }
- var className = toString.call(value),
- length = value.length;
-
- if ((className == arrayClass || className == stringClass ||
- (support.argsClass ? className == argsClass : isArguments(value))) ||
- (className == objectClass && typeof length == 'number' && isFunction(value.splice))) {
- return !length;
- }
- forOwn(value, function() {
- return (result = false);
- });
- return result;
- }
-
- /**
- * Performs a deep comparison between two values to determine if they are
- * equivalent to each other. If a callback is provided it will be executed
- * to compare values. If the callback returns `undefined` comparisons will
- * be handled by the method instead. The callback is bound to `thisArg` and
- * invoked with two arguments; (a, b).
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {*} a The value to compare.
- * @param {*} b The other value to compare.
- * @param {Function} [callback] The function to customize comparing values.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
- * @example
- *
- * var object = { 'name': 'fred' };
- * var copy = { 'name': 'fred' };
- *
- * object == copy;
- * // => false
- *
- * _.isEqual(object, copy);
- * // => true
- *
- * var words = ['hello', 'goodbye'];
- * var otherWords = ['hi', 'goodbye'];
- *
- * _.isEqual(words, otherWords, function(a, b) {
- * var reGreet = /^(?:hello|hi)$/i,
- * aGreet = _.isString(a) && reGreet.test(a),
- * bGreet = _.isString(b) && reGreet.test(b);
- *
- * return (aGreet || bGreet) ? (aGreet == bGreet) : undefined;
- * });
- * // => true
- */
- function isEqual(a, b, callback, thisArg) {
- return baseIsEqual(a, b, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 2));
- }
-
- /**
- * Checks if `value` is, or can be coerced to, a finite number.
- *
- * Note: This is not the same as native `isFinite` which will return true for
- * booleans and empty strings. See http://es5.github.io/#x15.1.2.5.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if the `value` is finite, else `false`.
- * @example
- *
- * _.isFinite(-101);
- * // => true
- *
- * _.isFinite('10');
- * // => true
- *
- * _.isFinite(true);
- * // => false
- *
- * _.isFinite('');
- * // => false
- *
- * _.isFinite(Infinity);
- * // => false
- */
- function isFinite(value) {
- return nativeIsFinite(value) && !nativeIsNaN(parseFloat(value));
- }
-
- /**
- * Checks if `value` is a function.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if the `value` is a function, else `false`.
- * @example
- *
- * _.isFunction(_);
- * // => true
- */
- function isFunction(value) {
- return typeof value == 'function';
- }
- // fallback for older versions of Chrome and Safari
- if (isFunction(/x/)) {
- isFunction = function(value) {
- return typeof value == 'function' && toString.call(value) == funcClass;
- };
- }
-
- /**
- * Checks if `value` is the language type of Object.
- * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if the `value` is an object, else `false`.
- * @example
- *
- * _.isObject({});
- * // => true
- *
- * _.isObject([1, 2, 3]);
- * // => true
- *
- * _.isObject(1);
- * // => false
- */
- function isObject(value) {
- // check if the value is the ECMAScript language type of Object
- // http://es5.github.io/#x8
- // and avoid a V8 bug
- // http://code.google.com/p/v8/issues/detail?id=2291
- return !!(value && objectTypes[typeof value]);
- }
-
- /**
- * Checks if `value` is `NaN`.
- *
- * Note: This is not the same as native `isNaN` which will return `true` for
- * `undefined` and other non-numeric values. See http://es5.github.io/#x15.1.2.4.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if the `value` is `NaN`, else `false`.
- * @example
- *
- * _.isNaN(NaN);
- * // => true
- *
- * _.isNaN(new Number(NaN));
- * // => true
- *
- * isNaN(undefined);
- * // => true
- *
- * _.isNaN(undefined);
- * // => false
- */
- function isNaN(value) {
- // `NaN` as a primitive is the only value that is not equal to itself
- // (perform the [[Class]] check first to avoid errors with some host objects in IE)
- return isNumber(value) && value != +value;
- }
-
- /**
- * Checks if `value` is `null`.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if the `value` is `null`, else `false`.
- * @example
- *
- * _.isNull(null);
- * // => true
- *
- * _.isNull(undefined);
- * // => false
- */
- function isNull(value) {
- return value === null;
- }
-
- /**
- * Checks if `value` is a number.
- *
- * Note: `NaN` is considered a number. See http://es5.github.io/#x8.5.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if the `value` is a number, else `false`.
- * @example
- *
- * _.isNumber(8.4 * 5);
- * // => true
- */
- function isNumber(value) {
- return typeof value == 'number' ||
- value && typeof value == 'object' && toString.call(value) == numberClass || false;
- }
-
- /**
- * Checks if `value` is an object created by the `Object` constructor.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
- * @example
- *
- * function Shape() {
- * this.x = 0;
- * this.y = 0;
- * }
- *
- * _.isPlainObject(new Shape);
- * // => false
- *
- * _.isPlainObject([1, 2, 3]);
- * // => false
- *
- * _.isPlainObject({ 'x': 0, 'y': 0 });
- * // => true
- */
- var isPlainObject = !getPrototypeOf ? shimIsPlainObject : function(value) {
- if (!(value && toString.call(value) == objectClass) || (!support.argsClass && isArguments(value))) {
- return false;
- }
- var valueOf = value.valueOf,
- objProto = isNative(valueOf) && (objProto = getPrototypeOf(valueOf)) && getPrototypeOf(objProto);
-
- return objProto
- ? (value == objProto || getPrototypeOf(value) == objProto)
- : shimIsPlainObject(value);
- };
-
- /**
- * Checks if `value` is a regular expression.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if the `value` is a regular expression, else `false`.
- * @example
- *
- * _.isRegExp(/fred/);
- * // => true
- */
- function isRegExp(value) {
- return value && objectTypes[typeof value] && toString.call(value) == regexpClass || false;
- }
-
- /**
- * Checks if `value` is a string.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if the `value` is a string, else `false`.
- * @example
- *
- * _.isString('fred');
- * // => true
- */
- function isString(value) {
- return typeof value == 'string' ||
- value && typeof value == 'object' && toString.call(value) == stringClass || false;
- }
-
- /**
- * Checks if `value` is `undefined`.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if the `value` is `undefined`, else `false`.
- * @example
- *
- * _.isUndefined(void 0);
- * // => true
- */
- function isUndefined(value) {
- return typeof value == 'undefined';
- }
-
- /**
- * Creates an object with the same keys as `object` and values generated by
- * running each own enumerable property of `object` through the callback.
- * The callback is bound to `thisArg` and invoked with three arguments;
- * (value, key, object).
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {Object} object The object to iterate over.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Array} Returns a new object with values of the results of each `callback` execution.
- * @example
- *
- * _.mapValues({ 'a': 1, 'b': 2, 'c': 3} , function(num) { return num * 3; });
- * // => { 'a': 3, 'b': 6, 'c': 9 }
- *
- * var characters = {
- * 'fred': { 'name': 'fred', 'age': 40 },
- * 'pebbles': { 'name': 'pebbles', 'age': 1 }
- * };
- *
- * // using "_.pluck" callback shorthand
- * _.mapValues(characters, 'age');
- * // => { 'fred': 40, 'pebbles': 1 }
- */
- function mapValues(object, callback, thisArg) {
- var result = {};
- callback = lodash.createCallback(callback, thisArg, 3);
-
- forOwn(object, function(value, key, object) {
- result[key] = callback(value, key, object);
- });
- return result;
- }
-
- /**
- * Recursively merges own enumerable properties of the source object(s), that
- * don't resolve to `undefined` into the destination object. Subsequent sources
- * will overwrite property assignments of previous sources. If a callback is
- * provided it will be executed to produce the merged values of the destination
- * and source properties. If the callback returns `undefined` merging will
- * be handled by the method instead. The callback is bound to `thisArg` and
- * invoked with two arguments; (objectValue, sourceValue).
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {Object} object The destination object.
- * @param {...Object} [source] The source objects.
- * @param {Function} [callback] The function to customize merging properties.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Object} Returns the destination object.
- * @example
- *
- * var names = {
- * 'characters': [
- * { 'name': 'barney' },
- * { 'name': 'fred' }
- * ]
- * };
- *
- * var ages = {
- * 'characters': [
- * { 'age': 36 },
- * { 'age': 40 }
- * ]
- * };
- *
- * _.merge(names, ages);
- * // => { 'characters': [{ 'name': 'barney', 'age': 36 }, { 'name': 'fred', 'age': 40 }] }
- *
- * var food = {
- * 'fruits': ['apple'],
- * 'vegetables': ['beet']
- * };
- *
- * var otherFood = {
- * 'fruits': ['banana'],
- * 'vegetables': ['carrot']
- * };
- *
- * _.merge(food, otherFood, function(a, b) {
- * return _.isArray(a) ? a.concat(b) : undefined;
- * });
- * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot] }
- */
- function merge(object) {
- var args = arguments,
- length = 2;
-
- if (!isObject(object)) {
- return object;
- }
- // allows working with `_.reduce` and `_.reduceRight` without using
- // their `index` and `collection` arguments
- if (typeof args[2] != 'number') {
- length = args.length;
- }
- if (length > 3 && typeof args[length - 2] == 'function') {
- var callback = baseCreateCallback(args[--length - 1], args[length--], 2);
- } else if (length > 2 && typeof args[length - 1] == 'function') {
- callback = args[--length];
- }
- var sources = slice(arguments, 1, length),
- index = -1,
- stackA = getArray(),
- stackB = getArray();
-
- while (++index < length) {
- baseMerge(object, sources[index], callback, stackA, stackB);
- }
- releaseArray(stackA);
- releaseArray(stackB);
- return object;
- }
-
- /**
- * Creates a shallow clone of `object` excluding the specified properties.
- * Property names may be specified as individual arguments or as arrays of
- * property names. If a callback is provided it will be executed for each
- * property of `object` omitting the properties the callback returns truey
- * for. The callback is bound to `thisArg` and invoked with three arguments;
- * (value, key, object).
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {Object} object The source object.
- * @param {Function|...string|string[]} [callback] The properties to omit or the
- * function called per iteration.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Object} Returns an object without the omitted properties.
- * @example
- *
- * _.omit({ 'name': 'fred', 'age': 40 }, 'age');
- * // => { 'name': 'fred' }
- *
- * _.omit({ 'name': 'fred', 'age': 40 }, function(value) {
- * return typeof value == 'number';
- * });
- * // => { 'name': 'fred' }
- */
- function omit(object, callback, thisArg) {
- var result = {};
- if (typeof callback != 'function') {
- var props = [];
- forIn(object, function(value, key) {
- props.push(key);
- });
- props = baseDifference(props, baseFlatten(arguments, true, false, 1));
-
- var index = -1,
- length = props.length;
-
- while (++index < length) {
- var key = props[index];
- result[key] = object[key];
- }
- } else {
- callback = lodash.createCallback(callback, thisArg, 3);
- forIn(object, function(value, key, object) {
- if (!callback(value, key, object)) {
- result[key] = value;
- }
- });
- }
- return result;
- }
-
- /**
- * Creates a two dimensional array of an object's key-value pairs,
- * i.e. `[[key1, value1], [key2, value2]]`.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {Object} object The object to inspect.
- * @returns {Array} Returns new array of key-value pairs.
- * @example
- *
- * _.pairs({ 'barney': 36, 'fred': 40 });
- * // => [['barney', 36], ['fred', 40]] (property order is not guaranteed across environments)
- */
- function pairs(object) {
- var index = -1,
- props = keys(object),
- length = props.length,
- result = Array(length);
-
- while (++index < length) {
- var key = props[index];
- result[index] = [key, object[key]];
- }
- return result;
- }
-
- /**
- * Creates a shallow clone of `object` composed of the specified properties.
- * Property names may be specified as individual arguments or as arrays of
- * property names. If a callback is provided it will be executed for each
- * property of `object` picking the properties the callback returns truey
- * for. The callback is bound to `thisArg` and invoked with three arguments;
- * (value, key, object).
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {Object} object The source object.
- * @param {Function|...string|string[]} [callback] The function called per
- * iteration or property names to pick, specified as individual property
- * names or arrays of property names.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Object} Returns an object composed of the picked properties.
- * @example
- *
- * _.pick({ 'name': 'fred', '_userid': 'fred1' }, 'name');
- * // => { 'name': 'fred' }
- *
- * _.pick({ 'name': 'fred', '_userid': 'fred1' }, function(value, key) {
- * return key.charAt(0) != '_';
- * });
- * // => { 'name': 'fred' }
- */
- function pick(object, callback, thisArg) {
- var result = {};
- if (typeof callback != 'function') {
- var index = -1,
- props = baseFlatten(arguments, true, false, 1),
- length = isObject(object) ? props.length : 0;
-
- while (++index < length) {
- var key = props[index];
- if (key in object) {
- result[key] = object[key];
- }
- }
- } else {
- callback = lodash.createCallback(callback, thisArg, 3);
- forIn(object, function(value, key, object) {
- if (callback(value, key, object)) {
- result[key] = value;
- }
- });
- }
- return result;
- }
-
- /**
- * An alternative to `_.reduce` this method transforms `object` to a new
- * `accumulator` object which is the result of running each of its own
- * enumerable properties through a callback, with each callback execution
- * potentially mutating the `accumulator` object. The callback is bound to
- * `thisArg` and invoked with four arguments; (accumulator, value, key, object).
- * Callbacks may exit iteration early by explicitly returning `false`.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {Array|Object} object The object to iterate over.
- * @param {Function} [callback=identity] The function called per iteration.
- * @param {*} [accumulator] The custom accumulator value.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {*} Returns the accumulated value.
- * @example
- *
- * var squares = _.transform([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], function(result, num) {
- * num *= num;
- * if (num % 2) {
- * return result.push(num) < 3;
- * }
- * });
- * // => [1, 9, 25]
- *
- * var mapped = _.transform({ 'a': 1, 'b': 2, 'c': 3 }, function(result, num, key) {
- * result[key] = num * 3;
- * });
- * // => { 'a': 3, 'b': 6, 'c': 9 }
- */
- function transform(object, callback, accumulator, thisArg) {
- var isArr = isArray(object);
- if (accumulator == null) {
- if (isArr) {
- accumulator = [];
- } else {
- var ctor = object && object.constructor,
- proto = ctor && ctor.prototype;
-
- accumulator = baseCreate(proto);
- }
- }
- if (callback) {
- callback = lodash.createCallback(callback, thisArg, 4);
- (isArr ? baseEach : forOwn)(object, function(value, index, object) {
- return callback(accumulator, value, index, object);
- });
- }
- return accumulator;
- }
-
- /**
- * Creates an array composed of the own enumerable property values of `object`.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {Object} object The object to inspect.
- * @returns {Array} Returns an array of property values.
- * @example
- *
- * _.values({ 'one': 1, 'two': 2, 'three': 3 });
- * // => [1, 2, 3] (property order is not guaranteed across environments)
- */
- function values(object) {
- var index = -1,
- props = keys(object),
- length = props.length,
- result = Array(length);
-
- while (++index < length) {
- result[index] = object[props[index]];
- }
- return result;
- }
-
- /*--------------------------------------------------------------------------*/
-
- /**
- * Creates an array of elements from the specified indexes, or keys, of the
- * `collection`. Indexes may be specified as individual arguments or as arrays
- * of indexes.
- *
- * @static
- * @memberOf _
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {...(number|number[]|string|string[])} [index] The indexes of `collection`
- * to retrieve, specified as individual indexes or arrays of indexes.
- * @returns {Array} Returns a new array of elements corresponding to the
- * provided indexes.
- * @example
- *
- * _.at(['a', 'b', 'c', 'd', 'e'], [0, 2, 4]);
- * // => ['a', 'c', 'e']
- *
- * _.at(['fred', 'barney', 'pebbles'], 0, 2);
- * // => ['fred', 'pebbles']
- */
- function at(collection) {
- var args = arguments,
- index = -1,
- props = baseFlatten(args, true, false, 1),
- length = (args[2] && args[2][args[1]] === collection) ? 1 : props.length,
- result = Array(length);
-
- if (support.unindexedChars && isString(collection)) {
- collection = collection.split('');
- }
- while(++index < length) {
- result[index] = collection[props[index]];
- }
- return result;
- }
-
- /**
- * Checks if a given value is present in a collection using strict equality
- * for comparisons, i.e. `===`. If `fromIndex` is negative, it is used as the
- * offset from the end of the collection.
- *
- * @static
- * @memberOf _
- * @alias include
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {*} target The value to check for.
- * @param {number} [fromIndex=0] The index to search from.
- * @returns {boolean} Returns `true` if the `target` element is found, else `false`.
- * @example
- *
- * _.contains([1, 2, 3], 1);
- * // => true
- *
- * _.contains([1, 2, 3], 1, 2);
- * // => false
- *
- * _.contains({ 'name': 'fred', 'age': 40 }, 'fred');
- * // => true
- *
- * _.contains('pebbles', 'eb');
- * // => true
- */
- function contains(collection, target, fromIndex) {
- var index = -1,
- indexOf = getIndexOf(),
- length = collection ? collection.length : 0,
- result = false;
-
- fromIndex = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex) || 0;
- if (isArray(collection)) {
- result = indexOf(collection, target, fromIndex) > -1;
- } else if (typeof length == 'number') {
- result = (isString(collection) ? collection.indexOf(target, fromIndex) : indexOf(collection, target, fromIndex)) > -1;
- } else {
- baseEach(collection, function(value) {
- if (++index >= fromIndex) {
- return !(result = value === target);
- }
- });
- }
- return result;
- }
-
- /**
- * Creates an object composed of keys generated from the results of running
- * each element of `collection` through the callback. The corresponding value
- * of each key is the number of times the key was returned by the callback.
- * The callback is bound to `thisArg` and invoked with three arguments;
- * (value, index|key, collection).
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Object} Returns the composed aggregate object.
- * @example
- *
- * _.countBy([4.3, 6.1, 6.4], function(num) { return Math.floor(num); });
- * // => { '4': 1, '6': 2 }
- *
- * _.countBy([4.3, 6.1, 6.4], function(num) { return this.floor(num); }, Math);
- * // => { '4': 1, '6': 2 }
- *
- * _.countBy(['one', 'two', 'three'], 'length');
- * // => { '3': 2, '5': 1 }
- */
- var countBy = createAggregator(function(result, value, key) {
- (hasOwnProperty.call(result, key) ? result[key]++ : result[key] = 1);
- });
-
- /**
- * Checks if the given callback returns truey value for **all** elements of
- * a collection. The callback is bound to `thisArg` and invoked with three
- * arguments; (value, index|key, collection).
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @alias all
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {boolean} Returns `true` if all elements passed the callback check,
- * else `false`.
- * @example
- *
- * _.every([true, 1, null, 'yes']);
- * // => false
- *
- * var characters = [
- * { 'name': 'barney', 'age': 36 },
- * { 'name': 'fred', 'age': 40 }
- * ];
- *
- * // using "_.pluck" callback shorthand
- * _.every(characters, 'age');
- * // => true
- *
- * // using "_.where" callback shorthand
- * _.every(characters, { 'age': 36 });
- * // => false
- */
- function every(collection, callback, thisArg) {
- var result = true;
- callback = lodash.createCallback(callback, thisArg, 3);
-
- if (isArray(collection)) {
- var index = -1,
- length = collection.length;
-
- while (++index < length) {
- if (!(result = !!callback(collection[index], index, collection))) {
- break;
- }
- }
- } else {
- baseEach(collection, function(value, index, collection) {
- return (result = !!callback(value, index, collection));
- });
- }
- return result;
- }
-
- /**
- * Iterates over elements of a collection, returning an array of all elements
- * the callback returns truey for. The callback is bound to `thisArg` and
- * invoked with three arguments; (value, index|key, collection).
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @alias select
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Array} Returns a new array of elements that passed the callback check.
- * @example
- *
- * var evens = _.filter([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; });
- * // => [2, 4, 6]
- *
- * var characters = [
- * { 'name': 'barney', 'age': 36, 'blocked': false },
- * { 'name': 'fred', 'age': 40, 'blocked': true }
- * ];
- *
- * // using "_.pluck" callback shorthand
- * _.filter(characters, 'blocked');
- * // => [{ 'name': 'fred', 'age': 40, 'blocked': true }]
- *
- * // using "_.where" callback shorthand
- * _.filter(characters, { 'age': 36 });
- * // => [{ 'name': 'barney', 'age': 36, 'blocked': false }]
- */
- function filter(collection, callback, thisArg) {
- var result = [];
- callback = lodash.createCallback(callback, thisArg, 3);
-
- if (isArray(collection)) {
- var index = -1,
- length = collection.length;
-
- while (++index < length) {
- var value = collection[index];
- if (callback(value, index, collection)) {
- result.push(value);
- }
- }
- } else {
- baseEach(collection, function(value, index, collection) {
- if (callback(value, index, collection)) {
- result.push(value);
- }
- });
- }
- return result;
- }
-
- /**
- * Iterates over elements of a collection, returning the first element that
- * the callback returns truey for. The callback is bound to `thisArg` and
- * invoked with three arguments; (value, index|key, collection).
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @alias detect, findWhere
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {*} Returns the found element, else `undefined`.
- * @example
- *
- * var characters = [
- * { 'name': 'barney', 'age': 36, 'blocked': false },
- * { 'name': 'fred', 'age': 40, 'blocked': true },
- * { 'name': 'pebbles', 'age': 1, 'blocked': false }
- * ];
- *
- * _.find(characters, function(chr) {
- * return chr.age < 40;
- * });
- * // => { 'name': 'barney', 'age': 36, 'blocked': false }
- *
- * // using "_.where" callback shorthand
- * _.find(characters, { 'age': 1 });
- * // => { 'name': 'pebbles', 'age': 1, 'blocked': false }
- *
- * // using "_.pluck" callback shorthand
- * _.find(characters, 'blocked');
- * // => { 'name': 'fred', 'age': 40, 'blocked': true }
- */
- function find(collection, callback, thisArg) {
- callback = lodash.createCallback(callback, thisArg, 3);
-
- if (isArray(collection)) {
- var index = -1,
- length = collection.length;
-
- while (++index < length) {
- var value = collection[index];
- if (callback(value, index, collection)) {
- return value;
- }
- }
- } else {
- var result;
- baseEach(collection, function(value, index, collection) {
- if (callback(value, index, collection)) {
- result = value;
- return false;
- }
- });
- return result;
- }
- }
-
- /**
- * This method is like `_.find` except that it iterates over elements
- * of a `collection` from right to left.
- *
- * @static
- * @memberOf _
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {*} Returns the found element, else `undefined`.
- * @example
- *
- * _.findLast([1, 2, 3, 4], function(num) {
- * return num % 2 == 1;
- * });
- * // => 3
- */
- function findLast(collection, callback, thisArg) {
- var result;
- callback = lodash.createCallback(callback, thisArg, 3);
- forEachRight(collection, function(value, index, collection) {
- if (callback(value, index, collection)) {
- result = value;
- return false;
- }
- });
- return result;
- }
-
- /**
- * Iterates over elements of a collection, executing the callback for each
- * element. The callback is bound to `thisArg` and invoked with three arguments;
- * (value, index|key, collection). Callbacks may exit iteration early by
- * explicitly returning `false`.
- *
- * Note: As with other "Collections" methods, objects with a `length` property
- * are iterated like arrays. To avoid this behavior `_.forIn` or `_.forOwn`
- * may be used for object iteration.
- *
- * @static
- * @memberOf _
- * @alias each
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function} [callback=identity] The function called per iteration.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Array|Object|string} Returns `collection`.
- * @example
- *
- * _([1, 2, 3]).forEach(function(num) { console.log(num); }).join(',');
- * // => logs each number and returns '1,2,3'
- *
- * _.forEach({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { console.log(num); });
- * // => logs each number and returns the object (property order is not guaranteed across environments)
- */
- function forEach(collection, callback, thisArg) {
- if (callback && typeof thisArg == 'undefined' && isArray(collection)) {
- var index = -1,
- length = collection.length;
-
- while (++index < length) {
- if (callback(collection[index], index, collection) === false) {
- break;
- }
- }
- } else {
- baseEach(collection, callback, thisArg);
- }
- return collection;
- }
-
- /**
- * This method is like `_.forEach` except that it iterates over elements
- * of a `collection` from right to left.
- *
- * @static
- * @memberOf _
- * @alias eachRight
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function} [callback=identity] The function called per iteration.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Array|Object|string} Returns `collection`.
- * @example
- *
- * _([1, 2, 3]).forEachRight(function(num) { console.log(num); }).join(',');
- * // => logs each number from right to left and returns '3,2,1'
- */
- function forEachRight(collection, callback, thisArg) {
- var iterable = collection,
- length = collection ? collection.length : 0;
-
- callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3);
- if (isArray(collection)) {
- while (length--) {
- if (callback(collection[length], length, collection) === false) {
- break;
- }
- }
- } else {
- if (typeof length != 'number') {
- var props = keys(collection);
- length = props.length;
- } else if (support.unindexedChars && isString(collection)) {
- iterable = collection.split('');
- }
- baseEach(collection, function(value, key, collection) {
- key = props ? props[--length] : --length;
- return callback(iterable[key], key, collection);
- });
- }
- return collection;
- }
-
- /**
- * Creates an object composed of keys generated from the results of running
- * each element of a collection through the callback. The corresponding value
- * of each key is an array of the elements responsible for generating the key.
- * The callback is bound to `thisArg` and invoked with three arguments;
- * (value, index|key, collection).
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`
- *
- * @static
- * @memberOf _
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Object} Returns the composed aggregate object.
- * @example
- *
- * _.groupBy([4.2, 6.1, 6.4], function(num) { return Math.floor(num); });
- * // => { '4': [4.2], '6': [6.1, 6.4] }
- *
- * _.groupBy([4.2, 6.1, 6.4], function(num) { return this.floor(num); }, Math);
- * // => { '4': [4.2], '6': [6.1, 6.4] }
- *
- * // using "_.pluck" callback shorthand
- * _.groupBy(['one', 'two', 'three'], 'length');
- * // => { '3': ['one', 'two'], '5': ['three'] }
- */
- var groupBy = createAggregator(function(result, value, key) {
- (hasOwnProperty.call(result, key) ? result[key] : result[key] = []).push(value);
- });
-
- /**
- * Creates an object composed of keys generated from the results of running
- * each element of the collection through the given callback. The corresponding
- * value of each key is the last element responsible for generating the key.
- * The callback is bound to `thisArg` and invoked with three arguments;
- * (value, index|key, collection).
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Object} Returns the composed aggregate object.
- * @example
- *
- * var keys = [
- * { 'dir': 'left', 'code': 97 },
- * { 'dir': 'right', 'code': 100 }
- * ];
- *
- * _.indexBy(keys, 'dir');
- * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } }
- *
- * _.indexBy(keys, function(key) { return String.fromCharCode(key.code); });
- * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
- *
- * _.indexBy(characters, function(key) { this.fromCharCode(key.code); }, String);
- * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
- */
- var indexBy = createAggregator(function(result, value, key) {
- result[key] = value;
- });
-
- /**
- * Invokes the method named by `methodName` on each element in the `collection`
- * returning an array of the results of each invoked method. Additional arguments
- * will be provided to each invoked method. If `methodName` is a function it
- * will be invoked for, and `this` bound to, each element in the `collection`.
- *
- * @static
- * @memberOf _
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|string} methodName The name of the method to invoke or
- * the function invoked per iteration.
- * @param {...*} [arg] Arguments to invoke the method with.
- * @returns {Array} Returns a new array of the results of each invoked method.
- * @example
- *
- * _.invoke([[5, 1, 7], [3, 2, 1]], 'sort');
- * // => [[1, 5, 7], [1, 2, 3]]
- *
- * _.invoke([123, 456], String.prototype.split, '');
- * // => [['1', '2', '3'], ['4', '5', '6']]
- */
- function invoke(collection, methodName) {
- var args = slice(arguments, 2),
- index = -1,
- isFunc = typeof methodName == 'function',
- length = collection ? collection.length : 0,
- result = Array(typeof length == 'number' ? length : 0);
-
- forEach(collection, function(value) {
- result[++index] = (isFunc ? methodName : value[methodName]).apply(value, args);
- });
- return result;
- }
-
- /**
- * Creates an array of values by running each element in the collection
- * through the callback. The callback is bound to `thisArg` and invoked with
- * three arguments; (value, index|key, collection).
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @alias collect
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Array} Returns a new array of the results of each `callback` execution.
- * @example
- *
- * _.map([1, 2, 3], function(num) { return num * 3; });
- * // => [3, 6, 9]
- *
- * _.map({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { return num * 3; });
- * // => [3, 6, 9] (property order is not guaranteed across environments)
- *
- * var characters = [
- * { 'name': 'barney', 'age': 36 },
- * { 'name': 'fred', 'age': 40 }
- * ];
- *
- * // using "_.pluck" callback shorthand
- * _.map(characters, 'name');
- * // => ['barney', 'fred']
- */
- function map(collection, callback, thisArg) {
- var index = -1,
- length = collection ? collection.length : 0,
- result = Array(typeof length == 'number' ? length : 0);
-
- callback = lodash.createCallback(callback, thisArg, 3);
- if (isArray(collection)) {
- while (++index < length) {
- result[index] = callback(collection[index], index, collection);
- }
- } else {
- baseEach(collection, function(value, key, collection) {
- result[++index] = callback(value, key, collection);
- });
- }
- return result;
- }
-
- /**
- * Retrieves the maximum value of a collection. If the collection is empty or
- * falsey `-Infinity` is returned. If a callback is provided it will be executed
- * for each value in the collection to generate the criterion by which the value
- * is ranked. The callback is bound to `thisArg` and invoked with three
- * arguments; (value, index, collection).
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {*} Returns the maximum value.
- * @example
- *
- * _.max([4, 2, 8, 6]);
- * // => 8
- *
- * var characters = [
- * { 'name': 'barney', 'age': 36 },
- * { 'name': 'fred', 'age': 40 }
- * ];
- *
- * _.max(characters, function(chr) { return chr.age; });
- * // => { 'name': 'fred', 'age': 40 };
- *
- * // using "_.pluck" callback shorthand
- * _.max(characters, 'age');
- * // => { 'name': 'fred', 'age': 40 };
- */
- function max(collection, callback, thisArg) {
- var computed = -Infinity,
- result = computed;
-
- // allows working with functions like `_.map` without using
- // their `index` argument as a callback
- if (typeof callback != 'function' && thisArg && thisArg[callback] === collection) {
- callback = null;
- }
- if (callback == null && isArray(collection)) {
- var index = -1,
- length = collection.length;
-
- while (++index < length) {
- var value = collection[index];
- if (value > result) {
- result = value;
- }
- }
- } else {
- callback = (callback == null && isString(collection))
- ? charAtCallback
- : lodash.createCallback(callback, thisArg, 3);
-
- baseEach(collection, function(value, index, collection) {
- var current = callback(value, index, collection);
- if (current > computed) {
- computed = current;
- result = value;
- }
- });
- }
- return result;
- }
-
- /**
- * Retrieves the minimum value of a collection. If the collection is empty or
- * falsey `Infinity` is returned. If a callback is provided it will be executed
- * for each value in the collection to generate the criterion by which the value
- * is ranked. The callback is bound to `thisArg` and invoked with three
- * arguments; (value, index, collection).
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {*} Returns the minimum value.
- * @example
- *
- * _.min([4, 2, 8, 6]);
- * // => 2
- *
- * var characters = [
- * { 'name': 'barney', 'age': 36 },
- * { 'name': 'fred', 'age': 40 }
- * ];
- *
- * _.min(characters, function(chr) { return chr.age; });
- * // => { 'name': 'barney', 'age': 36 };
- *
- * // using "_.pluck" callback shorthand
- * _.min(characters, 'age');
- * // => { 'name': 'barney', 'age': 36 };
- */
- function min(collection, callback, thisArg) {
- var computed = Infinity,
- result = computed;
-
- // allows working with functions like `_.map` without using
- // their `index` argument as a callback
- if (typeof callback != 'function' && thisArg && thisArg[callback] === collection) {
- callback = null;
- }
- if (callback == null && isArray(collection)) {
- var index = -1,
- length = collection.length;
-
- while (++index < length) {
- var value = collection[index];
- if (value < result) {
- result = value;
- }
- }
- } else {
- callback = (callback == null && isString(collection))
- ? charAtCallback
- : lodash.createCallback(callback, thisArg, 3);
-
- baseEach(collection, function(value, index, collection) {
- var current = callback(value, index, collection);
- if (current < computed) {
- computed = current;
- result = value;
- }
- });
- }
- return result;
- }
-
- /**
- * Retrieves the value of a specified property from all elements in the collection.
- *
- * @static
- * @memberOf _
- * @type Function
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {string} property The name of the property to pluck.
- * @returns {Array} Returns a new array of property values.
- * @example
- *
- * var characters = [
- * { 'name': 'barney', 'age': 36 },
- * { 'name': 'fred', 'age': 40 }
- * ];
- *
- * _.pluck(characters, 'name');
- * // => ['barney', 'fred']
- */
- var pluck = map;
-
- /**
- * Reduces a collection to a value which is the accumulated result of running
- * each element in the collection through the callback, where each successive
- * callback execution consumes the return value of the previous execution. If
- * `accumulator` is not provided the first element of the collection will be
- * used as the initial `accumulator` value. The callback is bound to `thisArg`
- * and invoked with four arguments; (accumulator, value, index|key, collection).
- *
- * @static
- * @memberOf _
- * @alias foldl, inject
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function} [callback=identity] The function called per iteration.
- * @param {*} [accumulator] Initial value of the accumulator.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {*} Returns the accumulated value.
- * @example
- *
- * var sum = _.reduce([1, 2, 3], function(sum, num) {
- * return sum + num;
- * });
- * // => 6
- *
- * var mapped = _.reduce({ 'a': 1, 'b': 2, 'c': 3 }, function(result, num, key) {
- * result[key] = num * 3;
- * return result;
- * }, {});
- * // => { 'a': 3, 'b': 6, 'c': 9 }
- */
- function reduce(collection, callback, accumulator, thisArg) {
- var noaccum = arguments.length < 3;
- callback = lodash.createCallback(callback, thisArg, 4);
-
- if (isArray(collection)) {
- var index = -1,
- length = collection.length;
-
- if (noaccum) {
- accumulator = collection[++index];
- }
- while (++index < length) {
- accumulator = callback(accumulator, collection[index], index, collection);
- }
- } else {
- baseEach(collection, function(value, index, collection) {
- accumulator = noaccum
- ? (noaccum = false, value)
- : callback(accumulator, value, index, collection)
- });
- }
- return accumulator;
- }
-
- /**
- * This method is like `_.reduce` except that it iterates over elements
- * of a `collection` from right to left.
- *
- * @static
- * @memberOf _
- * @alias foldr
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function} [callback=identity] The function called per iteration.
- * @param {*} [accumulator] Initial value of the accumulator.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {*} Returns the accumulated value.
- * @example
- *
- * var list = [[0, 1], [2, 3], [4, 5]];
- * var flat = _.reduceRight(list, function(a, b) { return a.concat(b); }, []);
- * // => [4, 5, 2, 3, 0, 1]
- */
- function reduceRight(collection, callback, accumulator, thisArg) {
- var noaccum = arguments.length < 3;
- callback = lodash.createCallback(callback, thisArg, 4);
- forEachRight(collection, function(value, index, collection) {
- accumulator = noaccum
- ? (noaccum = false, value)
- : callback(accumulator, value, index, collection);
- });
- return accumulator;
- }
-
- /**
- * The opposite of `_.filter` this method returns the elements of a
- * collection that the callback does **not** return truey for.
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Array} Returns a new array of elements that failed the callback check.
- * @example
- *
- * var odds = _.reject([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; });
- * // => [1, 3, 5]
- *
- * var characters = [
- * { 'name': 'barney', 'age': 36, 'blocked': false },
- * { 'name': 'fred', 'age': 40, 'blocked': true }
- * ];
- *
- * // using "_.pluck" callback shorthand
- * _.reject(characters, 'blocked');
- * // => [{ 'name': 'barney', 'age': 36, 'blocked': false }]
- *
- * // using "_.where" callback shorthand
- * _.reject(characters, { 'age': 36 });
- * // => [{ 'name': 'fred', 'age': 40, 'blocked': true }]
- */
- function reject(collection, callback, thisArg) {
- callback = lodash.createCallback(callback, thisArg, 3);
- return filter(collection, function(value, index, collection) {
- return !callback(value, index, collection);
- });
- }
-
- /**
- * Retrieves a random element or `n` random elements from a collection.
- *
- * @static
- * @memberOf _
- * @category Collections
- * @param {Array|Object|string} collection The collection to sample.
- * @param {number} [n] The number of elements to sample.
- * @param- {Object} [guard] Allows working with functions like `_.map`
- * without using their `index` arguments as `n`.
- * @returns {Array} Returns the random sample(s) of `collection`.
- * @example
- *
- * _.sample([1, 2, 3, 4]);
- * // => 2
- *
- * _.sample([1, 2, 3, 4], 2);
- * // => [3, 1]
- */
- function sample(collection, n, guard) {
- if (collection && typeof collection.length != 'number') {
- collection = values(collection);
- } else if (support.unindexedChars && isString(collection)) {
- collection = collection.split('');
- }
- if (n == null || guard) {
- return collection ? collection[baseRandom(0, collection.length - 1)] : undefined;
- }
- var result = shuffle(collection);
- result.length = nativeMin(nativeMax(0, n), result.length);
- return result;
- }
-
- /**
- * Creates an array of shuffled values, using a version of the Fisher-Yates
- * shuffle. See http://en.wikipedia.org/wiki/Fisher-Yates_shuffle.
- *
- * @static
- * @memberOf _
- * @category Collections
- * @param {Array|Object|string} collection The collection to shuffle.
- * @returns {Array} Returns a new shuffled collection.
- * @example
- *
- * _.shuffle([1, 2, 3, 4, 5, 6]);
- * // => [4, 1, 6, 3, 5, 2]
- */
- function shuffle(collection) {
- var index = -1,
- length = collection ? collection.length : 0,
- result = Array(typeof length == 'number' ? length : 0);
-
- forEach(collection, function(value) {
- var rand = baseRandom(0, ++index);
- result[index] = result[rand];
- result[rand] = value;
- });
- return result;
- }
-
- /**
- * Gets the size of the `collection` by returning `collection.length` for arrays
- * and array-like objects or the number of own enumerable properties for objects.
- *
- * @static
- * @memberOf _
- * @category Collections
- * @param {Array|Object|string} collection The collection to inspect.
- * @returns {number} Returns `collection.length` or number of own enumerable properties.
- * @example
- *
- * _.size([1, 2]);
- * // => 2
- *
- * _.size({ 'one': 1, 'two': 2, 'three': 3 });
- * // => 3
- *
- * _.size('pebbles');
- * // => 7
- */
- function size(collection) {
- var length = collection ? collection.length : 0;
- return typeof length == 'number' ? length : keys(collection).length;
- }
-
- /**
- * Checks if the callback returns a truey value for **any** element of a
- * collection. The function returns as soon as it finds a passing value and
- * does not iterate over the entire collection. The callback is bound to
- * `thisArg` and invoked with three arguments; (value, index|key, collection).
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @alias any
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {boolean} Returns `true` if any element passed the callback check,
- * else `false`.
- * @example
- *
- * _.some([null, 0, 'yes', false], Boolean);
- * // => true
- *
- * var characters = [
- * { 'name': 'barney', 'age': 36, 'blocked': false },
- * { 'name': 'fred', 'age': 40, 'blocked': true }
- * ];
- *
- * // using "_.pluck" callback shorthand
- * _.some(characters, 'blocked');
- * // => true
- *
- * // using "_.where" callback shorthand
- * _.some(characters, { 'age': 1 });
- * // => false
- */
- function some(collection, callback, thisArg) {
- var result;
- callback = lodash.createCallback(callback, thisArg, 3);
-
- if (isArray(collection)) {
- var index = -1,
- length = collection.length;
-
- while (++index < length) {
- if ((result = callback(collection[index], index, collection))) {
- break;
- }
- }
- } else {
- baseEach(collection, function(value, index, collection) {
- return !(result = callback(value, index, collection));
- });
- }
- return !!result;
- }
-
- /**
- * Creates an array of elements, sorted in ascending order by the results of
- * running each element in a collection through the callback. This method
- * performs a stable sort, that is, it will preserve the original sort order
- * of equal elements. The callback is bound to `thisArg` and invoked with
- * three arguments; (value, index|key, collection).
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an array of property names is provided for `callback` the collection
- * will be sorted by each property value.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Array|Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Array} Returns a new array of sorted elements.
- * @example
- *
- * _.sortBy([1, 2, 3], function(num) { return Math.sin(num); });
- * // => [3, 1, 2]
- *
- * _.sortBy([1, 2, 3], function(num) { return this.sin(num); }, Math);
- * // => [3, 1, 2]
- *
- * var characters = [
- * { 'name': 'barney', 'age': 36 },
- * { 'name': 'fred', 'age': 40 },
- * { 'name': 'barney', 'age': 26 },
- * { 'name': 'fred', 'age': 30 }
- * ];
- *
- * // using "_.pluck" callback shorthand
- * _.map(_.sortBy(characters, 'age'), _.values);
- * // => [['barney', 26], ['fred', 30], ['barney', 36], ['fred', 40]]
- *
- * // sorting by multiple properties
- * _.map(_.sortBy(characters, ['name', 'age']), _.values);
- * // = > [['barney', 26], ['barney', 36], ['fred', 30], ['fred', 40]]
- */
- function sortBy(collection, callback, thisArg) {
- var index = -1,
- isArr = isArray(callback),
- length = collection ? collection.length : 0,
- result = Array(typeof length == 'number' ? length : 0);
-
- if (!isArr) {
- callback = lodash.createCallback(callback, thisArg, 3);
- }
- forEach(collection, function(value, key, collection) {
- var object = result[++index] = getObject();
- if (isArr) {
- object.criteria = map(callback, function(key) { return value[key]; });
- } else {
- (object.criteria = getArray())[0] = callback(value, key, collection);
- }
- object.index = index;
- object.value = value;
- });
-
- length = result.length;
- result.sort(compareAscending);
- while (length--) {
- var object = result[length];
- result[length] = object.value;
- if (!isArr) {
- releaseArray(object.criteria);
- }
- releaseObject(object);
- }
- return result;
- }
-
- /**
- * Converts the `collection` to an array.
- *
- * @static
- * @memberOf _
- * @category Collections
- * @param {Array|Object|string} collection The collection to convert.
- * @returns {Array} Returns the new converted array.
- * @example
- *
- * (function() { return _.toArray(arguments).slice(1); })(1, 2, 3, 4);
- * // => [2, 3, 4]
- */
- function toArray(collection) {
- if (collection && typeof collection.length == 'number') {
- return (support.unindexedChars && isString(collection))
- ? collection.split('')
- : slice(collection);
- }
- return values(collection);
- }
-
- /**
- * Performs a deep comparison of each element in a `collection` to the given
- * `properties` object, returning an array of all elements that have equivalent
- * property values.
- *
- * @static
- * @memberOf _
- * @type Function
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Object} props The object of property values to filter by.
- * @returns {Array} Returns a new array of elements that have the given properties.
- * @example
- *
- * var characters = [
- * { 'name': 'barney', 'age': 36, 'pets': ['hoppy'] },
- * { 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] }
- * ];
- *
- * _.where(characters, { 'age': 36 });
- * // => [{ 'name': 'barney', 'age': 36, 'pets': ['hoppy'] }]
- *
- * _.where(characters, { 'pets': ['dino'] });
- * // => [{ 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] }]
- */
- var where = filter;
-
- /*--------------------------------------------------------------------------*/
-
- /**
- * Creates an array with all falsey values removed. The values `false`, `null`,
- * `0`, `""`, `undefined`, and `NaN` are all falsey.
- *
- * @static
- * @memberOf _
- * @category Arrays
- * @param {Array} array The array to compact.
- * @returns {Array} Returns a new array of filtered values.
- * @example
- *
- * _.compact([0, 1, false, 2, '', 3]);
- * // => [1, 2, 3]
- */
- function compact(array) {
- var index = -1,
- length = array ? array.length : 0,
- result = [];
-
- while (++index < length) {
- var value = array[index];
- if (value) {
- result.push(value);
- }
- }
- return result;
- }
-
- /**
- * Creates an array excluding all values of the provided arrays using strict
- * equality for comparisons, i.e. `===`.
- *
- * @static
- * @memberOf _
- * @category Arrays
- * @param {Array} array The array to process.
- * @param {...Array} [values] The arrays of values to exclude.
- * @returns {Array} Returns a new array of filtered values.
- * @example
- *
- * _.difference([1, 2, 3, 4, 5], [5, 2, 10]);
- * // => [1, 3, 4]
- */
- function difference(array) {
- return baseDifference(array, baseFlatten(arguments, true, true, 1));
- }
-
- /**
- * This method is like `_.find` except that it returns the index of the first
- * element that passes the callback check, instead of the element itself.
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @category Arrays
- * @param {Array} array The array to search.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {number} Returns the index of the found element, else `-1`.
- * @example
- *
- * var characters = [
- * { 'name': 'barney', 'age': 36, 'blocked': false },
- * { 'name': 'fred', 'age': 40, 'blocked': true },
- * { 'name': 'pebbles', 'age': 1, 'blocked': false }
- * ];
- *
- * _.findIndex(characters, function(chr) {
- * return chr.age < 20;
- * });
- * // => 2
- *
- * // using "_.where" callback shorthand
- * _.findIndex(characters, { 'age': 36 });
- * // => 0
- *
- * // using "_.pluck" callback shorthand
- * _.findIndex(characters, 'blocked');
- * // => 1
- */
- function findIndex(array, callback, thisArg) {
- var index = -1,
- length = array ? array.length : 0;
-
- callback = lodash.createCallback(callback, thisArg, 3);
- while (++index < length) {
- if (callback(array[index], index, array)) {
- return index;
- }
- }
- return -1;
- }
-
- /**
- * This method is like `_.findIndex` except that it iterates over elements
- * of a `collection` from right to left.
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @category Arrays
- * @param {Array} array The array to search.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {number} Returns the index of the found element, else `-1`.
- * @example
- *
- * var characters = [
- * { 'name': 'barney', 'age': 36, 'blocked': true },
- * { 'name': 'fred', 'age': 40, 'blocked': false },
- * { 'name': 'pebbles', 'age': 1, 'blocked': true }
- * ];
- *
- * _.findLastIndex(characters, function(chr) {
- * return chr.age > 30;
- * });
- * // => 1
- *
- * // using "_.where" callback shorthand
- * _.findLastIndex(characters, { 'age': 36 });
- * // => 0
- *
- * // using "_.pluck" callback shorthand
- * _.findLastIndex(characters, 'blocked');
- * // => 2
- */
- function findLastIndex(array, callback, thisArg) {
- var length = array ? array.length : 0;
- callback = lodash.createCallback(callback, thisArg, 3);
- while (length--) {
- if (callback(array[length], length, array)) {
- return length;
- }
- }
- return -1;
- }
-
- /**
- * Gets the first element or first `n` elements of an array. If a callback
- * is provided elements at the beginning of the array are returned as long
- * as the callback returns truey. The callback is bound to `thisArg` and
- * invoked with three arguments; (value, index, array).
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @alias head, take
- * @category Arrays
- * @param {Array} array The array to query.
- * @param {Function|Object|number|string} [callback] The function called
- * per element or the number of elements to return. If a property name or
- * object is provided it will be used to create a "_.pluck" or "_.where"
- * style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {*} Returns the first element(s) of `array`.
- * @example
- *
- * _.first([1, 2, 3]);
- * // => 1
- *
- * _.first([1, 2, 3], 2);
- * // => [1, 2]
- *
- * _.first([1, 2, 3], function(num) {
- * return num < 3;
- * });
- * // => [1, 2]
- *
- * var characters = [
- * { 'name': 'barney', 'blocked': true, 'employer': 'slate' },
- * { 'name': 'fred', 'blocked': false, 'employer': 'slate' },
- * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' }
- * ];
- *
- * // using "_.pluck" callback shorthand
- * _.first(characters, 'blocked');
- * // => [{ 'name': 'barney', 'blocked': true, 'employer': 'slate' }]
- *
- * // using "_.where" callback shorthand
- * _.pluck(_.first(characters, { 'employer': 'slate' }), 'name');
- * // => ['barney', 'fred']
- */
- function first(array, callback, thisArg) {
- var n = 0,
- length = array ? array.length : 0;
-
- if (typeof callback != 'number' && callback != null) {
- var index = -1;
- callback = lodash.createCallback(callback, thisArg, 3);
- while (++index < length && callback(array[index], index, array)) {
- n++;
- }
- } else {
- n = callback;
- if (n == null || thisArg) {
- return array ? array[0] : undefined;
- }
- }
- return slice(array, 0, nativeMin(nativeMax(0, n), length));
- }
-
- /**
- * Flattens a nested array (the nesting can be to any depth). If `isShallow`
- * is truey, the array will only be flattened a single level. If a callback
- * is provided each element of the array is passed through the callback before
- * flattening. The callback is bound to `thisArg` and invoked with three
- * arguments; (value, index, array).
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @category Arrays
- * @param {Array} array The array to flatten.
- * @param {boolean} [isShallow=false] A flag to restrict flattening to a single level.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Array} Returns a new flattened array.
- * @example
- *
- * _.flatten([1, [2], [3, [[4]]]]);
- * // => [1, 2, 3, 4];
- *
- * _.flatten([1, [2], [3, [[4]]]], true);
- * // => [1, 2, 3, [[4]]];
- *
- * var characters = [
- * { 'name': 'barney', 'age': 30, 'pets': ['hoppy'] },
- * { 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] }
- * ];
- *
- * // using "_.pluck" callback shorthand
- * _.flatten(characters, 'pets');
- * // => ['hoppy', 'baby puss', 'dino']
- */
- function flatten(array, isShallow, callback, thisArg) {
- // juggle arguments
- if (typeof isShallow != 'boolean' && isShallow != null) {
- thisArg = callback;
- callback = (typeof isShallow != 'function' && thisArg && thisArg[isShallow] === array) ? null : isShallow;
- isShallow = false;
- }
- if (callback != null) {
- array = map(array, callback, thisArg);
- }
- return baseFlatten(array, isShallow);
- }
-
- /**
- * Gets the index at which the first occurrence of `value` is found using
- * strict equality for comparisons, i.e. `===`. If the array is already sorted
- * providing `true` for `fromIndex` will run a faster binary search.
- *
- * @static
- * @memberOf _
- * @category Arrays
- * @param {Array} array The array to search.
- * @param {*} value The value to search for.
- * @param {boolean|number} [fromIndex=0] The index to search from or `true`
- * to perform a binary search on a sorted array.
- * @returns {number} Returns the index of the matched value or `-1`.
- * @example
- *
- * _.indexOf([1, 2, 3, 1, 2, 3], 2);
- * // => 1
- *
- * _.indexOf([1, 2, 3, 1, 2, 3], 2, 3);
- * // => 4
- *
- * _.indexOf([1, 1, 2, 2, 3, 3], 2, true);
- * // => 2
- */
- function indexOf(array, value, fromIndex) {
- if (typeof fromIndex == 'number') {
- var length = array ? array.length : 0;
- fromIndex = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex || 0);
- } else if (fromIndex) {
- var index = sortedIndex(array, value);
- return array[index] === value ? index : -1;
- }
- return baseIndexOf(array, value, fromIndex);
- }
-
- /**
- * Gets all but the last element or last `n` elements of an array. If a
- * callback is provided elements at the end of the array are excluded from
- * the result as long as the callback returns truey. The callback is bound
- * to `thisArg` and invoked with three arguments; (value, index, array).
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @category Arrays
- * @param {Array} array The array to query.
- * @param {Function|Object|number|string} [callback=1] The function called
- * per element or the number of elements to exclude. If a property name or
- * object is provided it will be used to create a "_.pluck" or "_.where"
- * style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Array} Returns a slice of `array`.
- * @example
- *
- * _.initial([1, 2, 3]);
- * // => [1, 2]
- *
- * _.initial([1, 2, 3], 2);
- * // => [1]
- *
- * _.initial([1, 2, 3], function(num) {
- * return num > 1;
- * });
- * // => [1]
- *
- * var characters = [
- * { 'name': 'barney', 'blocked': false, 'employer': 'slate' },
- * { 'name': 'fred', 'blocked': true, 'employer': 'slate' },
- * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' }
- * ];
- *
- * // using "_.pluck" callback shorthand
- * _.initial(characters, 'blocked');
- * // => [{ 'name': 'barney', 'blocked': false, 'employer': 'slate' }]
- *
- * // using "_.where" callback shorthand
- * _.pluck(_.initial(characters, { 'employer': 'na' }), 'name');
- * // => ['barney', 'fred']
- */
- function initial(array, callback, thisArg) {
- var n = 0,
- length = array ? array.length : 0;
-
- if (typeof callback != 'number' && callback != null) {
- var index = length;
- callback = lodash.createCallback(callback, thisArg, 3);
- while (index-- && callback(array[index], index, array)) {
- n++;
- }
- } else {
- n = (callback == null || thisArg) ? 1 : callback || n;
- }
- return slice(array, 0, nativeMin(nativeMax(0, length - n), length));
- }
-
- /**
- * Creates an array of unique values present in all provided arrays using
- * strict equality for comparisons, i.e. `===`.
- *
- * @static
- * @memberOf _
- * @category Arrays
- * @param {...Array} [array] The arrays to inspect.
- * @returns {Array} Returns an array of shared values.
- * @example
- *
- * _.intersection([1, 2, 3], [5, 2, 1, 4], [2, 1]);
- * // => [1, 2]
- */
- function intersection() {
- var args = [],
- argsIndex = -1,
- argsLength = arguments.length,
- caches = getArray(),
- indexOf = getIndexOf(),
- trustIndexOf = indexOf === baseIndexOf,
- seen = getArray();
-
- while (++argsIndex < argsLength) {
- var value = arguments[argsIndex];
- if (isArray(value) || isArguments(value)) {
- args.push(value);
- caches.push(trustIndexOf && value.length >= largeArraySize &&
- createCache(argsIndex ? args[argsIndex] : seen));
- }
- }
- var array = args[0],
- index = -1,
- length = array ? array.length : 0,
- result = [];
-
- outer:
- while (++index < length) {
- var cache = caches[0];
- value = array[index];
-
- if ((cache ? cacheIndexOf(cache, value) : indexOf(seen, value)) < 0) {
- argsIndex = argsLength;
- (cache || seen).push(value);
- while (--argsIndex) {
- cache = caches[argsIndex];
- if ((cache ? cacheIndexOf(cache, value) : indexOf(args[argsIndex], value)) < 0) {
- continue outer;
- }
- }
- result.push(value);
- }
- }
- while (argsLength--) {
- cache = caches[argsLength];
- if (cache) {
- releaseObject(cache);
- }
- }
- releaseArray(caches);
- releaseArray(seen);
- return result;
- }
-
- /**
- * Gets the last element or last `n` elements of an array. If a callback is
- * provided elements at the end of the array are returned as long as the
- * callback returns truey. The callback is bound to `thisArg` and invoked
- * with three arguments; (value, index, array).
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @category Arrays
- * @param {Array} array The array to query.
- * @param {Function|Object|number|string} [callback] The function called
- * per element or the number of elements to return. If a property name or
- * object is provided it will be used to create a "_.pluck" or "_.where"
- * style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {*} Returns the last element(s) of `array`.
- * @example
- *
- * _.last([1, 2, 3]);
- * // => 3
- *
- * _.last([1, 2, 3], 2);
- * // => [2, 3]
- *
- * _.last([1, 2, 3], function(num) {
- * return num > 1;
- * });
- * // => [2, 3]
- *
- * var characters = [
- * { 'name': 'barney', 'blocked': false, 'employer': 'slate' },
- * { 'name': 'fred', 'blocked': true, 'employer': 'slate' },
- * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' }
- * ];
- *
- * // using "_.pluck" callback shorthand
- * _.pluck(_.last(characters, 'blocked'), 'name');
- * // => ['fred', 'pebbles']
- *
- * // using "_.where" callback shorthand
- * _.last(characters, { 'employer': 'na' });
- * // => [{ 'name': 'pebbles', 'blocked': true, 'employer': 'na' }]
- */
- function last(array, callback, thisArg) {
- var n = 0,
- length = array ? array.length : 0;
-
- if (typeof callback != 'number' && callback != null) {
- var index = length;
- callback = lodash.createCallback(callback, thisArg, 3);
- while (index-- && callback(array[index], index, array)) {
- n++;
- }
- } else {
- n = callback;
- if (n == null || thisArg) {
- return array ? array[length - 1] : undefined;
- }
- }
- return slice(array, nativeMax(0, length - n));
- }
-
- /**
- * Gets the index at which the last occurrence of `value` is found using strict
- * equality for comparisons, i.e. `===`. If `fromIndex` is negative, it is used
- * as the offset from the end of the collection.
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @category Arrays
- * @param {Array} array The array to search.
- * @param {*} value The value to search for.
- * @param {number} [fromIndex=array.length-1] The index to search from.
- * @returns {number} Returns the index of the matched value or `-1`.
- * @example
- *
- * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2);
- * // => 4
- *
- * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2, 3);
- * // => 1
- */
- function lastIndexOf(array, value, fromIndex) {
- var index = array ? array.length : 0;
- if (typeof fromIndex == 'number') {
- index = (fromIndex < 0 ? nativeMax(0, index + fromIndex) : nativeMin(fromIndex, index - 1)) + 1;
- }
- while (index--) {
- if (array[index] === value) {
- return index;
- }
- }
- return -1;
- }
-
- /**
- * Removes all provided values from the given array using strict equality for
- * comparisons, i.e. `===`.
- *
- * @static
- * @memberOf _
- * @category Arrays
- * @param {Array} array The array to modify.
- * @param {...*} [value] The values to remove.
- * @returns {Array} Returns `array`.
- * @example
- *
- * var array = [1, 2, 3, 1, 2, 3];
- * _.pull(array, 2, 3);
- * console.log(array);
- * // => [1, 1]
- */
- function pull(array) {
- var args = arguments,
- argsIndex = 0,
- argsLength = args.length,
- length = array ? array.length : 0;
-
- while (++argsIndex < argsLength) {
- var index = -1,
- value = args[argsIndex];
- while (++index < length) {
- if (array[index] === value) {
- splice.call(array, index--, 1);
- length--;
- }
- }
- }
- return array;
- }
-
- /**
- * Creates an array of numbers (positive and/or negative) progressing from
- * `start` up to but not including `end`. If `start` is less than `stop` a
- * zero-length range is created unless a negative `step` is specified.
- *
- * @static
- * @memberOf _
- * @category Arrays
- * @param {number} [start=0] The start of the range.
- * @param {number} end The end of the range.
- * @param {number} [step=1] The value to increment or decrement by.
- * @returns {Array} Returns a new range array.
- * @example
- *
- * _.range(4);
- * // => [0, 1, 2, 3]
- *
- * _.range(1, 5);
- * // => [1, 2, 3, 4]
- *
- * _.range(0, 20, 5);
- * // => [0, 5, 10, 15]
- *
- * _.range(0, -4, -1);
- * // => [0, -1, -2, -3]
- *
- * _.range(1, 4, 0);
- * // => [1, 1, 1]
- *
- * _.range(0);
- * // => []
- */
- function range(start, end, step) {
- start = +start || 0;
- step = typeof step == 'number' ? step : (+step || 1);
-
- if (end == null) {
- end = start;
- start = 0;
- }
- // use `Array(length)` so engines like Chakra and V8 avoid slower modes
- // http://youtu.be/XAqIpGU8ZZk#t=17m25s
- var index = -1,
- length = nativeMax(0, ceil((end - start) / (step || 1))),
- result = Array(length);
-
- while (++index < length) {
- result[index] = start;
- start += step;
- }
- return result;
- }
-
- /**
- * Removes all elements from an array that the callback returns truey for
- * and returns an array of removed elements. The callback is bound to `thisArg`
- * and invoked with three arguments; (value, index, array).
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @category Arrays
- * @param {Array} array The array to modify.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Array} Returns a new array of removed elements.
- * @example
- *
- * var array = [1, 2, 3, 4, 5, 6];
- * var evens = _.remove(array, function(num) { return num % 2 == 0; });
- *
- * console.log(array);
- * // => [1, 3, 5]
- *
- * console.log(evens);
- * // => [2, 4, 6]
- */
- function remove(array, callback, thisArg) {
- var index = -1,
- length = array ? array.length : 0,
- result = [];
-
- callback = lodash.createCallback(callback, thisArg, 3);
- while (++index < length) {
- var value = array[index];
- if (callback(value, index, array)) {
- result.push(value);
- splice.call(array, index--, 1);
- length--;
- }
- }
- return result;
- }
-
- /**
- * The opposite of `_.initial` this method gets all but the first element or
- * first `n` elements of an array. If a callback function is provided elements
- * at the beginning of the array are excluded from the result as long as the
- * callback returns truey. The callback is bound to `thisArg` and invoked
- * with three arguments; (value, index, array).
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @alias drop, tail
- * @category Arrays
- * @param {Array} array The array to query.
- * @param {Function|Object|number|string} [callback=1] The function called
- * per element or the number of elements to exclude. If a property name or
- * object is provided it will be used to create a "_.pluck" or "_.where"
- * style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Array} Returns a slice of `array`.
- * @example
- *
- * _.rest([1, 2, 3]);
- * // => [2, 3]
- *
- * _.rest([1, 2, 3], 2);
- * // => [3]
- *
- * _.rest([1, 2, 3], function(num) {
- * return num < 3;
- * });
- * // => [3]
- *
- * var characters = [
- * { 'name': 'barney', 'blocked': true, 'employer': 'slate' },
- * { 'name': 'fred', 'blocked': false, 'employer': 'slate' },
- * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' }
- * ];
- *
- * // using "_.pluck" callback shorthand
- * _.pluck(_.rest(characters, 'blocked'), 'name');
- * // => ['fred', 'pebbles']
- *
- * // using "_.where" callback shorthand
- * _.rest(characters, { 'employer': 'slate' });
- * // => [{ 'name': 'pebbles', 'blocked': true, 'employer': 'na' }]
- */
- function rest(array, callback, thisArg) {
- if (typeof callback != 'number' && callback != null) {
- var n = 0,
- index = -1,
- length = array ? array.length : 0;
-
- callback = lodash.createCallback(callback, thisArg, 3);
- while (++index < length && callback(array[index], index, array)) {
- n++;
- }
- } else {
- n = (callback == null || thisArg) ? 1 : nativeMax(0, callback);
- }
- return slice(array, n);
- }
-
- /**
- * Uses a binary search to determine the smallest index at which a value
- * should be inserted into a given sorted array in order to maintain the sort
- * order of the array. If a callback is provided it will be executed for
- * `value` and each element of `array` to compute their sort ranking. The
- * callback is bound to `thisArg` and invoked with one argument; (value).
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @category Arrays
- * @param {Array} array The array to inspect.
- * @param {*} value The value to evaluate.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {number} Returns the index at which `value` should be inserted
- * into `array`.
- * @example
- *
- * _.sortedIndex([20, 30, 50], 40);
- * // => 2
- *
- * // using "_.pluck" callback shorthand
- * _.sortedIndex([{ 'x': 20 }, { 'x': 30 }, { 'x': 50 }], { 'x': 40 }, 'x');
- * // => 2
- *
- * var dict = {
- * 'wordToNumber': { 'twenty': 20, 'thirty': 30, 'fourty': 40, 'fifty': 50 }
- * };
- *
- * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) {
- * return dict.wordToNumber[word];
- * });
- * // => 2
- *
- * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) {
- * return this.wordToNumber[word];
- * }, dict);
- * // => 2
- */
- function sortedIndex(array, value, callback, thisArg) {
- var low = 0,
- high = array ? array.length : low;
-
- // explicitly reference `identity` for better inlining in Firefox
- callback = callback ? lodash.createCallback(callback, thisArg, 1) : identity;
- value = callback(value);
-
- while (low < high) {
- var mid = (low + high) >>> 1;
- (callback(array[mid]) < value)
- ? low = mid + 1
- : high = mid;
- }
- return low;
- }
-
- /**
- * Creates an array of unique values, in order, of the provided arrays using
- * strict equality for comparisons, i.e. `===`.
- *
- * @static
- * @memberOf _
- * @category Arrays
- * @param {...Array} [array] The arrays to inspect.
- * @returns {Array} Returns an array of combined values.
- * @example
- *
- * _.union([1, 2, 3], [5, 2, 1, 4], [2, 1]);
- * // => [1, 2, 3, 5, 4]
- */
- function union() {
- return baseUniq(baseFlatten(arguments, true, true));
- }
-
- /**
- * Creates a duplicate-value-free version of an array using strict equality
- * for comparisons, i.e. `===`. If the array is sorted, providing
- * `true` for `isSorted` will use a faster algorithm. If a callback is provided
- * each element of `array` is passed through the callback before uniqueness
- * is computed. The callback is bound to `thisArg` and invoked with three
- * arguments; (value, index, array).
- *
- * If a property name is provided for `callback` the created "_.pluck" style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style callback
- * will return `true` for elements that have the properties of the given object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @alias unique
- * @category Arrays
- * @param {Array} array The array to process.
- * @param {boolean} [isSorted=false] A flag to indicate that `array` is sorted.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Array} Returns a duplicate-value-free array.
- * @example
- *
- * _.uniq([1, 2, 1, 3, 1]);
- * // => [1, 2, 3]
- *
- * _.uniq([1, 1, 2, 2, 3], true);
- * // => [1, 2, 3]
- *
- * _.uniq(['A', 'b', 'C', 'a', 'B', 'c'], function(letter) { return letter.toLowerCase(); });
- * // => ['A', 'b', 'C']
- *
- * _.uniq([1, 2.5, 3, 1.5, 2, 3.5], function(num) { return this.floor(num); }, Math);
- * // => [1, 2.5, 3]
- *
- * // using "_.pluck" callback shorthand
- * _.uniq([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');
- * // => [{ 'x': 1 }, { 'x': 2 }]
- */
- function uniq(array, isSorted, callback, thisArg) {
- // juggle arguments
- if (typeof isSorted != 'boolean' && isSorted != null) {
- thisArg = callback;
- callback = (typeof isSorted != 'function' && thisArg && thisArg[isSorted] === array) ? null : isSorted;
- isSorted = false;
- }
- if (callback != null) {
- callback = lodash.createCallback(callback, thisArg, 3);
- }
- return baseUniq(array, isSorted, callback);
- }
-
- /**
- * Creates an array excluding all provided values using strict equality for
- * comparisons, i.e. `===`.
- *
- * @static
- * @memberOf _
- * @category Arrays
- * @param {Array} array The array to filter.
- * @param {...*} [value] The values to exclude.
- * @returns {Array} Returns a new array of filtered values.
- * @example
- *
- * _.without([1, 2, 1, 0, 3, 1, 4], 0, 1);
- * // => [2, 3, 4]
- */
- function without(array) {
- return baseDifference(array, slice(arguments, 1));
- }
-
- /**
- * Creates an array that is the symmetric difference of the provided arrays.
- * See http://en.wikipedia.org/wiki/Symmetric_difference.
- *
- * @static
- * @memberOf _
- * @category Arrays
- * @param {...Array} [array] The arrays to inspect.
- * @returns {Array} Returns an array of values.
- * @example
- *
- * _.xor([1, 2, 3], [5, 2, 1, 4]);
- * // => [3, 5, 4]
- *
- * _.xor([1, 2, 5], [2, 3, 5], [3, 4, 5]);
- * // => [1, 4, 5]
- */
- function xor() {
- var index = -1,
- length = arguments.length;
-
- while (++index < length) {
- var array = arguments[index];
- if (isArray(array) || isArguments(array)) {
- var result = result
- ? baseUniq(baseDifference(result, array).concat(baseDifference(array, result)))
- : array;
- }
- }
- return result || [];
- }
-
- /**
- * Creates an array of grouped elements, the first of which contains the first
- * elements of the given arrays, the second of which contains the second
- * elements of the given arrays, and so on.
- *
- * @static
- * @memberOf _
- * @alias unzip
- * @category Arrays
- * @param {...Array} [array] Arrays to process.
- * @returns {Array} Returns a new array of grouped elements.
- * @example
- *
- * _.zip(['fred', 'barney'], [30, 40], [true, false]);
- * // => [['fred', 30, true], ['barney', 40, false]]
- */
- function zip() {
- var array = arguments.length > 1 ? arguments : arguments[0],
- index = -1,
- length = array ? max(pluck(array, 'length')) : 0,
- result = Array(length < 0 ? 0 : length);
-
- while (++index < length) {
- result[index] = pluck(array, index);
- }
- return result;
- }
-
- /**
- * Creates an object composed from arrays of `keys` and `values`. Provide
- * either a single two dimensional array, i.e. `[[key1, value1], [key2, value2]]`
- * or two arrays, one of `keys` and one of corresponding `values`.
- *
- * @static
- * @memberOf _
- * @alias object
- * @category Arrays
- * @param {Array} keys The array of keys.
- * @param {Array} [values=[]] The array of values.
- * @returns {Object} Returns an object composed of the given keys and
- * corresponding values.
- * @example
- *
- * _.zipObject(['fred', 'barney'], [30, 40]);
- * // => { 'fred': 30, 'barney': 40 }
- */
- function zipObject(keys, values) {
- var index = -1,
- length = keys ? keys.length : 0,
- result = {};
-
- if (!values && length && !isArray(keys[0])) {
- values = [];
- }
- while (++index < length) {
- var key = keys[index];
- if (values) {
- result[key] = values[index];
- } else if (key) {
- result[key[0]] = key[1];
- }
- }
- return result;
- }
-
- /*--------------------------------------------------------------------------*/
-
- /**
- * Creates a function that executes `func`, with the `this` binding and
- * arguments of the created function, only after being called `n` times.
- *
- * @static
- * @memberOf _
- * @category Functions
- * @param {number} n The number of times the function must be called before
- * `func` is executed.
- * @param {Function} func The function to restrict.
- * @returns {Function} Returns the new restricted function.
- * @example
- *
- * var saves = ['profile', 'settings'];
- *
- * var done = _.after(saves.length, function() {
- * console.log('Done saving!');
- * });
- *
- * _.forEach(saves, function(type) {
- * asyncSave({ 'type': type, 'complete': done });
- * });
- * // => logs 'Done saving!', after all saves have completed
- */
- function after(n, func) {
- if (!isFunction(func)) {
- throw new TypeError;
- }
- return function() {
- if (--n < 1) {
- return func.apply(this, arguments);
- }
- };
- }
-
- /**
- * Creates a function that, when called, invokes `func` with the `this`
- * binding of `thisArg` and prepends any additional `bind` arguments to those
- * provided to the bound function.
- *
- * @static
- * @memberOf _
- * @category Functions
- * @param {Function} func The function to bind.
- * @param {*} [thisArg] The `this` binding of `func`.
- * @param {...*} [arg] Arguments to be partially applied.
- * @returns {Function} Returns the new bound function.
- * @example
- *
- * var func = function(greeting) {
- * return greeting + ' ' + this.name;
- * };
- *
- * func = _.bind(func, { 'name': 'fred' }, 'hi');
- * func();
- * // => 'hi fred'
- */
- function bind(func, thisArg) {
- return arguments.length > 2
- ? createWrapper(func, 17, slice(arguments, 2), null, thisArg)
- : createWrapper(func, 1, null, null, thisArg);
- }
-
- /**
- * Binds methods of an object to the object itself, overwriting the existing
- * method. Method names may be specified as individual arguments or as arrays
- * of method names. If no method names are provided all the function properties
- * of `object` will be bound.
- *
- * @static
- * @memberOf _
- * @category Functions
- * @param {Object} object The object to bind and assign the bound methods to.
- * @param {...string} [methodName] The object method names to
- * bind, specified as individual method names or arrays of method names.
- * @returns {Object} Returns `object`.
- * @example
- *
- * var view = {
- * 'label': 'docs',
- * 'onClick': function() { console.log('clicked ' + this.label); }
- * };
- *
- * _.bindAll(view);
- * jQuery('#docs').on('click', view.onClick);
- * // => logs 'clicked docs', when the button is clicked
- */
- function bindAll(object) {
- var funcs = arguments.length > 1 ? baseFlatten(arguments, true, false, 1) : functions(object),
- index = -1,
- length = funcs.length;
-
- while (++index < length) {
- var key = funcs[index];
- object[key] = createWrapper(object[key], 1, null, null, object);
- }
- return object;
- }
-
- /**
- * Creates a function that, when called, invokes the method at `object[key]`
- * and prepends any additional `bindKey` arguments to those provided to the bound
- * function. This method differs from `_.bind` by allowing bound functions to
- * reference methods that will be redefined or don't yet exist.
- * See http://michaux.ca/articles/lazy-function-definition-pattern.
- *
- * @static
- * @memberOf _
- * @category Functions
- * @param {Object} object The object the method belongs to.
- * @param {string} key The key of the method.
- * @param {...*} [arg] Arguments to be partially applied.
- * @returns {Function} Returns the new bound function.
- * @example
- *
- * var object = {
- * 'name': 'fred',
- * 'greet': function(greeting) {
- * return greeting + ' ' + this.name;
- * }
- * };
- *
- * var func = _.bindKey(object, 'greet', 'hi');
- * func();
- * // => 'hi fred'
- *
- * object.greet = function(greeting) {
- * return greeting + 'ya ' + this.name + '!';
- * };
- *
- * func();
- * // => 'hiya fred!'
- */
- function bindKey(object, key) {
- return arguments.length > 2
- ? createWrapper(key, 19, slice(arguments, 2), null, object)
- : createWrapper(key, 3, null, null, object);
- }
-
- /**
- * Creates a function that is the composition of the provided functions,
- * where each function consumes the return value of the function that follows.
- * For example, composing the functions `f()`, `g()`, and `h()` produces `f(g(h()))`.
- * Each function is executed with the `this` binding of the composed function.
- *
- * @static
- * @memberOf _
- * @category Functions
- * @param {...Function} [func] Functions to compose.
- * @returns {Function} Returns the new composed function.
- * @example
- *
- * var realNameMap = {
- * 'pebbles': 'penelope'
- * };
- *
- * var format = function(name) {
- * name = realNameMap[name.toLowerCase()] || name;
- * return name.charAt(0).toUpperCase() + name.slice(1).toLowerCase();
- * };
- *
- * var greet = function(formatted) {
- * return 'Hiya ' + formatted + '!';
- * };
- *
- * var welcome = _.compose(greet, format);
- * welcome('pebbles');
- * // => 'Hiya Penelope!'
- */
- function compose() {
- var funcs = arguments,
- length = funcs.length;
-
- while (length--) {
- if (!isFunction(funcs[length])) {
- throw new TypeError;
- }
- }
- return function() {
- var args = arguments,
- length = funcs.length;
-
- while (length--) {
- args = [funcs[length].apply(this, args)];
- }
- return args[0];
- };
- }
-
- /**
- * Creates a function which accepts one or more arguments of `func` that when
- * invoked either executes `func` returning its result, if all `func` arguments
- * have been provided, or returns a function that accepts one or more of the
- * remaining `func` arguments, and so on. The arity of `func` can be specified
- * if `func.length` is not sufficient.
- *
- * @static
- * @memberOf _
- * @category Functions
- * @param {Function} func The function to curry.
- * @param {number} [arity=func.length] The arity of `func`.
- * @returns {Function} Returns the new curried function.
- * @example
- *
- * var curried = _.curry(function(a, b, c) {
- * console.log(a + b + c);
- * });
- *
- * curried(1)(2)(3);
- * // => 6
- *
- * curried(1, 2)(3);
- * // => 6
- *
- * curried(1, 2, 3);
- * // => 6
- */
- function curry(func, arity) {
- arity = typeof arity == 'number' ? arity : (+arity || func.length);
- return createWrapper(func, 4, null, null, null, arity);
- }
-
- /**
- * Creates a function that will delay the execution of `func` until after
- * `wait` milliseconds have elapsed since the last time it was invoked.
- * Provide an options object to indicate that `func` should be invoked on
- * the leading and/or trailing edge of the `wait` timeout. Subsequent calls
- * to the debounced function will return the result of the last `func` call.
- *
- * Note: If `leading` and `trailing` options are `true` `func` will be called
- * on the trailing edge of the timeout only if the the debounced function is
- * invoked more than once during the `wait` timeout.
- *
- * @static
- * @memberOf _
- * @category Functions
- * @param {Function} func The function to debounce.
- * @param {number} wait The number of milliseconds to delay.
- * @param {Object} [options] The options object.
- * @param {boolean} [options.leading=false] Specify execution on the leading edge of the timeout.
- * @param {number} [options.maxWait] The maximum time `func` is allowed to be delayed before it's called.
- * @param {boolean} [options.trailing=true] Specify execution on the trailing edge of the timeout.
- * @returns {Function} Returns the new debounced function.
- * @example
- *
- * // avoid costly calculations while the window size is in flux
- * var lazyLayout = _.debounce(calculateLayout, 150);
- * jQuery(window).on('resize', lazyLayout);
- *
- * // execute `sendMail` when the click event is fired, debouncing subsequent calls
- * jQuery('#postbox').on('click', _.debounce(sendMail, 300, {
- * 'leading': true,
- * 'trailing': false
- * });
- *
- * // ensure `batchLog` is executed once after 1 second of debounced calls
- * var source = new EventSource('/stream');
- * source.addEventListener('message', _.debounce(batchLog, 250, {
- * 'maxWait': 1000
- * }, false);
- */
- function debounce(func, wait, options) {
- var args,
- maxTimeoutId,
- result,
- stamp,
- thisArg,
- timeoutId,
- trailingCall,
- lastCalled = 0,
- maxWait = false,
- trailing = true;
-
- if (!isFunction(func)) {
- throw new TypeError;
- }
- wait = nativeMax(0, wait) || 0;
- if (options === true) {
- var leading = true;
- trailing = false;
- } else if (isObject(options)) {
- leading = options.leading;
- maxWait = 'maxWait' in options && (nativeMax(wait, options.maxWait) || 0);
- trailing = 'trailing' in options ? options.trailing : trailing;
- }
- var delayed = function() {
- var remaining = wait - (now() - stamp);
- if (remaining <= 0) {
- if (maxTimeoutId) {
- clearTimeout(maxTimeoutId);
- }
- var isCalled = trailingCall;
- maxTimeoutId = timeoutId = trailingCall = undefined;
- if (isCalled) {
- lastCalled = now();
- result = func.apply(thisArg, args);
- if (!timeoutId && !maxTimeoutId) {
- args = thisArg = null;
- }
- }
- } else {
- timeoutId = setTimeout(delayed, remaining);
- }
- };
-
- var maxDelayed = function() {
- if (timeoutId) {
- clearTimeout(timeoutId);
- }
- maxTimeoutId = timeoutId = trailingCall = undefined;
- if (trailing || (maxWait !== wait)) {
- lastCalled = now();
- result = func.apply(thisArg, args);
- if (!timeoutId && !maxTimeoutId) {
- args = thisArg = null;
- }
- }
- };
-
- return function() {
- args = arguments;
- stamp = now();
- thisArg = this;
- trailingCall = trailing && (timeoutId || !leading);
-
- if (maxWait === false) {
- var leadingCall = leading && !timeoutId;
- } else {
- if (!maxTimeoutId && !leading) {
- lastCalled = stamp;
- }
- var remaining = maxWait - (stamp - lastCalled),
- isCalled = remaining <= 0;
-
- if (isCalled) {
- if (maxTimeoutId) {
- maxTimeoutId = clearTimeout(maxTimeoutId);
- }
- lastCalled = stamp;
- result = func.apply(thisArg, args);
- }
- else if (!maxTimeoutId) {
- maxTimeoutId = setTimeout(maxDelayed, remaining);
- }
- }
- if (isCalled && timeoutId) {
- timeoutId = clearTimeout(timeoutId);
- }
- else if (!timeoutId && wait !== maxWait) {
- timeoutId = setTimeout(delayed, wait);
- }
- if (leadingCall) {
- isCalled = true;
- result = func.apply(thisArg, args);
- }
- if (isCalled && !timeoutId && !maxTimeoutId) {
- args = thisArg = null;
- }
- return result;
- };
- }
-
- /**
- * Defers executing the `func` function until the current call stack has cleared.
- * Additional arguments will be provided to `func` when it is invoked.
- *
- * @static
- * @memberOf _
- * @category Functions
- * @param {Function} func The function to defer.
- * @param {...*} [arg] Arguments to invoke the function with.
- * @returns {number} Returns the timer id.
- * @example
- *
- * _.defer(function(text) { console.log(text); }, 'deferred');
- * // logs 'deferred' after one or more milliseconds
- */
- function defer(func) {
- if (!isFunction(func)) {
- throw new TypeError;
- }
- var args = slice(arguments, 1);
- return setTimeout(function() { func.apply(undefined, args); }, 1);
- }
-
- /**
- * Executes the `func` function after `wait` milliseconds. Additional arguments
- * will be provided to `func` when it is invoked.
- *
- * @static
- * @memberOf _
- * @category Functions
- * @param {Function} func The function to delay.
- * @param {number} wait The number of milliseconds to delay execution.
- * @param {...*} [arg] Arguments to invoke the function with.
- * @returns {number} Returns the timer id.
- * @example
- *
- * _.delay(function(text) { console.log(text); }, 1000, 'later');
- * // => logs 'later' after one second
- */
- function delay(func, wait) {
- if (!isFunction(func)) {
- throw new TypeError;
- }
- var args = slice(arguments, 2);
- return setTimeout(function() { func.apply(undefined, args); }, wait);
- }
-
- /**
- * Creates a function that memoizes the result of `func`. If `resolver` is
- * provided it will be used to determine the cache key for storing the result
- * based on the arguments provided to the memoized function. By default, the
- * first argument provided to the memoized function is used as the cache key.
- * The `func` is executed with the `this` binding of the memoized function.
- * The result cache is exposed as the `cache` property on the memoized function.
- *
- * @static
- * @memberOf _
- * @category Functions
- * @param {Function} func The function to have its output memoized.
- * @param {Function} [resolver] A function used to resolve the cache key.
- * @returns {Function} Returns the new memoizing function.
- * @example
- *
- * var fibonacci = _.memoize(function(n) {
- * return n < 2 ? n : fibonacci(n - 1) + fibonacci(n - 2);
- * });
- *
- * fibonacci(9)
- * // => 34
- *
- * var data = {
- * 'fred': { 'name': 'fred', 'age': 40 },
- * 'pebbles': { 'name': 'pebbles', 'age': 1 }
- * };
- *
- * // modifying the result cache
- * var get = _.memoize(function(name) { return data[name]; }, _.identity);
- * get('pebbles');
- * // => { 'name': 'pebbles', 'age': 1 }
- *
- * get.cache.pebbles.name = 'penelope';
- * get('pebbles');
- * // => { 'name': 'penelope', 'age': 1 }
- */
- function memoize(func, resolver) {
- if (!isFunction(func)) {
- throw new TypeError;
- }
- var memoized = function() {
- var cache = memoized.cache,
- key = resolver ? resolver.apply(this, arguments) : keyPrefix + arguments[0];
-
- return hasOwnProperty.call(cache, key)
- ? cache[key]
- : (cache[key] = func.apply(this, arguments));
- }
- memoized.cache = {};
- return memoized;
- }
-
- /**
- * Creates a function that is restricted to execute `func` once. Repeat calls to
- * the function will return the value of the first call. The `func` is executed
- * with the `this` binding of the created function.
- *
- * @static
- * @memberOf _
- * @category Functions
- * @param {Function} func The function to restrict.
- * @returns {Function} Returns the new restricted function.
- * @example
- *
- * var initialize = _.once(createApplication);
- * initialize();
- * initialize();
- * // `initialize` executes `createApplication` once
- */
- function once(func) {
- var ran,
- result;
-
- if (!isFunction(func)) {
- throw new TypeError;
- }
- return function() {
- if (ran) {
- return result;
- }
- ran = true;
- result = func.apply(this, arguments);
-
- // clear the `func` variable so the function may be garbage collected
- func = null;
- return result;
- };
- }
-
- /**
- * Creates a function that, when called, invokes `func` with any additional
- * `partial` arguments prepended to those provided to the new function. This
- * method is similar to `_.bind` except it does **not** alter the `this` binding.
- *
- * @static
- * @memberOf _
- * @category Functions
- * @param {Function} func The function to partially apply arguments to.
- * @param {...*} [arg] Arguments to be partially applied.
- * @returns {Function} Returns the new partially applied function.
- * @example
- *
- * var greet = function(greeting, name) { return greeting + ' ' + name; };
- * var hi = _.partial(greet, 'hi');
- * hi('fred');
- * // => 'hi fred'
- */
- function partial(func) {
- return createWrapper(func, 16, slice(arguments, 1));
- }
-
- /**
- * This method is like `_.partial` except that `partial` arguments are
- * appended to those provided to the new function.
- *
- * @static
- * @memberOf _
- * @category Functions
- * @param {Function} func The function to partially apply arguments to.
- * @param {...*} [arg] Arguments to be partially applied.
- * @returns {Function} Returns the new partially applied function.
- * @example
- *
- * var defaultsDeep = _.partialRight(_.merge, _.defaults);
- *
- * var options = {
- * 'variable': 'data',
- * 'imports': { 'jq': $ }
- * };
- *
- * defaultsDeep(options, _.templateSettings);
- *
- * options.variable
- * // => 'data'
- *
- * options.imports
- * // => { '_': _, 'jq': $ }
- */
- function partialRight(func) {
- return createWrapper(func, 32, null, slice(arguments, 1));
- }
-
- /**
- * Creates a function that, when executed, will only call the `func` function
- * at most once per every `wait` milliseconds. Provide an options object to
- * indicate that `func` should be invoked on the leading and/or trailing edge
- * of the `wait` timeout. Subsequent calls to the throttled function will
- * return the result of the last `func` call.
- *
- * Note: If `leading` and `trailing` options are `true` `func` will be called
- * on the trailing edge of the timeout only if the the throttled function is
- * invoked more than once during the `wait` timeout.
- *
- * @static
- * @memberOf _
- * @category Functions
- * @param {Function} func The function to throttle.
- * @param {number} wait The number of milliseconds to throttle executions to.
- * @param {Object} [options] The options object.
- * @param {boolean} [options.leading=true] Specify execution on the leading edge of the timeout.
- * @param {boolean} [options.trailing=true] Specify execution on the trailing edge of the timeout.
- * @returns {Function} Returns the new throttled function.
- * @example
- *
- * // avoid excessively updating the position while scrolling
- * var throttled = _.throttle(updatePosition, 100);
- * jQuery(window).on('scroll', throttled);
- *
- * // execute `renewToken` when the click event is fired, but not more than once every 5 minutes
- * jQuery('.interactive').on('click', _.throttle(renewToken, 300000, {
- * 'trailing': false
- * }));
- */
- function throttle(func, wait, options) {
- var leading = true,
- trailing = true;
-
- if (!isFunction(func)) {
- throw new TypeError;
- }
- if (options === false) {
- leading = false;
- } else if (isObject(options)) {
- leading = 'leading' in options ? options.leading : leading;
- trailing = 'trailing' in options ? options.trailing : trailing;
- }
- debounceOptions.leading = leading;
- debounceOptions.maxWait = wait;
- debounceOptions.trailing = trailing;
-
- return debounce(func, wait, debounceOptions);
- }
-
- /**
- * Creates a function that provides `value` to the wrapper function as its
- * first argument. Additional arguments provided to the function are appended
- * to those provided to the wrapper function. The wrapper is executed with
- * the `this` binding of the created function.
- *
- * @static
- * @memberOf _
- * @category Functions
- * @param {*} value The value to wrap.
- * @param {Function} wrapper The wrapper function.
- * @returns {Function} Returns the new function.
- * @example
- *
- * var p = _.wrap(_.escape, function(func, text) {
- * return '' + func(text) + '
';
- * });
- *
- * p('Fred, Wilma, & Pebbles');
- * // => 'Fred, Wilma, & Pebbles
'
- */
- function wrap(value, wrapper) {
- return createWrapper(wrapper, 16, [value]);
- }
-
- /*--------------------------------------------------------------------------*/
-
- /**
- * Creates a function that returns `value`.
- *
- * @static
- * @memberOf _
- * @category Utilities
- * @param {*} value The value to return from the new function.
- * @returns {Function} Returns the new function.
- * @example
- *
- * var object = { 'name': 'fred' };
- * var getter = _.constant(object);
- * getter() === object;
- * // => true
- */
- function constant(value) {
- return function() {
- return value;
- };
- }
-
- /**
- * Produces a callback bound to an optional `thisArg`. If `func` is a property
- * name the created callback will return the property value for a given element.
- * If `func` is an object the created callback will return `true` for elements
- * that contain the equivalent object properties, otherwise it will return `false`.
- *
- * @static
- * @memberOf _
- * @category Utilities
- * @param {*} [func=identity] The value to convert to a callback.
- * @param {*} [thisArg] The `this` binding of the created callback.
- * @param {number} [argCount] The number of arguments the callback accepts.
- * @returns {Function} Returns a callback function.
- * @example
- *
- * var characters = [
- * { 'name': 'barney', 'age': 36 },
- * { 'name': 'fred', 'age': 40 }
- * ];
- *
- * // wrap to create custom callback shorthands
- * _.createCallback = _.wrap(_.createCallback, function(func, callback, thisArg) {
- * var match = /^(.+?)__([gl]t)(.+)$/.exec(callback);
- * return !match ? func(callback, thisArg) : function(object) {
- * return match[2] == 'gt' ? object[match[1]] > match[3] : object[match[1]] < match[3];
- * };
- * });
- *
- * _.filter(characters, 'age__gt38');
- * // => [{ 'name': 'fred', 'age': 40 }]
- */
- function createCallback(func, thisArg, argCount) {
- var type = typeof func;
- if (func == null || type == 'function') {
- return baseCreateCallback(func, thisArg, argCount);
- }
- // handle "_.pluck" style callback shorthands
- if (type != 'object') {
- return property(func);
- }
- var props = keys(func),
- key = props[0],
- a = func[key];
-
- // handle "_.where" style callback shorthands
- if (props.length == 1 && a === a && !isObject(a)) {
- // fast path the common case of providing an object with a single
- // property containing a primitive value
- return function(object) {
- var b = object[key];
- return a === b && (a !== 0 || (1 / a == 1 / b));
- };
- }
- return function(object) {
- var length = props.length,
- result = false;
-
- while (length--) {
- if (!(result = baseIsEqual(object[props[length]], func[props[length]], null, true))) {
- break;
- }
- }
- return result;
- };
- }
-
- /**
- * Converts the characters `&`, `<`, `>`, `"`, and `'` in `string` to their
- * corresponding HTML entities.
- *
- * @static
- * @memberOf _
- * @category Utilities
- * @param {string} string The string to escape.
- * @returns {string} Returns the escaped string.
- * @example
- *
- * _.escape('Fred, Wilma, & Pebbles');
- * // => 'Fred, Wilma, & Pebbles'
- */
- function escape(string) {
- return string == null ? '' : String(string).replace(reUnescapedHtml, escapeHtmlChar);
- }
-
- /**
- * This method returns the first argument provided to it.
- *
- * @static
- * @memberOf _
- * @category Utilities
- * @param {*} value Any value.
- * @returns {*} Returns `value`.
- * @example
- *
- * var object = { 'name': 'fred' };
- * _.identity(object) === object;
- * // => true
- */
- function identity(value) {
- return value;
- }
-
- /**
- * Adds function properties of a source object to the destination object.
- * If `object` is a function methods will be added to its prototype as well.
- *
- * @static
- * @memberOf _
- * @category Utilities
- * @param {Function|Object} [object=lodash] object The destination object.
- * @param {Object} source The object of functions to add.
- * @param {Object} [options] The options object.
- * @param {boolean} [options.chain=true] Specify whether the functions added are chainable.
- * @example
- *
- * function capitalize(string) {
- * return string.charAt(0).toUpperCase() + string.slice(1).toLowerCase();
- * }
- *
- * _.mixin({ 'capitalize': capitalize });
- * _.capitalize('fred');
- * // => 'Fred'
- *
- * _('fred').capitalize().value();
- * // => 'Fred'
- *
- * _.mixin({ 'capitalize': capitalize }, { 'chain': false });
- * _('fred').capitalize();
- * // => 'Fred'
- */
- function mixin(object, source, options) {
- var chain = true,
- methodNames = source && functions(source);
-
- if (!source || (!options && !methodNames.length)) {
- if (options == null) {
- options = source;
- }
- ctor = lodashWrapper;
- source = object;
- object = lodash;
- methodNames = functions(source);
- }
- if (options === false) {
- chain = false;
- } else if (isObject(options) && 'chain' in options) {
- chain = options.chain;
- }
- var ctor = object,
- isFunc = isFunction(ctor);
-
- forEach(methodNames, function(methodName) {
- var func = object[methodName] = source[methodName];
- if (isFunc) {
- ctor.prototype[methodName] = function() {
- var chainAll = this.__chain__,
- value = this.__wrapped__,
- args = [value];
-
- push.apply(args, arguments);
- var result = func.apply(object, args);
- if (chain || chainAll) {
- if (value === result && isObject(result)) {
- return this;
- }
- result = new ctor(result);
- result.__chain__ = chainAll;
- }
- return result;
- };
- }
- });
- }
-
- /**
- * Reverts the '_' variable to its previous value and returns a reference to
- * the `lodash` function.
- *
- * @static
- * @memberOf _
- * @category Utilities
- * @returns {Function} Returns the `lodash` function.
- * @example
- *
- * var lodash = _.noConflict();
- */
- function noConflict() {
- context._ = oldDash;
- return this;
- }
-
- /**
- * A no-operation function.
- *
- * @static
- * @memberOf _
- * @category Utilities
- * @example
- *
- * var object = { 'name': 'fred' };
- * _.noop(object) === undefined;
- * // => true
- */
- function noop() {
- // no operation performed
- }
-
- /**
- * Gets the number of milliseconds that have elapsed since the Unix epoch
- * (1 January 1970 00:00:00 UTC).
- *
- * @static
- * @memberOf _
- * @category Utilities
- * @example
- *
- * var stamp = _.now();
- * _.defer(function() { console.log(_.now() - stamp); });
- * // => logs the number of milliseconds it took for the deferred function to be called
- */
- var now = isNative(now = Date.now) && now || function() {
- return new Date().getTime();
- };
-
- /**
- * Converts the given value into an integer of the specified radix.
- * If `radix` is `undefined` or `0` a `radix` of `10` is used unless the
- * `value` is a hexadecimal, in which case a `radix` of `16` is used.
- *
- * Note: This method avoids differences in native ES3 and ES5 `parseInt`
- * implementations. See http://es5.github.io/#E.
- *
- * @static
- * @memberOf _
- * @category Utilities
- * @param {string} value The value to parse.
- * @param {number} [radix] The radix used to interpret the value to parse.
- * @returns {number} Returns the new integer value.
- * @example
- *
- * _.parseInt('08');
- * // => 8
- */
- var parseInt = nativeParseInt(whitespace + '08') == 8 ? nativeParseInt : function(value, radix) {
- // Firefox < 21 and Opera < 15 follow the ES3 specified implementation of `parseInt`
- return nativeParseInt(isString(value) ? value.replace(reLeadingSpacesAndZeros, '') : value, radix || 0);
- };
-
- /**
- * Creates a "_.pluck" style function, which returns the `key` value of a
- * given object.
- *
- * @static
- * @memberOf _
- * @category Utilities
- * @param {string} key The name of the property to retrieve.
- * @returns {Function} Returns the new function.
- * @example
- *
- * var characters = [
- * { 'name': 'fred', 'age': 40 },
- * { 'name': 'barney', 'age': 36 }
- * ];
- *
- * var getName = _.property('name');
- *
- * _.map(characters, getName);
- * // => ['barney', 'fred']
- *
- * _.sortBy(characters, getName);
- * // => [{ 'name': 'barney', 'age': 36 }, { 'name': 'fred', 'age': 40 }]
- */
- function property(key) {
- return function(object) {
- return object[key];
- };
- }
-
- /**
- * Produces a random number between `min` and `max` (inclusive). If only one
- * argument is provided a number between `0` and the given number will be
- * returned. If `floating` is truey or either `min` or `max` are floats a
- * floating-point number will be returned instead of an integer.
- *
- * @static
- * @memberOf _
- * @category Utilities
- * @param {number} [min=0] The minimum possible value.
- * @param {number} [max=1] The maximum possible value.
- * @param {boolean} [floating=false] Specify returning a floating-point number.
- * @returns {number} Returns a random number.
- * @example
- *
- * _.random(0, 5);
- * // => an integer between 0 and 5
- *
- * _.random(5);
- * // => also an integer between 0 and 5
- *
- * _.random(5, true);
- * // => a floating-point number between 0 and 5
- *
- * _.random(1.2, 5.2);
- * // => a floating-point number between 1.2 and 5.2
- */
- function random(min, max, floating) {
- var noMin = min == null,
- noMax = max == null;
-
- if (floating == null) {
- if (typeof min == 'boolean' && noMax) {
- floating = min;
- min = 1;
- }
- else if (!noMax && typeof max == 'boolean') {
- floating = max;
- noMax = true;
- }
- }
- if (noMin && noMax) {
- max = 1;
- }
- min = +min || 0;
- if (noMax) {
- max = min;
- min = 0;
- } else {
- max = +max || 0;
- }
- if (floating || min % 1 || max % 1) {
- var rand = nativeRandom();
- return nativeMin(min + (rand * (max - min + parseFloat('1e-' + ((rand +'').length - 1)))), max);
- }
- return baseRandom(min, max);
- }
-
- /**
- * Resolves the value of property `key` on `object`. If `key` is a function
- * it will be invoked with the `this` binding of `object` and its result returned,
- * else the property value is returned. If `object` is falsey then `undefined`
- * is returned.
- *
- * @static
- * @memberOf _
- * @category Utilities
- * @param {Object} object The object to inspect.
- * @param {string} key The name of the property to resolve.
- * @returns {*} Returns the resolved value.
- * @example
- *
- * var object = {
- * 'cheese': 'crumpets',
- * 'stuff': function() {
- * return 'nonsense';
- * }
- * };
- *
- * _.result(object, 'cheese');
- * // => 'crumpets'
- *
- * _.result(object, 'stuff');
- * // => 'nonsense'
- */
- function result(object, key) {
- if (object) {
- var value = object[key];
- return isFunction(value) ? object[key]() : value;
- }
- }
-
- /**
- * A micro-templating method that handles arbitrary delimiters, preserves
- * whitespace, and correctly escapes quotes within interpolated code.
- *
- * Note: In the development build, `_.template` utilizes sourceURLs for easier
- * debugging. See http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl
- *
- * For more information on precompiling templates see:
- * http://lodash.com/custom-builds
- *
- * For more information on Chrome extension sandboxes see:
- * http://developer.chrome.com/stable/extensions/sandboxingEval.html
- *
- * @static
- * @memberOf _
- * @category Utilities
- * @param {string} text The template text.
- * @param {Object} data The data object used to populate the text.
- * @param {Object} [options] The options object.
- * @param {RegExp} [options.escape] The "escape" delimiter.
- * @param {RegExp} [options.evaluate] The "evaluate" delimiter.
- * @param {Object} [options.imports] An object to import into the template as local variables.
- * @param {RegExp} [options.interpolate] The "interpolate" delimiter.
- * @param {string} [sourceURL] The sourceURL of the template's compiled source.
- * @param {string} [variable] The data object variable name.
- * @returns {Function|string} Returns a compiled function when no `data` object
- * is given, else it returns the interpolated text.
- * @example
- *
- * // using the "interpolate" delimiter to create a compiled template
- * var compiled = _.template('hello <%= name %>');
- * compiled({ 'name': 'fred' });
- * // => 'hello fred'
- *
- * // using the "escape" delimiter to escape HTML in data property values
- * _.template('<%- value %>', { 'value': '').stripTags()
-=> 'a linkalert("hello world!")'
-```
-
-**toSentence** _.toSentence(array, [delimiter, lastDelimiter])
-
-Join an array into a human readable sentence.
-
-```javascript
-_.toSentence(['jQuery', 'Mootools', 'Prototype'])
-=> 'jQuery, Mootools and Prototype';
-
-_.toSentence(['jQuery', 'Mootools', 'Prototype'], ', ', ' unt ')
-=> 'jQuery, Mootools unt Prototype';
-```
-
-**toSentenceSerial** _.toSentenceSerial(array, [delimiter, lastDelimiter])
-
-The same as `toSentence`, but adjusts delimeters to use [Serial comma](http://en.wikipedia.org/wiki/Serial_comma).
-
-```javascript
-_.toSentenceSerial(['jQuery', 'Mootools'])
-=> 'jQuery and Mootools';
-
-_.toSentenceSerial(['jQuery', 'Mootools', 'Prototype'])
-=> 'jQuery, Mootools, and Prototype'
-
-_.toSentenceSerial(['jQuery', 'Mootools', 'Prototype'], ', ', ' unt ');
-=> 'jQuery, Mootools, unt Prototype';
-```
-
-**repeat** _.repeat(string, count, [separator])
-
-Repeats a string count times.
-
-```javascript
-_.repeat("foo", 3)
-=> 'foofoofoo';
-
-_.repeat("foo", 3, "bar")
-=> 'foobarfoobarfoo'
-```
-
-**surround** _.surround(string, wrap)
-
-Surround a string with another string.
-
-```javascript
-_.surround("foo", "ab")
-=> 'abfooab';
-```
-
-**quote** _.quote(string, quoteChar) or _.q(string, quoteChar)
-
-Quotes a string. `quoteChar` defaults to `"`.
-
-```javascript
-_.quote('foo', quoteChar)
-=> '"foo"';
-```
-**unquote** _.unquote(string, quoteChar)
-
-Unquotes a string. `quoteChar` defaults to `"`.
-
-```javascript
-_.unquote('"foo"')
-=> 'foo';
-_.unquote("'foo'", "'")
-=> 'foo';
-```
-
-
-**slugify** _.slugify(string)
-
-Transform text into a URL slug. Replaces whitespaces, accentuated, and special characters with a dash.
-
-```javascript
-_.slugify("Un éléphant à l'orée du bois")
-=> 'un-elephant-a-loree-du-bois';
-```
-
-***Caution: this function is charset dependent***
-
-**naturalCmp** array.sort(_.naturalCmp)
-
-Naturally sort strings like humans would do.
-
-```javascript
-['foo20', 'foo5'].sort(_.naturalCmp)
-=> [ 'foo5', 'foo20' ]
-```
-
-**toBoolean** _.toBoolean(string) or _.toBool(string)
-
-Turn strings that can be commonly considered as booleas to real booleans. Such as "true", "false", "1" and "0". This function is case insensitive.
-
-```javascript
-_.toBoolean("true")
-=> true
-_.toBoolean("FALSE")
-=> false
-_.toBoolean("random")
-=> undefined
-```
-
-It can be customized by giving arrays of truth and falsy value matcher as parameters. Matchers can be also RegExp objects.
-
-```javascript
-_.toBoolean("truthy", ["truthy"], ["falsy"])
-=> true
-_.toBoolean("true only at start", [/^true/])
-=> true
-```
-
-## Roadmap ##
-
-Any suggestions or bug reports are welcome. Just email me or more preferably open an issue.
-
-#### Problems
-
-We lose two things for `include` and `reverse` methods from `_.string`:
-
-* Calls like `_('foobar').include('bar')` aren't available;
-* Chaining isn't available too.
-
-But if you need this functionality you can create aliases for conflict functions which will be convenient for you:
-
-```javascript
-_.mixin({
- includeString: _.str.include,
- reverseString: _.str.reverse
-})
-
-// Now wrapper calls and chaining are available.
-_('foobar').chain().reverseString().includeString('rab').value()
-```
-
-#### Standalone Usage
-
-If you are using Underscore.string without Underscore. You also have `_.string` namespace for it and `_.str` alias
-But of course you can just reassign `_` variable with `_.string`
-
-```javascript
-_ = _.string
-```
-
-## Changelog ##
-
-### 2.3.3 ###
-
-* Add `toBoolean`
-* Add `unquote`
-* Add quote char option to `quote`
-* Support dash-separated words in `titleize`
-
-### 2.3.2 ###
-
-* Add `naturalCmp`
-* Bug fix to `camelize`
-* Add ă, ș, ț and ś to `slugify`
-* Doc updates
-* Add support for [component](http://component.io/)
-* [Full changelog](https://github.com/epeli/underscore.string/compare/v2.3.1...v2.3.2)
-
-### 2.3.1 ###
-
-* Bug fixes to `escapeHTML`, `classify`, `substr`
-* Faster `count`
-* Documentation fixes
-* [Full changelog](https://github.com/epeli/underscore.string/compare/v2.3.0...v2.3.1)
-
-### 2.3.0 ###
-
-* Added `numberformat` method
-* Added `levenshtein` method (Levenshtein distance calculation)
-* Added `swapCase` method
-* Changed default behavior of `words` method
-* Added `toSentenceSerial` method
-* Added `surround` and `quote` methods
-
-### 2.2.1 ###
-
-* Same as 2.2.0 (2.2.0rc on npm) to fix some npm drama
-
-### 2.2.0 ###
-
-* Capitalize method behavior changed
-* Various perfomance tweaks
-
-### 2.1.1###
-
-* Fixed words method bug
-* Added classify method
-
-### 2.1.0 ###
-
-* AMD support
-* Added toSentence method
-* Added slugify method
-* Lots of speed optimizations
-
-### 2.0.0 ###
-
-* Added prune, humanize functions
-* Added _.string (_.str) namespace for Underscore.string library
-* Removed includes function
-
-For upgrading to this version you need to mix in Underscore.string library to Underscore object:
-
-```javascript
-_.mixin(_.string.exports());
-```
-
-and all non-conflict Underscore.string functions will be available through Underscore object.
-Also function `includes` has been removed, you should replace this function by `_.str.include`
-or create alias `_.includes = _.str.include` and all your code will work fine.
-
-### 1.1.6 ###
-
-* Fixed reverse and truncate
-* Added isBlank, stripTags, inlude(alias for includes)
-* Added uglifier compression
-
-### 1.1.5 ###
-
-* Added strRight, strRightBack, strLeft, strLeftBack
-
-### 1.1.4 ###
-
-* Added pad, lpad, rpad, lrpad methods and aliases center, ljust, rjust
-* Integration with Underscore 1.1.6
-
-### 1.1.3 ###
-
-* Added methods: underscored, camelize, dasherize
-* Support newer version of npm
-
-### 1.1.2 ###
-
-* Created functions: lines, chars, words functions
-
-### 1.0.2 ###
-
-* Created integration test suite with underscore.js 1.1.4 (now it's absolutely compatible)
-* Removed 'reverse' function, because this function override underscore.js 'reverse'
-
-## Contribute ##
-
-* Fork & pull request. Don't forget about tests.
-* If you planning add some feature please create issue before.
-
-Otherwise changes will be rejected.
-
-## Contributors list ##
-[Can be found here](https://github.com/epeli/underscore.string/graphs/contributors).
-
-
-## Licence ##
-
-The MIT License
-
-Copyright (c) 2011 Esa-Matti Suuronen esa-matti@suuronen.org
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
diff --git a/spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/Rakefile b/spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/Rakefile
deleted file mode 100644
index 2cd9eed9..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/Rakefile
+++ /dev/null
@@ -1,23 +0,0 @@
-# encoding: utf-8
-task default: :test
-
-desc 'Use UglifyJS to compress Underscore.string'
-task :build do
- require 'uglifier'
- source = File.read('lib/underscore.string.js', :encoding => 'utf-8')
- compressed = Uglifier.compile(source, copyright: false)
- File.open('dist/underscore.string.min.js', 'w'){ |f| f.write compressed }
- compression_rate = compressed.length.to_f/source.length
- puts "compressed dist/underscore.string.min.js: #{compressed.length}/#{source.length} #{(compression_rate * 100).round}%"
-end
-
-desc 'Run tests'
-task :test do
- puts "Running underscore.string test suite."
- result1 = system %{phantomjs ./test/run-qunit.js "test/test.html"}
-
- puts "Running Underscore test suite."
- result2 = system %{phantomjs ./test/run-qunit.js "test/test_underscore/index.html"}
-
- exit(result1 && result2 ? 0 : 1)
-end
diff --git a/spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/component.json b/spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/component.json
deleted file mode 100644
index ae91b65b..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/component.json
+++ /dev/null
@@ -1,11 +0,0 @@
-{
- "name": "underscore.string",
- "repo": "epeli/underscore.string",
- "description": "String manipulation extensions for Underscore.js javascript library",
- "version": "2.3.3",
- "keywords": ["underscore", "string"],
- "dependencies": {},
- "development": {},
- "main": "lib/underscore.string.js",
- "scripts": ["lib/underscore.string.js"]
-}
diff --git a/spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/dist/underscore.string.min.js b/spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/dist/underscore.string.min.js
deleted file mode 100644
index 4f6b2b93..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/dist/underscore.string.min.js
+++ /dev/null
@@ -1 +0,0 @@
-!function(e,n){"use strict";function r(e,n){var r,t,u=e.toLowerCase();for(n=[].concat(n),r=0;n.length>r;r+=1)if(t=n[r]){if(t.test&&t.test(e))return!0;if(t.toLowerCase()===u)return!0}}var t=n.prototype.trim,u=n.prototype.trimRight,i=n.prototype.trimLeft,l=function(e){return 1*e||0},o=function(e,n){if(1>n)return"";for(var r="";n>0;)1&n&&(r+=e),n>>=1,e+=e;return r},a=[].slice,c=function(e){return null==e?"\\s":e.source?e.source:"["+g.escapeRegExp(e)+"]"},s={lt:"<",gt:">",quot:'"',amp:"&",apos:"'"},f={};for(var p in s)f[s[p]]=p;f["'"]="#39";var h=function(){function e(e){return Object.prototype.toString.call(e).slice(8,-1).toLowerCase()}var r=o,t=function(){return t.cache.hasOwnProperty(arguments[0])||(t.cache[arguments[0]]=t.parse(arguments[0])),t.format.call(null,t.cache[arguments[0]],arguments)};return t.format=function(t,u){var i,l,o,a,c,s,f,p=1,g=t.length,d="",m=[];for(l=0;g>l;l++)if(d=e(t[l]),"string"===d)m.push(t[l]);else if("array"===d){if(a=t[l],a[2])for(i=u[p],o=0;a[2].length>o;o++){if(!i.hasOwnProperty(a[2][o]))throw new Error(h('[_.sprintf] property "%s" does not exist',a[2][o]));i=i[a[2][o]]}else i=a[1]?u[a[1]]:u[p++];if(/[^s]/.test(a[8])&&"number"!=e(i))throw new Error(h("[_.sprintf] expecting number but found %s",e(i)));switch(a[8]){case"b":i=i.toString(2);break;case"c":i=n.fromCharCode(i);break;case"d":i=parseInt(i,10);break;case"e":i=a[7]?i.toExponential(a[7]):i.toExponential();break;case"f":i=a[7]?parseFloat(i).toFixed(a[7]):parseFloat(i);break;case"o":i=i.toString(8);break;case"s":i=(i=n(i))&&a[7]?i.substring(0,a[7]):i;break;case"u":i=Math.abs(i);break;case"x":i=i.toString(16);break;case"X":i=i.toString(16).toUpperCase()}i=/[def]/.test(a[8])&&a[3]&&i>=0?"+"+i:i,s=a[4]?"0"==a[4]?"0":a[4].charAt(1):" ",f=a[6]-n(i).length,c=a[6]?r(s,f):"",m.push(a[5]?i+c:c+i)}return m.join("")},t.cache={},t.parse=function(e){for(var n=e,r=[],t=[],u=0;n;){if(null!==(r=/^[^\x25]+/.exec(n)))t.push(r[0]);else if(null!==(r=/^\x25{2}/.exec(n)))t.push("%");else{if(null===(r=/^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/.exec(n)))throw new Error("[_.sprintf] huh?");if(r[2]){u|=1;var i=[],l=r[2],o=[];if(null===(o=/^([a-z_][a-z_\d]*)/i.exec(l)))throw new Error("[_.sprintf] huh?");for(i.push(o[1]);""!==(l=l.substring(o[0].length));)if(null!==(o=/^\.([a-z_][a-z_\d]*)/i.exec(l)))i.push(o[1]);else{if(null===(o=/^\[(\d+)\]/.exec(l)))throw new Error("[_.sprintf] huh?");i.push(o[1])}r[2]=i}else u|=2;if(3===u)throw new Error("[_.sprintf] mixing positional and named placeholders is not (yet) supported");t.push(r)}n=n.substring(r[0].length)}return t},t}(),g={VERSION:"2.3.0",isBlank:function(e){return null==e&&(e=""),/^\s*$/.test(e)},stripTags:function(e){return null==e?"":n(e).replace(/<\/?[^>]+>/g,"")},capitalize:function(e){return e=null==e?"":n(e),e.charAt(0).toUpperCase()+e.slice(1)},chop:function(e,r){return null==e?[]:(e=n(e),r=~~r,r>0?e.match(new RegExp(".{1,"+r+"}","g")):[e])},clean:function(e){return g.strip(e).replace(/\s+/g," ")},count:function(e,r){if(null==e||null==r)return 0;e=n(e),r=n(r);for(var t=0,u=0,i=r.length;;){if(u=e.indexOf(r,u),-1===u)break;t++,u+=i}return t},chars:function(e){return null==e?[]:n(e).split("")},swapCase:function(e){return null==e?"":n(e).replace(/\S/g,function(e){return e===e.toUpperCase()?e.toLowerCase():e.toUpperCase()})},escapeHTML:function(e){return null==e?"":n(e).replace(/[&<>"']/g,function(e){return"&"+f[e]+";"})},unescapeHTML:function(e){return null==e?"":n(e).replace(/\&([^;]+);/g,function(e,r){var t;return r in s?s[r]:(t=r.match(/^#x([\da-fA-F]+)$/))?n.fromCharCode(parseInt(t[1],16)):(t=r.match(/^#(\d+)$/))?n.fromCharCode(~~t[1]):e})},escapeRegExp:function(e){return null==e?"":n(e).replace(/([.*+?^=!:${}()|[\]\/\\])/g,"\\$1")},splice:function(e,n,r,t){var u=g.chars(e);return u.splice(~~n,~~r,t),u.join("")},insert:function(e,n,r){return g.splice(e,n,0,r)},include:function(e,r){return""===r?!0:null==e?!1:-1!==n(e).indexOf(r)},join:function(){var e=a.call(arguments),n=e.shift();return null==n&&(n=""),e.join(n)},lines:function(e){return null==e?[]:n(e).split("\n")},reverse:function(e){return g.chars(e).reverse().join("")},startsWith:function(e,r){return""===r?!0:null==e||null==r?!1:(e=n(e),r=n(r),e.length>=r.length&&e.slice(0,r.length)===r)},endsWith:function(e,r){return""===r?!0:null==e||null==r?!1:(e=n(e),r=n(r),e.length>=r.length&&e.slice(e.length-r.length)===r)},succ:function(e){return null==e?"":(e=n(e),e.slice(0,-1)+n.fromCharCode(e.charCodeAt(e.length-1)+1))},titleize:function(e){return null==e?"":(e=n(e).toLowerCase(),e.replace(/(?:^|\s|-)\S/g,function(e){return e.toUpperCase()}))},camelize:function(e){return g.trim(e).replace(/[-_\s]+(.)?/g,function(e,n){return n?n.toUpperCase():""})},underscored:function(e){return g.trim(e).replace(/([a-z\d])([A-Z]+)/g,"$1_$2").replace(/[-\s]+/g,"_").toLowerCase()},dasherize:function(e){return g.trim(e).replace(/([A-Z])/g,"-$1").replace(/[-_\s]+/g,"-").toLowerCase()},classify:function(e){return g.titleize(n(e).replace(/[\W_]/g," ")).replace(/\s/g,"")},humanize:function(e){return g.capitalize(g.underscored(e).replace(/_id$/,"").replace(/_/g," "))},trim:function(e,r){return null==e?"":!r&&t?t.call(e):(r=c(r),n(e).replace(new RegExp("^"+r+"+|"+r+"+$","g"),""))},ltrim:function(e,r){return null==e?"":!r&&i?i.call(e):(r=c(r),n(e).replace(new RegExp("^"+r+"+"),""))},rtrim:function(e,r){return null==e?"":!r&&u?u.call(e):(r=c(r),n(e).replace(new RegExp(r+"+$"),""))},truncate:function(e,r,t){return null==e?"":(e=n(e),t=t||"...",r=~~r,e.length>r?e.slice(0,r)+t:e)},prune:function(e,r,t){if(null==e)return"";if(e=n(e),r=~~r,t=null!=t?n(t):"...",r>=e.length)return e;var u=function(e){return e.toUpperCase()!==e.toLowerCase()?"A":" "},i=e.slice(0,r+1).replace(/.(?=\W*\w*$)/g,u);return i=i.slice(i.length-2).match(/\w\w/)?i.replace(/\s*\S+$/,""):g.rtrim(i.slice(0,i.length-1)),(i+t).length>e.length?e:e.slice(0,i.length)+t},words:function(e,n){return g.isBlank(e)?[]:g.trim(e,n).split(n||/\s+/)},pad:function(e,r,t,u){e=null==e?"":n(e),r=~~r;var i=0;switch(t?t.length>1&&(t=t.charAt(0)):t=" ",u){case"right":return i=r-e.length,e+o(t,i);case"both":return i=r-e.length,o(t,Math.ceil(i/2))+e+o(t,Math.floor(i/2));default:return i=r-e.length,o(t,i)+e}},lpad:function(e,n,r){return g.pad(e,n,r)},rpad:function(e,n,r){return g.pad(e,n,r,"right")},lrpad:function(e,n,r){return g.pad(e,n,r,"both")},sprintf:h,vsprintf:function(e,n){return n.unshift(e),h.apply(null,n)},toNumber:function(e,n){return e?(e=g.trim(e),e.match(/^-?\d+(?:\.\d+)?$/)?l(l(e).toFixed(~~n)):0/0):0},numberFormat:function(e,n,r,t){if(isNaN(e)||null==e)return"";e=e.toFixed(~~n),t="string"==typeof t?t:",";var u=e.split("."),i=u[0],l=u[1]?(r||".")+u[1]:"";return i.replace(/(\d)(?=(?:\d{3})+$)/g,"$1"+t)+l},strRight:function(e,r){if(null==e)return"";e=n(e),r=null!=r?n(r):r;var t=r?e.indexOf(r):-1;return~t?e.slice(t+r.length,e.length):e},strRightBack:function(e,r){if(null==e)return"";e=n(e),r=null!=r?n(r):r;var t=r?e.lastIndexOf(r):-1;return~t?e.slice(t+r.length,e.length):e},strLeft:function(e,r){if(null==e)return"";e=n(e),r=null!=r?n(r):r;var t=r?e.indexOf(r):-1;return~t?e.slice(0,t):e},strLeftBack:function(e,n){if(null==e)return"";e+="",n=null!=n?""+n:n;var r=e.lastIndexOf(n);return~r?e.slice(0,r):e},toSentence:function(e,n,r,t){n=n||", ",r=r||" and ";var u=e.slice(),i=u.pop();return e.length>2&&t&&(r=g.rtrim(n)+r),u.length?u.join(n)+r+i:i},toSentenceSerial:function(){var e=a.call(arguments);return e[3]=!0,g.toSentence.apply(g,e)},slugify:function(e){if(null==e)return"";var r="ąàáäâãåæăćęèéëêìíïîłńòóöôõøśșțùúüûñçżź",t="aaaaaaaaaceeeeeiiiilnoooooosstuuuunczz",u=new RegExp(c(r),"g");return e=n(e).toLowerCase().replace(u,function(e){var n=r.indexOf(e);return t.charAt(n)||"-"}),g.dasherize(e.replace(/[^\w\s-]/g,""))},surround:function(e,n){return[n,e,n].join("")},quote:function(e,n){return g.surround(e,n||'"')},unquote:function(e,n){return n=n||'"',e[0]===n&&e[e.length-1]===n?e.slice(1,e.length-1):e},exports:function(){var e={};for(var n in this)this.hasOwnProperty(n)&&!n.match(/^(?:include|contains|reverse)$/)&&(e[n]=this[n]);return e},repeat:function(e,r,t){if(null==e)return"";if(r=~~r,null==t)return o(n(e),r);for(var u=[];r>0;u[--r]=e);return u.join(t)},naturalCmp:function(e,r){if(e==r)return 0;if(!e)return-1;if(!r)return 1;for(var t=/(\.\d+)|(\d+)|(\D+)/g,u=n(e).toLowerCase().match(t),i=n(r).toLowerCase().match(t),l=Math.min(u.length,i.length),o=0;l>o;o++){var a=u[o],c=i[o];if(a!==c){var s=parseInt(a,10);if(!isNaN(s)){var f=parseInt(c,10);if(!isNaN(f)&&s-f)return s-f}return c>a?-1:1}}return u.length===i.length?u.length-i.length:r>e?-1:1},levenshtein:function(e,r){if(null==e&&null==r)return 0;if(null==e)return n(r).length;if(null==r)return n(e).length;e=n(e),r=n(r);for(var t,u,i=[],l=0;r.length>=l;l++)for(var o=0;e.length>=o;o++)u=l&&o?e.charAt(o-1)===r.charAt(l-1)?t:Math.min(i[o],i[o-1],t)+1:l+o,t=i[o],i[o]=u;return i.pop()},toBoolean:function(e,n,t){return"number"==typeof e&&(e=""+e),"string"!=typeof e?!!e:(e=g.trim(e),r(e,n||["true","1"])?!0:r(e,t||["false","0"])?!1:void 0)}};g.strip=g.trim,g.lstrip=g.ltrim,g.rstrip=g.rtrim,g.center=g.lrpad,g.rjust=g.lpad,g.ljust=g.rpad,g.contains=g.include,g.q=g.quote,g.toBool=g.toBoolean,"undefined"!=typeof exports&&("undefined"!=typeof module&&module.exports&&(module.exports=g),exports._s=g),"function"==typeof define&&define.amd&&define("underscore.string",[],function(){return g}),e._=e._||{},e._.string=e._.str=g}(this,String);
\ No newline at end of file
diff --git a/spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/lib/underscore.string.js b/spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/lib/underscore.string.js
deleted file mode 100644
index 87611173..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/lib/underscore.string.js
+++ /dev/null
@@ -1,673 +0,0 @@
-// Underscore.string
-// (c) 2010 Esa-Matti Suuronen
-// Underscore.string is freely distributable under the terms of the MIT license.
-// Documentation: https://github.com/epeli/underscore.string
-// Some code is borrowed from MooTools and Alexandru Marasteanu.
-// Version '2.3.2'
-
-!function(root, String){
- 'use strict';
-
- // Defining helper functions.
-
- var nativeTrim = String.prototype.trim;
- var nativeTrimRight = String.prototype.trimRight;
- var nativeTrimLeft = String.prototype.trimLeft;
-
- var parseNumber = function(source) { return source * 1 || 0; };
-
- var strRepeat = function(str, qty){
- if (qty < 1) return '';
- var result = '';
- while (qty > 0) {
- if (qty & 1) result += str;
- qty >>= 1, str += str;
- }
- return result;
- };
-
- var slice = [].slice;
-
- var defaultToWhiteSpace = function(characters) {
- if (characters == null)
- return '\\s';
- else if (characters.source)
- return characters.source;
- else
- return '[' + _s.escapeRegExp(characters) + ']';
- };
-
- // Helper for toBoolean
- function boolMatch(s, matchers) {
- var i, matcher, down = s.toLowerCase();
- matchers = [].concat(matchers);
- for (i = 0; i < matchers.length; i += 1) {
- matcher = matchers[i];
- if (!matcher) continue;
- if (matcher.test && matcher.test(s)) return true;
- if (matcher.toLowerCase() === down) return true;
- }
- }
-
- var escapeChars = {
- lt: '<',
- gt: '>',
- quot: '"',
- amp: '&',
- apos: "'"
- };
-
- var reversedEscapeChars = {};
- for(var key in escapeChars) reversedEscapeChars[escapeChars[key]] = key;
- reversedEscapeChars["'"] = '#39';
-
- // sprintf() for JavaScript 0.7-beta1
- // http://www.diveintojavascript.com/projects/javascript-sprintf
- //
- // Copyright (c) Alexandru Marasteanu
- // All rights reserved.
-
- var sprintf = (function() {
- function get_type(variable) {
- return Object.prototype.toString.call(variable).slice(8, -1).toLowerCase();
- }
-
- var str_repeat = strRepeat;
-
- var str_format = function() {
- if (!str_format.cache.hasOwnProperty(arguments[0])) {
- str_format.cache[arguments[0]] = str_format.parse(arguments[0]);
- }
- return str_format.format.call(null, str_format.cache[arguments[0]], arguments);
- };
-
- str_format.format = function(parse_tree, argv) {
- var cursor = 1, tree_length = parse_tree.length, node_type = '', arg, output = [], i, k, match, pad, pad_character, pad_length;
- for (i = 0; i < tree_length; i++) {
- node_type = get_type(parse_tree[i]);
- if (node_type === 'string') {
- output.push(parse_tree[i]);
- }
- else if (node_type === 'array') {
- match = parse_tree[i]; // convenience purposes only
- if (match[2]) { // keyword argument
- arg = argv[cursor];
- for (k = 0; k < match[2].length; k++) {
- if (!arg.hasOwnProperty(match[2][k])) {
- throw new Error(sprintf('[_.sprintf] property "%s" does not exist', match[2][k]));
- }
- arg = arg[match[2][k]];
- }
- } else if (match[1]) { // positional argument (explicit)
- arg = argv[match[1]];
- }
- else { // positional argument (implicit)
- arg = argv[cursor++];
- }
-
- if (/[^s]/.test(match[8]) && (get_type(arg) != 'number')) {
- throw new Error(sprintf('[_.sprintf] expecting number but found %s', get_type(arg)));
- }
- switch (match[8]) {
- case 'b': arg = arg.toString(2); break;
- case 'c': arg = String.fromCharCode(arg); break;
- case 'd': arg = parseInt(arg, 10); break;
- case 'e': arg = match[7] ? arg.toExponential(match[7]) : arg.toExponential(); break;
- case 'f': arg = match[7] ? parseFloat(arg).toFixed(match[7]) : parseFloat(arg); break;
- case 'o': arg = arg.toString(8); break;
- case 's': arg = ((arg = String(arg)) && match[7] ? arg.substring(0, match[7]) : arg); break;
- case 'u': arg = Math.abs(arg); break;
- case 'x': arg = arg.toString(16); break;
- case 'X': arg = arg.toString(16).toUpperCase(); break;
- }
- arg = (/[def]/.test(match[8]) && match[3] && arg >= 0 ? '+'+ arg : arg);
- pad_character = match[4] ? match[4] == '0' ? '0' : match[4].charAt(1) : ' ';
- pad_length = match[6] - String(arg).length;
- pad = match[6] ? str_repeat(pad_character, pad_length) : '';
- output.push(match[5] ? arg + pad : pad + arg);
- }
- }
- return output.join('');
- };
-
- str_format.cache = {};
-
- str_format.parse = function(fmt) {
- var _fmt = fmt, match = [], parse_tree = [], arg_names = 0;
- while (_fmt) {
- if ((match = /^[^\x25]+/.exec(_fmt)) !== null) {
- parse_tree.push(match[0]);
- }
- else if ((match = /^\x25{2}/.exec(_fmt)) !== null) {
- parse_tree.push('%');
- }
- else if ((match = /^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/.exec(_fmt)) !== null) {
- if (match[2]) {
- arg_names |= 1;
- var field_list = [], replacement_field = match[2], field_match = [];
- if ((field_match = /^([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) {
- field_list.push(field_match[1]);
- while ((replacement_field = replacement_field.substring(field_match[0].length)) !== '') {
- if ((field_match = /^\.([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) {
- field_list.push(field_match[1]);
- }
- else if ((field_match = /^\[(\d+)\]/.exec(replacement_field)) !== null) {
- field_list.push(field_match[1]);
- }
- else {
- throw new Error('[_.sprintf] huh?');
- }
- }
- }
- else {
- throw new Error('[_.sprintf] huh?');
- }
- match[2] = field_list;
- }
- else {
- arg_names |= 2;
- }
- if (arg_names === 3) {
- throw new Error('[_.sprintf] mixing positional and named placeholders is not (yet) supported');
- }
- parse_tree.push(match);
- }
- else {
- throw new Error('[_.sprintf] huh?');
- }
- _fmt = _fmt.substring(match[0].length);
- }
- return parse_tree;
- };
-
- return str_format;
- })();
-
-
-
- // Defining underscore.string
-
- var _s = {
-
- VERSION: '2.3.0',
-
- isBlank: function(str){
- if (str == null) str = '';
- return (/^\s*$/).test(str);
- },
-
- stripTags: function(str){
- if (str == null) return '';
- return String(str).replace(/<\/?[^>]+>/g, '');
- },
-
- capitalize : function(str){
- str = str == null ? '' : String(str);
- return str.charAt(0).toUpperCase() + str.slice(1);
- },
-
- chop: function(str, step){
- if (str == null) return [];
- str = String(str);
- step = ~~step;
- return step > 0 ? str.match(new RegExp('.{1,' + step + '}', 'g')) : [str];
- },
-
- clean: function(str){
- return _s.strip(str).replace(/\s+/g, ' ');
- },
-
- count: function(str, substr){
- if (str == null || substr == null) return 0;
-
- str = String(str);
- substr = String(substr);
-
- var count = 0,
- pos = 0,
- length = substr.length;
-
- while (true) {
- pos = str.indexOf(substr, pos);
- if (pos === -1) break;
- count++;
- pos += length;
- }
-
- return count;
- },
-
- chars: function(str) {
- if (str == null) return [];
- return String(str).split('');
- },
-
- swapCase: function(str) {
- if (str == null) return '';
- return String(str).replace(/\S/g, function(c){
- return c === c.toUpperCase() ? c.toLowerCase() : c.toUpperCase();
- });
- },
-
- escapeHTML: function(str) {
- if (str == null) return '';
- return String(str).replace(/[&<>"']/g, function(m){ return '&' + reversedEscapeChars[m] + ';'; });
- },
-
- unescapeHTML: function(str) {
- if (str == null) return '';
- return String(str).replace(/\&([^;]+);/g, function(entity, entityCode){
- var match;
-
- if (entityCode in escapeChars) {
- return escapeChars[entityCode];
- } else if (match = entityCode.match(/^#x([\da-fA-F]+)$/)) {
- return String.fromCharCode(parseInt(match[1], 16));
- } else if (match = entityCode.match(/^#(\d+)$/)) {
- return String.fromCharCode(~~match[1]);
- } else {
- return entity;
- }
- });
- },
-
- escapeRegExp: function(str){
- if (str == null) return '';
- return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1');
- },
-
- splice: function(str, i, howmany, substr){
- var arr = _s.chars(str);
- arr.splice(~~i, ~~howmany, substr);
- return arr.join('');
- },
-
- insert: function(str, i, substr){
- return _s.splice(str, i, 0, substr);
- },
-
- include: function(str, needle){
- if (needle === '') return true;
- if (str == null) return false;
- return String(str).indexOf(needle) !== -1;
- },
-
- join: function() {
- var args = slice.call(arguments),
- separator = args.shift();
-
- if (separator == null) separator = '';
-
- return args.join(separator);
- },
-
- lines: function(str) {
- if (str == null) return [];
- return String(str).split("\n");
- },
-
- reverse: function(str){
- return _s.chars(str).reverse().join('');
- },
-
- startsWith: function(str, starts){
- if (starts === '') return true;
- if (str == null || starts == null) return false;
- str = String(str); starts = String(starts);
- return str.length >= starts.length && str.slice(0, starts.length) === starts;
- },
-
- endsWith: function(str, ends){
- if (ends === '') return true;
- if (str == null || ends == null) return false;
- str = String(str); ends = String(ends);
- return str.length >= ends.length && str.slice(str.length - ends.length) === ends;
- },
-
- succ: function(str){
- if (str == null) return '';
- str = String(str);
- return str.slice(0, -1) + String.fromCharCode(str.charCodeAt(str.length-1) + 1);
- },
-
- titleize: function(str){
- if (str == null) return '';
- str = String(str).toLowerCase();
- return str.replace(/(?:^|\s|-)\S/g, function(c){ return c.toUpperCase(); });
- },
-
- camelize: function(str){
- return _s.trim(str).replace(/[-_\s]+(.)?/g, function(match, c){ return c ? c.toUpperCase() : ""; });
- },
-
- underscored: function(str){
- return _s.trim(str).replace(/([a-z\d])([A-Z]+)/g, '$1_$2').replace(/[-\s]+/g, '_').toLowerCase();
- },
-
- dasherize: function(str){
- return _s.trim(str).replace(/([A-Z])/g, '-$1').replace(/[-_\s]+/g, '-').toLowerCase();
- },
-
- classify: function(str){
- return _s.titleize(String(str).replace(/[\W_]/g, ' ')).replace(/\s/g, '');
- },
-
- humanize: function(str){
- return _s.capitalize(_s.underscored(str).replace(/_id$/,'').replace(/_/g, ' '));
- },
-
- trim: function(str, characters){
- if (str == null) return '';
- if (!characters && nativeTrim) return nativeTrim.call(str);
- characters = defaultToWhiteSpace(characters);
- return String(str).replace(new RegExp('\^' + characters + '+|' + characters + '+$', 'g'), '');
- },
-
- ltrim: function(str, characters){
- if (str == null) return '';
- if (!characters && nativeTrimLeft) return nativeTrimLeft.call(str);
- characters = defaultToWhiteSpace(characters);
- return String(str).replace(new RegExp('^' + characters + '+'), '');
- },
-
- rtrim: function(str, characters){
- if (str == null) return '';
- if (!characters && nativeTrimRight) return nativeTrimRight.call(str);
- characters = defaultToWhiteSpace(characters);
- return String(str).replace(new RegExp(characters + '+$'), '');
- },
-
- truncate: function(str, length, truncateStr){
- if (str == null) return '';
- str = String(str); truncateStr = truncateStr || '...';
- length = ~~length;
- return str.length > length ? str.slice(0, length) + truncateStr : str;
- },
-
- /**
- * _s.prune: a more elegant version of truncate
- * prune extra chars, never leaving a half-chopped word.
- * @author github.com/rwz
- */
- prune: function(str, length, pruneStr){
- if (str == null) return '';
-
- str = String(str); length = ~~length;
- pruneStr = pruneStr != null ? String(pruneStr) : '...';
-
- if (str.length <= length) return str;
-
- var tmpl = function(c){ return c.toUpperCase() !== c.toLowerCase() ? 'A' : ' '; },
- template = str.slice(0, length+1).replace(/.(?=\W*\w*$)/g, tmpl); // 'Hello, world' -> 'HellAA AAAAA'
-
- if (template.slice(template.length-2).match(/\w\w/))
- template = template.replace(/\s*\S+$/, '');
- else
- template = _s.rtrim(template.slice(0, template.length-1));
-
- return (template+pruneStr).length > str.length ? str : str.slice(0, template.length)+pruneStr;
- },
-
- words: function(str, delimiter) {
- if (_s.isBlank(str)) return [];
- return _s.trim(str, delimiter).split(delimiter || /\s+/);
- },
-
- pad: function(str, length, padStr, type) {
- str = str == null ? '' : String(str);
- length = ~~length;
-
- var padlen = 0;
-
- if (!padStr)
- padStr = ' ';
- else if (padStr.length > 1)
- padStr = padStr.charAt(0);
-
- switch(type) {
- case 'right':
- padlen = length - str.length;
- return str + strRepeat(padStr, padlen);
- case 'both':
- padlen = length - str.length;
- return strRepeat(padStr, Math.ceil(padlen/2)) + str
- + strRepeat(padStr, Math.floor(padlen/2));
- default: // 'left'
- padlen = length - str.length;
- return strRepeat(padStr, padlen) + str;
- }
- },
-
- lpad: function(str, length, padStr) {
- return _s.pad(str, length, padStr);
- },
-
- rpad: function(str, length, padStr) {
- return _s.pad(str, length, padStr, 'right');
- },
-
- lrpad: function(str, length, padStr) {
- return _s.pad(str, length, padStr, 'both');
- },
-
- sprintf: sprintf,
-
- vsprintf: function(fmt, argv){
- argv.unshift(fmt);
- return sprintf.apply(null, argv);
- },
-
- toNumber: function(str, decimals) {
- if (!str) return 0;
- str = _s.trim(str);
- if (!str.match(/^-?\d+(?:\.\d+)?$/)) return NaN;
- return parseNumber(parseNumber(str).toFixed(~~decimals));
- },
-
- numberFormat : function(number, dec, dsep, tsep) {
- if (isNaN(number) || number == null) return '';
-
- number = number.toFixed(~~dec);
- tsep = typeof tsep == 'string' ? tsep : ',';
-
- var parts = number.split('.'), fnums = parts[0],
- decimals = parts[1] ? (dsep || '.') + parts[1] : '';
-
- return fnums.replace(/(\d)(?=(?:\d{3})+$)/g, '$1' + tsep) + decimals;
- },
-
- strRight: function(str, sep){
- if (str == null) return '';
- str = String(str); sep = sep != null ? String(sep) : sep;
- var pos = !sep ? -1 : str.indexOf(sep);
- return ~pos ? str.slice(pos+sep.length, str.length) : str;
- },
-
- strRightBack: function(str, sep){
- if (str == null) return '';
- str = String(str); sep = sep != null ? String(sep) : sep;
- var pos = !sep ? -1 : str.lastIndexOf(sep);
- return ~pos ? str.slice(pos+sep.length, str.length) : str;
- },
-
- strLeft: function(str, sep){
- if (str == null) return '';
- str = String(str); sep = sep != null ? String(sep) : sep;
- var pos = !sep ? -1 : str.indexOf(sep);
- return ~pos ? str.slice(0, pos) : str;
- },
-
- strLeftBack: function(str, sep){
- if (str == null) return '';
- str += ''; sep = sep != null ? ''+sep : sep;
- var pos = str.lastIndexOf(sep);
- return ~pos ? str.slice(0, pos) : str;
- },
-
- toSentence: function(array, separator, lastSeparator, serial) {
- separator = separator || ', ';
- lastSeparator = lastSeparator || ' and ';
- var a = array.slice(), lastMember = a.pop();
-
- if (array.length > 2 && serial) lastSeparator = _s.rtrim(separator) + lastSeparator;
-
- return a.length ? a.join(separator) + lastSeparator + lastMember : lastMember;
- },
-
- toSentenceSerial: function() {
- var args = slice.call(arguments);
- args[3] = true;
- return _s.toSentence.apply(_s, args);
- },
-
- slugify: function(str) {
- if (str == null) return '';
-
- var from = "ąàáäâãåæăćęèéëêìíïîłńòóöôõøśșțùúüûñçżź",
- to = "aaaaaaaaaceeeeeiiiilnoooooosstuuuunczz",
- regex = new RegExp(defaultToWhiteSpace(from), 'g');
-
- str = String(str).toLowerCase().replace(regex, function(c){
- var index = from.indexOf(c);
- return to.charAt(index) || '-';
- });
-
- return _s.dasherize(str.replace(/[^\w\s-]/g, ''));
- },
-
- surround: function(str, wrapper) {
- return [wrapper, str, wrapper].join('');
- },
-
- quote: function(str, quoteChar) {
- return _s.surround(str, quoteChar || '"');
- },
-
- unquote: function(str, quoteChar) {
- quoteChar = quoteChar || '"';
- if (str[0] === quoteChar && str[str.length-1] === quoteChar)
- return str.slice(1,str.length-1);
- else return str;
- },
-
- exports: function() {
- var result = {};
-
- for (var prop in this) {
- if (!this.hasOwnProperty(prop) || prop.match(/^(?:include|contains|reverse)$/)) continue;
- result[prop] = this[prop];
- }
-
- return result;
- },
-
- repeat: function(str, qty, separator){
- if (str == null) return '';
-
- qty = ~~qty;
-
- // using faster implementation if separator is not needed;
- if (separator == null) return strRepeat(String(str), qty);
-
- // this one is about 300x slower in Google Chrome
- for (var repeat = []; qty > 0; repeat[--qty] = str) {}
- return repeat.join(separator);
- },
-
- naturalCmp: function(str1, str2){
- if (str1 == str2) return 0;
- if (!str1) return -1;
- if (!str2) return 1;
-
- var cmpRegex = /(\.\d+)|(\d+)|(\D+)/g,
- tokens1 = String(str1).toLowerCase().match(cmpRegex),
- tokens2 = String(str2).toLowerCase().match(cmpRegex),
- count = Math.min(tokens1.length, tokens2.length);
-
- for(var i = 0; i < count; i++) {
- var a = tokens1[i], b = tokens2[i];
-
- if (a !== b){
- var num1 = parseInt(a, 10);
- if (!isNaN(num1)){
- var num2 = parseInt(b, 10);
- if (!isNaN(num2) && num1 - num2)
- return num1 - num2;
- }
- return a < b ? -1 : 1;
- }
- }
-
- if (tokens1.length === tokens2.length)
- return tokens1.length - tokens2.length;
-
- return str1 < str2 ? -1 : 1;
- },
-
- levenshtein: function(str1, str2) {
- if (str1 == null && str2 == null) return 0;
- if (str1 == null) return String(str2).length;
- if (str2 == null) return String(str1).length;
-
- str1 = String(str1); str2 = String(str2);
-
- var current = [], prev, value;
-
- for (var i = 0; i <= str2.length; i++)
- for (var j = 0; j <= str1.length; j++) {
- if (i && j)
- if (str1.charAt(j - 1) === str2.charAt(i - 1))
- value = prev;
- else
- value = Math.min(current[j], current[j - 1], prev) + 1;
- else
- value = i + j;
-
- prev = current[j];
- current[j] = value;
- }
-
- return current.pop();
- },
-
- toBoolean: function(str, trueValues, falseValues) {
- if (typeof str === "number") str = "" + str;
- if (typeof str !== "string") return !!str;
- str = _s.trim(str);
- if (boolMatch(str, trueValues || ["true", "1"])) return true;
- if (boolMatch(str, falseValues || ["false", "0"])) return false;
- }
- };
-
- // Aliases
-
- _s.strip = _s.trim;
- _s.lstrip = _s.ltrim;
- _s.rstrip = _s.rtrim;
- _s.center = _s.lrpad;
- _s.rjust = _s.lpad;
- _s.ljust = _s.rpad;
- _s.contains = _s.include;
- _s.q = _s.quote;
- _s.toBool = _s.toBoolean;
-
- // Exporting
-
- // CommonJS module is defined
- if (typeof exports !== 'undefined') {
- if (typeof module !== 'undefined' && module.exports)
- module.exports = _s;
-
- exports._s = _s;
- }
-
- // Register as a named module with AMD.
- if (typeof define === 'function' && define.amd)
- define('underscore.string', [], function(){ return _s; });
-
-
- // Integrate with Underscore.js if defined
- // or create our own underscore object.
- root._ = root._ || {};
- root._.string = root._.str = _s;
-}(this, String);
diff --git a/spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/libpeerconnection.log b/spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/libpeerconnection.log
deleted file mode 100644
index e69de29b..00000000
diff --git a/spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/package.json b/spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/package.json
deleted file mode 100644
index 1d0ca134..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/package.json
+++ /dev/null
@@ -1,98 +0,0 @@
-{
- "name": "underscore.string",
- "version": "2.3.3",
- "description": "String manipulation extensions for Underscore.js javascript library.",
- "homepage": "http://epeli.github.com/underscore.string/",
- "contributors": [
- {
- "name": "Esa-Matti Suuronen",
- "email": "esa-matti@suuronen.org",
- "url": "http://esa-matti.suuronen.org/"
- },
- {
- "name": "Edward Tsech",
- "email": "edtsech@gmail.com"
- },
- {
- "name": "Pavel Pravosud",
- "email": "pavel@pravosud.com",
- "url": ""
- },
- {
- "name": "Sasha Koss",
- "email": "kossnocorp@gmail.com",
- "url": "http://koss.nocorp.me/"
- },
- {
- "name": "Vladimir Dronnikov",
- "email": "dronnikov@gmail.com"
- },
- {
- "name": "Pete Kruckenberg",
- "email": "https://github.com/kruckenb",
- "url": ""
- },
- {
- "name": "Paul Chavard",
- "email": "paul@chavard.net",
- "url": ""
- },
- {
- "name": "Ed Finkler",
- "email": "coj@funkatron.com",
- "url": ""
- }
- ],
- "keywords": [
- "underscore",
- "string"
- ],
- "main": "./lib/underscore.string",
- "directories": {
- "lib": "./lib"
- },
- "engines": {
- "node": "*"
- },
- "repository": {
- "type": "git",
- "url": "https://github.com/epeli/underscore.string.git"
- },
- "bugs": {
- "url": "https://github.com/epeli/underscore.string/issues"
- },
- "licenses": [
- {
- "type": "MIT"
- }
- ],
- "_id": "underscore.string@2.3.3",
- "dist": {
- "shasum": "71c08bf6b428b1133f37e78fa3a21c82f7329b0d",
- "tarball": "http://registry.npmjs.org/underscore.string/-/underscore.string-2.3.3.tgz"
- },
- "_from": "underscore.string@~2.3.3",
- "_npmVersion": "1.2.32",
- "_npmUser": {
- "name": "epeli",
- "email": "esa-matti@suuronen.org"
- },
- "maintainers": [
- {
- "name": "edtsech",
- "email": "edtsech@gmail.com"
- },
- {
- "name": "rwz",
- "email": "rwz@duckroll.ru"
- },
- {
- "name": "epeli",
- "email": "esa-matti@suuronen.org"
- }
- ],
- "_shasum": "71c08bf6b428b1133f37e78fa3a21c82f7329b0d",
- "_resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-2.3.3.tgz",
- "readme": "ERROR: No README data found!",
- "scripts": {}
-}
diff --git a/spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/test/run-qunit.js b/spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/test/run-qunit.js
deleted file mode 100644
index 44a21670..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/test/run-qunit.js
+++ /dev/null
@@ -1,45 +0,0 @@
-function waitFor(test, complete, timeout) {
- var result, start = new Date().getTime()
- setInterval(function interval() {
- if ((new Date().getTime() - start < timeout) && !result) {
- result = test()
- } else {
- if (!result) {
- phantom.exit(1)
- } else {
- complete()
- clearInterval(interval)
- }
- }
- }, 100)
-}
-
-
-var fs = require('fs'), page = require('webpage').create();
-var url = 'file://localhost' + fs.workingDirectory + '/' + phantom.args[0];
-
-page.onConsoleMessage = function(msg) {
- console.log(msg)
-}
-
-page.open(url, function(status) {
- waitFor(function() {
- return page.evaluate(function(){
- var el = document.getElementById('qunit-testresult')
- return el && el.innerText.match('completed')
- })
- }, function() {
- var failures = page.evaluate(function() {
- var el = document.getElementById('qunit-testresult'),
- fails = document.getElementsByClassName('fail')
-
- for (var i = 0; i < fails.length; i++)
- console.log(fails[i].innerText)
-
- console.log(el.innerText)
-
- return parseInt(el.getElementsByClassName('failed')[0].innerHTML)
- })
- phantom.exit(failures > 0 ? 1 : 0)
- }, 10000)
-})
\ No newline at end of file
diff --git a/spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/test/speed.js b/spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/test/speed.js
deleted file mode 100644
index 9ceeea76..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/test/speed.js
+++ /dev/null
@@ -1,148 +0,0 @@
-(function() {
-
- JSLitmus.test('levenshtein', function() {
- return [
- _.levenshtein('pineapple', 'potato'),
- _.levenshtein('seven', 'eight'),
- _.levenshtein('the very same string', 'the very same string'),
- _.levenshtein('very very very long string', 'something completely different')
- ];
- });
-
-
- JSLitmus.test('trimNoNative', function() {
- return _.trim(" foobar ", " ");
- });
-
- JSLitmus.test('trim', function() {
- return _.trim(" foobar ");
- });
-
- JSLitmus.test('trim object-oriented', function() {
- return _(" foobar ").trim();
- });
-
- JSLitmus.test('trim jQuery', function() {
- return jQuery.trim(" foobar ");
- });
-
- JSLitmus.test('ltrimp', function() {
- return _.ltrim(" foobar ", " ");
- });
-
- JSLitmus.test('rtrimp', function() {
- return _.rtrim(" foobar ", " ");
- });
-
- JSLitmus.test('startsWith', function() {
- return _.startsWith("foobar", "foo");
- });
-
- JSLitmus.test('endsWith', function() {
- return _.endsWith("foobar", "xx");
- });
-
- JSLitmus.test('chop', function(){
- return _('whitespace').chop(2);
- });
-
- JSLitmus.test('count', function(){
- return _('Hello worls').count('l');
- });
-
- JSLitmus.test('insert', function() {
- return _('Hello ').insert(6, 'world');
- });
-
- JSLitmus.test('splice', function() {
- return _('https://edtsech@bitbucket.org/edtsech/underscore.strings').splice(30, 7, 'epeli');
- });
-
- JSLitmus.test('succ', function(){
- var let = 'a', alphabet = [];
-
- for (var i=0; i < 26; i++) {
- alphabet.push(let);
- let = _(let).succ();
- }
-
- return alphabet;
- });
-
- JSLitmus.test('titleize', function(){
- return _('the titleize string method').titleize();
- });
-
- JSLitmus.test('truncate', function(){
- return _('Hello world').truncate(5);
- });
-
- JSLitmus.test('prune', function(){
- return _('Hello world').prune(5);
- });
-
- JSLitmus.test('isBlank', function(){
- return _('').isBlank();
- });
-
- JSLitmus.test('escapeHTML', function(){
- _('Blah blah blah
').escapeHTML();
- });
-
- JSLitmus.test('unescapeHTML', function(){
- _('<div>Blah blah blah</div>').unescapeHTML();
- });
-
- JSLitmus.test('reverse', function(){
- _('Hello World').reverse();
- });
-
- JSLitmus.test('pad default', function(){
- _('foo').pad(12);
- });
-
- JSLitmus.test('pad hash left', function(){
- _('foo').pad(12, '#');
- });
-
- JSLitmus.test('pad hash right', function(){
- _('foo').pad(12, '#', 'right');
- });
-
- JSLitmus.test('pad hash both', function(){
- _('foo').pad(12, '#', 'both');
- });
-
- JSLitmus.test('pad hash both longPad', function(){
- _('foo').pad(12, 'f00f00f00', 'both');
- });
-
- JSLitmus.test('toNumber', function(){
- _('10.232323').toNumber(2);
- });
-
- JSLitmus.test('strRight', function(){
- _('aaa_bbb_ccc').strRight('_');
- });
-
- JSLitmus.test('strRightBack', function(){
- _('aaa_bbb_ccc').strRightBack('_');
- });
-
- JSLitmus.test('strLeft', function(){
- _('aaa_bbb_ccc').strLeft('_');
- });
-
- JSLitmus.test('strLeftBack', function(){
- _('aaa_bbb_ccc').strLeftBack('_');
- });
-
- JSLitmus.test('join', function(){
- _('separator').join(1, 2, 3, 4, 5, 6, 7, 8, 'foo', 'bar', 'lol', 'wut');
- });
-
- JSLitmus.test('slugify', function(){
- _("Un éléphant à l'orée du bois").slugify();
- });
-
-})();
diff --git a/spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/test/strings.js b/spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/test/strings.js
deleted file mode 100644
index 77364f20..00000000
--- a/spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/test/strings.js
+++ /dev/null
@@ -1,685 +0,0 @@
-$(document).ready(function() {
-
- // Include Underscore.string methods to Underscore namespace
- _.mixin(_.str.exports());
-
- module('String extensions');
-
- test('Strings: naturalSort', function() {
- var arr = ['foo2', 'foo1', 'foo10', 'foo30', 'foo100', 'foo10bar'],
- sorted = ['foo1', 'foo2', 'foo10', 'foo10bar', 'foo30', 'foo100'];
- deepEqual(arr.sort(_.naturalCmp), sorted);
- });
-
- test('Strings: trim', function() {
- equal(_.trim(123), '123', 'Non string');
- equal(_(' foo').trim(), 'foo');
- equal(_('foo ').trim(), 'foo');
- equal(_(' foo ').trim(), 'foo');
- equal(_(' foo ').trim(), 'foo');
- equal(_(' foo ').trim(' '), 'foo', 'Manually set whitespace');
- equal(_('\t foo \t ').trim(/\s/), 'foo', 'Manually set RegExp /\\s+/');
-
- equal(_('ffoo').trim('f'), 'oo');
- equal(_('ooff').trim('f'), 'oo');
- equal(_('ffooff').trim('f'), 'oo');
-
-
- equal(_('_-foobar-_').trim('_-'), 'foobar');
-
- equal(_('http://foo/').trim('/'), 'http://foo');
- equal(_('c:\\').trim('\\'), 'c:');
-
- equal(_(123).trim(), '123');
- equal(_(123).trim(3), '12');
- equal(_('').trim(), '', 'Trim empty string should return empty string');
- equal(_(null).trim(), '', 'Trim null should return empty string');
- equal(_(undefined).trim(), '', 'Trim undefined should return empty string');
- });
-
- test('String: levenshtein', function() {
- equal(_.levenshtein('Godfather', 'Godfather'), 0);
- equal(_.levenshtein('Godfather', 'Godfathe'), 1);
- equal(_.levenshtein('Godfather', 'odfather'), 1);
- equal(_.levenshtein('Godfather', 'Gdfthr'), 3);
- equal(_.levenshtein('seven', 'eight'), 5);
- equal(_.levenshtein('123', 123), 0);
- equal(_.levenshtein(321, '321'), 0);
- equal(_.levenshtein('lol', null), 3);
- equal(_.levenshtein('lol'), 3);
- equal(_.levenshtein(null, 'lol'), 3);
- equal(_.levenshtein(undefined, 'lol'), 3);
- equal(_.levenshtein(), 0);
- });
-
- test('Strings: ltrim', function() {
- equal(_(' foo').ltrim(), 'foo');
- equal(_(' foo').ltrim(), 'foo');
- equal(_('foo ').ltrim(), 'foo ');
- equal(_(' foo ').ltrim(), 'foo ');
- equal(_('').ltrim(), '', 'ltrim empty string should return empty string');
- equal(_(null).ltrim(), '', 'ltrim null should return empty string');
- equal(_(undefined).ltrim(), '', 'ltrim undefined should return empty string');
-
- equal(_('ffoo').ltrim('f'), 'oo');
- equal(_('ooff').ltrim('f'), 'ooff');
- equal(_('ffooff').ltrim('f'), 'ooff');
-
- equal(_('_-foobar-_').ltrim('_-'), 'foobar-_');
-
- equal(_(123).ltrim(1), '23');
- });
-
- test('Strings: rtrim', function() {
- equal(_('http://foo/').rtrim('/'), 'http://foo', 'clean trailing slash');
- equal(_(' foo').rtrim(), ' foo');
- equal(_('foo ').rtrim(), 'foo');
- equal(_('foo ').rtrim(), 'foo');
- equal(_('foo bar ').rtrim(), 'foo bar');
- equal(_(' foo ').rtrim(), ' foo');
-
- equal(_('ffoo').rtrim('f'), 'ffoo');
- equal(_('ooff').rtrim('f'), 'oo');
- equal(_('ffooff').rtrim('f'), 'ffoo');
-
- equal(_('_-foobar-_').rtrim('_-'), '_-foobar');
-
- equal(_(123).rtrim(3), '12');
- equal(_('').rtrim(), '', 'rtrim empty string should return empty string');
- equal(_(null).rtrim(), '', 'rtrim null should return empty string');
- });
-
- test('Strings: capitalize', function() {
- equal(_('fabio').capitalize(), 'Fabio', 'First letter is upper case');
- equal(_.capitalize('fabio'), 'Fabio', 'First letter is upper case');
- equal(_.capitalize('FOO'), 'FOO', 'Other letters unchanged');
- equal(_(123).capitalize(), '123', 'Non string');
- equal(_.capitalize(''), '', 'Capitalizing empty string returns empty string');
- equal(_.capitalize(null), '', 'Capitalizing null returns empty string');
- equal(_.capitalize(undefined), '', 'Capitalizing undefined returns empty string');
- });
-
- test('Strings: join', function() {
- equal(_.join('', 'foo', 'bar'), 'foobar', 'basic join');
- equal(_.join('', 1, 'foo', 2), '1foo2', 'join numbers and strings');
- equal(_.join(' ','foo', 'bar'), 'foo bar', 'join with spaces');
- equal(_.join('1', '2', '2'), '212', 'join number strings');
- equal(_.join(1, 2, 2), '212', 'join numbers');
- equal(_.join('','foo', null), 'foo', 'join null with string returns string');
- equal(_.join(null,'foo', 'bar'), 'foobar', 'join strings with null returns string');
- equal(_(' ').join('foo', 'bar'), 'foo bar', 'join object oriented');
- });
-
- test('Strings: reverse', function() {
- equal(_.str.reverse('foo'), 'oof' );
- equal(_.str.reverse('foobar'), 'raboof' );
- equal(_.str.reverse('foo bar'), 'rab oof' );
- equal(_.str.reverse('saippuakauppias'), 'saippuakauppias' );
- equal(_.str.reverse(123), '321', 'Non string');
- equal(_.str.reverse(123.45), '54.321', 'Non string');
- equal(_.str.reverse(''), '', 'reversing empty string returns empty string' );
- equal(_.str.reverse(null), '', 'reversing null returns empty string' );
- equal(_.str.reverse(undefined), '', 'reversing undefined returns empty string' );
- });
-
- test('Strings: clean', function() {
- equal(_(' foo bar ').clean(), 'foo bar');
- equal(_(123).clean(), '123');
- equal(_('').clean(), '', 'claning empty string returns empty string');
- equal(_(null).clean(), '', 'claning null returns empty string');
- equal(_(undefined).clean(), '', 'claning undefined returns empty string');
- });
-
- test('Strings: sprintf', function() {
- // Should be very tested function already. Thanks to
- // http://www.diveintojavascript.com/projects/sprintf-for-javascript
- equal(_.sprintf('Hello %s', 'me'), 'Hello me', 'basic');
- equal(_('Hello %s').sprintf('me'), 'Hello me', 'object');
- equal(_('hello %s').chain().sprintf('me').capitalize().value(), 'Hello me', 'Chaining works');
- equal(_.sprintf('%.1f', 1.22222), '1.2', 'round');
- equal(_.sprintf('%.1f', 1.17), '1.2', 'round 2');
- equal(_.sprintf('%(id)d - %(name)s', {id: 824, name: 'Hello World'}), '824 - Hello World', 'Named replacements work');
- equal(_.sprintf('%(args[0].id)d - %(args[1].name)s', {args: [{id: 824}, {name: 'Hello World'}]}), '824 - Hello World', 'Named replacements with arrays work');
- });
-
-
- test('Strings: vsprintf', function() {
- equal(_.vsprintf('Hello %s', ['me']), 'Hello me', 'basic');
- equal(_('Hello %s').vsprintf(['me']), 'Hello me', 'object');
- equal(_('hello %s').chain().vsprintf(['me']).capitalize().value(), 'Hello me', 'Chaining works');
- equal(_.vsprintf('%.1f', [1.22222]), '1.2', 'round');
- equal(_.vsprintf('%.1f', [1.17]), '1.2', 'round 2');
- equal(_.vsprintf('%(id)d - %(name)s', [{id: 824, name: 'Hello World'}]), '824 - Hello World', 'Named replacement works');
- equal(_.vsprintf('%(args[0].id)d - %(args[1].name)s', [{args: [{id: 824}, {name: 'Hello World'}]}]), '824 - Hello World', 'Named replacement with arrays works');
- });
-
- test('Strings: startsWith', function() {
- ok(_('foobar').startsWith('foo'), 'foobar starts with foo');
- ok(!_('oobar').startsWith('foo'), 'oobar does not start with foo');
- ok(_(12345).startsWith(123), '12345 starts with 123');
- ok(!_(2345).startsWith(123), '2345 does not start with 123');
- ok(_('').startsWith(''), 'empty string starts with empty string');
- ok(_(null).startsWith(''), 'null starts with empty string');
- ok(!_(null).startsWith('foo'), 'null starts with foo');
- });
-
- test('Strings: endsWith', function() {
- ok(_('foobar').endsWith('bar'), 'foobar ends with bar');
- ok(_.endsWith('foobar', 'bar'), 'foobar ends with bar');
- ok(_.endsWith('00018-0000062.Plone.sdh264.1a7264e6912a91aa4a81b64dc5517df7b8875994.mp4', 'mp4'), 'endsWith .mp4');
- ok(!_('fooba').endsWith('bar'), 'fooba does not end with bar');
- ok(_.endsWith(12345, 45), '12345 ends with 45');
- ok(!_.endsWith(12345, 6), '12345 does not end with 6');
- ok(_('').endsWith(''), 'empty string ends with empty string');
- ok(_(null).endsWith(''), 'null ends with empty string');
- ok(!_(null).endsWith('foo'), 'null ends with foo');
- });
-
- test('Strings: include', function() {
- ok(_.str.include('foobar', 'bar'), 'foobar includes bar');
- ok(!_.str.include('foobar', 'buzz'), 'foobar does not includes buzz');
- ok(_.str.include(12345, 34), '12345 includes 34');
- ok(!_.str.contains(12345, 6), '12345 does not includes 6');
- ok(!_.str.include('', 34), 'empty string includes 34');
- ok(!_.str.include(null, 34), 'null includes 34');
- ok(_.str.include(null, ''), 'null includes empty string');
- });
-
- test('String: chop', function(){
- ok(_('whitespace').chop(2).length === 5, 'output [wh, it, es, pa, ce]');
- ok(_('whitespace').chop(3).length === 4, 'output [whi, tes, pac, e]');
- ok(_('whitespace').chop()[0].length === 10, 'output [whitespace]');
- ok(_(12345).chop(1).length === 5, 'output [1, 2, 3, 4, 5]');
- });
-
- test('String: clean', function(){
- equal(_.clean(' foo bar '), 'foo bar');
- equal(_.clean(''), '');
- equal(_.clean(null), '');
- equal(_.clean(1), '1');
- });
-
- test('String: count', function(){
- equal(_('Hello world').count('l'), 3);
- equal(_('Hello world').count('Hello'), 1);
- equal(_('Hello world').count('foo'), 0);
- equal(_('x.xx....x.x').count('x'), 5);
- equal(_('').count('x'), 0);
- equal(_(null).count('x'), 0);
- equal(_(undefined).count('x'), 0);
- equal(_(12345).count(1), 1);
- equal(_(11345).count(1), 2);
- });
-
- test('String: insert', function(){
- equal(_('Hello ').insert(6, 'Jessy'), 'Hello Jessy');
- equal(_('Hello ').insert(100, 'Jessy'), 'Hello Jessy');
- equal(_('').insert(100, 'Jessy'), 'Jessy');
- equal(_(null).insert(100, 'Jessy'), 'Jessy');
- equal(_(undefined).insert(100, 'Jessy'), 'Jessy');
- equal(_(12345).insert(6, 'Jessy'), '12345Jessy');
- });
-
- test('String: splice', function(){
- equal(_('https://edtsech@bitbucket.org/edtsech/underscore.strings').splice(30, 7, 'epeli'),
- 'https://edtsech@bitbucket.org/epeli/underscore.strings');
- equal(_.splice(12345, 1, 2, 321), '132145', 'Non strings');
- });
-
- test('String: succ', function(){
- equal(_('a').succ(), 'b');
- equal(_('A').succ(), 'B');
- equal(_('+').succ(), ',');
- equal(_(1).succ(), '2');
- });
-
- test('String: titleize', function(){
- equal(_('the titleize string method').titleize(), 'The Titleize String Method');
- equal(_('the titleize string method').titleize(), 'The Titleize String Method');
- equal(_('').titleize(), '', 'Titleize empty string returns empty string');
- equal(_(null).titleize(), '', 'Titleize null returns empty string');
- equal(_(undefined).titleize(), '', 'Titleize undefined returns empty string');
- equal(_('let\'s have some fun').titleize(), 'Let\'s Have Some Fun');
- equal(_('a-dash-separated-string').titleize(), 'A-Dash-Separated-String');
- equal(_('A-DASH-SEPARATED-STRING').titleize(), 'A-Dash-Separated-String');
- equal(_(123).titleize(), '123');
- });
-
- test('String: camelize', function(){
- equal(_('the_camelize_string_method').camelize(), 'theCamelizeStringMethod');
- equal(_('-the-camelize-string-method').camelize(), 'TheCamelizeStringMethod');
- equal(_('the camelize string method').camelize(), 'theCamelizeStringMethod');
- equal(_(' the camelize string method').camelize(), 'theCamelizeStringMethod');
- equal(_('the camelize string method').camelize(), 'theCamelizeStringMethod');
- equal(_('').camelize(), '', 'Camelize empty string returns empty string');
- equal(_(null).camelize(), '', 'Camelize null returns empty string');
- equal(_(undefined).camelize(), '', 'Camelize undefined returns empty string');
- equal(_(123).camelize(), '123');
- });
-
- test('String: underscored', function(){
- equal(_('the-underscored-string-method').underscored(), 'the_underscored_string_method');
- equal(_('theUnderscoredStringMethod').underscored(), 'the_underscored_string_method');
- equal(_('TheUnderscoredStringMethod').underscored(), 'the_underscored_string_method');
- equal(_(' the underscored string method').underscored(), 'the_underscored_string_method');
- equal(_('').underscored(), '');
- equal(_(null).underscored(), '');
- equal(_(undefined).underscored(), '');
- equal(_(123).underscored(), '123');
- });
-
- test('String: dasherize', function(){
- equal(_('the_dasherize_string_method').dasherize(), 'the-dasherize-string-method');
- equal(_('TheDasherizeStringMethod').dasherize(), '-the-dasherize-string-method');
- equal(_('thisIsATest').dasherize(), 'this-is-a-test');
- equal(_('this Is A Test').dasherize(), 'this-is-a-test');
- equal(_('thisIsATest123').dasherize(), 'this-is-a-test123');
- equal(_('123thisIsATest').dasherize(), '123this-is-a-test');
- equal(_('the dasherize string method').dasherize(), 'the-dasherize-string-method');
- equal(_('the dasherize string method ').dasherize(), 'the-dasherize-string-method');
- equal(_('téléphone').dasherize(), 'téléphone');
- equal(_('foo$bar').dasherize(), 'foo$bar');
- equal(_('').dasherize(), '');
- equal(_(null).dasherize(), '');
- equal(_(undefined).dasherize(), '');
- equal(_(123).dasherize(), '123');
- });
-
- test('String: camelize', function(){
- equal(_.camelize('-moz-transform'), 'MozTransform');
- equal(_.camelize('webkit-transform'), 'webkitTransform');
- equal(_.camelize('under_scored'), 'underScored');
- equal(_.camelize(' with spaces'), 'withSpaces');
- equal(_('').camelize(), '');
- equal(_(null).camelize(), '');
- equal(_(undefined).camelize(), '');
- equal(_("_som eWeird---name-").camelize(), 'SomEWeirdName');
- });
-
- test('String: join', function(){
- equal(_.join(1, 2, 3, 4), '21314');
- equal(_.join('|', 'foo', 'bar', 'baz'), 'foo|bar|baz');
- equal(_.join('',2,3,null), '23');
- equal(_.join(null,2,3), '23');
- });
-
- test('String: classify', function(){
- equal(_.classify(1), '1');
- equal(_('some_class_name').classify(), 'SomeClassName');
- equal(_('my wonderfull class_name').classify(), 'MyWonderfullClassName');
- equal(_('my wonderfull.class.name').classify(), 'MyWonderfullClassName');
- });
-
- test('String: humanize', function(){
- equal(_('the_humanize_string_method').humanize(), 'The humanize string method');
- equal(_('ThehumanizeStringMethod').humanize(), 'Thehumanize string method');
- equal(_('the humanize string method').humanize(), 'The humanize string method');
- equal(_('the humanize_id string method_id').humanize(), 'The humanize id string method');
- equal(_('the humanize string method ').humanize(), 'The humanize string method');
- equal(_(' capitalize dash-CamelCase_underscore trim ').humanize(), 'Capitalize dash camel case underscore trim');
- equal(_(123).humanize(), '123');
- equal(_('').humanize(), '');
- equal(_(null).humanize(), '');
- equal(_(undefined).humanize(), '');
- });
-
- test('String: truncate', function(){
- equal(_('Hello world').truncate(6, 'read more'), 'Hello read more');
- equal(_('Hello world').truncate(5), 'Hello...');
- equal(_('Hello').truncate(10), 'Hello');
- equal(_('').truncate(10), '');
- equal(_(null).truncate(10), '');
- equal(_(undefined).truncate(10), '');
- equal(_(1234567890).truncate(5), '12345...');
- });
-
- test('String: prune', function(){
- equal(_('Hello, cruel world').prune(6, ' read more'), 'Hello read more');
- equal(_('Hello, world').prune(5, 'read a lot more'), 'Hello, world');
- equal(_('Hello, world').prune(5), 'Hello...');
- equal(_('Hello, world').prune(8), 'Hello...');
- equal(_('Hello, cruel world').prune(15), 'Hello, cruel...');
- equal(_('Hello world').prune(22), 'Hello world');
- equal(_('Привет, жестокий мир').prune(6, ' read more'), 'Привет read more');
- equal(_('Привет, мир').prune(6, 'read a lot more'), 'Привет, мир');
- equal(_('Привет, мир').prune(6), 'Привет...');
- equal(_('Привет, мир').prune(8), 'Привет...');
- equal(_('Привет, жестокий мир').prune(16), 'Привет, жестокий...');
- equal(_('Привет, мир').prune(22), 'Привет, мир');
- equal(_('alksjd!!!!!!....').prune(100, ''), 'alksjd!!!!!!....');
- equal(_(123).prune(10), '123');
- equal(_(123).prune(1, 321), '321');
- equal(_('').prune(5), '');
- equal(_(null).prune(5), '');
- equal(_(undefined).prune(5), '');
- });
-
- test('String: isBlank', function(){
- ok(_('').isBlank());
- ok(_(' ').isBlank());
- ok(_('\n').isBlank());
- ok(!_('a').isBlank());
- ok(!_('0').isBlank());
- ok(!_(0).isBlank());
- ok(_('').isBlank());
- ok(_(null).isBlank());
- ok(_(undefined).isBlank());
- });
-
- test('String: escapeRegExp', function(){
- equal(_.escapeRegExp(/hello(?=\sworld)/.source), 'hello\\(\\?\\=\\\\sworld\\)', 'with lookahead');
- equal(_.escapeRegExp(/hello(?!\shell)/.source), 'hello\\(\\?\\!\\\\shell\\)', 'with negative lookahead');
- });
-
- test('String: escapeHTML', function(){
- equal(_('Blah & "blah" & \'blah\'
').escapeHTML(),
- '<div>Blah & "blah" & 'blah'</div>');
- equal(_('<').escapeHTML(), '<');
- equal(_(5).escapeHTML(), '5');
- equal(_('').escapeHTML(), '');
- equal(_(null).escapeHTML(), '');
- equal(_(undefined).escapeHTML(), '');
- });
-
- test('String: unescapeHTML', function(){
- equal(_('<div>Blah & "blah" & 'blah'</div>').unescapeHTML(),
- 'Blah & "blah" & \'blah\'
');
- equal(_('<').unescapeHTML(), '<');
- equal(_(''').unescapeHTML(), '\'');
- equal(_(''').unescapeHTML(), '\'');
- equal(_(''').unescapeHTML(), '\'');
- equal(_('J').unescapeHTML(), 'J');
- equal(_('J').unescapeHTML(), 'J');
- equal(_('J').unescapeHTML(), 'J');
- equal(_('&_#39;').unescapeHTML(), '&_#39;');
- equal(_(''_;').unescapeHTML(), ''_;');
- equal(_('&').unescapeHTML(), '&');
- equal(_('&').unescapeHTML(), '&');
- equal(_('').unescapeHTML(), '');
- equal(_(null).unescapeHTML(), '');
- equal(_(undefined).unescapeHTML(), '');
- equal(_(5).unescapeHTML(), '5');
- // equal(_(undefined).unescapeHTML(), '');
- });
-
- test('String: words', function() {
- deepEqual(_('I love you!').words(), ['I', 'love', 'you!']);
- deepEqual(_(' I love you! ').words(), ['I', 'love', 'you!']);
- deepEqual(_('I_love_you!').words('_'), ['I', 'love', 'you!']);
- deepEqual(_('I-love-you!').words(/-/), ['I', 'love', 'you!']);
- deepEqual(_(123).words(), ['123'], '123 number has one word "123".');
- deepEqual(_(0).words(), ['0'], 'Zero number has one word "0".');
- deepEqual(_('').words(), [], 'Empty strings has no words.');
- deepEqual(_(' ').words(), [], 'Blank strings has no words.');
- deepEqual(_(null).words(), [], 'null has no words.');
- deepEqual(_(undefined).words(), [], 'undefined has no words.');
- });
-
- test('String: chars', function() {
- equal(_('Hello').chars().length, 5);
- equal(_(123).chars().length, 3);
- equal(_('').chars().length, 0);
- equal(_(null).chars().length, 0);
- equal(_(undefined).chars().length, 0);
- });
-
- test('String: swapCase', function(){
- equal(_('AaBbCcDdEe').swapCase(), 'aAbBcCdDeE');
- equal(_('Hello World').swapCase(), 'hELLO wORLD');
- equal(_('').swapCase(), '');
- equal(_(null).swapCase(), '');
- equal(_(undefined).swapCase(), '');
- });
-
- test('String: lines', function() {
- equal(_('Hello\nWorld').lines().length, 2);
- equal(_('Hello World').lines().length, 1);
- equal(_(123).lines().length, 1);
- equal(_('').lines().length, 1);
- equal(_(null).lines().length, 0);
- equal(_(undefined).lines().length, 0);
- });
-
- test('String: pad', function() {
- equal(_('1').pad(8), ' 1');
- equal(_(1).pad(8), ' 1');
- equal(_('1').pad(8, '0'), '00000001');
- equal(_('1').pad(8, '0', 'left'), '00000001');
- equal(_('1').pad(8, '0', 'right'), '10000000');
- equal(_('1').pad(8, '0', 'both'), '00001000');
- equal(_('foo').pad(8, '0', 'both'), '000foo00');
- equal(_('foo').pad(7, '0', 'both'), '00foo00');
- equal(_('foo').pad(7, '!@$%dofjrofj', 'both'), '!!foo!!');
- equal(_('').pad(2), ' ');
- equal(_(null).pad(2), ' ');
- equal(_(undefined).pad(2), ' ');
- });
-
- test('String: lpad', function() {
- equal(_('1').lpad(8), ' 1');
- equal(_(1).lpad(8), ' 1');
- equal(_('1').lpad(8, '0'), '00000001');
- equal(_('1').lpad(8, '0', 'left'), '00000001');
- equal(_('').lpad(2), ' ');
- equal(_(null).lpad(2), ' ');
- equal(_(undefined).lpad(2), ' ');
- });
-
- test('String: rpad', function() {
- equal(_('1').rpad(8), '1 ');
- equal(_(1).lpad(8), ' 1');
- equal(_('1').rpad(8, '0'), '10000000');
- equal(_('foo').rpad(8, '0'), 'foo00000');
- equal(_('foo').rpad(7, '0'), 'foo0000');
- equal(_('').rpad(2), ' ');
- equal(_(null).rpad(2), ' ');
- equal(_(undefined).rpad(2), ' ');
- });
-
- test('String: lrpad', function() {
- equal(_('1').lrpad(8), ' 1 ');
- equal(_(1).lrpad(8), ' 1 ');
- equal(_('1').lrpad(8, '0'), '00001000');
- equal(_('foo').lrpad(8, '0'), '000foo00');
- equal(_('foo').lrpad(7, '0'), '00foo00');
- equal(_('foo').lrpad(7, '!@$%dofjrofj'), '!!foo!!');
- equal(_('').lrpad(2), ' ');
- equal(_(null).lrpad(2), ' ');
- equal(_(undefined).lrpad(2), ' ');
- });
-
- test('String: toNumber', function() {
- deepEqual(_('not a number').toNumber(), NaN);
- equal(_(0).toNumber(), 0);
- equal(_('0').toNumber(), 0);
- equal(_('0.0').toNumber(), 0);
- equal(_('0.1').toNumber(), 0);
- equal(_('0.1').toNumber(1), 0.1);
- equal(_(' 0.1 ').toNumber(1), 0.1);
- equal(_('0000').toNumber(), 0);
- equal(_('2.345').toNumber(), 2);
- equal(_('2.345').toNumber(NaN), 2);
- equal(_('2.345').toNumber(2), 2.35);
- equal(_('2.344').toNumber(2), 2.34);
- equal(_('2').toNumber(2), 2.00);
- equal(_(2).toNumber(2), 2.00);
- equal(_(-2).toNumber(), -2);
- equal(_('-2').toNumber(), -2);
- equal(_('').toNumber(), 0);
- equal(_(null).toNumber(), 0);
- equal(_(undefined).toNumber(), 0);
- });
-
- test('String: numberFormat', function() {
- equal(_.numberFormat(9000), '9,000');
- equal(_.numberFormat(9000, 0), '9,000');
- equal(_.numberFormat(9000, 0, '', ''), '9000');
- equal(_.numberFormat(90000, 2), '90,000.00');
- equal(_.numberFormat(1000.754), '1,001');
- equal(_.numberFormat(1000.754, 2), '1,000.75');
- equal(_.numberFormat(1000.754, 0, ',', '.'), '1.001');
- equal(_.numberFormat(1000.754, 2, ',', '.'), '1.000,75');
- equal(_.numberFormat(1000000.754, 2, ',', '.'), '1.000.000,75');
- equal(_.numberFormat(1000000000), '1,000,000,000');
- equal(_.numberFormat(100000000), '100,000,000');
- equal(_.numberFormat('not number'), '');
- equal(_.numberFormat(), '');
- equal(_.numberFormat(null, '.', ','), '');
- equal(_.numberFormat(undefined, '.', ','), '');
- equal(_.numberFormat(new Number(5000)), '5,000');
- });
-
- test('String: strRight', function() {
- equal(_('This_is_a_test_string').strRight('_'), 'is_a_test_string');
- equal(_('This_is_a_test_string').strRight('string'), '');
- equal(_('This_is_a_test_string').strRight(), 'This_is_a_test_string');
- equal(_('This_is_a_test_string').strRight(''), 'This_is_a_test_string');
- equal(_('This_is_a_test_string').strRight('-'), 'This_is_a_test_string');
- equal(_('This_is_a_test_string').strRight(''), 'This_is_a_test_string');
- equal(_('').strRight('foo'), '');
- equal(_(null).strRight('foo'), '');
- equal(_(undefined).strRight('foo'), '');
- equal(_(12345).strRight(2), '345');
- });
-
- test('String: strRightBack', function() {
- equal(_('This_is_a_test_string').strRightBack('_'), 'string');
- equal(_('This_is_a_test_string').strRightBack('string'), '');
- equal(_('This_is_a_test_string').strRightBack(), 'This_is_a_test_string');
- equal(_('This_is_a_test_string').strRightBack(''), 'This_is_a_test_string');
- equal(_('This_is_a_test_string').strRightBack('-'), 'This_is_a_test_string');
- equal(_('').strRightBack('foo'), '');
- equal(_(null).strRightBack('foo'), '');
- equal(_(undefined).strRightBack('foo'), '');
- equal(_(12345).strRightBack(2), '345');
- });
-
- test('String: strLeft', function() {
- equal(_('This_is_a_test_string').strLeft('_'), 'This');
- equal(_('This_is_a_test_string').strLeft('This'), '');
- equal(_('This_is_a_test_string').strLeft(), 'This_is_a_test_string');
- equal(_('This_is_a_test_string').strLeft(''), 'This_is_a_test_string');
- equal(_('This_is_a_test_string').strLeft('-'), 'This_is_a_test_string');
- equal(_('').strLeft('foo'), '');
- equal(_(null).strLeft('foo'), '');
- equal(_(undefined).strLeft('foo'), '');
- equal(_(123454321).strLeft(3), '12');
- });
-
- test('String: strLeftBack', function() {
- equal(_('This_is_a_test_string').strLeftBack('_'), 'This_is_a_test');
- equal(_('This_is_a_test_string').strLeftBack('This'), '');
- equal(_('This_is_a_test_string').strLeftBack(), 'This_is_a_test_string');
- equal(_('This_is_a_test_string').strLeftBack(''), 'This_is_a_test_string');
- equal(_('This_is_a_test_string').strLeftBack('-'), 'This_is_a_test_string');
- equal(_('').strLeftBack('foo'), '');
- equal(_(null).strLeftBack('foo'), '');
- equal(_(undefined).strLeftBack('foo'), '');
- equal(_(123454321).strLeftBack(3), '123454');
- });
-
- test('Strings: stripTags', function() {
- equal(_('a link').stripTags(), 'a link');
- equal(_('a link
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-