diff --git a/.babelrc b/.babelrc
new file mode 100644
index 000000000..c13c5f627
--- /dev/null
+++ b/.babelrc
@@ -0,0 +1,3 @@
+{
+ "presets": ["es2015"]
+}
diff --git a/.editorconfig b/.editorconfig
index 7f502d449..44b5d3126 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -8,3 +8,10 @@ trim_trailing_whitespace = true
insert_final_newline = true
indent_style = space
indent_size = 4
+
+[package.json]
+indent_size = 2
+
+[Makefile]
+indent_style = tab
+indent_size = 4
diff --git a/.gitignore b/.gitignore
index 9134974d9..1f0529227 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,10 @@
node_modules
-dist
perf/versions
nyc_output
coverage
*.log
+.DS_Store
+npm-debug.log
+tmp
+build
+build-es
diff --git a/.gitmodules b/.gitmodules
deleted file mode 100644
index a9aae984f..000000000
--- a/.gitmodules
+++ /dev/null
@@ -1,9 +0,0 @@
-[submodule "deps/nodeunit"]
- path = deps/nodeunit
- url = git://github.com/caolan/nodeunit.git
-[submodule "deps/UglifyJS"]
- path = deps/UglifyJS
- url = https://github.com/mishoo/UglifyJS.git
-[submodule "deps/nodelint"]
- path = deps/nodelint
- url = https://github.com/tav/nodelint.git
diff --git a/.jscsrc b/.jscsrc
index b8cfa1731..3e93b597f 100644
--- a/.jscsrc
+++ b/.jscsrc
@@ -1,3 +1,4 @@
{
- "validateIndentation": 4
-}
\ No newline at end of file
+ "validateIndentation": 4,
+ "esnext": true
+}
diff --git a/.jshintrc b/.jshintrc
index 76be34a84..375fbdfda 100644
--- a/.jshintrc
+++ b/.jshintrc
@@ -9,6 +9,7 @@
"trailing": true,
"evil": true,
"laxcomma": true,
+ "esnext": true,
// Relaxing options
"onevar": false,
@@ -24,6 +25,8 @@
"define": true,
"describe": true,
"context": true,
- "it": true
+ "it": true,
+ "before": true,
+ "after": true
}
}
diff --git a/.npmignore b/.npmignore
new file mode 100644
index 000000000..4274f795c
--- /dev/null
+++ b/.npmignore
@@ -0,0 +1,4 @@
+lib
+scripts
+support/dependencies.json
+support/module_template.md
diff --git a/Makefile b/Makefile
index 87279f40c..80e8f5286 100644
--- a/Makefile
+++ b/Makefile
@@ -1,37 +1,123 @@
+# This makefile is meant to be run on OSX/Linux. Make sure any artifacts
+# created here are checked in so people on all platforms can run npm scripts.
+# This build should be run once per release.
+
export PATH := ./node_modules/.bin/:$(PATH):./bin/
PACKAGE = asyncjs
-XYZ = node_modules/.bin/xyz --repo git@github.com:caolan/async.git
+REQUIRE_NAME = async
+BABEL_NODE = babel-node
+UGLIFY = uglifyjs
+XYZ = support/xyz.sh --repo git@github.com:caolan/async.git
+
+BUILDDIR = build
+BUILD_ES = build-es
+DIST = dist
+SRC = lib/index.js
+SCRIPTS = ./support
+JS_SRC = $(shell find lib/ -type f -name '*.js')
+LINT_FILES = lib/ test/ mocha_test/ $(shell find perf/ -maxdepth 2 -type f) support/ gulpfile.js karma.conf.js
-BUILDDIR = dist
-SRC = lib/async.js
+UMD_BUNDLE = $(BUILDDIR)/dist/async.js
+UMD_BUNDLE_MIN = $(BUILDDIR)/dist/async.min.js
+CJS_BUNDLE = $(BUILDDIR)/index.js
+ES_MODULES = $(patsubst lib/%.js, build-es/%.js, $(JS_SRC))
-all: lint test clean build
-build: $(wildcard lib/*.js)
- mkdir -p $(BUILDDIR)
- cp $(SRC) $(BUILDDIR)/async.js
- uglifyjs $(BUILDDIR)/async.js -mc \
- --source-map $(BUILDDIR)/async.min.map \
- -o $(BUILDDIR)/async.min.js
+all: clean lint build test
test:
- nodeunit test
+ npm test
clean:
rm -rf $(BUILDDIR)
+ rm -rf $(BUILD_ES)
+ rm -rf $(DIST)
+ rm -rf tmp/
lint:
- jshint $(SRC) test/*.js mocha_test/* perf/*.js
- jscs $(SRC) test/*.js mocha_test/* perf/*.js
+ jshint $(LINT_FILES)
+ jscs $(LINT_FILES)
-.PHONY: test lint build all clean
+# Compile the ES6 modules to singular bundles, and individual bundles
+build-bundle: build-modules $(UMD_BUNDLE) $(CJS_BUNDLE)
+
+build-modules:
+ $(BABEL_NODE) $(SCRIPTS)/build/modules-cjs.js
+
+$(UMD_BUNDLE): $(JS_SRC) package.json
+ mkdir -p "$(@D)"
+ $(BABEL_NODE) $(SCRIPTS)/build/aggregate-bundle.js
+
+$(CJS_BUNDLE): $(JS_SRC) package.json
+ $(BABEL_NODE) $(SCRIPTS)/build/aggregate-cjs.js
+
+# Create the minified UMD versions and copy them to dist/ for bower
+build-dist: $(DIST) $(UMD_BUNDLE) $(UMD_BUNDLE_MIN) $(DIST)/async.js $(DIST)/async.min.js
+
+$(DIST):
+ mkdir -p $@
+
+$(UMD_BUNDLE_MIN): $(UMD_BUNDLE)
+ mkdir -p "$(@D)"
+ $(UGLIFY) $< --mangle --compress \
+ --source-map $(DIST)/async.min.map \
+ -o $@
+
+$(DIST)/async.js: $(UMD_BUNDLE)
+ cp $< $@
+
+$(DIST)/async.min.js: $(UMD_BUNDLE_MIN)
+ cp $< $@
+
+build-es: $(ES_MODULES)
+
+$(BUILD_ES)/%.js: lib/%.js
+ mkdir -p "$(@D)"
+ sed -r "s/(import.+)lodash/\1lodash-es/g" $< > $@
+test-build:
+ mocha support/build.test.js
+
+build-config: $(BUILDDIR)/package.json $(BUILDDIR)/component.json $(BUILDDIR)/bower.json $(BUILDDIR)/README.md $(BUILDDIR)/LICENSE $(BUILDDIR)/CHANGELOG.md
+
+build-es-config: $(BUILD_ES)/package.json $(BUILD_ES)/README.md $(BUILD_ES)/LICENSE $(BUILD_ES)/CHANGELOG.md
+
+bower.json: package.json
+ support/sync-package-managers.js
+
+component.json: package.json
+ support/sync-package-managers.js
+
+$(BUILDDIR)/package.json: package.json
+ mkdir -p "$(@D)"
+ support/sync-cjs-package.js > $@
+
+$(BUILDDIR)/%: %
+ mkdir -p "$(@D)"
+ cp $< $@
+
+$(BUILD_ES)/package.json: package.json
+ mkdir -p "$(@D)"
+ support/sync-es-package.js > $@
+
+$(BUILD_ES)/%: %
+ mkdir -p "$(@D)"
+ cp $< $@
+
+.PHONY: build-modules build-bundle build-dist build-es build-config build-es-config test-build
+
+build: clean build-bundle build-dist build-es build-config build-es-config test-build
+
+.PHONY: test lint build all clean
.PHONY: release-major release-minor release-patch
release-major release-minor release-patch: all
- ./support/sync-package-managers.js
- git add --force *.json
- git add --force $(BUILDDIR)
+ git add --force $(DIST)
git commit -am "update minified build"; true
$(XYZ) --increment $(@:release-%=%)
+ # build again to propagate the version
+ $(MAKE) build-config
+ $(MAKE) build-es-config
+ cd build/ && npm pack
+ cd build-es/ && npm pack
diff --git a/README.md b/README.md
index d731b82b1..9763875e1 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,6 @@
-# Async.js
+**NOTE: This is the README for Async 2.0, currently under development. For docs for async@1.5.2 go [HERE](https://github.com/caolan/async/blob/v1.5.2/README.md).
+
+# Async.js v2.0.0-pre
[![Build Status via Travis CI](https://travis-ci.org/caolan/async.svg?branch=master)](https://travis-ci.org/caolan/async)
[![NPM version](http://img.shields.io/npm/v/async.svg)](https://www.npmjs.org/package/async)
@@ -32,7 +34,11 @@ async.map(['file1','file2','file3'], fs.stat, function(err, results){
// results is now an array of stats for each file
});
-async.filter(['file1','file2','file3'], fs.exists, function(results){
+async.filter(['file1','file2','file3'], function(filePath, callback) {
+ fs.access(filePath, function(err) {
+ callback(null, !err)
+ });
+}, function(err, results){
// results now equals an array of the existing files
});
@@ -393,25 +399,26 @@ __Related__
__Alias:__ `select`
Returns a new array of all the values in `arr` which pass an async truth test.
-_The callback for each `iteratee` call only accepts a single argument of `true` or
-`false`; it does not accept an error argument first!_ This is in-line with the
-way node libraries work with truth tests like `fs.exists`. This operation is
-performed in parallel, but the results array will be in the same order as the
-original.
+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.
* `iteratee(item, callback)` - A truth test to apply to each item in `arr`.
- The `iteratee` is passed a `callback(truthValue)`, which must be called with a
+ The `iteratee` is passed a `callback(err, truthValue)`, which must be called with a
boolean argument once it has completed.
-* `callback(results)` - *Optional* A callback which is called after all the `iteratee`
+* `callback(err, results)` - *Optional* A callback which is called after all the `iteratee`
functions have finished.
__Example__
```js
-async.filter(['file1','file2','file3'], fs.exists, function(results){
+async.filter(['file1','file2','file3'], function(filePath, callback) {
+ fs.access(filePath, function(err) {
+ callback(null, !err)
+ });
+}, function(err, results){
// results now equals an array of the existing files
});
```
@@ -500,17 +507,21 @@ __Arguments__
* `arr` - An array to iterate over.
* `iteratee(item, callback)` - A truth test to apply to each item in `arr`.
- The iteratee is passed a `callback(truthValue)` which must be called with a
- boolean argument once it has completed. **Note: this callback does not take an error as its first argument.**
-* `callback(result)` - *Optional* A callback which is called as soon as any iteratee returns
+ The iteratee is passed a `callback(err, truthValue)` which must be called with a
+ boolean argument once it has completed.
+* `callback(err, result)` - *Optional* A callback which is called as soon as any iteratee returns
`true`, or after all the `iteratee` functions have finished. Result will be
the first item in the array that passes the truth test (iteratee) or the
- value `undefined` if none passed. **Note: this callback does not take an error as its first argument.**
+ value `undefined` if none passed.
__Example__
```js
-async.detect(['file1','file2','file3'], fs.exists, function(result){
+async.detect(['file1','file2','file3'], function(filePath, callback) {
+ fs.access(filePath, function(err) {
+ callback(null, !err)
+ });
+}, function(err, result){
// result now equals the first file in the list that exists
});
```
@@ -579,10 +590,7 @@ async.sortBy([1,9,3,5], function(x, callback){
__Alias:__ `any`
Returns `true` if at least one element in the `arr` satisfies an async test.
-_The callback for each iteratee call only accepts a single argument of `true` or
-`false`; it does not accept an error argument first!_ This is in-line with the
-way node libraries work with truth tests like `fs.exists`. Once any iteratee
-call returns `true`, the main `callback` is immediately called.
+If any iteratee call returns `true`, the main `callback` is immediately called.
__Arguments__
@@ -590,15 +598,18 @@ __Arguments__
* `iteratee(item, callback)` - A truth test to apply to each item in the array
in parallel. The iteratee is passed a `callback(truthValue)`` which must be
called with a boolean argument once it has completed.
-* `callback(result)` - *Optional* A callback which is called as soon as any iteratee returns
+* `callback(err, result)` - *Optional* A callback which is called as soon as any iteratee returns
`true`, or after all the iteratee functions have finished. Result will be
either `true` or `false` depending on the values of the async tests.
- **Note: the callbacks do not take an error as their first argument.**
__Example__
```js
-async.some(['file1','file2','file3'], fs.exists, function(result){
+async.some(['file1','file2','file3'], function(filePath, callback) {
+ fs.access(filePath, function(err) {
+ callback(null, !err)
+ });
+}, function(err, result){
// if result is true then at least one of the files exists
});
```
@@ -615,26 +626,26 @@ __Related__
__Alias:__ `all`
Returns `true` if every element in `arr` satisfies an async test.
-_The callback for each `iteratee` call only accepts a single argument of `true` or
-`false`; it does not accept an error argument first!_ This is in-line with the
-way node libraries work with truth tests like `fs.exists`.
+If any iteratee call returns `false`, the main `callback` is immediately called.
__Arguments__
* `arr` - An array to iterate over.
* `iteratee(item, callback)` - A truth test to apply to each item in the array
- in parallel. The iteratee is passed a `callback(truthValue)` which must be
+ in parallel. The iteratee is passed a `callback(err, truthValue)` which must be
called with a boolean argument once it has completed.
-* `callback(result)` - *Optional* A callback which is called as soon as any iteratee returns
- `false`, or after all the iteratee functions have finished. Result will be
- either `true` or `false` depending on the values of the async tests.
-
- **Note: the callbacks do not take an error as their first argument.**
+* `callback(err, result)` - *Optional* A callback which is called after all the `iteratee`
+ functions have finished. Result will be either `true` or `false` depending on
+ the values of the async tests.
__Example__
```js
-async.every(['file1','file2','file3'], fs.exists, function(result){
+async.every(['file1','file2','file3'], function(filePath, callback) {
+ fs.access(filePath, function(err) {
+ callback(null, !err)
+ });
+}, function(err, result){
// if result is true then every file exists
});
```
@@ -1180,8 +1191,9 @@ methods:
the `worker` has finished processing the task. Instead of a single task, a `tasks` array
can be submitted. The respective callback is used for every task in the list.
* `unshift(task, [callback])` - add a new task to the front of the `queue`.
-* `saturated` - a callback that is called when the `queue` length hits the `concurrency` limit,
- and further tasks will be queued.
+* `saturated` - a callback that is called when the `queue` length hits the `concurrency` limit, and further tasks will be queued.
+* `unsaturated` - a callback that is called when the `queue` length is less than the `concurrency` & `buffer` limits, and further tasks will not be queued.
+* `buffer` A minimum threshold buffer in order to say that the `queue` is `unsaturated`.
* `empty` - a callback that is called when the last item from the `queue` is given to a `worker`.
* `drain` - a callback that is called when the last item from the `queue` has returned from the `worker`.
* `paused` - a boolean for determining whether the queue is in a paused state
@@ -1446,7 +1458,7 @@ __Arguments__
* `opts` - Can be either an object with `times` and `interval` or a number.
* `times` - The number of attempts to make before giving up. The default is `5`.
* `interval` - The time to wait between retries, in milliseconds. The default is `0`.
- * If `opts` is a number, the number specifies the number of times to retry, with the default interval of `0`.
+ * If `opts` is a number, the number specifies the number of times to retry, with the default interval of `0`.
* `task(callback, results)` - A function which receives two arguments: (1) a `callback(err, result)`
which must be called when finished, passing `err` (which can be `null`) and the `result` of
the function's execution, and (2) a `results` object, containing the results of
@@ -1464,14 +1476,14 @@ async.retry(3, apiMethod, function(err, result) {
```
```js
-// try calling apiMethod 3 times, waiting 200 ms between each retry
+// try calling apiMethod 3 times, waiting 200 ms between each retry
async.retry({times: 3, interval: 200}, apiMethod, function(err, result) {
// do something with the result
});
```
```js
-// try calling apiMethod the default 5 times no delay between each retry
+// try calling apiMethod the default 5 times no delay between each retry
async.retry(apiMethod, function(err, result) {
// do something with the result
});
@@ -1792,7 +1804,7 @@ async.waterfall([
return db.model.create(contents);
}),
function (model, next) {
- // `model` is the instantiated model object.
+ // `model` is the instantiated model object.
// If there was an error, this function would be skipped.
}
], callback)
diff --git a/bower.json b/bower.json
index 0ce24babb..c708594f4 100644
--- a/bower.json
+++ b/bower.json
@@ -1,12 +1,12 @@
{
"name": "async",
"description": "Higher-order functions and common patterns for asynchronous code",
- "main": "lib/async.js",
+ "main": "dist/async.js",
"keywords": [
"async",
"callback",
- "utility",
- "module"
+ "module",
+ "utility"
],
"license": "MIT",
"repository": {
@@ -14,11 +14,19 @@
"url": "https://github.com/caolan/async.git"
},
"devDependencies": {
+ "babel-cli": "^6.3.17",
+ "babel-core": "^6.3.26",
+ "babel-plugin-add-module-exports": "~0.1.2",
+ "babel-plugin-transform-es2015-modules-commonjs": "^6.3.16",
+ "babel-preset-es2015": "^6.3.13",
+ "babelify": "^7.2.0",
"benchmark": "bestiejs/benchmark.js",
"bluebird": "^2.9.32",
"chai": "^3.1.0",
"coveralls": "^2.11.2",
"es6-promise": "^2.3.0",
+ "fs-extra": "^0.26.3",
+ "gulp": "~3.9.0",
"jscs": "^1.13.1",
"jshint": "~2.8.0",
"karma": "^0.13.2",
@@ -26,16 +34,19 @@
"karma-firefox-launcher": "^0.1.6",
"karma-mocha": "^0.2.0",
"karma-mocha-reporter": "^1.0.2",
- "lodash": "^3.9.0",
- "mkdirp": "~0.5.1",
"mocha": "^2.2.5",
"native-promise-only": "^0.8.0-a",
"nodeunit": ">0.0.0",
"nyc": "^2.1.0",
+ "recursive-readdir": "^1.3.0",
+ "rimraf": "^2.5.0",
+ "rollup": "^0.25.0",
+ "rollup-plugin-npm": "~1.3.0",
"rsvp": "^3.0.18",
"semver": "^4.3.6",
"uglify-js": "~2.4.0",
- "xyz": "^0.5.0",
+ "vinyl-buffer": "~1.0.0",
+ "vinyl-source-stream": "~1.1.0",
"yargs": "~3.9.1"
},
"moduleType": [
@@ -52,6 +63,5 @@
],
"authors": [
"Caolan McMahon"
- ],
- "version": "1.5.2"
-}
+ ]
+}
\ No newline at end of file
diff --git a/component.json b/component.json
index 103558d6d..2ce99fc51 100644
--- a/component.json
+++ b/component.json
@@ -1,17 +1,17 @@
{
"name": "async",
"description": "Higher-order functions and common patterns for asynchronous code",
- "version": "1.5.2",
+ "version": "2.0.0-alpha",
"keywords": [
"async",
"callback",
- "utility",
- "module"
+ "module",
+ "utility"
],
"license": "MIT",
- "main": "lib/async.js",
+ "main": "dist/async.js",
"repository": "caolan/async",
"scripts": [
- "lib/async.js"
+ "dist/async.js"
]
-}
+}
\ No newline at end of file
diff --git a/dist/async.js b/dist/async.js
index 31e7620fb..0032ce5ca 100644
--- a/dist/async.js
+++ b/dist/async.js
@@ -1,1265 +1,2563 @@
-/*!
- * async
- * https://github.com/caolan/async
- *
- * Copyright 2010-2014 Caolan McMahon
- * Released under the MIT license
- */
-(function () {
-
- var async = {};
- function noop() {}
- function identity(v) {
- return v;
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
+ typeof define === 'function' && define.amd ? define(['exports'], factory) :
+ (factory((global.async = {})));
+}(this, function (exports) { 'use strict';
+
+ /**
+ * A faster alternative to `Function#apply`, this function invokes `func`
+ * with the `this` binding of `thisArg` and the arguments of `args`.
+ *
+ * @private
+ * @param {Function} func The function to invoke.
+ * @param {*} thisArg The `this` binding of `func`.
+ * @param {...*} args The arguments to invoke `func` with.
+ * @returns {*} Returns the result of `func`.
+ */
+ function apply$1(func, thisArg, args) {
+ var length = args.length;
+ switch (length) {
+ case 0: return func.call(thisArg);
+ case 1: return func.call(thisArg, args[0]);
+ case 2: return func.call(thisArg, args[0], args[1]);
+ case 3: return func.call(thisArg, args[0], args[1], args[2]);
}
- function toBool(v) {
- return !!v;
+ return func.apply(thisArg, args);
+ }
+
+ /**
+ * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.
+ * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is an object, else `false`.
+ * @example
+ *
+ * _.isObject({});
+ * // => true
+ *
+ * _.isObject([1, 2, 3]);
+ * // => true
+ *
+ * _.isObject(_.noop);
+ * // => true
+ *
+ * _.isObject(null);
+ * // => false
+ */
+ function isObject(value) {
+ var type = typeof value;
+ return !!value && (type == 'object' || type == 'function');
+ }
+
+ var funcTag = '[object Function]';
+ var genTag = '[object GeneratorFunction]';
+ /** Used for built-in method references. */
+ var objectProto$4 = Object.prototype;
+
+ /**
+ * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
+ * of values.
+ */
+ var objectToString$2 = objectProto$4.toString;
+
+ /**
+ * Checks if `value` is classified as a `Function` object.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
+ * @example
+ *
+ * _.isFunction(_);
+ * // => true
+ *
+ * _.isFunction(/abc/);
+ * // => false
+ */
+ function isFunction(value) {
+ // The use of `Object#toString` avoids issues with the `typeof` operator
+ // in Safari 8 which returns 'object' for typed array constructors, and
+ // PhantomJS 1.9 which returns 'function' for `NodeList` instances.
+ var tag = isObject(value) ? objectToString$2.call(value) : '';
+ return tag == funcTag || tag == genTag;
+ }
+
+ /** Used as references for various `Number` constants. */
+ var NAN = 0 / 0;
+
+ /** Used to match leading and trailing whitespace. */
+ var reTrim = /^\s+|\s+$/g;
+
+ /** Used to detect bad signed hexadecimal string values. */
+ var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;
+
+ /** Used to detect binary string values. */
+ var reIsBinary = /^0b[01]+$/i;
+
+ /** Used to detect octal string values. */
+ var reIsOctal = /^0o[0-7]+$/i;
+
+ /** Built-in method references without a dependency on `root`. */
+ var freeParseInt = parseInt;
+
+ /**
+ * Converts `value` to a number.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to process.
+ * @returns {number} Returns the number.
+ * @example
+ *
+ * _.toNumber(3);
+ * // => 3
+ *
+ * _.toNumber(Number.MIN_VALUE);
+ * // => 5e-324
+ *
+ * _.toNumber(Infinity);
+ * // => Infinity
+ *
+ * _.toNumber('3');
+ * // => 3
+ */
+ function toNumber(value) {
+ if (isObject(value)) {
+ var other = isFunction(value.valueOf) ? value.valueOf() : value;
+ value = isObject(other) ? (other + '') : other;
}
- function notId(v) {
- return !v;
+ if (typeof value != 'string') {
+ return value === 0 ? value : +value;
}
-
- // global on the server, window in the browser
- var previous_async;
-
- // Establish the root object, `window` (`self`) in the browser, `global`
- // on the server, or `this` in some virtual machines. We use `self`
- // instead of `window` for `WebWorker` support.
- var root = typeof self === 'object' && self.self === self && self ||
- typeof global === 'object' && global.global === global && global ||
- this;
-
- if (root != null) {
- previous_async = root.async;
+ value = value.replace(reTrim, '');
+ var isBinary = reIsBinary.test(value);
+ return (isBinary || reIsOctal.test(value))
+ ? freeParseInt(value.slice(2), isBinary ? 2 : 8)
+ : (reIsBadHex.test(value) ? NAN : +value);
+ }
+
+ var INFINITY = 1 / 0;
+ var MAX_INTEGER = 1.7976931348623157e+308;
+ /**
+ * Converts `value` to an integer.
+ *
+ * **Note:** This function is loosely based on [`ToInteger`](http://www.ecma-international.org/ecma-262/6.0/#sec-tointeger).
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to convert.
+ * @returns {number} Returns the converted integer.
+ * @example
+ *
+ * _.toInteger(3);
+ * // => 3
+ *
+ * _.toInteger(Number.MIN_VALUE);
+ * // => 0
+ *
+ * _.toInteger(Infinity);
+ * // => 1.7976931348623157e+308
+ *
+ * _.toInteger('3');
+ * // => 3
+ */
+ function toInteger(value) {
+ if (!value) {
+ return value === 0 ? value : 0;
}
-
- async.noConflict = function () {
- root.async = previous_async;
- return async;
- };
-
- function only_once(fn) {
- return function() {
- if (fn === null) throw new Error("Callback was already called.");
- fn.apply(this, arguments);
- fn = null;
- };
+ value = toNumber(value);
+ if (value === INFINITY || value === -INFINITY) {
+ var sign = (value < 0 ? -1 : 1);
+ return sign * MAX_INTEGER;
}
-
- function _once(fn) {
- return function() {
- if (fn === null) return;
- fn.apply(this, arguments);
- fn = null;
- };
+ var remainder = value % 1;
+ return value === value ? (remainder ? value - remainder : value) : 0;
+ }
+
+ /** Used as the `TypeError` message for "Functions" methods. */
+ var FUNC_ERROR_TEXT = 'Expected a function';
+
+ /* Built-in method references for those with the same name as other `lodash` methods. */
+ var nativeMax = Math.max;
+
+ /**
+ * Creates a function that invokes `func` with the `this` binding of the
+ * created function and arguments from `start` and beyond provided as an array.
+ *
+ * **Note:** This method is based on the [rest parameter](https://mdn.io/rest_parameters).
+ *
+ * @static
+ * @memberOf _
+ * @category Function
+ * @param {Function} func The function to apply a rest parameter to.
+ * @param {number} [start=func.length-1] The start position of the rest parameter.
+ * @returns {Function} Returns the new function.
+ * @example
+ *
+ * var say = _.rest(function(what, names) {
+ * return what + ' ' + _.initial(names).join(', ') +
+ * (_.size(names) > 1 ? ', & ' : '') + _.last(names);
+ * });
+ *
+ * say('hello', 'fred', 'barney', 'pebbles');
+ * // => 'hello fred, barney, & pebbles'
+ */
+ function rest(func, start) {
+ if (typeof func != 'function') {
+ throw new TypeError(FUNC_ERROR_TEXT);
}
-
- //// cross-browser compatiblity functions ////
-
- var _toString = Object.prototype.toString;
-
- var _isArray = Array.isArray || function (obj) {
- return _toString.call(obj) === '[object Array]';
- };
-
- // Ported from underscore.js isObject
- var _isObject = function(obj) {
- var type = typeof obj;
- return type === 'function' || type === 'object' && !!obj;
+ start = nativeMax(start === undefined ? (func.length - 1) : toInteger(start), 0);
+ return function() {
+ var args = arguments,
+ index = -1,
+ length = nativeMax(args.length - start, 0),
+ array = Array(length);
+
+ while (++index < length) {
+ array[index] = args[start + index];
+ }
+ switch (start) {
+ case 0: return func.call(this, array);
+ case 1: return func.call(this, args[0], array);
+ case 2: return func.call(this, args[0], args[1], array);
+ }
+ var otherArgs = Array(start + 1);
+ index = -1;
+ while (++index < start) {
+ otherArgs[index] = args[index];
+ }
+ otherArgs[start] = array;
+ return apply$1(func, this, otherArgs);
};
-
- function _isArrayLike(arr) {
- return _isArray(arr) || (
- // has a positive integer length property
- typeof arr.length === "number" &&
- arr.length >= 0 &&
- arr.length % 1 === 0
- );
+ }
+
+ function applyEach$1(eachfn) {
+ return rest(function (fns, args) {
+ var go = rest(function (args) {
+ var that = this;
+ var callback = args.pop();
+ return eachfn(fns, function (fn, _, cb) {
+ fn.apply(that, args.concat([cb]));
+ }, callback);
+ });
+ if (args.length) {
+ return go.apply(this, args);
+ } else {
+ return go;
+ }
+ });
+ }
+
+ /** Used as the `TypeError` message for "Functions" methods. */
+ var FUNC_ERROR_TEXT$1 = 'Expected a function';
+
+ /**
+ * Creates a function that invokes `func`, with the `this` binding and arguments
+ * of the created function, while it's called less than `n` times. Subsequent
+ * calls to the created function return the result of the last `func` invocation.
+ *
+ * @static
+ * @memberOf _
+ * @category Function
+ * @param {number} n The number of calls at which `func` is no longer invoked.
+ * @param {Function} func The function to restrict.
+ * @returns {Function} Returns the new restricted function.
+ * @example
+ *
+ * jQuery(element).on('click', _.before(5, addContactToList));
+ * // => allows adding up to 4 contacts to the list
+ */
+ function before(n, func) {
+ var result;
+ if (typeof func != 'function') {
+ throw new TypeError(FUNC_ERROR_TEXT$1);
}
-
- function _arrayEach(arr, iterator) {
- var index = -1,
- length = arr.length;
-
- while (++index < length) {
- iterator(arr[index], index, arr);
- }
+ n = toInteger(n);
+ return function() {
+ if (--n > 0) {
+ result = func.apply(this, arguments);
+ }
+ if (n <= 1) {
+ func = undefined;
+ }
+ return result;
+ };
+ }
+
+ /**
+ * Creates a function that is restricted to invoking `func` once. Repeat calls
+ * to the function return the value of the first invocation. The `func` is
+ * invoked with the `this` binding and arguments of the created function.
+ *
+ * @static
+ * @memberOf _
+ * @category Function
+ * @param {Function} func The function to restrict.
+ * @returns {Function} Returns the new restricted function.
+ * @example
+ *
+ * var initialize = _.once(createApplication);
+ * initialize();
+ * initialize();
+ * // `initialize` invokes `createApplication` once
+ */
+ function once(func) {
+ return before(2, func);
+ }
+
+ /**
+ * A no-operation function that returns `undefined` regardless of the
+ * arguments it receives.
+ *
+ * @static
+ * @memberOf _
+ * @category Util
+ * @example
+ *
+ * var object = { 'user': 'fred' };
+ *
+ * _.noop(object) === undefined;
+ * // => true
+ */
+ function noop() {
+ // No operation performed.
+ }
+
+ /**
+ * The base implementation of `_.property` without support for deep paths.
+ *
+ * @private
+ * @param {string} key The key of the property to get.
+ * @returns {Function} Returns the new function.
+ */
+ function baseProperty(key) {
+ return function(object) {
+ return object == null ? undefined : object[key];
+ };
+ }
+
+ /**
+ * Gets the "length" property value of `object`.
+ *
+ * **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792)
+ * that affects Safari on at least iOS 8.1-8.3 ARM64.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @returns {*} Returns the "length" value.
+ */
+ var getLength = baseProperty('length');
+
+ /** Used as references for various `Number` constants. */
+ var MAX_SAFE_INTEGER$1 = 9007199254740991;
+
+ /**
+ * Checks if `value` is a valid array-like length.
+ *
+ * **Note:** This function is loosely based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
+ * @example
+ *
+ * _.isLength(3);
+ * // => true
+ *
+ * _.isLength(Number.MIN_VALUE);
+ * // => false
+ *
+ * _.isLength(Infinity);
+ * // => false
+ *
+ * _.isLength('3');
+ * // => false
+ */
+ function isLength(value) {
+ return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER$1;
+ }
+
+ /**
+ * Checks if `value` is array-like. A value is considered array-like if it's
+ * not a function and has a `value.length` that's an integer greater than or
+ * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
+ *
+ * @static
+ * @memberOf _
+ * @type Function
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
+ * @example
+ *
+ * _.isArrayLike([1, 2, 3]);
+ * // => true
+ *
+ * _.isArrayLike(document.body.children);
+ * // => true
+ *
+ * _.isArrayLike('abc');
+ * // => true
+ *
+ * _.isArrayLike(_.noop);
+ * // => false
+ */
+ function isArrayLike(value) {
+ return value != null &&
+ !(typeof value == 'function' && isFunction(value)) && isLength(getLength(value));
+ }
+
+ /** Used for built-in method references. */
+ var objectProto = Object.prototype;
+
+ /** Used to check objects for own properties. */
+ var hasOwnProperty = objectProto.hasOwnProperty;
+
+ /** Built-in value references. */
+ var getPrototypeOf = Object.getPrototypeOf;
+
+ /**
+ * The base implementation of `_.has` without support for deep paths.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @param {Array|string} key The key to check.
+ * @returns {boolean} Returns `true` if `key` exists, else `false`.
+ */
+ function baseHas(object, key) {
+ // Avoid a bug in IE 10-11 where objects with a [[Prototype]] of `null`,
+ // that are composed entirely of index properties, return `false` for
+ // `hasOwnProperty` checks of them.
+ return hasOwnProperty.call(object, key) ||
+ (typeof object == 'object' && key in object && getPrototypeOf(object) === null);
+ }
+
+ /* Built-in method references for those with the same name as other `lodash` methods. */
+ var nativeKeys = Object.keys;
+
+ /**
+ * The base implementation of `_.keys` which doesn't skip the constructor
+ * property of prototypes or treat sparse arrays as dense.
+ *
+ * @private
+ * @type Function
+ * @param {Object} object The object to query.
+ * @returns {Array} Returns the array of property names.
+ */
+ function baseKeys(object) {
+ return nativeKeys(Object(object));
+ }
+
+ /**
+ * The base implementation of `_.times` without support for iteratee shorthands
+ * or max array length checks.
+ *
+ * @private
+ * @param {number} n The number of times to invoke `iteratee`.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @returns {Array} Returns the array of results.
+ */
+ function baseTimes(n, iteratee) {
+ var index = -1,
+ result = Array(n);
+
+ while (++index < n) {
+ result[index] = iteratee(index);
}
-
- function _map(arr, iterator) {
- var index = -1,
- length = arr.length,
- result = Array(length);
-
- while (++index < length) {
- result[index] = iterator(arr[index], index, arr);
- }
- return result;
+ return result;
+ }
+
+ /**
+ * Checks if `value` is object-like. A value is object-like if it's not `null`
+ * and has a `typeof` result of "object".
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
+ * @example
+ *
+ * _.isObjectLike({});
+ * // => true
+ *
+ * _.isObjectLike([1, 2, 3]);
+ * // => true
+ *
+ * _.isObjectLike(_.noop);
+ * // => false
+ *
+ * _.isObjectLike(null);
+ * // => false
+ */
+ function isObjectLike(value) {
+ return !!value && typeof value == 'object';
+ }
+
+ /**
+ * This method is like `_.isArrayLike` except that it also checks if `value`
+ * is an object.
+ *
+ * @static
+ * @memberOf _
+ * @type Function
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is an array-like object, else `false`.
+ * @example
+ *
+ * _.isArrayLikeObject([1, 2, 3]);
+ * // => true
+ *
+ * _.isArrayLikeObject(document.body.children);
+ * // => true
+ *
+ * _.isArrayLikeObject('abc');
+ * // => false
+ *
+ * _.isArrayLikeObject(_.noop);
+ * // => false
+ */
+ function isArrayLikeObject(value) {
+ return isObjectLike(value) && isArrayLike(value);
+ }
+
+ /** `Object#toString` result references. */
+ var argsTag = '[object Arguments]';
+
+ /** Used for built-in method references. */
+ var objectProto$2 = Object.prototype;
+
+ /** Used to check objects for own properties. */
+ var hasOwnProperty$1 = objectProto$2.hasOwnProperty;
+
+ /**
+ * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
+ * of values.
+ */
+ var objectToString = objectProto$2.toString;
+
+ /** Built-in value references. */
+ var propertyIsEnumerable = objectProto$2.propertyIsEnumerable;
+
+ /**
+ * Checks if `value` is likely an `arguments` object.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
+ * @example
+ *
+ * _.isArguments(function() { return arguments; }());
+ * // => true
+ *
+ * _.isArguments([1, 2, 3]);
+ * // => false
+ */
+ function isArguments(value) {
+ // Safari 8.1 incorrectly makes `arguments.callee` enumerable in strict mode.
+ return isArrayLikeObject(value) && hasOwnProperty$1.call(value, 'callee') &&
+ (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag);
+ }
+
+ /**
+ * Checks if `value` is classified as an `Array` object.
+ *
+ * @static
+ * @memberOf _
+ * @type Function
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
+ * @example
+ *
+ * _.isArray([1, 2, 3]);
+ * // => true
+ *
+ * _.isArray(document.body.children);
+ * // => false
+ *
+ * _.isArray('abc');
+ * // => false
+ *
+ * _.isArray(_.noop);
+ * // => false
+ */
+ var isArray = Array.isArray;
+
+ /** `Object#toString` result references. */
+ var stringTag = '[object String]';
+
+ /** Used for built-in method references. */
+ var objectProto$3 = Object.prototype;
+
+ /**
+ * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
+ * of values.
+ */
+ var objectToString$1 = objectProto$3.toString;
+
+ /**
+ * Checks if `value` is classified as a `String` primitive or object.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
+ * @example
+ *
+ * _.isString('abc');
+ * // => true
+ *
+ * _.isString(1);
+ * // => false
+ */
+ function isString(value) {
+ return typeof value == 'string' ||
+ (!isArray(value) && isObjectLike(value) && objectToString$1.call(value) == stringTag);
+ }
+
+ /**
+ * Creates an array of index keys for `object` values of arrays,
+ * `arguments` objects, and strings, otherwise `null` is returned.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @returns {Array|null} Returns index keys, else `null`.
+ */
+ function indexKeys(object) {
+ var length = object ? object.length : undefined;
+ if (isLength(length) &&
+ (isArray(object) || isString(object) || isArguments(object))) {
+ return baseTimes(length, String);
}
-
- function _range(count) {
- return _map(Array(count), function (v, i) { return i; });
+ return null;
+ }
+
+ /** Used as references for various `Number` constants. */
+ var MAX_SAFE_INTEGER = 9007199254740991;
+
+ /** Used to detect unsigned integer values. */
+ var reIsUint = /^(?:0|[1-9]\d*)$/;
+
+ /**
+ * Checks if `value` is a valid array-like index.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
+ * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
+ */
+ function isIndex(value, length) {
+ value = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1;
+ length = length == null ? MAX_SAFE_INTEGER : length;
+ return value > -1 && value % 1 == 0 && value < length;
+ }
+
+ /** Used for built-in method references. */
+ var objectProto$1 = Object.prototype;
+
+ /**
+ * Checks if `value` is likely a prototype object.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.
+ */
+ function isPrototype(value) {
+ var Ctor = value && value.constructor,
+ proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto$1;
+
+ return value === proto;
+ }
+
+ /**
+ * Creates an array of the own enumerable property names of `object`.
+ *
+ * **Note:** Non-object values are coerced to objects. See the
+ * [ES spec](http://ecma-international.org/ecma-262/6.0/#sec-object.keys)
+ * for more details.
+ *
+ * @static
+ * @memberOf _
+ * @category Object
+ * @param {Object} object The object to query.
+ * @returns {Array} Returns the array of property names.
+ * @example
+ *
+ * function Foo() {
+ * this.a = 1;
+ * this.b = 2;
+ * }
+ *
+ * Foo.prototype.c = 3;
+ *
+ * _.keys(new Foo);
+ * // => ['a', 'b'] (iteration order is not guaranteed)
+ *
+ * _.keys('hi');
+ * // => ['0', '1']
+ */
+ function keys(object) {
+ var isProto = isPrototype(object);
+ if (!(isProto || isArrayLike(object))) {
+ return baseKeys(object);
}
-
- function _reduce(arr, iterator, memo) {
- _arrayEach(arr, function (x, i, a) {
- memo = iterator(memo, x, i, a);
- });
- return memo;
+ var indexes = indexKeys(object),
+ skipIndexes = !!indexes,
+ result = indexes || [],
+ length = result.length;
+
+ for (var key in object) {
+ if (baseHas(object, key) &&
+ !(skipIndexes && (key == 'length' || isIndex(key, length))) &&
+ !(isProto && key == 'constructor')) {
+ result.push(key);
+ }
}
-
- function _forEachOf(object, iterator) {
- _arrayEach(_keys(object), function (key) {
- iterator(object[key], key);
- });
+ return result;
+ }
+
+ function keyIterator(coll) {
+ var i = -1;
+ var len;
+ if (isArrayLike(coll)) {
+ len = coll.length;
+ return function next() {
+ i++;
+ return i < len ? i : null;
+ };
+ } else {
+ var okeys = keys(coll);
+ len = okeys.length;
+ return function next() {
+ i++;
+ return i < len ? okeys[i] : null;
+ };
+ }
+ }
+
+ function onlyOnce(fn) {
+ return function () {
+ if (fn === null) throw new Error("Callback was already called.");
+ fn.apply(this, arguments);
+ fn = null;
+ };
+ }
+
+ function eachOf(object, iterator, callback) {
+ callback = once(callback || noop);
+ object = object || [];
+
+ var iter = keyIterator(object);
+ var key,
+ completed = 0;
+
+ while ((key = iter()) != null) {
+ completed += 1;
+ iterator(object[key], key, onlyOnce(done));
+ }
+
+ if (completed === 0) callback(null);
+
+ function done(err) {
+ completed--;
+ if (err) {
+ callback(err);
+ }
+ // Check key is null in case iterator isn't exhausted
+ // and done resolved synchronously.
+ else if (key === null && completed <= 0) {
+ callback(null);
+ }
+ }
+ }
+
+ var applyEach = applyEach$1(eachOf);
+
+ var _setImmediate = typeof setImmediate === 'function' && setImmediate;
+
+ var _delay;
+ if (_setImmediate) {
+ _delay = function (fn) {
+ // not a direct alias for IE10 compatibility
+ _setImmediate(fn);
+ };
+ } else if (typeof process === 'object' && typeof process.nextTick === 'function') {
+ _delay = process.nextTick;
+ } else {
+ _delay = function (fn) {
+ setTimeout(fn, 0);
+ };
+ }
+
+ var setImmediate$1 = _delay;
+
+ function eachOfSeries(obj, iterator, callback) {
+ callback = once(callback || noop);
+ obj = obj || [];
+ var nextKey = keyIterator(obj);
+ var key = nextKey();
+
+ function iterate() {
+ var sync = true;
+ if (key === null) {
+ return callback(null);
+ }
+ iterator(obj[key], key, onlyOnce(function (err) {
+ if (err) {
+ callback(err);
+ } else {
+ key = nextKey();
+ if (key === null) {
+ return callback(null);
+ } else {
+ if (sync) {
+ setImmediate$1(iterate);
+ } else {
+ iterate();
+ }
+ }
+ }
+ }));
+ sync = false;
+ }
+ iterate();
+ }
+
+ var applyEachSeries = applyEach$1(eachOfSeries);
+
+ var apply = rest(function (fn, args) {
+ return rest(function (callArgs) {
+ return fn.apply(null, args.concat(callArgs));
+ });
+ });
+
+ function asyncify(func) {
+ return rest(function (args) {
+ var callback = args.pop();
+ var result;
+ try {
+ result = func.apply(this, args);
+ } catch (e) {
+ return callback(e);
+ }
+ // if result is Promise object
+ if (isObject(result) && typeof result.then === 'function') {
+ result.then(function (value) {
+ callback(null, value);
+ })['catch'](function (err) {
+ callback(err.message ? err : new Error(err));
+ });
+ } else {
+ callback(null, result);
+ }
+ });
+ }
+
+ /**
+ * A specialized version of `_.forEach` for arrays without support for
+ * iteratee shorthands.
+ *
+ * @private
+ * @param {Array} array The array to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @returns {Array} Returns `array`.
+ */
+ function arrayEach(array, iteratee) {
+ var index = -1,
+ length = array.length;
+
+ while (++index < length) {
+ if (iteratee(array[index], index, array) === false) {
+ break;
+ }
}
-
- function _indexOf(arr, item) {
- for (var i = 0; i < arr.length; i++) {
- if (arr[i] === item) return i;
- }
- return -1;
+ return array;
+ }
+
+ /**
+ * A specialized version of `_.every` for arrays without support for
+ * iteratee shorthands.
+ *
+ * @private
+ * @param {Array} array The array to iterate over.
+ * @param {Function} predicate The function invoked per iteration.
+ * @returns {boolean} Returns `true` if all elements pass the predicate check, else `false`.
+ */
+ function arrayEvery(array, predicate) {
+ var index = -1,
+ length = array.length;
+
+ while (++index < length) {
+ if (!predicate(array[index], index, array)) {
+ return false;
+ }
}
-
- var _keys = Object.keys || function (obj) {
- var keys = [];
- for (var k in obj) {
- if (obj.hasOwnProperty(k)) {
- keys.push(k);
- }
+ return true;
+ }
+
+ /**
+ * Creates a base function for methods like `_.forIn`.
+ *
+ * @private
+ * @param {boolean} [fromRight] Specify iterating from right to left.
+ * @returns {Function} Returns the new base function.
+ */
+ function createBaseFor(fromRight) {
+ return function(object, iteratee, keysFunc) {
+ var index = -1,
+ iterable = Object(object),
+ props = keysFunc(object),
+ length = props.length;
+
+ while (length--) {
+ var key = props[fromRight ? length : ++index];
+ if (iteratee(iterable[key], key, iterable) === false) {
+ break;
}
- return keys;
+ }
+ return object;
};
-
- function _keyIterator(coll) {
- var i = -1;
- var len;
- var keys;
- if (_isArrayLike(coll)) {
- len = coll.length;
- return function next() {
- i++;
- return i < len ? i : null;
- };
- } else {
- keys = _keys(coll);
- len = keys.length;
- return function next() {
- i++;
- return i < len ? keys[i] : null;
- };
- }
+ }
+
+ /**
+ * The base implementation of `baseForIn` and `baseForOwn` which iterates
+ * over `object` properties returned by `keysFunc` invoking `iteratee` for
+ * each property. Iteratee functions may exit iteration early by explicitly
+ * returning `false`.
+ *
+ * @private
+ * @param {Object} object The object to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @param {Function} keysFunc The function to get the keys of `object`.
+ * @returns {Object} Returns `object`.
+ */
+ var baseFor = createBaseFor();
+
+ /**
+ * The base implementation of `_.forOwn` without support for iteratee shorthands.
+ *
+ * @private
+ * @param {Object} object The object to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @returns {Object} Returns `object`.
+ */
+ function baseForOwn(object, iteratee) {
+ return object && baseFor(object, iteratee, keys);
+ }
+
+ /**
+ * This method returns the first argument given to it.
+ *
+ * @static
+ * @memberOf _
+ * @category Util
+ * @param {*} value Any value.
+ * @returns {*} Returns `value`.
+ * @example
+ *
+ * var object = { 'user': 'fred' };
+ *
+ * _.identity(object) === object;
+ * // => true
+ */
+ function identity(value) {
+ return value;
+ }
+
+ /**
+ * Converts `value` to a function if it's not one.
+ *
+ * @private
+ * @param {*} value The value to process.
+ * @returns {Function} Returns the function.
+ */
+ function toFunction(value) {
+ return typeof value == 'function' ? value : identity;
+ }
+
+ /**
+ * Iterates over own enumerable properties of an object invoking `iteratee`
+ * for each property. The iteratee is invoked with three arguments:
+ * (value, key, object). Iteratee functions may exit iteration early by
+ * explicitly returning `false`.
+ *
+ * @static
+ * @memberOf _
+ * @category Object
+ * @param {Object} object The object to iterate over.
+ * @param {Function} [iteratee=_.identity] The function invoked per iteration.
+ * @returns {Object} Returns `object`.
+ * @example
+ *
+ * function Foo() {
+ * this.a = 1;
+ * this.b = 2;
+ * }
+ *
+ * Foo.prototype.c = 3;
+ *
+ * _.forOwn(new Foo, function(value, key) {
+ * console.log(key);
+ * });
+ * // => logs 'a' then 'b' (iteration order is not guaranteed)
+ */
+ function forOwn(object, iteratee) {
+ return object && baseForOwn(object, toFunction(iteratee));
+ }
+
+ /**
+ * Gets the index at which the first occurrence of `NaN` is found in `array`.
+ *
+ * @private
+ * @param {Array} array The array to search.
+ * @param {number} fromIndex The index to search from.
+ * @param {boolean} [fromRight] Specify iterating from right to left.
+ * @returns {number} Returns the index of the matched `NaN`, else `-1`.
+ */
+ function indexOfNaN(array, fromIndex, fromRight) {
+ var length = array.length,
+ index = fromIndex + (fromRight ? 0 : -1);
+
+ while ((fromRight ? index-- : ++index < length)) {
+ var other = array[index];
+ if (other !== other) {
+ return index;
+ }
}
-
- // Similar to ES6's rest param (http://ariya.ofilabs.com/2013/03/es6-and-rest-parameter.html)
- // This accumulates the arguments passed into an array, after a given index.
- // From underscore.js (https://github.com/jashkenas/underscore/pull/2140).
- function _restParam(func, startIndex) {
- startIndex = startIndex == null ? func.length - 1 : +startIndex;
- return function() {
- var length = Math.max(arguments.length - startIndex, 0);
- var rest = Array(length);
- for (var index = 0; index < length; index++) {
- rest[index] = arguments[index + startIndex];
- }
- switch (startIndex) {
- case 0: return func.call(this, rest);
- case 1: return func.call(this, arguments[0], rest);
- }
- // Currently unused but handle cases outside of the switch statement:
- // var args = Array(startIndex + 1);
- // for (index = 0; index < startIndex; index++) {
- // args[index] = arguments[index];
- // }
- // args[startIndex] = rest;
- // return func.apply(this, args);
- };
+ return -1;
+ }
+
+ /**
+ * The base implementation of `_.indexOf` without `fromIndex` bounds checks.
+ *
+ * @private
+ * @param {Array} array The array to search.
+ * @param {*} value The value to search for.
+ * @param {number} fromIndex The index to search from.
+ * @returns {number} Returns the index of the matched value, else `-1`.
+ */
+ function baseIndexOf(array, value, fromIndex) {
+ if (value !== value) {
+ return indexOfNaN(array, fromIndex);
}
+ var index = fromIndex - 1,
+ length = array.length;
- function _withoutIndex(iterator) {
- return function (value, index, callback) {
- return iterator(value, callback);
- };
+ while (++index < length) {
+ if (array[index] === value) {
+ return index;
+ }
}
-
- //// exported async module functions ////
-
- //// nextTick implementation with browser-compatible fallback ////
-
- // capture the global reference to guard against fakeTimer mocks
- var _setImmediate = typeof setImmediate === 'function' && setImmediate;
-
- var _delay = _setImmediate ? function(fn) {
- // not a direct alias for IE10 compatibility
- _setImmediate(fn);
- } : function(fn) {
- setTimeout(fn, 0);
- };
-
- if (typeof process === 'object' && typeof process.nextTick === 'function') {
- async.nextTick = process.nextTick;
- } else {
- async.nextTick = _delay;
+ return -1;
+ }
+
+ /* Built-in method references for those with the same name as other `lodash` methods. */
+ var nativeMax$1 = Math.max;
+
+ /**
+ * Gets the index at which the first occurrence of `value` is found in `array`
+ * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
+ * for equality comparisons. If `fromIndex` is negative, it's used as the offset
+ * from the end of `array`.
+ *
+ * @static
+ * @memberOf _
+ * @category Array
+ * @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, else `-1`.
+ * @example
+ *
+ * _.indexOf([1, 2, 1, 2], 2);
+ * // => 1
+ *
+ * // Search from the `fromIndex`.
+ * _.indexOf([1, 2, 1, 2], 2, 2);
+ * // => 3
+ */
+ function indexOf(array, value, fromIndex) {
+ var length = array ? array.length : 0;
+ if (!length) {
+ return -1;
}
- async.setImmediate = _setImmediate ? _delay : async.nextTick;
-
-
- async.forEach =
- async.each = function (arr, iterator, callback) {
- return async.eachOf(arr, _withoutIndex(iterator), callback);
- };
-
- async.forEachSeries =
- async.eachSeries = function (arr, iterator, callback) {
- return async.eachOfSeries(arr, _withoutIndex(iterator), callback);
- };
-
-
- async.forEachLimit =
- async.eachLimit = function (arr, limit, iterator, callback) {
- return _eachOfLimit(limit)(arr, _withoutIndex(iterator), callback);
- };
-
- async.forEachOf =
- async.eachOf = function (object, iterator, callback) {
- callback = _once(callback || noop);
- object = object || [];
-
- var iter = _keyIterator(object);
- var key, completed = 0;
-
- while ((key = iter()) != null) {
- completed += 1;
- iterator(object[key], key, only_once(done));
- }
-
- if (completed === 0) callback(null);
-
- function done(err) {
- completed--;
- if (err) {
- callback(err);
- }
- // Check key is null in case iterator isn't exhausted
- // and done resolved synchronously.
- else if (key === null && completed <= 0) {
- callback(null);
- }
- }
- };
-
- async.forEachOfSeries =
- async.eachOfSeries = function (obj, iterator, callback) {
- callback = _once(callback || noop);
- obj = obj || [];
- var nextKey = _keyIterator(obj);
- var key = nextKey();
- function iterate() {
- var sync = true;
- if (key === null) {
- return callback(null);
- }
- iterator(obj[key], key, only_once(function (err) {
- if (err) {
- callback(err);
- }
- else {
- key = nextKey();
- if (key === null) {
- return callback(null);
- } else {
- if (sync) {
- async.setImmediate(iterate);
- } else {
- iterate();
- }
- }
- }
- }));
- sync = false;
- }
- iterate();
- };
-
-
-
- async.forEachOfLimit =
- async.eachOfLimit = function (obj, limit, iterator, callback) {
- _eachOfLimit(limit)(obj, iterator, callback);
- };
-
- function _eachOfLimit(limit) {
-
- return function (obj, iterator, callback) {
- callback = _once(callback || noop);
- obj = obj || [];
- var nextKey = _keyIterator(obj);
- if (limit <= 0) {
- return callback(null);
- }
- var done = false;
- var running = 0;
- var errored = false;
-
- (function replenish () {
- if (done && running <= 0) {
- return callback(null);
- }
-
- while (running < limit && !errored) {
- var key = nextKey();
- if (key === null) {
- done = true;
- if (running <= 0) {
- callback(null);
- }
- return;
- }
- running += 1;
- iterator(obj[key], key, only_once(function (err) {
- running -= 1;
- if (err) {
- callback(err);
- errored = true;
- }
- else {
- replenish();
- }
- }));
- }
- })();
- };
- }
-
-
- function doParallel(fn) {
- return function (obj, iterator, callback) {
- return fn(async.eachOf, obj, iterator, callback);
- };
+ fromIndex = toInteger(fromIndex);
+ if (fromIndex < 0) {
+ fromIndex = nativeMax$1(length + fromIndex, 0);
}
- function doParallelLimit(fn) {
- return function (obj, limit, iterator, callback) {
- return fn(_eachOfLimit(limit), obj, iterator, callback);
- };
+ return baseIndexOf(array, value, fromIndex);
+ }
+
+ function auto (tasks, concurrency, callback) {
+ if (typeof arguments[1] === 'function') {
+ // concurrency is optional, shift the args.
+ callback = concurrency;
+ concurrency = null;
+ }
+ callback = once(callback || noop);
+ var keys$$ = keys(tasks);
+ var remainingTasks = keys$$.length;
+ if (!remainingTasks) {
+ return callback(null);
+ }
+ if (!concurrency) {
+ concurrency = remainingTasks;
+ }
+
+ var results = {};
+ var runningTasks = 0;
+ var hasError = false;
+
+ var listeners = [];
+ function addListener(fn) {
+ listeners.unshift(fn);
+ }
+ function removeListener(fn) {
+ var idx = indexOf(listeners, fn);
+ if (idx >= 0) listeners.splice(idx, 1);
+ }
+ function taskComplete() {
+ remainingTasks--;
+ arrayEach(listeners.slice(), function (fn) {
+ fn();
+ });
+ }
+
+ addListener(function () {
+ if (!remainingTasks) {
+ callback(null, results);
+ }
+ });
+
+ arrayEach(keys$$, function (k) {
+ if (hasError) return;
+ var task = isArray(tasks[k]) ? tasks[k] : [tasks[k]];
+ var taskCallback = rest(function (err, args) {
+ runningTasks--;
+ if (args.length <= 1) {
+ args = args[0];
+ }
+ if (err) {
+ var safeResults = {};
+ forOwn(results, function (val, rkey) {
+ safeResults[rkey] = val;
+ });
+ safeResults[k] = args;
+ hasError = true;
+
+ callback(err, safeResults);
+ } else {
+ results[k] = args;
+ setImmediate$1(taskComplete);
+ }
+ });
+ var requires = task.slice(0, task.length - 1);
+ // prevent dead-locks
+ var len = requires.length;
+ var dep;
+ while (len--) {
+ if (!(dep = tasks[requires[len]])) {
+ throw new Error('Has non-existent dependency in ' + requires.join(', '));
+ }
+ if (isArray(dep) && indexOf(dep, k) >= 0) {
+ throw new Error('Has cyclic dependencies');
+ }
+ }
+ function ready() {
+ return runningTasks < concurrency && !baseHas(results, k) && arrayEvery(requires, function (x) {
+ return baseHas(results, x);
+ });
+ }
+ if (ready()) {
+ runningTasks++;
+ task[task.length - 1](taskCallback, results);
+ } else {
+ addListener(listener);
+ }
+ function listener() {
+ if (ready()) {
+ runningTasks++;
+ removeListener(listener);
+ task[task.length - 1](taskCallback, results);
+ }
+ }
+ });
+ }
+
+ /**
+ * A specialized version of `_.map` for arrays without support for iteratee
+ * shorthands.
+ *
+ * @private
+ * @param {Array} array The array to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @returns {Array} Returns the new mapped array.
+ */
+ function arrayMap(array, iteratee) {
+ var index = -1,
+ length = array.length,
+ result = Array(length);
+
+ while (++index < length) {
+ result[index] = iteratee(array[index], index, array);
}
- function doSeries(fn) {
- return function (obj, iterator, callback) {
- return fn(async.eachOfSeries, obj, iterator, callback);
- };
+ return result;
+ }
+
+ function queue$1(worker, concurrency, payload) {
+ if (concurrency == null) {
+ concurrency = 1;
+ } else if (concurrency === 0) {
+ throw new Error('Concurrency must not be zero');
+ }
+ function _insert(q, data, pos, callback) {
+ if (callback != null && typeof callback !== 'function') {
+ throw new Error('task callback must be a function');
+ }
+ q.started = true;
+ if (!isArray(data)) {
+ data = [data];
+ }
+ if (data.length === 0 && q.idle()) {
+ // call drain immediately if there are no tasks
+ return setImmediate$1(function () {
+ q.drain();
+ });
+ }
+ arrayEach(data, function (task) {
+ var item = {
+ data: task,
+ callback: callback || noop
+ };
+
+ if (pos) {
+ q.tasks.unshift(item);
+ } else {
+ q.tasks.push(item);
+ }
+
+ if (q.tasks.length === q.concurrency) {
+ q.saturated();
+ }
+ });
+ setImmediate$1(q.process);
+ }
+ function _next(q, tasks) {
+ return function () {
+ workers -= 1;
+
+ var removed = false;
+ var args = arguments;
+ arrayEach(tasks, function (task) {
+ arrayEach(workersList, function (worker, index) {
+ if (worker === task && !removed) {
+ workersList.splice(index, 1);
+ removed = true;
+ }
+ });
+
+ task.callback.apply(task, args);
+ });
+ if (q.tasks.length + workers === 0) {
+ q.drain();
+ }
+ q.process();
+ };
+ }
+
+ var workers = 0;
+ var workersList = [];
+ var q = {
+ tasks: [],
+ concurrency: concurrency,
+ payload: payload,
+ saturated: noop,
+ empty: noop,
+ drain: noop,
+ started: false,
+ paused: false,
+ push: function (data, callback) {
+ _insert(q, data, false, callback);
+ },
+ kill: function () {
+ q.drain = noop;
+ q.tasks = [];
+ },
+ unshift: function (data, callback) {
+ _insert(q, data, true, callback);
+ },
+ process: function () {
+ while (!q.paused && workers < q.concurrency && q.tasks.length) {
+
+ var tasks = q.payload ? q.tasks.splice(0, q.payload) : q.tasks.splice(0, q.tasks.length);
+
+ var data = arrayMap(tasks, baseProperty('data'));
+
+ if (q.tasks.length === 0) {
+ q.empty();
+ }
+ workers += 1;
+ workersList.push(tasks[0]);
+ var cb = onlyOnce(_next(q, tasks));
+ worker(data, cb);
+ }
+ },
+ length: function () {
+ return q.tasks.length;
+ },
+ running: function () {
+ return workers;
+ },
+ workersList: function () {
+ return workersList;
+ },
+ idle: function () {
+ return q.tasks.length + workers === 0;
+ },
+ pause: function () {
+ q.paused = true;
+ },
+ resume: function () {
+ if (q.paused === false) {
+ return;
+ }
+ q.paused = false;
+ var resumeCount = Math.min(q.concurrency, q.tasks.length);
+ // Need to call q.process once per concurrent
+ // worker to preserve full concurrency after pause
+ for (var w = 1; w <= resumeCount; w++) {
+ setImmediate$1(q.process);
+ }
+ }
+ };
+ return q;
+ }
+
+ function cargo(worker, payload) {
+ return queue$1(worker, 1, payload);
+ }
+
+ function reduce(arr, memo, iterator, cb) {
+ eachOfSeries(arr, function (x, i, cb) {
+ iterator(memo, x, function (err, v) {
+ memo = v;
+ cb(err);
+ });
+ }, function (err) {
+ cb(err, memo);
+ });
+ }
+
+ function seq() /* functions... */{
+ var fns = arguments;
+ return rest(function (args) {
+ var that = this;
+
+ var cb = args[args.length - 1];
+ if (typeof cb == 'function') {
+ args.pop();
+ } else {
+ cb = noop;
+ }
+
+ reduce(fns, args, function (newargs, fn, cb) {
+ fn.apply(that, newargs.concat([rest(function (err, nextargs) {
+ cb(err, nextargs);
+ })]));
+ }, function (err, results) {
+ cb.apply(that, [err].concat(results));
+ });
+ });
+ }
+
+ var reverse = Array.prototype.reverse;
+
+ function compose() /* functions... */{
+ return seq.apply(null, reverse.call(arguments));
+ }
+
+ function concat$1(eachfn, arr, fn, callback) {
+ var result = [];
+ eachfn(arr, function (x, index, cb) {
+ fn(x, function (err, y) {
+ result = result.concat(y || []);
+ cb(err);
+ });
+ }, function (err) {
+ callback(err, result);
+ });
+ }
+
+ function doParallel(fn) {
+ return function (obj, iterator, callback) {
+ return fn(eachOf, obj, iterator, callback);
+ };
+ }
+
+ var concat = doParallel(concat$1);
+
+ function doSeries(fn) {
+ return function (obj, iterator, callback) {
+ return fn(eachOfSeries, obj, iterator, callback);
+ };
+ }
+
+ var concatSeries = doSeries(concat$1);
+
+ var constant = rest(function (values) {
+ var args = [null].concat(values);
+ return function (cb) {
+ return cb.apply(this, args);
+ };
+ });
+
+ function _createTester(eachfn, check, getResult) {
+ return function (arr, limit, iterator, cb) {
+ function done(err) {
+ if (cb) {
+ if (err) {
+ cb(err);
+ } else {
+ cb(null, getResult(false, void 0));
+ }
+ }
+ }
+ function iteratee(x, _, callback) {
+ if (!cb) return callback();
+ iterator(x, function (err, v) {
+ if (cb) {
+ if (err) {
+ cb(err);
+ cb = iterator = false;
+ } else if (check(v)) {
+ cb(null, getResult(true, x));
+ cb = iterator = false;
+ }
+ }
+ callback();
+ });
+ }
+ if (arguments.length > 3) {
+ eachfn(arr, limit, iteratee, done);
+ } else {
+ cb = iterator;
+ iterator = limit;
+ eachfn(arr, iteratee, done);
+ }
+ };
+ }
+
+ function _findGetResult(v, x) {
+ return x;
+ }
+
+ var detect = _createTester(eachOf, identity, _findGetResult);
+
+ function _eachOfLimit(limit) {
+ return function (obj, iterator, callback) {
+ callback = once(callback || noop);
+ obj = obj || [];
+ var nextKey = keyIterator(obj);
+ if (limit <= 0) {
+ return callback(null);
+ }
+ var done = false;
+ var running = 0;
+ var errored = false;
+
+ (function replenish() {
+ if (done && running <= 0) {
+ return callback(null);
+ }
+
+ while (running < limit && !errored) {
+ var key = nextKey();
+ if (key === null) {
+ done = true;
+ if (running <= 0) {
+ callback(null);
+ }
+ return;
+ }
+ running += 1;
+ iterator(obj[key], key, onlyOnce(function (err) {
+ running -= 1;
+ if (err) {
+ callback(err);
+ errored = true;
+ } else {
+ replenish();
+ }
+ }));
+ }
+ })();
+ };
+ }
+
+ function eachOfLimit(obj, limit, iterator, cb) {
+ _eachOfLimit(limit)(obj, iterator, cb);
+ }
+
+ var detectLimit = _createTester(eachOfLimit, identity, _findGetResult);
+
+ var detectSeries = _createTester(eachOfSeries, identity, _findGetResult);
+
+ function consoleFunc(name) {
+ return rest(function (fn, args) {
+ fn.apply(null, args.concat([rest(function (err, args) {
+ if (typeof console === 'object') {
+ if (err) {
+ if (console.error) {
+ console.error(err);
+ }
+ } else if (console[name]) {
+ arrayEach(args, function (x) {
+ console[name](x);
+ });
+ }
+ }
+ })]));
+ });
+ }
+
+ var dir = consoleFunc('dir');
+
+ function during(test, iterator, cb) {
+ cb = cb || noop;
+
+ var next = rest(function (err, args) {
+ if (err) {
+ cb(err);
+ } else {
+ args.push(check);
+ test.apply(this, args);
+ }
+ });
+
+ var check = function (err, truth) {
+ if (err) return cb(err);
+ if (!truth) return cb(null);
+ iterator(next);
+ };
+
+ test(check);
+ }
+
+ function doDuring(iterator, test, cb) {
+ var calls = 0;
+
+ during(function (next) {
+ if (calls++ < 1) return next(null, true);
+ test.apply(this, arguments);
+ }, iterator, cb);
+ }
+
+ function whilst(test, iterator, cb) {
+ cb = cb || noop;
+ if (!test()) return cb(null);
+ var next = rest(function (err, args) {
+ if (err) return cb(err);
+ if (test.apply(this, args)) return iterator(next);
+ cb.apply(null, [null].concat(args));
+ });
+ iterator(next);
+ }
+
+ function doWhilst(iterator, test, cb) {
+ var calls = 0;
+ return whilst(function () {
+ return ++calls <= 1 || test.apply(this, arguments);
+ }, iterator, cb);
+ }
+
+ function doUntil(iterator, test, cb) {
+ return doWhilst(iterator, function () {
+ return !test.apply(this, arguments);
+ }, cb);
+ }
+
+ function _withoutIndex(iterator) {
+ return function (value, index, callback) {
+ return iterator(value, callback);
+ };
+ }
+
+ function each(arr, iterator, cb) {
+ return eachOf(arr, _withoutIndex(iterator), cb);
+ }
+
+ function eachLimit(arr, limit, iterator, cb) {
+ return _eachOfLimit(limit)(arr, _withoutIndex(iterator), cb);
+ }
+
+ function eachSeries(arr, iterator, cb) {
+ return eachOfSeries(arr, _withoutIndex(iterator), cb);
+ }
+
+ function ensureAsync(fn) {
+ return rest(function (args) {
+ var callback = args.pop();
+ var sync = true;
+ args.push(function () {
+ var innerArgs = arguments;
+ if (sync) {
+ setImmediate$1(function () {
+ callback.apply(null, innerArgs);
+ });
+ } else {
+ callback.apply(null, innerArgs);
+ }
+ });
+ fn.apply(this, args);
+ sync = false;
+ });
+ }
+
+ function notId(v) {
+ return !v;
+ }
+
+ var every = _createTester(eachOf, notId, notId);
+
+ var everyLimit = _createTester(eachOfLimit, notId, notId);
+
+ function _filter(eachfn, arr, iterator, callback) {
+ var results = [];
+ eachfn(arr, function (x, index, callback) {
+ iterator(x, function (err, v) {
+ if (err) {
+ callback(err);
+ } else {
+ if (v) {
+ results.push({ index: index, value: x });
+ }
+ callback();
+ }
+ });
+ }, function (err) {
+ if (err) {
+ callback(err);
+ } else {
+ callback(null, arrayMap(results.sort(function (a, b) {
+ return a.index - b.index;
+ }), baseProperty('value')));
+ }
+ });
+ }
+
+ var filter = doParallel(_filter);
+
+ function doParallelLimit(fn) {
+ return function (obj, limit, iterator, callback) {
+ return fn(_eachOfLimit(limit), obj, iterator, callback);
+ };
+ }
+
+ var filterLimit = doParallelLimit(_filter);
+
+ var filterSeries = doSeries(_filter);
+
+ function forever(fn, cb) {
+ var done = onlyOnce(cb || noop);
+ var task = ensureAsync(fn);
+
+ function next(err) {
+ if (err) return done(err);
+ task(next);
+ }
+ next();
+ }
+
+ function iterator (tasks) {
+ function makeCallback(index) {
+ function fn() {
+ 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);
+ }
+
+ var log = consoleFunc('log');
+
+ function _asyncMap(eachfn, arr, iterator, callback) {
+ callback = once(callback || noop);
+ arr = arr || [];
+ var results = isArrayLike(arr) ? [] : {};
+ eachfn(arr, function (value, index, callback) {
+ iterator(value, function (err, v) {
+ results[index] = v;
+ callback(err);
+ });
+ }, function (err) {
+ callback(err, results);
+ });
+ }
+
+ var map = doParallel(_asyncMap);
+
+ var mapLimit = doParallelLimit(_asyncMap);
+
+ var mapSeries = doSeries(_asyncMap);
+
+ /**
+ * Checks if `value` is a global object.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {null|Object} Returns `value` if it's a global object, else `null`.
+ */
+ function checkGlobal(value) {
+ return (value && value.Object === Object) ? value : null;
+ }
+
+ /** Used to determine if values are of the language type `Object`. */
+ var objectTypes = {
+ 'function': true,
+ 'object': true
+ };
+
+ /** Detect free variable `exports`. */
+ var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType) ? exports : null;
+
+ /** Detect free variable `module`. */
+ var freeModule = (objectTypes[typeof module] && module && !module.nodeType) ? module : null;
+
+ /** Detect free variable `global` from Node.js. */
+ var freeGlobal = checkGlobal(freeExports && freeModule && typeof global == 'object' && global);
+
+ /** Detect free variable `self`. */
+ var freeSelf = checkGlobal(objectTypes[typeof self] && self);
+
+ /** Detect free variable `window`. */
+ var freeWindow = checkGlobal(objectTypes[typeof window] && window);
+
+ /** Detect `this` as the global object. */
+ var thisGlobal = checkGlobal(objectTypes[typeof this] && this);
+
+ /**
+ * Used as a reference to the global object.
+ *
+ * The `this` value is used if it's the global object to avoid Greasemonkey's
+ * restricted `window` object, otherwise the `window` object is used.
+ */
+ var root = freeGlobal || ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) || freeSelf || thisGlobal || Function('return this')();
+
+ /** Built-in value references. */
+ var Symbol = root.Symbol;
+
+ /** `Object#toString` result references. */
+ var symbolTag = '[object Symbol]';
+
+ /** Used for built-in method references. */
+ var objectProto$5 = Object.prototype;
+
+ /**
+ * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
+ * of values.
+ */
+ var objectToString$3 = objectProto$5.toString;
+
+ /**
+ * Checks if `value` is classified as a `Symbol` primitive or object.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
+ * @example
+ *
+ * _.isSymbol(Symbol.iterator);
+ * // => true
+ *
+ * _.isSymbol('abc');
+ * // => false
+ */
+ function isSymbol(value) {
+ return typeof value == 'symbol' ||
+ (isObjectLike(value) && objectToString$3.call(value) == symbolTag);
+ }
+
+ /** Used as references for various `Number` constants. */
+ var INFINITY$1 = 1 / 0;
+
+ /** Used to convert symbols to primitives and strings. */
+ var symbolProto = Symbol ? Symbol.prototype : undefined;
+ var symbolToString = Symbol ? symbolProto.toString : undefined;
+ /**
+ * Converts `value` to a string if it's not one. An empty string is returned
+ * for `null` and `undefined` values. The sign of `-0` is preserved.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to process.
+ * @returns {string} Returns the string.
+ * @example
+ *
+ * _.toString(null);
+ * // => ''
+ *
+ * _.toString(-0);
+ * // => '-0'
+ *
+ * _.toString([1, 2, 3]);
+ * // => '1,2,3'
+ */
+ function toString(value) {
+ // Exit early for strings to avoid a performance hit in some environments.
+ if (typeof value == 'string') {
+ return value;
}
-
- function _asyncMap(eachfn, arr, iterator, callback) {
- callback = _once(callback || noop);
- arr = arr || [];
- var results = _isArrayLike(arr) ? [] : {};
- eachfn(arr, function (value, index, callback) {
- iterator(value, function (err, v) {
- results[index] = v;
- callback(err);
- });
- }, function (err) {
- callback(err, results);
- });
+ if (value == null) {
+ return '';
}
-
- async.map = doParallel(_asyncMap);
- async.mapSeries = doSeries(_asyncMap);
- async.mapLimit = doParallelLimit(_asyncMap);
-
- // reduce only has a series version, as doing reduce in parallel won't
- // work in many situations.
- async.inject =
- async.foldl =
- async.reduce = function (arr, memo, iterator, callback) {
- async.eachOfSeries(arr, function (x, i, callback) {
- iterator(memo, x, function (err, v) {
- memo = v;
- callback(err);
- });
- }, function (err) {
- callback(err, memo);
- });
- };
-
- async.foldr =
- async.reduceRight = function (arr, memo, iterator, callback) {
- var reversed = _map(arr, identity).reverse();
- async.reduce(reversed, memo, iterator, callback);
- };
-
- async.transform = function (arr, memo, iterator, callback) {
- if (arguments.length === 3) {
- callback = iterator;
- iterator = memo;
- memo = _isArray(arr) ? [] : {};
- }
-
- async.eachOf(arr, function(v, k, cb) {
- iterator(memo, v, k, cb);
- }, function(err) {
- callback(err, memo);
- });
- };
-
- function _filter(eachfn, arr, iterator, callback) {
- var results = [];
- eachfn(arr, function (x, index, callback) {
- iterator(x, function (v) {
- if (v) {
- results.push({index: index, value: x});
- }
- callback();
- });
- }, function () {
- callback(_map(results.sort(function (a, b) {
- return a.index - b.index;
- }), function (x) {
- return x.value;
- }));
- });
- }
-
- async.select =
- async.filter = doParallel(_filter);
-
- async.selectLimit =
- async.filterLimit = doParallelLimit(_filter);
-
- async.selectSeries =
- async.filterSeries = doSeries(_filter);
-
- function _reject(eachfn, arr, iterator, callback) {
- _filter(eachfn, arr, function(value, cb) {
- iterator(value, function(v) {
- cb(!v);
- });
- }, callback);
- }
- async.reject = doParallel(_reject);
- async.rejectLimit = doParallelLimit(_reject);
- async.rejectSeries = doSeries(_reject);
-
- function _createTester(eachfn, check, getResult) {
- return function(arr, limit, iterator, cb) {
- function done() {
- if (cb) cb(getResult(false, void 0));
- }
- function iteratee(x, _, callback) {
- if (!cb) return callback();
- iterator(x, function (v) {
- if (cb && check(v)) {
- cb(getResult(true, x));
- cb = iterator = false;
- }
- callback();
- });
- }
- if (arguments.length > 3) {
- eachfn(arr, limit, iteratee, done);
- } else {
- cb = iterator;
- iterator = limit;
- eachfn(arr, iteratee, done);
- }
- };
- }
-
- async.any =
- async.some = _createTester(async.eachOf, toBool, identity);
-
- async.someLimit = _createTester(async.eachOfLimit, toBool, identity);
-
- async.all =
- async.every = _createTester(async.eachOf, notId, notId);
-
- async.everyLimit = _createTester(async.eachOfLimit, notId, notId);
-
- function _findGetResult(v, x) {
- return x;
- }
- async.detect = _createTester(async.eachOf, identity, _findGetResult);
- async.detectSeries = _createTester(async.eachOfSeries, identity, _findGetResult);
- async.detectLimit = _createTester(async.eachOfLimit, identity, _findGetResult);
-
- 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 {
- callback(null, _map(results.sort(comparator), function (x) {
- return x.value;
- }));
- }
-
- });
-
- function comparator(left, right) {
- var a = left.criteria, b = right.criteria;
- return a < b ? -1 : a > b ? 1 : 0;
- }
- };
-
- async.auto = function (tasks, concurrency, callback) {
- if (typeof arguments[1] === 'function') {
- // concurrency is optional, shift the args.
- callback = concurrency;
- concurrency = null;
- }
- callback = _once(callback || noop);
- var keys = _keys(tasks);
- var remainingTasks = keys.length;
- if (!remainingTasks) {
- return callback(null);
- }
- if (!concurrency) {
- concurrency = remainingTasks;
- }
-
- var results = {};
- var runningTasks = 0;
-
- var hasError = false;
-
- var listeners = [];
- function addListener(fn) {
- listeners.unshift(fn);
- }
- function removeListener(fn) {
- var idx = _indexOf(listeners, fn);
- if (idx >= 0) listeners.splice(idx, 1);
- }
- function taskComplete() {
- remainingTasks--;
- _arrayEach(listeners.slice(0), function (fn) {
- fn();
- });
- }
-
- addListener(function () {
- if (!remainingTasks) {
- callback(null, results);
- }
- });
-
- _arrayEach(keys, function (k) {
- if (hasError) return;
- var task = _isArray(tasks[k]) ? tasks[k]: [tasks[k]];
- var taskCallback = _restParam(function(err, args) {
- runningTasks--;
- if (args.length <= 1) {
- args = args[0];
- }
- if (err) {
- var safeResults = {};
- _forEachOf(results, function(val, rkey) {
- safeResults[rkey] = val;
- });
- safeResults[k] = args;
- hasError = true;
-
- callback(err, safeResults);
- }
- else {
- results[k] = args;
- async.setImmediate(taskComplete);
- }
- });
- var requires = task.slice(0, task.length - 1);
- // prevent dead-locks
- var len = requires.length;
- var dep;
- while (len--) {
- if (!(dep = tasks[requires[len]])) {
- throw new Error('Has nonexistent dependency in ' + requires.join(', '));
- }
- if (_isArray(dep) && _indexOf(dep, k) >= 0) {
- throw new Error('Has cyclic dependencies');
- }
- }
- function ready() {
- return runningTasks < concurrency && _reduce(requires, function (a, x) {
- return (a && results.hasOwnProperty(x));
- }, true) && !results.hasOwnProperty(k);
- }
- if (ready()) {
- runningTasks++;
- task[task.length - 1](taskCallback, results);
- }
- else {
- addListener(listener);
- }
- function listener() {
- if (ready()) {
- runningTasks++;
- removeListener(listener);
- task[task.length - 1](taskCallback, results);
- }
- }
- });
- };
-
-
-
- async.retry = function(times, task, callback) {
- var DEFAULT_TIMES = 5;
- var DEFAULT_INTERVAL = 0;
-
- var attempts = [];
-
- var opts = {
- times: DEFAULT_TIMES,
- interval: DEFAULT_INTERVAL
- };
-
- function parseTimes(acc, t){
- if(typeof t === 'number'){
- acc.times = parseInt(t, 10) || DEFAULT_TIMES;
- } else if(typeof t === 'object'){
- acc.times = parseInt(t.times, 10) || DEFAULT_TIMES;
- acc.interval = parseInt(t.interval, 10) || DEFAULT_INTERVAL;
- } else {
- throw new Error('Unsupported argument type for \'times\': ' + typeof t);
- }
- }
-
- var length = arguments.length;
- if (length < 1 || length > 3) {
- throw new Error('Invalid arguments - must be either (task), (task, callback), (times, task) or (times, task, callback)');
- } else if (length <= 2 && typeof times === 'function') {
- callback = task;
- task = times;
- }
- if (typeof times !== 'function') {
- parseTimes(opts, times);
- }
- opts.callback = callback;
- opts.task = task;
-
- function wrappedTask(wrappedCallback, wrappedResults) {
- function retryAttempt(task, finalAttempt) {
- return function(seriesCallback) {
- task(function(err, result){
- seriesCallback(!err || finalAttempt, {err: err, result: result});
- }, wrappedResults);
- };
- }
-
- function retryInterval(interval){
- return function(seriesCallback){
- setTimeout(function(){
- seriesCallback(null);
- }, interval);
- };
- }
-
- while (opts.times) {
-
- var finalAttempt = !(opts.times-=1);
- attempts.push(retryAttempt(opts.task, finalAttempt));
- if(!finalAttempt && opts.interval > 0){
- attempts.push(retryInterval(opts.interval));
- }
- }
-
- async.series(attempts, function(done, data){
- data = data[data.length - 1];
- (wrappedCallback || opts.callback)(data.err, data.result);
- });
- }
-
- // If a callback is passed, run this as a controll flow
- return opts.callback ? wrappedTask() : wrappedTask;
- };
-
- async.waterfall = function (tasks, callback) {
- callback = _once(callback || noop);
- if (!_isArray(tasks)) {
- var err = new Error('First argument to waterfall must be an array of functions');
- return callback(err);
- }
- if (!tasks.length) {
- return callback();
- }
- function wrapIterator(iterator) {
- return _restParam(function (err, args) {
- if (err) {
- callback.apply(null, [err].concat(args));
- }
- else {
- var next = iterator.next();
- if (next) {
- args.push(wrapIterator(next));
- }
- else {
- args.push(callback);
- }
- ensureAsync(iterator).apply(null, args);
- }
- });
- }
- wrapIterator(async.iterator(tasks))();
- };
-
- function _parallel(eachfn, tasks, callback) {
- callback = callback || noop;
- var results = _isArrayLike(tasks) ? [] : {};
-
- eachfn(tasks, function (task, key, callback) {
- task(_restParam(function (err, args) {
- if (args.length <= 1) {
- args = args[0];
- }
- results[key] = args;
- callback(err);
- }));
- }, function (err) {
- callback(err, results);
- });
+ if (isSymbol(value)) {
+ return Symbol ? symbolToString.call(value) : '';
}
-
- async.parallel = function (tasks, callback) {
- _parallel(async.eachOf, tasks, callback);
- };
-
- async.parallelLimit = function(tasks, limit, callback) {
- _parallel(_eachOfLimit(limit), tasks, callback);
- };
-
- async.series = function(tasks, callback) {
- _parallel(async.eachOfSeries, tasks, callback);
- };
-
- async.iterator = function (tasks) {
- function makeCallback(index) {
- function fn() {
- 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 = _restParam(function (fn, args) {
- return _restParam(function (callArgs) {
- return fn.apply(
- null, args.concat(callArgs)
- );
- });
+ var result = (value + '');
+ return (result == '0' && (1 / value) == -INFINITY$1) ? '-0' : result;
+ }
+
+ /** Used to match property names within property paths. */
+ var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]/g;
+
+ /** Used to match backslashes in property paths. */
+ var reEscapeChar = /\\(\\)?/g;
+
+ /**
+ * Converts `string` to a property path array.
+ *
+ * @private
+ * @param {string} string The string to convert.
+ * @returns {Array} Returns the property path array.
+ */
+ function stringToPath(string) {
+ var result = [];
+ toString(string).replace(rePropName, function(match, number, quote, string) {
+ result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match));
});
-
- function _concat(eachfn, arr, fn, callback) {
- var result = [];
- eachfn(arr, function (x, index, cb) {
- fn(x, function (err, y) {
- result = result.concat(y || []);
- cb(err);
- });
- }, function (err) {
- callback(err, result);
- });
+ return result;
+ }
+
+ /**
+ * The base implementation of `_.toPath` which only converts `value` to a
+ * path if it's not one.
+ *
+ * @private
+ * @param {*} value The value to process.
+ * @returns {Array} Returns the property path array.
+ */
+ function baseToPath(value) {
+ return isArray(value) ? value : stringToPath(value);
+ }
+
+ var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/;
+ var reIsPlainProp = /^\w*$/;
+ /**
+ * Checks if `value` is a property name and not a property path.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @param {Object} [object] The object to query keys on.
+ * @returns {boolean} Returns `true` if `value` is a property name, else `false`.
+ */
+ function isKey(value, object) {
+ if (typeof value == 'number') {
+ return true;
}
- async.concat = doParallel(_concat);
- async.concatSeries = doSeries(_concat);
-
- async.whilst = function (test, iterator, callback) {
- callback = callback || noop;
- if (test()) {
- var next = _restParam(function(err, args) {
- if (err) {
- callback(err);
- } else if (test.apply(this, args)) {
- iterator(next);
- } else {
- callback.apply(null, [null].concat(args));
- }
- });
- iterator(next);
- } else {
- callback(null);
- }
- };
-
- async.doWhilst = function (iterator, test, callback) {
- var calls = 0;
- return async.whilst(function() {
- return ++calls <= 1 || test.apply(this, arguments);
- }, iterator, callback);
- };
-
- async.until = function (test, iterator, callback) {
- return async.whilst(function() {
- return !test.apply(this, arguments);
- }, iterator, callback);
- };
-
- async.doUntil = function (iterator, test, callback) {
- return async.doWhilst(iterator, function() {
- return !test.apply(this, arguments);
- }, callback);
- };
-
- async.during = function (test, iterator, callback) {
- callback = callback || noop;
-
- var next = _restParam(function(err, args) {
- if (err) {
- callback(err);
- } else {
- args.push(check);
- test.apply(this, args);
- }
- });
-
- var check = function(err, truth) {
- if (err) {
- callback(err);
- } else if (truth) {
- iterator(next);
- } else {
- callback(null);
- }
- };
-
- test(check);
- };
-
- async.doDuring = function (iterator, test, callback) {
- var calls = 0;
- async.during(function(next) {
- if (calls++ < 1) {
- next(null, true);
- } else {
- test.apply(this, arguments);
- }
- }, iterator, callback);
- };
-
- function _queue(worker, concurrency, payload) {
- if (concurrency == null) {
- concurrency = 1;
- }
- else if(concurrency === 0) {
- throw new Error('Concurrency must not be zero');
- }
- function _insert(q, data, pos, callback) {
- if (callback != null && typeof callback !== "function") {
- throw new Error("task callback must be a function");
- }
- q.started = true;
- if (!_isArray(data)) {
- data = [data];
- }
- if(data.length === 0 && q.idle()) {
- // call drain immediately if there are no tasks
- return async.setImmediate(function() {
- q.drain();
- });
- }
- _arrayEach(data, function(task) {
- var item = {
- data: task,
- callback: callback || noop
- };
-
- if (pos) {
- q.tasks.unshift(item);
- } else {
- q.tasks.push(item);
- }
-
- if (q.tasks.length === q.concurrency) {
- q.saturated();
- }
- });
- async.setImmediate(q.process);
- }
- function _next(q, tasks) {
- return function(){
- workers -= 1;
-
- var removed = false;
- var args = arguments;
- _arrayEach(tasks, function (task) {
- _arrayEach(workersList, function (worker, index) {
- if (worker === task && !removed) {
- workersList.splice(index, 1);
- removed = true;
- }
- });
-
- task.callback.apply(task, args);
- });
- if (q.tasks.length + workers === 0) {
- q.drain();
- }
- q.process();
- };
- }
-
- var workers = 0;
- var workersList = [];
- var q = {
- tasks: [],
- concurrency: concurrency,
- payload: payload,
- saturated: noop,
- empty: noop,
- drain: noop,
- started: false,
- paused: false,
- push: function (data, callback) {
- _insert(q, data, false, callback);
- },
- kill: function () {
- q.drain = noop;
- q.tasks = [];
- },
- unshift: function (data, callback) {
- _insert(q, data, true, callback);
- },
- process: function () {
- while(!q.paused && workers < q.concurrency && q.tasks.length){
-
- var tasks = q.payload ?
- q.tasks.splice(0, q.payload) :
- q.tasks.splice(0, q.tasks.length);
-
- var data = _map(tasks, function (task) {
- return task.data;
- });
-
- if (q.tasks.length === 0) {
- q.empty();
- }
- workers += 1;
- workersList.push(tasks[0]);
- var cb = only_once(_next(q, tasks));
- worker(data, cb);
- }
- },
- length: function () {
- return q.tasks.length;
- },
- running: function () {
- return workers;
- },
- workersList: function () {
- return workersList;
- },
- idle: function() {
- return q.tasks.length + workers === 0;
- },
- pause: function () {
- q.paused = true;
- },
- resume: function () {
- if (q.paused === false) { return; }
- q.paused = false;
- var resumeCount = Math.min(q.concurrency, q.tasks.length);
- // Need to call q.process once per concurrent
- // worker to preserve full concurrency after pause
- for (var w = 1; w <= resumeCount; w++) {
- async.setImmediate(q.process);
- }
- }
- };
- return q;
+ return !isArray(value) &&
+ (reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||
+ (object != null && value in Object(object)));
+ }
+
+ /**
+ * Gets the last element of `array`.
+ *
+ * @static
+ * @memberOf _
+ * @category Array
+ * @param {Array} array The array to query.
+ * @returns {*} Returns the last element of `array`.
+ * @example
+ *
+ * _.last([1, 2, 3]);
+ * // => 3
+ */
+ function last(array) {
+ var length = array ? array.length : 0;
+ return length ? array[length - 1] : undefined;
+ }
+
+ /**
+ * The base implementation of `_.slice` without an iteratee call guard.
+ *
+ * @private
+ * @param {Array} array The array to slice.
+ * @param {number} [start=0] The start position.
+ * @param {number} [end=array.length] The end position.
+ * @returns {Array} Returns the slice of `array`.
+ */
+ function baseSlice(array, start, end) {
+ var index = -1,
+ length = array.length;
+
+ if (start < 0) {
+ start = -start > length ? 0 : (length + start);
}
-
- async.queue = function (worker, concurrency) {
- var q = _queue(function (items, cb) {
- worker(items[0], cb);
- }, concurrency, 1);
-
- return q;
- };
-
- async.priorityQueue = function (worker, concurrency) {
-
- function _compareTasks(a, b){
- return a.priority - b.priority;
- }
-
- function _binarySearch(sequence, item, compare) {
- var beg = -1,
- end = sequence.length - 1;
- while (beg < end) {
- var mid = beg + ((end - beg + 1) >>> 1);
- if (compare(item, sequence[mid]) >= 0) {
- beg = mid;
- } else {
- end = mid - 1;
- }
- }
- return beg;
- }
-
- function _insert(q, data, priority, callback) {
- if (callback != null && typeof callback !== "function") {
- throw new Error("task callback must be a function");
- }
- q.started = true;
- if (!_isArray(data)) {
- data = [data];
- }
- if(data.length === 0) {
- // call drain immediately if there are no tasks
- return async.setImmediate(function() {
- q.drain();
- });
- }
- _arrayEach(data, function(task) {
- var item = {
- data: task,
- priority: priority,
- callback: typeof callback === 'function' ? callback : noop
- };
-
- q.tasks.splice(_binarySearch(q.tasks, item, _compareTasks) + 1, 0, item);
-
- if (q.tasks.length === q.concurrency) {
- q.saturated();
- }
- async.setImmediate(q.process);
- });
- }
-
- // Start with a normal queue
- var q = async.queue(worker, concurrency);
-
- // Override push to accept second parameter representing priority
- q.push = function (data, priority, callback) {
- _insert(q, data, priority, callback);
- };
-
- // Remove unshift function
- delete q.unshift;
-
- return q;
- };
-
- async.cargo = function (worker, payload) {
- return _queue(worker, 1, payload);
- };
-
- function _console_fn(name) {
- return _restParam(function (fn, args) {
- fn.apply(null, args.concat([_restParam(function (err, args) {
- if (typeof console === 'object') {
- if (err) {
- if (console.error) {
- console.error(err);
- }
- }
- else if (console[name]) {
- _arrayEach(args, function (x) {
- console[name](x);
- });
- }
- }
- })]));
- });
+ end = end > length ? length : end;
+ if (end < 0) {
+ end += length;
}
- 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 = {};
- var has = Object.prototype.hasOwnProperty;
- hasher = hasher || identity;
- var memoized = _restParam(function memoized(args) {
- var callback = args.pop();
- var key = hasher.apply(null, args);
- if (has.call(memo, key)) {
- async.setImmediate(function () {
- callback.apply(null, memo[key]);
- });
- }
- else if (has.call(queues, key)) {
- queues[key].push(callback);
- }
- else {
- queues[key] = [callback];
- fn.apply(null, args.concat([_restParam(function (args) {
- memo[key] = args;
- var q = queues[key];
- delete queues[key];
- for (var i = 0, l = q.length; i < l; i++) {
- q[i].apply(null, args);
- }
- })]));
- }
- });
- memoized.memo = memo;
- memoized.unmemoized = fn;
- return memoized;
- };
+ length = start > end ? 0 : ((end - start) >>> 0);
+ start >>>= 0;
- async.unmemoize = function (fn) {
- return function () {
- return (fn.unmemoized || fn).apply(null, arguments);
- };
- };
-
- function _times(mapper) {
- return function (count, iterator, callback) {
- mapper(_range(count), iterator, callback);
- };
+ var result = Array(length);
+ while (++index < length) {
+ result[index] = array[index + start];
}
-
- async.times = _times(async.map);
- async.timesSeries = _times(async.mapSeries);
- async.timesLimit = function (count, limit, iterator, callback) {
- return async.mapLimit(_range(count), limit, iterator, callback);
- };
-
- async.seq = function (/* functions... */) {
- var fns = arguments;
- return _restParam(function (args) {
- var that = this;
-
- var callback = args[args.length - 1];
- if (typeof callback == 'function') {
- args.pop();
- } else {
- callback = noop;
- }
-
- async.reduce(fns, args, function (newargs, fn, cb) {
- fn.apply(that, newargs.concat([_restParam(function (err, nextargs) {
- cb(err, nextargs);
- })]));
- },
- function (err, results) {
- callback.apply(that, [err].concat(results));
- });
- });
- };
-
- async.compose = function (/* functions... */) {
- return async.seq.apply(null, Array.prototype.reverse.call(arguments));
- };
-
-
- function _applyEach(eachfn) {
- return _restParam(function(fns, args) {
- var go = _restParam(function(args) {
- var that = this;
- var callback = args.pop();
- return eachfn(fns, function (fn, _, cb) {
- fn.apply(that, args.concat([cb]));
- },
- callback);
- });
- if (args.length) {
- return go.apply(this, args);
- }
- else {
- return go;
- }
- });
+ return result;
+ }
+
+ /**
+ * The base implementation of `_.get` without support for default values.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @param {Array|string} path The path of the property to get.
+ * @returns {*} Returns the resolved value.
+ */
+ function baseGet(object, path) {
+ path = isKey(path, object) ? [path + ''] : baseToPath(path);
+
+ var index = 0,
+ length = path.length;
+
+ while (object != null && index < length) {
+ object = object[path[index++]];
}
-
- async.applyEach = _applyEach(async.eachOf);
- async.applyEachSeries = _applyEach(async.eachOfSeries);
-
-
- async.forever = function (fn, callback) {
- var done = only_once(callback || noop);
- var task = ensureAsync(fn);
- function next(err) {
- if (err) {
- return done(err);
- }
- task(next);
- }
- next();
- };
-
- function ensureAsync(fn) {
- return _restParam(function (args) {
- var callback = args.pop();
- args.push(function () {
- var innerArgs = arguments;
- if (sync) {
- async.setImmediate(function () {
- callback.apply(null, innerArgs);
- });
- } else {
- callback.apply(null, innerArgs);
- }
- });
- var sync = true;
- fn.apply(this, args);
- sync = false;
- });
+ return (index && index == length) ? object : undefined;
+ }
+
+ /**
+ * Gets the value at `path` of `object`. If the resolved value is
+ * `undefined` the `defaultValue` is used in its place.
+ *
+ * @static
+ * @memberOf _
+ * @category Object
+ * @param {Object} object The object to query.
+ * @param {Array|string} path The path of the property to get.
+ * @param {*} [defaultValue] The value returned if the resolved value is `undefined`.
+ * @returns {*} Returns the resolved value.
+ * @example
+ *
+ * var object = { 'a': [{ 'b': { 'c': 3 } }] };
+ *
+ * _.get(object, 'a[0].b.c');
+ * // => 3
+ *
+ * _.get(object, ['a', '0', 'b', 'c']);
+ * // => 3
+ *
+ * _.get(object, 'a.b.c', 'default');
+ * // => 'default'
+ */
+ function get(object, path, defaultValue) {
+ var result = object == null ? undefined : baseGet(object, path);
+ return result === undefined ? defaultValue : result;
+ }
+
+ /**
+ * Gets the parent value at `path` of `object`.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @param {Array} path The path to get the parent value of.
+ * @returns {*} Returns the parent value.
+ */
+ function parent(object, path) {
+ return path.length == 1 ? object : get(object, baseSlice(path, 0, -1));
+ }
+
+ /**
+ * Checks if `path` exists on `object`.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @param {Array|string} path The path to check.
+ * @param {Function} hasFunc The function to check properties.
+ * @returns {boolean} Returns `true` if `path` exists, else `false`.
+ */
+ function hasPath(object, path, hasFunc) {
+ if (object == null) {
+ return false;
}
-
- async.ensureAsync = ensureAsync;
-
- async.constant = _restParam(function(values) {
- var args = [null].concat(values);
- return function (callback) {
- return callback.apply(this, args);
- };
- });
-
- async.wrapSync =
- async.asyncify = function asyncify(func) {
- return _restParam(function (args) {
- var callback = args.pop();
- var result;
- try {
- result = func.apply(this, args);
- } catch (e) {
- return callback(e);
- }
- // if result is Promise object
- if (_isObject(result) && typeof result.then === "function") {
- result.then(function(value) {
- callback(null, value);
- })["catch"](function(err) {
- callback(err.message ? err : new Error(err));
- });
- } else {
- callback(null, result);
- }
- });
- };
-
- // Node.js
- if (typeof module === 'object' && module.exports) {
- module.exports = async;
+ var result = hasFunc(object, path);
+ if (!result && !isKey(path)) {
+ path = baseToPath(path);
+ object = parent(object, path);
+ if (object != null) {
+ path = last(path);
+ result = hasFunc(object, path);
+ }
}
- // AMD / RequireJS
- else if (typeof define === 'function' && define.amd) {
- define([], function () {
- return async;
- });
+ var length = object ? object.length : undefined;
+ return result || (
+ !!length && isLength(length) && isIndex(path, length) &&
+ (isArray(object) || isString(object) || isArguments(object))
+ );
+ }
+
+ /**
+ * Checks if `path` is a direct property of `object`.
+ *
+ * @static
+ * @memberOf _
+ * @category Object
+ * @param {Object} object The object to query.
+ * @param {Array|string} path The path to check.
+ * @returns {boolean} Returns `true` if `path` exists, else `false`.
+ * @example
+ *
+ * var object = { 'a': { 'b': { 'c': 3 } } };
+ * var other = _.create({ 'a': _.create({ 'b': _.create({ 'c': 3 }) }) });
+ *
+ * _.has(object, 'a');
+ * // => true
+ *
+ * _.has(object, 'a.b.c');
+ * // => true
+ *
+ * _.has(object, ['a', 'b', 'c']);
+ * // => true
+ *
+ * _.has(other, 'a');
+ * // => false
+ */
+ function has(object, path) {
+ return hasPath(object, path, baseHas);
+ }
+
+ function memoize(fn, hasher) {
+ var memo = Object.create(null);
+ var queues = Object.create(null);
+ hasher = hasher || identity;
+ var memoized = rest(function memoized(args) {
+ var callback = args.pop();
+ var key = hasher.apply(null, args);
+ if (has(memo, key)) {
+ setImmediate$1(function () {
+ callback.apply(null, memo[key]);
+ });
+ } else if (has(queues, key)) {
+ queues[key].push(callback);
+ } else {
+ queues[key] = [callback];
+ fn.apply(null, args.concat([rest(function (args) {
+ memo[key] = args;
+ var q = queues[key];
+ delete queues[key];
+ for (var i = 0, l = q.length; i < l; i++) {
+ q[i].apply(null, args);
+ }
+ })]));
+ }
+ });
+ memoized.memo = memo;
+ memoized.unmemoized = fn;
+ return memoized;
+ }
+
+ var nexTick = typeof process === 'object' && typeof process.nextTick === 'function' ? process.nextTick : setImmediate$1;
+
+ function _parallel(eachfn, tasks, callback) {
+ callback = callback || noop;
+ var results = isArrayLike(tasks) ? [] : {};
+
+ eachfn(tasks, function (task, key, callback) {
+ task(rest(function (err, args) {
+ if (args.length <= 1) {
+ args = args[0];
+ }
+ results[key] = args;
+ callback(err);
+ }));
+ }, function (err) {
+ callback(err, results);
+ });
+ }
+
+ function parallel(tasks, cb) {
+ return _parallel(eachOf, tasks, cb);
+ }
+
+ function parallelLimit(tasks, limit, cb) {
+ return _parallel(_eachOfLimit(limit), tasks, cb);
+ }
+
+ function queue (worker, concurrency) {
+ return queue$1(function (items, cb) {
+ worker(items[0], cb);
+ }, concurrency, 1);
+ }
+
+ function priorityQueue (worker, concurrency) {
+ function _compareTasks(a, b) {
+ return a.priority - b.priority;
+ }
+
+ function _binarySearch(sequence, item, compare) {
+ var beg = -1,
+ end = sequence.length - 1;
+ while (beg < end) {
+ var mid = beg + (end - beg + 1 >>> 1);
+ if (compare(item, sequence[mid]) >= 0) {
+ beg = mid;
+ } else {
+ end = mid - 1;
+ }
+ }
+ return beg;
+ }
+
+ function _insert(q, data, priority, callback) {
+ if (callback != null && typeof callback !== 'function') {
+ throw new Error('task callback must be a function');
+ }
+ q.started = true;
+ if (!isArray(data)) {
+ data = [data];
+ }
+ if (data.length === 0) {
+ // call drain immediately if there are no tasks
+ return setImmediate$1(function () {
+ q.drain();
+ });
+ }
+ arrayEach(data, function (task) {
+ var item = {
+ data: task,
+ priority: priority,
+ callback: typeof callback === 'function' ? callback : noop
+ };
+
+ q.tasks.splice(_binarySearch(q.tasks, item, _compareTasks) + 1, 0, item);
+
+ if (q.tasks.length === q.concurrency) {
+ q.saturated();
+ }
+ setImmediate$1(q.process);
+ });
+ }
+
+ // Start with a normal queue
+ var q = queue(worker, concurrency);
+
+ // Override push to accept second parameter representing priority
+ q.push = function (data, priority, callback) {
+ _insert(q, data, priority, callback);
+ };
+
+ // Remove unshift function
+ delete q.unshift;
+
+ return q;
+ }
+
+ var slice = Array.prototype.slice;
+
+ function reduceRight(arr, memo, iterator, cb) {
+ var reversed = slice.call(arr).reverse();
+ reduce(reversed, memo, iterator, cb);
+ }
+
+ function reject$1(eachfn, arr, iterator, callback) {
+ _filter(eachfn, arr, function (value, cb) {
+ iterator(value, function (err, v) {
+ if (err) {
+ cb(err);
+ } else {
+ cb(null, !v);
+ }
+ });
+ }, callback);
+ }
+
+ var reject = doParallel(reject$1);
+
+ var rejectLimit = doParallelLimit(reject$1);
+
+ var rejectSeries = doSeries(reject$1);
+
+ function series(tasks, cb) {
+ return _parallel(eachOfSeries, tasks, cb);
+ }
+
+ function retry(times, task, callback) {
+ var DEFAULT_TIMES = 5;
+ var DEFAULT_INTERVAL = 0;
+
+ var attempts = [];
+
+ var opts = {
+ times: DEFAULT_TIMES,
+ interval: DEFAULT_INTERVAL
+ };
+
+ function parseTimes(acc, t) {
+ if (typeof t === 'number') {
+ acc.times = parseInt(t, 10) || DEFAULT_TIMES;
+ } else if (typeof t === 'object') {
+ acc.times = parseInt(t.times, 10) || DEFAULT_TIMES;
+ acc.interval = parseInt(t.interval, 10) || DEFAULT_INTERVAL;
+ } else {
+ throw new Error('Unsupported argument type for \'times\': ' + typeof t);
+ }
+ }
+
+ var length = arguments.length;
+ if (length < 1 || length > 3) {
+ throw new Error('Invalid arguments - must be either (task), (task, callback), (times, task) or (times, task, callback)');
+ } else if (length <= 2 && typeof times === 'function') {
+ callback = task;
+ task = times;
+ }
+ if (typeof times !== 'function') {
+ parseTimes(opts, times);
+ }
+ opts.callback = callback;
+ opts.task = task;
+
+ function wrappedTask(wrappedCallback, wrappedResults) {
+ function retryAttempt(task, finalAttempt) {
+ return function (seriesCallback) {
+ task(function (err, result) {
+ seriesCallback(!err || finalAttempt, {
+ err: err,
+ result: result
+ });
+ }, wrappedResults);
+ };
+ }
+
+ function retryInterval(interval) {
+ return function (seriesCallback) {
+ setTimeout(function () {
+ seriesCallback(null);
+ }, interval);
+ };
+ }
+
+ while (opts.times) {
+
+ var finalAttempt = !(opts.times -= 1);
+ attempts.push(retryAttempt(opts.task, finalAttempt));
+ if (!finalAttempt && opts.interval > 0) {
+ attempts.push(retryInterval(opts.interval));
+ }
+ }
+
+ series(attempts, function (done, data) {
+ data = data[data.length - 1];
+ (wrappedCallback || opts.callback)(data.err, data.result);
+ });
+ }
+
+ // If a callback is passed, run this as a controll flow
+ return opts.callback ? wrappedTask() : wrappedTask;
+ }
+
+ var some = _createTester(eachOf, Boolean, identity);
+
+ var someLimit = _createTester(eachOfLimit, Boolean, identity);
+
+ function sortBy(arr, iterator, cb) {
+ map(arr, function (x, cb) {
+ iterator(x, function (err, criteria) {
+ if (err) return cb(err);
+ cb(null, { value: x, criteria: criteria });
+ });
+ }, function (err, results) {
+ if (err) return cb(err);
+ cb(null, arrayMap(results.sort(comparator), baseProperty('value')));
+ });
+
+ function comparator(left, right) {
+ var a = left.criteria,
+ b = right.criteria;
+ return a < b ? -1 : a > b ? 1 : 0;
+ }
+ }
+
+ /* Built-in method references for those with the same name as other `lodash` methods. */
+ var nativeCeil = Math.ceil;
+ var nativeMax$2 = Math.max;
+ /**
+ * The base implementation of `_.range` and `_.rangeRight` which doesn't
+ * coerce arguments to numbers.
+ *
+ * @private
+ * @param {number} start The start of the range.
+ * @param {number} end The end of the range.
+ * @param {number} step The value to increment or decrement by.
+ * @param {boolean} [fromRight] Specify iterating from right to left.
+ * @returns {Array} Returns the new array of numbers.
+ */
+ function baseRange(start, end, step, fromRight) {
+ var index = -1,
+ length = nativeMax$2(nativeCeil((end - start) / (step || 1)), 0),
+ result = Array(length);
+
+ while (length--) {
+ result[fromRight ? length : ++index] = start;
+ start += step;
}
- // included directly via
-
+