Index: frontend/node_modules/neo-async/LICENSE
===================================================================
--- frontend/node_modules/neo-async/LICENSE	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/LICENSE	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,22 @@
+MIT License
+
+Copyright (c) 2014-2018 Suguru Motegi
+Based on Async.js, Copyright Caolan McMahon
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
Index: frontend/node_modules/neo-async/README.md
===================================================================
--- frontend/node_modules/neo-async/README.md	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/README.md	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,273 @@
+<h1 align="center">Neo-Async</h1>
+
+<p align="center">
+  <img src="https://raw.githubusercontent.com/wiki/suguru03/neo-async/images/neo_async_v2.png" width="250px" />
+</p>
+
+<p align="center">
+  <a href="https://www.npmjs.com/package/neo-async"><img alt="npm" src="https://img.shields.io/npm/v/neo-async.svg"></a>
+  <a href="https://travis-ci.org/suguru03/neo-async"><img alt="Travis Status" src="https://img.shields.io/travis/suguru03/neo-async.svg"></a>
+  <a href="https://codecov.io/gh/suguru03/neo-async"><img alt="Coverage Status" src="https://img.shields.io/codecov/c/github/suguru03/neo-async/master.svg"></a>
+  <a href="https://www.npmjs.com/package/neo-async"><img alt="download" src="https://img.shields.io/npm/dm/neo-async.svg"></a>
+  <a href="https://lgtm.com/projects/g/suguru03/neo-async/context:javascript"><img src="https://img.shields.io/lgtm/grade/javascript/g/suguru03/neo-async.svg?logo=lgtm&logoWidth=18" alt="Code Quality: Javascript" height="18"></a>
+  <a href="https://lgtm.com/projects/g/suguru03/neo-async/alerts"><img src="https://img.shields.io/lgtm/alerts/g/suguru03/neo-async.svg?logo=lgtm&logoWidth=18" alt="Total Alerts" height="18"></a>
+  <a href="https://app.fossa.io/projects/git%2Bgithub.com%2Fsuguru03%2Fneo-async?ref=badge_shield"><img src="https://app.fossa.io/api/projects/git%2Bgithub.com%2Fsuguru03%2Fneo-async.svg?type=shield" alt="FOSSA" height="18"></a>
+</p>
+
+Neo-Async is thought to be used as a drop-in replacement for [Async](https://github.com/caolan/async), it almost fully covers its functionality and runs [faster](#benchmark).
+
+Benchmark is [here](#benchmark)!
+
+Bluebird's benchmark is [here](https://github.com/suguru03/bluebird/tree/aigle/benchmark)!
+
+## Code Coverage
+![coverage](https://raw.githubusercontent.com/wiki/suguru03/neo-async/images/coverage.png)
+
+## Installation
+
+### In a browser
+```html
+<script src="async.min.js"></script>
+```
+
+### In an AMD loader
+```js
+require(['async'], function(async) {});
+```
+
+### Promise and async/await
+
+I recommend to use [`Aigle`](https://github.com/suguru03/aigle).
+
+It is optimized for Promise handling and has almost the same functionality as `neo-async`.
+
+### Node.js
+
+#### standard
+
+```bash
+$ npm install neo-async
+```
+```js
+var async = require('neo-async');
+```
+
+#### replacement
+```bash
+$ npm install neo-async
+$ ln -s ./node_modules/neo-async ./node_modules/async
+```
+```js
+var async = require('async');
+```
+
+### Bower
+
+```bash
+bower install neo-async
+```
+
+## Feature
+
+[JSDoc](http://suguru03.github.io/neo-async/doc/async.html)
+
+\* not in Async
+
+### Collections
+
+- [`each`](http://suguru03.github.io/neo-async/doc/async.each.html)
+- [`eachSeries`](http://suguru03.github.io/neo-async/doc/async.eachSeries.html)
+- [`eachLimit`](http://suguru03.github.io/neo-async/doc/async.eachLimit.html)
+- [`forEach`](http://suguru03.github.io/neo-async/doc/async.each.html) -> [`each`](http://suguru03.github.io/neo-async/doc/async.each.html)
+- [`forEachSeries`](http://suguru03.github.io/neo-async/doc/async.eachSeries.html) -> [`eachSeries`](http://suguru03.github.io/neo-async/doc/async.eachSeries.html)
+- [`forEachLimit`](http://suguru03.github.io/neo-async/doc/async.eachLimit.html) -> [`eachLimit`](http://suguru03.github.io/neo-async/doc/async.eachLimit.html)
+- [`eachOf`](http://suguru03.github.io/neo-async/doc/async.each.html) -> [`each`](http://suguru03.github.io/neo-async/doc/async.each.html)
+- [`eachOfSeries`](http://suguru03.github.io/neo-async/doc/async.eachSeries.html) -> [`eachSeries`](http://suguru03.github.io/neo-async/doc/async.eachSeries.html)
+- [`eachOfLimit`](http://suguru03.github.io/neo-async/doc/async.eachLimit.html) -> [`eachLimit`](http://suguru03.github.io/neo-async/doc/async.eachLimit.html)
+- [`forEachOf`](http://suguru03.github.io/neo-async/doc/async.each.html) -> [`each`](http://suguru03.github.io/neo-async/doc/async.each.html)
+- [`forEachOfSeries`](http://suguru03.github.io/neo-async/doc/async.eachSeries.html) -> [`eachSeries`](http://suguru03.github.io/neo-async/doc/async.eachSeries.html)
+- [`eachOfLimit`](http://suguru03.github.io/neo-async/doc/async.eachLimit.html) -> [`forEachLimit`](http://suguru03.github.io/neo-async/doc/async.eachLimit.html)
+- [`map`](http://suguru03.github.io/neo-async/doc/async.map.html)
+- [`mapSeries`](http://suguru03.github.io/neo-async/doc/async.mapSeries.html)
+- [`mapLimit`](http://suguru03.github.io/neo-async/doc/async.mapLimit.html)
+- [`mapValues`](http://suguru03.github.io/neo-async/doc/async.mapValues.html)
+- [`mapValuesSeries`](http://suguru03.github.io/neo-async/doc/async.mapValuesSeries.html)
+- [`mapValuesLimit`](http://suguru03.github.io/neo-async/doc/async.mapValuesLimit.html)
+- [`filter`](http://suguru03.github.io/neo-async/doc/async.filter.html)
+- [`filterSeries`](http://suguru03.github.io/neo-async/doc/async.filterSeries.html)
+- [`filterLimit`](http://suguru03.github.io/neo-async/doc/async.filterLimit.html)
+- [`select`](http://suguru03.github.io/neo-async/doc/async.filter.html) -> [`filter`](http://suguru03.github.io/neo-async/doc/async.filter.html)
+- [`selectSeries`](http://suguru03.github.io/neo-async/doc/async.filterSeries.html) -> [`filterSeries`](http://suguru03.github.io/neo-async/doc/async.filterSeries.html)
+- [`selectLimit`](http://suguru03.github.io/neo-async/doc/async.filterLimit.html) -> [`filterLimit`](http://suguru03.github.io/neo-async/doc/async.filterLimit.html)
+- [`reject`](http://suguru03.github.io/neo-async/doc/async.reject.html)
+- [`rejectSeries`](http://suguru03.github.io/neo-async/doc/async.rejectSeries.html)
+- [`rejectLimit`](http://suguru03.github.io/neo-async/doc/async.rejectLimit.html)
+- [`detect`](http://suguru03.github.io/neo-async/doc/async.detect.html)
+- [`detectSeries`](http://suguru03.github.io/neo-async/doc/async.detectSeries.html)
+- [`detectLimit`](http://suguru03.github.io/neo-async/doc/async.detectLimit.html)
+- [`find`](http://suguru03.github.io/neo-async/doc/async.detect.html) -> [`detect`](http://suguru03.github.io/neo-async/doc/async.detect.html)
+- [`findSeries`](http://suguru03.github.io/neo-async/doc/async.detectSeries.html) -> [`detectSeries`](http://suguru03.github.io/neo-async/doc/async.detectSeries.html)
+- [`findLimit`](http://suguru03.github.io/neo-async/doc/async.detectLimit.html) -> [`detectLimit`](http://suguru03.github.io/neo-async/doc/async.detectLimit.html)
+- [`pick`](http://suguru03.github.io/neo-async/doc/async.pick.html) *
+- [`pickSeries`](http://suguru03.github.io/neo-async/doc/async.pickSeries.html) *
+- [`pickLimit`](http://suguru03.github.io/neo-async/doc/async.pickLimit.html) *
+- [`omit`](http://suguru03.github.io/neo-async/doc/async.omit.html) *
+- [`omitSeries`](http://suguru03.github.io/neo-async/doc/async.omitSeries.html) *
+- [`omitLimit`](http://suguru03.github.io/neo-async/doc/async.omitLimit.html) *
+- [`reduce`](http://suguru03.github.io/neo-async/doc/async.reduce.html)
+- [`inject`](http://suguru03.github.io/neo-async/doc/async.reduce.html) -> [`reduce`](http://suguru03.github.io/neo-async/doc/async.reduce.html)
+- [`foldl`](http://suguru03.github.io/neo-async/doc/async.reduce.html) -> [`reduce`](http://suguru03.github.io/neo-async/doc/async.reduce.html)
+- [`reduceRight`](http://suguru03.github.io/neo-async/doc/async.reduceRight.html)
+- [`foldr`](http://suguru03.github.io/neo-async/doc/async.reduceRight.html) -> [`reduceRight`](http://suguru03.github.io/neo-async/doc/async.reduceRight.html)
+- [`transform`](http://suguru03.github.io/neo-async/doc/async.transform.html)
+- [`transformSeries`](http://suguru03.github.io/neo-async/doc/async.transformSeries.html) *
+- [`transformLimit`](http://suguru03.github.io/neo-async/doc/async.transformLimit.html) *
+- [`sortBy`](http://suguru03.github.io/neo-async/doc/async.sortBy.html)
+- [`sortBySeries`](http://suguru03.github.io/neo-async/doc/async.sortBySeries.html) *
+- [`sortByLimit`](http://suguru03.github.io/neo-async/doc/async.sortByLimit.html) *
+- [`some`](http://suguru03.github.io/neo-async/doc/async.some.html)
+- [`someSeries`](http://suguru03.github.io/neo-async/doc/async.someSeries.html)
+- [`someLimit`](http://suguru03.github.io/neo-async/doc/async.someLimit.html)
+- [`any`](http://suguru03.github.io/neo-async/doc/async.some.html) -> [`some`](http://suguru03.github.io/neo-async/doc/async.some.html)
+- [`anySeries`](http://suguru03.github.io/neo-async/doc/async.someSeries.html) -> [`someSeries`](http://suguru03.github.io/neo-async/doc/async.someSeries.html)
+- [`anyLimit`](http://suguru03.github.io/neo-async/doc/async.someLimit.html) -> [`someLimit`](http://suguru03.github.io/neo-async/doc/async.someLimit.html)
+- [`every`](http://suguru03.github.io/neo-async/doc/async.every.html)
+- [`everySeries`](http://suguru03.github.io/neo-async/doc/async.everySeries.html)
+- [`everyLimit`](http://suguru03.github.io/neo-async/doc/async.everyLimit.html)
+- [`all`](http://suguru03.github.io/neo-async/doc/async.every.html) -> [`every`](http://suguru03.github.io/neo-async/doc/async.every.html)
+- [`allSeries`](http://suguru03.github.io/neo-async/doc/async.everySeries.html) -> [`every`](http://suguru03.github.io/neo-async/doc/async.everySeries.html)
+- [`allLimit`](http://suguru03.github.io/neo-async/doc/async.everyLimit.html) -> [`every`](http://suguru03.github.io/neo-async/doc/async.everyLimit.html)
+- [`concat`](http://suguru03.github.io/neo-async/doc/async.concat.html)
+- [`concatSeries`](http://suguru03.github.io/neo-async/doc/async.concatSeries.html)
+- [`concatLimit`](http://suguru03.github.io/neo-async/doc/async.concatLimit.html) *
+
+### Control Flow
+
+- [`parallel`](http://suguru03.github.io/neo-async/doc/async.parallel.html)
+- [`series`](http://suguru03.github.io/neo-async/doc/async.series.html)
+- [`parallelLimit`](http://suguru03.github.io/neo-async/doc/async.series.html)
+- [`tryEach`](http://suguru03.github.io/neo-async/doc/async.tryEach.html)
+- [`waterfall`](http://suguru03.github.io/neo-async/doc/async.waterfall.html)
+- [`angelFall`](http://suguru03.github.io/neo-async/doc/async.angelFall.html) *
+- [`angelfall`](http://suguru03.github.io/neo-async/doc/async.angelFall.html) -> [`angelFall`](http://suguru03.github.io/neo-async/doc/async.angelFall.html) *
+- [`whilst`](#whilst)
+- [`doWhilst`](#doWhilst)
+- [`until`](#until)
+- [`doUntil`](#doUntil)
+- [`during`](#during)
+- [`doDuring`](#doDuring)
+- [`forever`](#forever)
+- [`compose`](#compose)
+- [`seq`](#seq)
+- [`applyEach`](#applyEach)
+- [`applyEachSeries`](#applyEachSeries)
+- [`queue`](#queue)
+- [`priorityQueue`](#priorityQueue)
+- [`cargo`](#cargo)
+- [`auto`](#auto)
+- [`autoInject`](#autoInject)
+- [`retry`](#retry)
+- [`retryable`](#retryable)
+- [`iterator`](#iterator)
+- [`times`](http://suguru03.github.io/neo-async/doc/async.times.html)
+- [`timesSeries`](http://suguru03.github.io/neo-async/doc/async.timesSeries.html)
+- [`timesLimit`](http://suguru03.github.io/neo-async/doc/async.timesLimit.html)
+- [`race`](#race)
+
+### Utils
+- [`apply`](#apply)
+- [`setImmediate`](#setImmediate)
+- [`nextTick`](#nextTick)
+- [`memoize`](#memoize)
+- [`unmemoize`](#unmemoize)
+- [`ensureAsync`](#ensureAsync)
+- [`constant`](#constant)
+- [`asyncify`](#asyncify)
+- [`wrapSync`](#asyncify) -> [`asyncify`](#asyncify)
+- [`log`](#log)
+- [`dir`](#dir)
+- [`timeout`](http://suguru03.github.io/neo-async/doc/async.timeout.html)
+- [`reflect`](#reflect)
+- [`reflectAll`](#reflectAll)
+- [`createLogger`](#createLogger)
+
+## Mode
+- [`safe`](#safe) *
+- [`fast`](#fast) *
+
+## Benchmark
+
+[Benchmark: Async vs Neo-Async](http://suguru03.hatenablog.com/entry/2016/06/10/135559)
+
+### How to check
+
+```bash
+$ node perf
+```
+
+### Environment
+
+* Darwin 17.3.0 x64
+* Node.js v8.9.4
+* async v2.6.0
+* neo-async v2.5.0
+* benchmark v2.1.4
+
+### Result
+
+The value is the ratio (Neo-Async/Async) of the average speed.
+
+#### Collections
+|function|benchmark|
+|---|--:|
+|each/forEach|2.43|
+|eachSeries/forEachSeries|1.75|
+|eachLimit/forEachLimit|1.68|
+|eachOf|3.29|
+|eachOfSeries|1.50|
+|eachOfLimit|1.59|
+|map|3.95|
+|mapSeries|1.81|
+|mapLimit|1.27|
+|mapValues|2.73|
+|mapValuesSeries|1.59|
+|mapValuesLimit|1.23|
+|filter|3.00|
+|filterSeries|1.74|
+|filterLimit|1.17|
+|reject|4.59|
+|rejectSeries|2.31|
+|rejectLimit|1.58|
+|detect|4.30|
+|detectSeries|1.86|
+|detectLimit|1.32|
+|reduce|1.82|
+|transform|2.46|
+|sortBy|4.08|
+|some|2.19|
+|someSeries|1.83|
+|someLimit|1.32|
+|every|2.09|
+|everySeries|1.84|
+|everyLimit|1.35|
+|concat|3.79|
+|concatSeries|4.45|
+
+#### Control Flow
+|funciton|benchmark|
+|---|--:|
+|parallel|2.93|
+|series|1.96|
+|waterfall|1.29|
+|whilst|1.00|
+|doWhilst|1.12|
+|until|1.12|
+|doUntil|1.12|
+|during|1.18|
+|doDuring|2.42|
+|times|4.25|
+|auto|1.97|
+
+
+## License
+[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fsuguru03%2Fneo-async.svg?type=large)](https://app.fossa.io/projects/git%2Bgithub.com%2Fsuguru03%2Fneo-async?ref=badge_large)
Index: frontend/node_modules/neo-async/all.js
===================================================================
--- frontend/node_modules/neo-async/all.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/all.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').all;
Index: frontend/node_modules/neo-async/allLimit.js
===================================================================
--- frontend/node_modules/neo-async/allLimit.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/allLimit.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').allLimit;
Index: frontend/node_modules/neo-async/allSeries.js
===================================================================
--- frontend/node_modules/neo-async/allSeries.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/allSeries.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').allSeries;
Index: frontend/node_modules/neo-async/angelFall.js
===================================================================
--- frontend/node_modules/neo-async/angelFall.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/angelFall.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').angelfall;
Index: frontend/node_modules/neo-async/any.js
===================================================================
--- frontend/node_modules/neo-async/any.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/any.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').any;
Index: frontend/node_modules/neo-async/anyLimit.js
===================================================================
--- frontend/node_modules/neo-async/anyLimit.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/anyLimit.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').anyLimit;
Index: frontend/node_modules/neo-async/anySeries.js
===================================================================
--- frontend/node_modules/neo-async/anySeries.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/anySeries.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').anySeries;
Index: frontend/node_modules/neo-async/apply.js
===================================================================
--- frontend/node_modules/neo-async/apply.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/apply.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').apply;
Index: frontend/node_modules/neo-async/applyEach.js
===================================================================
--- frontend/node_modules/neo-async/applyEach.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/applyEach.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').applyEach;
Index: frontend/node_modules/neo-async/applyEachSeries.js
===================================================================
--- frontend/node_modules/neo-async/applyEachSeries.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/applyEachSeries.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').applyEachSeries;
Index: frontend/node_modules/neo-async/async.js
===================================================================
--- frontend/node_modules/neo-async/async.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/async.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,9184 @@
+(function(global, factory) {
+  /*jshint -W030 */
+  'use strict';
+  typeof exports === 'object' && typeof module !== 'undefined'
+    ? factory(exports)
+    : typeof define === 'function' && define.amd
+    ? define(['exports'], factory)
+    : global.async
+    ? factory((global.neo_async = global.neo_async || {}))
+    : factory((global.async = global.async || {}));
+})(this, function(exports) {
+  'use strict';
+
+  var noop = function noop() {};
+  var throwError = function throwError() {
+    throw new Error('Callback was already called.');
+  };
+
+  var DEFAULT_TIMES = 5;
+  var DEFAULT_INTERVAL = 0;
+
+  var obj = 'object';
+  var func = 'function';
+  var isArray = Array.isArray;
+  var nativeKeys = Object.keys;
+  var nativePush = Array.prototype.push;
+  var iteratorSymbol = typeof Symbol === func && Symbol.iterator;
+
+  var nextTick, asyncNextTick, asyncSetImmediate;
+  createImmediate();
+
+  /**
+   * @memberof async
+   * @namespace each
+   * @param {Array|Object} collection
+   * @param {Function} iterator
+   * @param {Function} callback
+   * @example
+   *
+   * // array
+   * var order = [];
+   * var array = [1, 3, 2];
+   * var iterator = function(num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     done();
+   *   }, num * 10);
+   * };
+   * async.each(array, iterator, function(err, res) {
+   *   console.log(res); // undefined
+   *   console.log(order); // [1, 2, 3]
+   * });
+   *
+   * @example
+   *
+   * // array with index
+   * var order = [];
+   * var array = [1, 3, 2];
+   * var iterator = function(num, index, done) {
+   *   setTimeout(function() {
+   *     order.push([num, index]);
+   *     done();
+   *   }, num * 10);
+   * };
+   * async.each(array, iterator, function(err, res) {
+   *   console.log(res); // undefined
+   *   console.log(order); // [[1, 0], [2, 2], [3, 1]]
+   * });
+   *
+   * @example
+   *
+   * // object
+   * var order = [];
+   * var object = { a: 1, b: 3, c: 2 };
+   * var iterator = function(num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     done();
+   *   }, num * 10);
+   * };
+   * async.each(object, iterator, function(err, res) {
+   *   console.log(res); // undefined
+   *   console.log(order); // [1, 2, 3]
+   * });
+   *
+   * @example
+   *
+   * // object with key
+   * var order = [];
+   * var object = { a: 1, b: 3, c: 2 };
+   * var iterator = function(num, key, done) {
+   *   setTimeout(function() {
+   *     order.push([num, key]);
+   *     done();
+   *   }, num * 10);
+   * };
+   * async.each(object, iterator, function(err, res) {
+   *   console.log(res); // undefined
+   *   console.log(order); // [[1, 'a'], [2, 'c'], [3, 'b']]
+   * });
+   *
+   * @example
+   *
+   * // break
+   * var order = [];
+   * var array = [1, 3, 2];
+   * var iterator = function(num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     done(null, num !== 2);
+   *   }, num * 10);
+   * };
+   * async.each(array, iterator, function(err, res) {
+   *   console.log(res); // undefined
+   *   console.log(order); // [1, 2]
+   * });
+   *
+   */
+  var each = createEach(arrayEach, baseEach, symbolEach);
+
+  /**
+   * @memberof async
+   * @namespace map
+   * @param {Array|Object} collection
+   * @param {Function} iterator
+   * @param {Function} callback
+   * @example
+   *
+   * // array
+   * var order = [];
+   * var array = [1, 3, 2];
+   * var iterator = function(num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     done(null, num);
+   *   }, num * 10);
+   * };
+   * async.map(array, iterator, function(err, res) {
+   *   console.log(res); // [1, 3, 2];
+   *   console.log(order); // [1, 2, 3]
+   * });
+   *
+   * @example
+   *
+   * // array with index
+   * var order = [];
+   * var array = [1, 3, 2];
+   * var iterator = function(num, index, done) {
+   *   setTimeout(function() {
+   *     order.push([num, index]);
+   *     done(null, num);
+   *   }, num * 10);
+   * };
+   * async.map(array, iterator, function(err, res) {
+   *   console.log(res); // [1, 3, 2]
+   *   console.log(order); // [[1, 0], [2, 2], [3, 1]]
+   * });
+   *
+   * @example
+   *
+   * // object
+   * var order = [];
+   * var object = { a: 1, b: 3, c: 2 };
+   * var iterator = function(num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     done(null, num);
+   *   }, num * 10);
+   * };
+   * async.map(object, iterator, function(err, res) {
+   *   console.log(res); // [1, 3, 2]
+   *   console.log(order); // [1, 2, 3]
+   * });
+   *
+   * @example
+   *
+   * // object with key
+   * var order = [];
+   * var object = { a: 1, b: 3, c: 2 };
+   * var iterator = function(num, key, done) {
+   *   setTimeout(function() {
+   *     order.push([num, key]);
+   *     done(null, num);
+   *   }, num * 10);
+   * };
+   * async.map(object, iterator, function(err, res) {
+   *   console.log(res); // [1, 3, 2]
+   *   console.log(order); // [[1, 'a'], [2, 'c'], [3, 'b']]
+   * });
+   *
+   */
+  var map = createMap(arrayEachIndex, baseEachIndex, symbolEachIndex, true);
+
+  /**
+   * @memberof async
+   * @namespace mapValues
+   * @param {Array|Object} collection
+   * @param {Function} iterator
+   * @param {Function} callback
+   * @example
+   *
+   * // array
+   * var order = [];
+   * var array = [1, 3, 2];
+   * var iterator = function(num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     done(null, num);
+   *   }, num * 10);
+   * };
+   * async.mapValues(array, iterator, function(err, res) {
+   *   console.log(res); // { '0': 1, '1': 3, '2': 2 }
+   *   console.log(order); // [1, 2, 3]
+   * });
+   *
+   * @example
+   *
+   * // array with index
+   * var order = [];
+   * var array = [1, 3, 2];
+   * var iterator = function(num, index, done) {
+   *   setTimeout(function() {
+   *     order.push([num, index]);
+   *     done(null, num);
+   *   }, num * 10);
+   * };
+   * async.mapValues(array, iterator, function(err, res) {
+   *   console.log(res); // { '0': 1, '1': 3, '2': 2 }
+   *   console.log(order); // [[1, 0], [2, 2], [3, 1]]
+   * });
+   *
+   * @example
+   *
+   * // object
+   * var order = [];
+   * var object = { a: 1, b: 3, c: 2 };
+   * var iterator = function(num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     done(null, num);
+   *   }, num * 10);
+   * };
+   * async.mapValues(object, iterator, function(err, res) {
+   *   console.log(res); // { a: 1, b: 3, c: 2 }
+   *   console.log(order); // [1, 2, 3]
+   * });
+   *
+   * @example
+   *
+   * // object with key
+   * var order = [];
+   * var object = { a: 1, b: 3, c: 2 };
+   * var iterator = function(num, key, done) {
+   *   setTimeout(function() {
+   *     order.push([num, key]);
+   *     done(null, num);
+   *   }, num * 10);
+   * };
+   * async.mapValues(object, iterator, function(err, res) {
+   *   console.log(res); // { a: 1, b: 3, c: 2 }
+   *   console.log(order); // [[1, 'a'], [2, 'c'], [3, 'b']]
+   * });
+   *
+   */
+  var mapValues = createMap(arrayEachIndex, baseEachKey, symbolEachKey, false);
+
+  /**
+   * @memberof async
+   * @namespace filter
+   * @param {Array|Object} collection
+   * @param {Function} iterator
+   * @param {Function} callback
+   * @example
+   *
+   * // array
+   * var order = [];
+   * var array = [1, 3, 2];
+   * var iterator = function(num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     done(null, num % 2);
+   *   }, num * 10);
+   * };
+   * async.filter(array, iterator, function(err, res) {
+   *   console.log(res); // [1, 3];
+   *   console.log(order); // [1, 2, 3]
+   * });
+   *
+   * @example
+   *
+   * // array with index
+   * var order = [];
+   * var array = [1, 3, 2];
+   * var iterator = function(num, index, done) {
+   *   setTimeout(function() {
+   *     order.push([num, index]);
+   *     done(null, num % 2);
+   *   }, num * 10);
+   * };
+   * async.filter(array, iterator, function(err, res) {
+   *   console.log(res); // [1, 3];
+   *   console.log(order); // [[1, 0], [2, 2], [3, 1]]
+   * });
+   *
+   * @example
+   *
+   * // object
+   * var order = [];
+   * var object = { a: 1, b: 3, c: 2 };
+   * var iterator = function(num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     done(null, num % 2);
+   *   }, num * 10);
+   * };
+   * async.filter(object, iterator, function(err, res) {
+   *   console.log(res); // [1, 3];
+   *   console.log(order); // [1, 2, 3]
+   * });
+   *
+   * @example
+   *
+   * // object with key
+   * var order = [];
+   * var object = { a: 1, b: 3, c: 2 };
+   * var iterator = function(num, key, done) {
+   *   setTimeout(function() {
+   *     order.push([num, key]);
+   *     done(null, num % 2);
+   *   }, num * 10);
+   * };
+   * async.filter(object, iterator, function(err, res) {
+   *   console.log(res); // [1, 3];
+   *   console.log(order); // [[1, 'a'], [2, 'c'], [3, 'b']]
+   * });
+   *
+   */
+  var filter = createFilter(arrayEachIndexValue, baseEachIndexValue, symbolEachIndexValue, true);
+
+  /**
+   * @memberof async
+   * @namespace filterSeries
+   * @param {Array|Object} collection
+   * @param {Function} iterator
+   * @param {Function} callback
+   * @example
+   *
+   * // array
+   * var order = [];
+   * var array = [1, 3, 2];
+   * var iterator = function(num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     done(null, num % 2);
+   *   }, num * 10);
+   * };
+   * async.filterSeries(array, iterator, function(err, res) {
+   *   console.log(res); // [1, 3];
+   *   console.log(order); // [1, 3, 2]
+   * });
+   *
+   * @example
+   *
+   * // array with index
+   * var order = [];
+   * var array = [1, 3, 2];
+   * var iterator = function(num, index, done) {
+   *   setTimeout(function() {
+   *     order.push([num, index]);
+   *     done(null, num % 2);
+   *   }, num * 10);
+   * };
+   * async.filterSeries(array, iterator, function(err, res) {
+   *   console.log(res); // [1, 3]
+   *   console.log(order); // [[1, 0], [3, 1], [2, 2]]
+   * });
+   *
+   * @example
+   *
+   * // object
+   * var order = [];
+   * var object = { a: 1, b: 3, c: 2 };
+   * var iterator = function(num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     done(null, num % 2);
+   *   }, num * 10);
+   * };
+   * async.filterSeries(object, iterator, function(err, res) {
+   *   console.log(res); // [1, 3]
+   *   console.log(order); // [1, 3, 2]
+   * });
+   *
+   * @example
+   *
+   * // object with key
+   * var order = [];
+   * var object = { a: 1, b: 3, c: 2 };
+   * var iterator = function(num, key, done) {
+   *   setTimeout(function() {
+   *     order.push([num, key]);
+   *     done(null, num % 2);
+   *   }, num * 10);
+   * };
+   * async.filterSeries(object, iterator, function(err, res) {
+   *   console.log(res); // [1, 3]
+   *   console.log(order); // [[1, 'a'], [3, 'b'], [2, 'c']]
+   * });
+   *
+   */
+  var filterSeries = createFilterSeries(true);
+
+  /**
+   * @memberof async
+   * @namespace filterLimit
+   * @param {Array|Object} collection
+   * @param {number} limit - limit >= 1
+   * @param {Function} iterator
+   * @param {Function} callback
+   * @example
+   *
+   * // array
+   * var order = [];
+   * var array = [1, 5, 3, 4, 2];
+   * var iterator = function(num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     done(null, num % 2);
+   *   }, num * 10);
+   * };
+   * async.filterLimit(array, 2, iterator, function(err, res) {
+   *   console.log(res); // [1, 5, 3]
+   *   console.log(order); // [1, 3, 5, 2, 4]
+   * });
+   *
+   * @example
+   *
+   * // array with index
+   * var order = [];
+   * var array = [1, 5, 3, 4, 2];
+   * var iterator = function(num, index, done) {
+   *   setTimeout(function() {
+   *     order.push([num, index]);
+   *     done(null, num % 2);
+   *   }, num * 10);
+   * };
+   * async.filterLimit(array, 2, iterator, function(err, res) {
+   *   console.log(res); // [1, 5, 3]
+   *   console.log(order); // [[1, 0], [3, 2], [5, 1], [2, 4], [4, 3]]
+   * });
+   *
+   * @example
+   *
+   * // object
+   * var order = [];
+   * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 };
+   * var iterator = function(num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     done(null, num % 2);
+   *   }, num * 10);
+   * };
+   * async.filterLimit(object, 2, iterator, function(err, res) {
+   *   console.log(res); // [1, 5, 3]
+   *   console.log(order); // [1, 3, 5, 2, 4]
+   * });
+   *
+   * @example
+   *
+   * // object with key
+   * var order = [];
+   * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 };
+   * var iterator = function(num, key, done) {
+   *   setTimeout(function() {
+   *     order.push([num, key]);
+   *     done(null, num % 2);
+   *   }, num * 10);
+   * };
+   * async.filterLimit(object, 2, iterator, function(err, res) {
+   *   console.log(res); // [1, 5, 3]
+   *   console.log(order); // [[1, 'a'], [3, 'c'], [5, 'b'], [2, 'e'], [4, 'd']]
+   * });
+   *
+   */
+  var filterLimit = createFilterLimit(true);
+
+  /**
+   * @memberof async
+   * @namespace reject
+   * @param {Array|Object} collection
+   * @param {Function} iterator
+   * @param {Function} callback
+   * @example
+   *
+   * // array
+   * var order = [];
+   * var array = [1, 3, 2];
+   * var iterator = function(num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     done(null, num % 2);
+   *   }, num * 10);
+   * };
+   * async.reject(array, iterator, function(err, res) {
+   *   console.log(res); // [2];
+   *   console.log(order); // [1, 2, 3]
+   * });
+   *
+   * @example
+   *
+   * // array with index
+   * var order = [];
+   * var array = [1, 3, 2];
+   * var iterator = function(num, index, done) {
+   *   setTimeout(function() {
+   *     order.push([num, index]);
+   *     done(null, num % 2);
+   *   }, num * 10);
+   * };
+   * async.reject(array, iterator, function(err, res) {
+   *   console.log(res); // [2];
+   *   console.log(order); // [[1, 0], [2, 2], [3, 1]]
+   * });
+   *
+   * @example
+   *
+   * // object
+   * var order = [];
+   * var object = { a: 1, b: 3, c: 2 };
+   * var iterator = function(num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     done(null, num % 2);
+   *   }, num * 10);
+   * };
+   * async.reject(object, iterator, function(err, res) {
+   *   console.log(res); // [2];
+   *   console.log(order); // [1, 2, 3]
+   * });
+   *
+   * @example
+   *
+   * // object with key
+   * var order = [];
+   * var object = { a: 1, b: 3, c: 2 };
+   * var iterator = function(num, key, done) {
+   *   setTimeout(function() {
+   *     order.push([num, key]);
+   *     done(null, num % 2);
+   *   }, num * 10);
+   * };
+   * async.reject(object, iterator, function(err, res) {
+   *   console.log(res); // [2];
+   *   console.log(order); // [[1, 'a'], [2, 'c'], [3, 'b']]
+   * });
+   *
+   */
+  var reject = createFilter(arrayEachIndexValue, baseEachIndexValue, symbolEachIndexValue, false);
+
+  /**
+   * @memberof async
+   * @namespace rejectSeries
+   * @param {Array|Object} collection
+   * @param {Function} iterator
+   * @param {Function} callback
+   * @example
+   *
+   * // array
+   * var order = [];
+   * var array = [1, 3, 2];
+   * var iterator = function(num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     done(null, num % 2);
+   *   }, num * 10);
+   * };
+   * async.rejectSeries(array, iterator, function(err, res) {
+   *   console.log(res); // [2];
+   *   console.log(order); // [1, 3, 2]
+   * });
+   *
+   * @example
+   *
+   * // object
+   * var order = [];
+   * var object = { a: 1, b: 3, c: 2 };
+   * var iterator = function(num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     done(null, num % 2);
+   *   }, num * 10);
+   * };
+   * async.rejectSeries(object, iterator, function(err, res) {
+   *   console.log(res); // [2];
+   *   console.log(order); // [1, 3, 2]
+   * });
+   *
+   * @example
+   *
+   * // object with key
+   * var order = [];
+   * var object = { a: 1, b: 3, c: 2 };
+   * var iterator = function(num, key, done) {
+   *   setTimeout(function() {
+   *     order.push([num, key]);
+   *     done(null, num % 2);
+   *   }, num * 10);
+   * };
+   * async.rejectSeries(object, iterator, function(err, res) {
+   *   console.log(res); // [2];
+   *   console.log(order); // [[1, 'a'], [3, 'b'], [2, 'c']]
+   * });
+   *
+   */
+  var rejectSeries = createFilterSeries(false);
+
+  /**
+   * @memberof async
+   * @namespace rejectLimit
+   * @param {Array|Object} collection
+   * @param {number} limit - limit >= 1
+   * @param {Function} iterator
+   * @param {Function} callback
+   * @example
+   *
+   * // array
+   * var order = [];
+   * var array = [1, 5, 3, 4, 2];
+   * var iterator = function(num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     done(null, num % 2);
+   *   }, num * 10);
+   * };
+   * async.rejectLimit(array, 2, iterator, function(err, res) {
+   *   console.log(res); // [4, 2]
+   *   console.log(order); // [1, 3, 5, 2, 4]
+   * });
+   *
+   * @example
+   *
+   * // array with index
+   * var order = [];
+   * var array = [1, 5, 3, 4, 2];
+   * var iterator = function(num, index, done) {
+   *   setTimeout(function() {
+   *     order.push([num, index]);
+   *     done(null, num % 2);
+   *   }, num * 10);
+   * };
+   * async.rejectLimit(array, 2, iterator, function(err, res) {
+   *   console.log(res); // [4, 2]
+   *   console.log(order); // [[1, 0], [3, 2], [5, 1], [2, 4], [4, 3]]
+   * });
+   *
+   * @example
+   *
+   * // object
+   * var order = [];
+   * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 };
+   * var iterator = function(num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     done(null, num % 2);
+   *   }, num * 10);
+   * };
+   * async.rejectLimit(object, 2, iterator, function(err, res) {
+   *   console.log(res); // [4, 2]
+   *   console.log(order); // [1, 3, 5, 2, 4]
+   * });
+   *
+   * @example
+   *
+   * // object with key
+   * var order = [];
+   * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 };
+   * var iterator = function(num, key, done) {
+   *   setTimeout(function() {
+   *     order.push([num, key]);
+   *     done(null, num % 2);
+   *   }, num * 10);
+   * };
+   * async.rejectLimit(object, 2, iterator, function(err, res) {
+   *   console.log(res); // [4, 2]
+   *   console.log(order); // [[1, 'a'], [3, 'c'], [5, 'b'], [2, 'e'], [4, 'd']]
+   * });
+   *
+   */
+  var rejectLimit = createFilterLimit(false);
+
+  /**
+   * @memberof async
+   * @namespace detect
+   * @param {Array|Object} collection
+   * @param {Function} iterator
+   * @param {Function} callback
+   * @example
+   *
+   * // array
+   * var order = [];
+   * var array = [1, 3, 2];
+   * var iterator = function(num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     done(null, num % 2);
+   *   }, num * 10);
+   * };
+   * async.detect(array, iterator, function(err, res) {
+   *   console.log(res); // 1
+   *   console.log(order); // [1]
+   * });
+   *
+   * @example
+   *
+   * // array with index
+   * var order = [];
+   * var array = [1, 3, 2];
+   * var iterator = function(num, index, done) {
+   *   setTimeout(function() {
+   *     order.push([num, index]);
+   *     done(null, num % 2);
+   *   }, num * 10);
+   * };
+   * async.detect(array, iterator, function(err, res) {
+   *   console.log(res); // 1
+   *   console.log(order); // [[1, 0]]
+   * });
+   *
+   * @example
+   *
+   * // object
+   * var order = [];
+   * var object = { a: 1, b: 3, c: 2 };
+   * var iterator = function(num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     done(null, num % 2);
+   *   }, num * 10);
+   * };
+   * async.detect(object, iterator, function(err, res) {
+   *   console.log(res); // 1
+   *   console.log(order); // [1]
+   * });
+   *
+   * @example
+   *
+   * // object with key
+   * var order = [];
+   * var object = { a: 1, b: 3, c: 2 };
+   * var iterator = function(num, key, done) {
+   *   setTimeout(function() {
+   *     order.push([num, key]);
+   *     done(null, num % 2);
+   *   }, num * 10);
+   * };
+   * async.detect(object, iterator, function(err, res) {
+   *   console.log(res); // 1
+   *   console.log(order); // [[1, 'a']]
+   * });
+   *
+   */
+  var detect = createDetect(arrayEachValue, baseEachValue, symbolEachValue, true);
+
+  /**
+   * @memberof async
+   * @namespace detectSeries
+   * @param {Array|Object} collection
+   * @param {Function} iterator
+   * @param {Function} callback
+   * @example
+   *
+   * // array
+   * var order = [];
+   * var array = [1, 3, 2];
+   * var iterator = function(num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     done(null, num % 2);
+   *   }, num * 10);
+   * };
+   * async.detectSeries(array, iterator, function(err, res) {
+   *   console.log(res); // 1
+   *   console.log(order); // [1]
+   * });
+   *
+   * @example
+   *
+   * // array with index
+   * var order = [];
+   * var array = [1, 3, 2];
+   * var iterator = function(num, index, done) {
+   *   setTimeout(function() {
+   *     order.push([num, index]);
+   *     done(null, num % 2);
+   *   }, num * 10);
+   * };
+   * async.detectSeries(array, iterator, function(err, res) {
+   *   console.log(res); // 1
+   *   console.log(order); // [[1, 0]]
+   * });
+   *
+   * @example
+   *
+   * // object
+   * var order = [];
+   * var object = { a: 1, b: 3, c: 2 };
+   * var iterator = function(num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     done(null, num % 2);
+   *   }, num * 10);
+   * };
+   * async.detectSeries(object, iterator, function(err, res) {
+   *   console.log(res); // 1
+   *   console.log(order); // [1]
+   * });
+   *
+   * @example
+   *
+   * // object with key
+   * var order = [];
+   * var object = { a: 1, b: 3, c: 2 };
+   * var iterator = function(num, key, done) {
+   *   setTimeout(function() {
+   *     order.push([num, key]);
+   *     done(null, num % 2);
+   *   }, num * 10);
+   * };
+   * async.detectSeries(object, iterator, function(err, res) {
+   *   console.log(res); // 1
+   *   console.log(order); // [[1, 'a']]
+   * });
+   *
+   */
+  var detectSeries = createDetectSeries(true);
+
+  /**
+   * @memberof async
+   * @namespace detectLimit
+   * @param {Array|Object} collection
+   * @param {number} limit - limit >= 1
+   * @param {Function} iterator
+   * @param {Function} callback
+   * @example
+   *
+   * // array
+   * var order = [];
+   * var array = [1, 5, 3, 4, 2];
+   * var iterator = function(num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     done(null, num % 2);
+   *   }, num * 10);
+   * };
+   * async.detectLimit(array, 2, iterator, function(err, res) {
+   *   console.log(res); // 1
+   *   console.log(order); // [1]
+   * });
+   *
+   * @example
+   *
+   * // array with index
+   * var order = [];
+   * var array = [1, 5, 3, 4, 2];
+   * var iterator = function(num, index, done) {
+   *   setTimeout(function() {
+   *     order.push([num, index]);
+   *     done(null, num % 2);
+   *   }, num * 10);
+   * };
+   * async.detectLimit(array, 2, iterator, function(err, res) {
+   *   console.log(res); // 1
+   *   console.log(order); // [[1, 0]]
+   * });
+   *
+   * @example
+   *
+   * // object
+   * var order = [];
+   * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 };
+   * var iterator = function(num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     done(null, num % 2);
+   *   }, num * 10);
+   * };
+   * async.detectLimit(object, 2, iterator, function(err, res) {
+   *   console.log(res); // 1
+   *   console.log(order); // [1]
+   * });
+   *
+   * @example
+   *
+   * // object with key
+   * var order = [];
+   * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 };
+   * var iterator = function(num, key, done) {
+   *   setTimeout(function() {
+   *     order.push([num, key]);
+   *     done(null, num % 2);
+   *   }, num * 10);
+   * };
+   * async.detectLimit(object, 2, iterator, function(err, res) {
+   *   console.log(res); // 1
+   *   console.log(order); // [[1, 'a']]
+   * });
+   *
+   */
+  var detectLimit = createDetectLimit(true);
+
+  /**
+   * @memberof async
+   * @namespace every
+   * @param {Array|Object} collection
+   * @param {Function} iterator
+   * @param {Function} callback
+   * @example
+   *
+   * // array
+   * var order = [];
+   * var array = [1, 3, 2];
+   * var iterator = function(num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     done(null, num % 2);
+   *   }, num * 10);
+   * };
+   * async.every(array, iterator, function(err, res) {
+   *   console.log(res); // false
+   *   console.log(order); // [1, 2]
+   * });
+   *
+   * @example
+   *
+   * // array with index
+   * var order = [];
+   * var array = [1, 3, 2];
+   * var iterator = function(num, index, done) {
+   *   setTimeout(function() {
+   *     order.push([num, index]);
+   *     done(null, num % 2);
+   *   }, num * 10);
+   * };
+   * async.every(array, iterator, function(err, res) {
+   *   console.log(res); // false
+   *   console.log(order); // [[1, 0], [2, 2]]
+   * });
+   *
+   * @example
+   *
+   * // object
+   * var order = [];
+   * var object = { a: 1, b: 3, c: 2 };
+   * var iterator = function(num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     done(null, num % 2);
+   *   }, num * 10);
+   * };
+   * async.every(object, iterator, function(err, res) {
+   *   console.log(res); // false
+   *   console.log(order); // [1, 2]
+   * });
+   *
+   * @example
+   *
+   * // object with key
+   * var order = [];
+   * var object = { a: 1, b: 3, c: 2 };
+   * var iterator = function(num, key, done) {
+   *   setTimeout(function() {
+   *     order.push([num, key]);
+   *     done(null, num % 2);
+   *   }, num * 10);
+   * };
+   * async.every(object, iterator, function(err, res) {
+   *   console.log(res); // false
+   *   console.log(order); // [[1, 'a'], [2, 'c']]
+   * });
+   *
+   */
+  var every = createEvery(arrayEachValue, baseEachValue, symbolEachValue);
+
+  /**
+   * @memberof async
+   * @namespace everySeries
+   * @param {Array|Object} collection
+   * @param {Function} iterator
+   * @param {Function} callback
+   * @example
+   *
+   * // array
+   * var order = [];
+   * var array = [1, 3, 2];
+   * var iterator = function(num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     done(null, num % 2);
+   *   }, num * 10);
+   * };
+   * async.everySeries(array, iterator, function(err, res) {
+   *   console.log(res); // false
+   *   console.log(order); // [1, 3, 2]
+   * });
+   *
+   * @example
+   *
+   * // array with index
+   * var order = [];
+   * var array = [1, 3, 2];
+   * var iterator = function(num, index, done) {
+   *   setTimeout(function() {
+   *     order.push([num, index]);
+   *     done(null, num % 2);
+   *   }, num * 10);
+   * };
+   * async.everySeries(array, iterator, function(err, res) {
+   *   console.log(res); // false
+   *   console.log(order); // [[1, 0], [3, 1], [2, 2]]
+   * });
+   *
+   * @example
+   *
+   * // object
+   * var order = [];
+   * var object = { a: 1, b: 3, c: 2 };
+   * var iterator = function(num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     done(null, num % 2);
+   *   }, num * 10);
+   * };
+   * async.everySeries(object, iterator, function(err, res) {
+   *   console.log(res); // false
+   *   console.log(order); // [1, 3, 2]
+   * });
+   *
+   * @example
+   *
+   * // object with key
+   * var order = [];
+   * var object = { a: 1, b: 3, c: 2 };
+   * var iterator = function(num, key, done) {
+   *   setTimeout(function() {
+   *     order.push([num, key]);
+   *     done(null, num % 2);
+   *   }, num * 10);
+   * };
+   * async.everySeries(object, iterator, function(err, res) {
+   *   console.log(res); // false
+   *   console.log(order); // [[1, 'a'], [3, 'b'] [2, 'c']]
+   * });
+   *
+   */
+  var everySeries = createEverySeries();
+
+  /**
+   * @memberof async
+   * @namespace everyLimit
+   * @param {Array|Object} collection
+   * @param {number} limit - limit >= 1
+   * @param {Function} iterator
+   * @param {Function} callback
+   * @example
+   *
+   * // array
+   * var order = [];
+   * var array = [1, 5, 3, 4, 2];
+   * var iterator = function(num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     done(null, num % 2);
+   *   }, num * 10);
+   * };
+   * async.everyLimit(array, 2, iterator, function(err, res) {
+   *   console.log(res); // false
+   *   console.log(order); // [1, 3, 5, 2]
+   * });
+   *
+   * @example
+   *
+   * // array with index
+   * var order = [];
+   * var array = [1, 5, 3, 4, 2];
+   * var iterator = function(num, index, done) {
+   *   setTimeout(function() {
+   *     order.push([num, index]);
+   *     done(null, num % 2);
+   *   }, num * 10);
+   * };
+   * async.everyLimit(array, 2, iterator, function(err, res) {
+   *   console.log(res); // false
+   *   console.log(order); // [[1, 0], [3, 2], [5, 1], [2, 4]]
+   * });
+   *
+   * @example
+   *
+   * // object
+   * var order = [];
+   * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 };
+   * var iterator = function(num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     done(null, num % 2);
+   *   }, num * 10);
+   * };
+   * async.everyLimit(object, 2, iterator, function(err, res) {
+   *   console.log(res); // false
+   *   console.log(order); // [1, 3, 5, 2]
+   * });
+   *
+   * @example
+   *
+   * // object with key
+   * var order = [];
+   * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 };
+   * var iterator = function(num, key, done) {
+   *   setTimeout(function() {
+   *     order.push([num, key]);
+   *     done(null, num % 2);
+   *   }, num * 10);
+   * };
+   * async.everyLimit(object, 2, iterator, function(err, res) {
+   *   console.log(res); // false
+   *   console.log(order); // [[1, 'a'], [3, 'c'], [5, 'b'], [2, 'e']]
+   * });
+   *
+   */
+  var everyLimit = createEveryLimit();
+
+  /**
+   * @memberof async
+   * @namespace pick
+   * @param {Array|Object} collection
+   * @param {Function} iterator
+   * @param {Function} callback
+   * @example
+   *
+   * // array
+   * var order = [];
+   * var array = [1, 3, 2, 4];
+   * var iterator = function(num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     done(null, num % 2);
+   *   }, num * 10);
+   * };
+   * async.pick(array, iterator, function(err, res) {
+   *   console.log(res); // { '0': 1, '1': 3 }
+   *   console.log(order); // [1, 2, 3, 4]
+   * });
+   *
+   * @example
+   *
+   * // array with index
+   * var order = [];
+   * var array = [1, 3, 2, 4];
+   * var iterator = function(num, index, done) {
+   *   setTimeout(function() {
+   *     order.push([num, index]);
+   *     done(null, num % 2);
+   *   }, num * 10);
+   * };
+   * async.pick(array, iterator, function(err, res) {
+   *   console.log(res); // { '0': 1, '1': 3 }
+   *   console.log(order); // [[0, 1], [2, 2], [3, 1], [4, 3]]
+   * });
+   *
+   * @example
+   *
+   * // object
+   * var order = [];
+   * var object = { a: 1, b: 3, c: 2, d: 4 };
+   * var iterator = function(num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     done(null, num % 2);
+   *   }, num * 10);
+   * };
+   * async.pick(object, iterator, function(err, res) {
+   *   console.log(res); // { a: 1, b: 3 }
+   *   console.log(order); // [1, 2, 3, 4]
+   * });
+   *
+   * @example
+   *
+   * // object with key
+   * var order = [];
+   * var object = { a: 1, b: 3, c: 2, d: 4 };
+   * var iterator = function(num, key, done) {
+   *   setTimeout(function() {
+   *     order.push([num, key]);
+   *     done(null, num % 2);
+   *   }, num * 10);
+   * };
+   * async.pick(object, iterator, function(err, res) {
+   *   console.log(res); // { a: 1, b: 3 }
+   *   console.log(order); // [[1, 'a'], [2, 'c'], [3, 'b'], [4, 'd']]
+   * });
+   *
+   */
+  var pick = createPick(arrayEachIndexValue, baseEachKeyValue, symbolEachKeyValue, true);
+
+  /**
+   * @memberof async
+   * @namespace pickSeries
+   * @param {Array|Object} collection
+   * @param {Function} iterator
+   * @param {Function} callback
+   * @example
+   *
+   * // array
+   * var order = [];
+   * var array = [1, 3, 2, 4];
+   * var iterator = function(num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     done(null, num % 2);
+   *   }, num * 10);
+   * };
+   * async.pickSeries(array, iterator, function(err, res) {
+   *   console.log(res); // { '0': 1, '1': 3 }
+   *   console.log(order); // [1, 3, 2, 4]
+   * });
+   *
+   * @example
+   *
+   * // array with index
+   * var order = [];
+   * var array = [1, 3, 2, 4];
+   * var iterator = function(num, index, done) {
+   *   setTimeout(function() {
+   *     order.push([num, index]);
+   *     done(null, num % 2);
+   *   }, num * 10);
+   * };
+   * async.pickSeries(array, iterator, function(err, res) {
+   *   console.log(res); // { '0': 1, '1': 3 }
+   *   console.log(order); // [[0, 1], [3, 1], [2, 2], [4, 3]]
+   * });
+   *
+   * @example
+   *
+   * // object
+   * var order = [];
+   * var object = { a: 1, b: 3, c: 2, d: 4 };
+   * var iterator = function(num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     done(null, num % 2);
+   *   }, num * 10);
+   * };
+   * async.pickSeries(object, iterator, function(err, res) {
+   *   console.log(res); // { a: 1, b: 3 }
+   *   console.log(order); // [1, 3, 2, 4]
+   * });
+   *
+   * @example
+   *
+   * // object with key
+   * var order = [];
+   * var object = { a: 1, b: 3, c: 2, d: 4 };
+   * var iterator = function(num, key, done) {
+   *   setTimeout(function() {
+   *     order.push([num, key]);
+   *     done(null, num % 2);
+   *   }, num * 10);
+   * };
+   * async.pickSeries(object, iterator, function(err, res) {
+   *   console.log(res); // { a: 1, b: 3 }
+   *   console.log(order); // [[1, 'a'], [3, 'b'], [2, 'c'], [4, 'd']]
+   * });
+   *
+   */
+  var pickSeries = createPickSeries(true);
+
+  /**
+   * @memberof async
+   * @namespace pickLimit
+   * @param {Array|Object} collection
+   * @param {number} limit - limit >= 1
+   * @param {Function} iterator
+   * @param {Function} callback
+   * @example
+   *
+   * // array
+   * var order = [];
+   * var array = [1, 5, 3, 4, 2];
+   * var iterator = function(num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     done(null, num % 2);
+   *   }, num * 10);
+   * };
+   * async.pickLimit(array, 2, iterator, function(err, res) {
+   *   console.log(res); // { '0': 1, '1': 5, '2': 3 }
+   *   console.log(order); // [1, 3, 5, 2, 4]
+   * });
+   *
+   * @example
+   *
+   * // array with index
+   * var order = [];
+   * var array = [1, 5, 3, 4, 2];
+   * var iterator = function(num, index, done) {
+   *   setTimeout(function() {
+   *     order.push([num, index]);
+   *     done(null, num % 2);
+   *   }, num * 10);
+   * };
+   * async.pickLimit(array, 2, iterator, function(err, res) {
+   *   console.log(res); // { '0': 1, '1': 5, '2': 3 }
+   *   console.log(order); // [[1, 0], [3, 2], [5, 1], [2, 4], [4, 3]]
+   * });
+   *
+   * @example
+   *
+   * // object
+   * var order = [];
+   * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 };
+   * var iterator = function(num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     done(null, num % 2);
+   *   }, num * 10);
+   * };
+   * async.pickLimit(object, 2, iterator, function(err, res) {
+   *   console.log(res); // { a: 1, b: 5, c: 3 }
+   *   console.log(order); // [1, 3, 5, 2, 4]
+   * });
+   *
+   * @example
+   *
+   * // object with key
+   * var order = [];
+   * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 };
+   * var iterator = function(num, key, done) {
+   *   setTimeout(function() {
+   *     order.push([num, key]);
+   *     done(null, num % 2);
+   *   }, num * 10);
+   * };
+   * async.pickLimit(object, 2, iterator, function(err, res) {
+   *   console.log(res); // { a: 1, b: 5, c: 3 }
+   *   console.log(order); // [[1, 'a'], [3, 'c'], [5, 'b'], [2, 'e'], [4, 'd']]
+   * });
+   *
+   */
+  var pickLimit = createPickLimit(true);
+
+  /**
+   * @memberof async
+   * @namespace omit
+   * @param {Array|Object} collection
+   * @param {Function} iterator
+   * @param {Function} callback
+   * @example
+   *
+   * // array
+   * var order = [];
+   * var array = [1, 3, 2, 4];
+   * var iterator = function(num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     done(null, num % 2);
+   *   }, num * 10);
+   * };
+   * async.omit(array, iterator, function(err, res) {
+   *   console.log(res); // { '2': 2, '3': 4 }
+   *   console.log(order); // [1, 2, 3, 4]
+   * });
+   *
+   * @example
+   *
+   * // array with index
+   * var order = [];
+   * var array = [1, 3, 2, 4];
+   * var iterator = function(num, index, done) {
+   *   setTimeout(function() {
+   *     order.push([num, index]);
+   *     done(null, num % 2);
+   *   }, num * 10);
+   * };
+   * async.omit(array, iterator, function(err, res) {
+   *   console.log(res); // { '2': 2, '3': 4 }
+   *   console.log(order); // [[0, 1], [2, 2], [3, 1], [4, 3]]
+   * });
+   *
+   * @example
+   *
+   * // object
+   * var order = [];
+   * var object = { a: 1, b: 3, c: 2, d: 4 };
+   * var iterator = function(num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     done(null, num % 2);
+   *   }, num * 10);
+   * };
+   * async.omit(object, iterator, function(err, res) {
+   *   console.log(res); // { c: 2, d: 4 }
+   *   console.log(order); // [1, 2, 3, 4]
+   * });
+   *
+   * @example
+   *
+   * // object with key
+   * var order = [];
+   * var object = { a: 1, b: 3, c: 2, d: 4 };
+   * var iterator = function(num, key, done) {
+   *   setTimeout(function() {
+   *     order.push([num, key]);
+   *     done(null, num % 2);
+   *   }, num * 10);
+   * };
+   * async.omit(object, iterator, function(err, res) {
+   *   console.log(res); // { c: 2, d: 4 }
+   *   console.log(order); // [[1, 'a'], [2, 'c'], [3, 'b'], [4, 'd']]
+   * });
+   *
+   */
+  var omit = createPick(arrayEachIndexValue, baseEachKeyValue, symbolEachKeyValue, false);
+
+  /**
+   * @memberof async
+   * @namespace omitSeries
+   * @param {Array|Object} collection
+   * @param {Function} iterator
+   * @param {Function} callback
+   * @example
+   *
+   * // array
+   * var order = [];
+   * var array = [1, 3, 2, 4];
+   * var iterator = function(num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     done(null, num % 2);
+   *   }, num * 10);
+   * };
+   * async.omitSeries(array, iterator, function(err, res) {
+   *   console.log(res); // { '2': 2, '3': 4 }
+   *   console.log(order); // [1, 3, 2, 4]
+   * });
+   *
+   * @example
+   *
+   * // array with index
+   * var order = [];
+   * var array = [1, 3, 2, 4];
+   * var iterator = function(num, index, done) {
+   *   setTimeout(function() {
+   *     order.push([num, index]);
+   *     done(null, num % 2);
+   *   }, num * 10);
+   * };
+   * async.omitSeries(array, iterator, function(err, res) {
+   *   console.log(res); // { '2': 2, '3': 4 }
+   *   console.log(order); // [[0, 1], [3, 1], [2, 2], [4, 3]]
+   * });
+   *
+   * @example
+   *
+   * // object
+   * var order = [];
+   * var object = { a: 1, b: 3, c: 2, d: 4 };
+   * var iterator = function(num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     done(null, num % 2);
+   *   }, num * 10);
+   * };
+   * async.omitSeries(object, iterator, function(err, res) {
+   *   console.log(res); // { c: 2, d: 4 }
+   *   console.log(order); // [1, 3, 2, 4]
+   * });
+   *
+   * @example
+   *
+   * // object with key
+   * var order = [];
+   * var object = { a: 1, b: 3, c: 2, d: 4 };
+   * var iterator = function(num, key, done) {
+   *   setTimeout(function() {
+   *     order.push([num, key]);
+   *     done(null, num % 2);
+   *   }, num * 10);
+   * };
+   * async.omitSeries(object, iterator, function(err, res) {
+   *   console.log(res); // { c: 2, d: 4 }
+   *   console.log(order); // [[1, 'a'], [3, 'b'], [2, 'c'], [4, 'd']]
+   * });
+   *
+   */
+  var omitSeries = createPickSeries(false);
+
+  /**
+   * @memberof async
+   * @namespace omitLimit
+   * @param {Array|Object} collection
+   * @param {number} limit - limit >= 1
+   * @param {Function} iterator
+   * @param {Function} callback
+   * @example
+   *
+   * // array
+   * var order = [];
+   * var array = [1, 5, 3, 4, 2];
+   * var iterator = function(num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     done(null, num % 2);
+   *   }, num * 10);
+   * };
+   * async.omitLimit(array, 2, iterator, function(err, res) {
+   *   console.log(res); // { '3': 4, '4': 2 }
+   *   console.log(order); // [1, 3, 5, 2, 4]
+   * });
+   *
+   * @example
+   *
+   * // array with index
+   * var order = [];
+   * var array = [1, 5, 3, 4, 2];
+   * var iterator = function(num, index, done) {
+   *   setTimeout(function() {
+   *     order.push([num, index]);
+   *     done(null, num % 2);
+   *   }, num * 10);
+   * };
+   * async.omitLimit(array, 2, iterator, function(err, res) {
+   *   console.log(res); // { '3': 4, '4': 2 }
+   *   console.log(order); // [[1, 0], [3, 2], [5, 1], [2, 4], [4, 3]]
+   * });
+   *
+   * @example
+   *
+   * // object
+   * var order = [];
+   * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 };
+   * var iterator = function(num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     done(null, num % 2);
+   *   }, num * 10);
+   * };
+   * async.omitLimit(object, 2, iterator, function(err, res) {
+   *   console.log(res); // { d: 4, e: 2 }
+   *   console.log(order); // [1, 3, 5, 2, 4]
+   * });
+   *
+   * @example
+   *
+   * // object with key
+   * var order = [];
+   * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 };
+   * var iterator = function(num, key, done) {
+   *   setTimeout(function() {
+   *     order.push([num, key]);
+   *     done(null, num % 2);
+   *   }, num * 10);
+   * };
+   * async.omitLimit(object, 2, iterator, function(err, res) {
+   *   console.log(res); // { d: 4, e: 2 }
+   *   console.log(order); // [[1, 'a'], [3, 'c'], [5, 'b'], [2, 'e'], [4, 'd']]
+   * });
+   *
+   */
+  var omitLimit = createPickLimit(false);
+
+  /**
+   * @memberof async
+   * @namespace transform
+   * @param {Array|Object} collection
+   * @param {Array|Object|Function} [accumulator]
+   * @param {Function} [iterator]
+   * @param {Function} [callback]
+   * @example
+   *
+   * // array
+   * var order = [];
+   * var collection = [1, 3, 2, 4];
+   * var iterator = function(result, num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     result.push(num)
+   *     done();
+   *   }, num * 10);
+   * };
+   * async.transform(collection, iterator, function(err, res) {
+   *   console.log(res); // [1, 2, 3, 4]
+   *   console.log(order); // [1, 2, 3, 4]
+   * });
+   *
+   * @example
+   *
+   * // array with index and accumulator
+   * var order = [];
+   * var collection = [1, 3, 2, 4];
+   * var iterator = function(result, num, index, done) {
+   *   setTimeout(function() {
+   *     order.push([num, index]);
+   *     result[index] = num;
+   *     done();
+   *   }, num * 10);
+   * };
+   * async.transform(collection, {}, iterator, function(err, res) {
+   *   console.log(res); // { '0': 1, '1': 3, '2': 2, '3': 4 }
+   *   console.log(order); // [[1, 0], [2, 2], [3, 1], [4, 3]]
+   * });
+   *
+   * @example
+   *
+   * // object with accumulator
+   * var order = [];
+   * var object = { a: 1, b: 3, c: 2, d: 4 };
+   * var iterator = function(result, num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     result.push(num);
+   *     done();
+   *   }, num * 10);
+   * };
+   * async.transform(collection, [], iterator, function(err, res) {
+   *   console.log(res); // [1, 2, 3, 4]
+   *   console.log(order); // [1, 2, 3, 4]
+   * });
+   *
+   * @example
+   *
+   * // object with key
+   * var order = [];
+   * var object = { a: 1, b: 3, c: 2, d: 4 };
+   * var iterator = function(result, num, key, done) {
+   *   setTimeout(function() {
+   *     order.push([num, key]);
+   *     result[key] = num;
+   *     done();
+   *   }, num * 10);
+   * };
+   * async.transform(collection, iterator, function(err, res) {
+   *   console.log(res); //  { a: 1, b: 3, c: 2, d: 4 }
+   *   console.log(order); // [[1, 'a'], [2, 'c'], [3, 'b'], [4, 'd']]
+   * });
+   *
+   */
+  var transform = createTransform(arrayEachResult, baseEachResult, symbolEachResult);
+
+  /**
+   * @memberof async
+   * @namespace sortBy
+   * @param {Array|Object} collection
+   * @param {Function} iterator
+   * @param {Function} callback
+   * @example
+   *
+   * // array
+   * var order = [];
+   * var array = [1, 3, 2];
+   * var iterator = function(num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     done(null, num);
+   *   }, num * 10);
+   * };
+   * async.sortBy(array, iterator, function(err, res) {
+   *   console.log(res); // [1, 2, 3];
+   *   console.log(order); // [1, 2, 3]
+   * });
+   *
+   * @example
+   *
+   * // array with index
+   * var order = [];
+   * var array = [1, 3, 2];
+   * var iterator = function(num, index, done) {
+   *   setTimeout(function() {
+   *     order.push([num, index]);
+   *     done(null, num);
+   *   }, num * 10);
+   * };
+   * async.sortBy(array, iterator, function(err, res) {
+   *   console.log(res); // [1, 2, 3]
+   *   console.log(order); // [[1, 0], [2, 2], [3, 1]]
+   * });
+   *
+   * @example
+   *
+   * // object
+   * var order = [];
+   * var object = { a: 1, b: 3, c: 2 };
+   * var iterator = function(num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     done(null, num);
+   *   }, num * 10);
+   * };
+   * async.sortBy(object, iterator, function(err, res) {
+   *   console.log(res); // [1, 2, 3]
+   *   console.log(order); // [1, 2, 3]
+   * });
+   *
+   * @example
+   *
+   * // object with key
+   * var order = [];
+   * var object = { a: 1, b: 3, c: 2 };
+   * var iterator = function(num, key, done) {
+   *   setTimeout(function() {
+   *     order.push([num, key]);
+   *     done(null, num);
+   *   }, num * 10);
+   * };
+   * async.sortBy(object, iterator, function(err, res) {
+   *   console.log(res); // [1, 2, 3]
+   *   console.log(order); // [[1, 'a'], [2, 'c'], [3, 'b']]
+   * });
+   *
+   */
+  var sortBy = createSortBy(arrayEachIndexValue, baseEachIndexValue, symbolEachIndexValue);
+
+  /**
+   * @memberof async
+   * @namespace concat
+   * @param {Array|Object} collection
+   * @param {Function} iterator
+   * @param {Function} callback
+   * @example
+   *
+   * // array
+   * var order = [];
+   * var array = [1, 3, 2];
+   * var iterator = function(num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     done(null, [num]);
+   *   }, num * 10);
+   * };
+   * async.concat(array, iterator, function(err, res) {
+   *   console.log(res); // [1, 2, 3];
+   *   console.log(order); // [1, 2, 3]
+   * });
+   *
+   * @example
+   *
+   * // array with index
+   * var order = [];
+   * var array = [1, 3, 2];
+   * var iterator = function(num, index, done) {
+   *   setTimeout(function() {
+   *     order.push([num, index]);
+   *     done(null, [num]);
+   *   }, num * 10);
+   * };
+   * async.concat(array, iterator, function(err, res) {
+   *   console.log(res); // [1, 2, 3]
+   *   console.log(order); // [[1, 0], [2, 2], [3, 1]]
+   * });
+   *
+   * @example
+   *
+   * // object
+   * var order = [];
+   * var object = { a: 1, b: 3, c: 2 };
+   * var iterator = function(num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     done(null, [num]);
+   *   }, num * 10);
+   * };
+   * async.concat(object, iterator, function(err, res) {
+   *   console.log(res); // [1, 2, 3]
+   *   console.log(order); // [1, 2, 3]
+   * });
+   *
+   * @example
+   *
+   * // object with key
+   * var order = [];
+   * var object = { a: 1, b: 3, c: 2 };
+   * var iterator = function(num, key, done) {
+   *   setTimeout(function() {
+   *     order.push([num, key]);
+   *     done(null, [num]);
+   *   }, num * 10);
+   * };
+   * async.concat(object, iterator, function(err, res) {
+   *   console.log(res); // [1, 2, 3]
+   *   console.log(order); // [[1, 'a'], [2, 'c'], [3, 'b']]
+   * });
+   *
+   */
+  var concat = createConcat(arrayEachIndex, baseEachIndex, symbolEachIndex);
+
+  /**
+   * @memberof async
+   * @namespace groupBy
+   * @param {Array|Object} collection
+   * @param {Function} iterator
+   * @param {Function} callback
+   * @example
+   *
+   * // array
+   * var order = [];
+   * var array = [4.2, 6.4, 6.1];
+   * var iterator = function(num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     done(null, Math.floor(num));
+   *   }, num * 10);
+   * };
+   * async.groupBy(array, iterator, function(err, res) {
+   *   console.log(res); // { '4': [4.2], '6': [6.1, 6.4] }
+   *   console.log(order); // [4.2, 6.1, 6.4]
+   * });
+   *
+   * @example
+   *
+   * // array with index
+   * var order = [];
+   * var array = [4.2, 6.4, 6.1];
+   * var iterator = function(num, index, done) {
+   *   setTimeout(function() {
+   *     order.push([num, index]);
+   *     done(null, Math.floor(num));
+   *   }, num * 10);
+   * };
+   * async.groupBy(array, iterator, function(err, res) {
+   *   console.log(res); // { '4': [4.2], '6': [6.1, 6.4] }
+   *   console.log(order); // [[4.2, 0], [6.1, 2], [6.4, 1]]
+   * });
+   *
+   * @example
+   *
+   * // object
+   * var order = [];
+   * var object = { a: 4.2, b: 6.4, c: 6.1 };
+   * var iterator = function(num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     done(null, Math.floor(num));
+   *   }, num * 10);
+   * };
+   * async.groupBy(object, iterator, function(err, res) {
+   *   console.log(res); // { '4': [4.2], '6': [6.1, 6.4] }
+   *   console.log(order); // [4.2, 6.1, 6.4]
+   * });
+   *
+   * @example
+   *
+   * // object with key
+   * var order = [];
+   * var object = { a: 4.2, b: 6.4, c: 6.1 };
+   * var iterator = function(num, key, done) {
+   *   setTimeout(function() {
+   *     order.push([num, key]);
+   *     done(null, Math.floor(num));
+   *   }, num * 10);
+   * };
+   * async.groupBy(object, iterator, function(err, res) {
+   *   console.log(res); // { '4': [4.2], '6': [6.1, 6.4] }
+   *   console.log(order); // [[4.2, 'a'], [6.1, 'c'], [6.4, 'b']]
+   * });
+   *
+   */
+  var groupBy = createGroupBy(arrayEachValue, baseEachValue, symbolEachValue);
+
+  /**
+   * @memberof async
+   * @namespace parallel
+   * @param {Array|Object} tasks - functions
+   * @param {Function} callback
+   * @example
+   *
+   * var order = [];
+   * var tasks = [
+   *  function(done) {
+   *    setTimeout(function() {
+   *      order.push(1);
+   *      done(null, 1);
+   *    }, 10);
+   *  },
+   *  function(done) {
+   *    setTimeout(function() {
+   *      order.push(2);
+   *      done(null, 2);
+   *    }, 30);
+   *  },
+   *  function(done) {
+   *    setTimeout(function() {
+   *      order.push(3);
+   *      done(null, 3);
+   *    }, 40);
+   *  },
+   *  function(done) {
+   *    setTimeout(function() {
+   *      order.push(4);
+   *      done(null, 4);
+   *    }, 20);
+   *  }
+   * ];
+   * async.parallel(tasks, function(err, res) {
+   *   console.log(res); // [1, 2, 3, 4];
+   *   console.log(order); // [1, 4, 2, 3]
+   * });
+   *
+   * @example
+   *
+   * var order = [];
+   * var tasks = {
+   *   'a': function(done) {
+   *     setTimeout(function() {
+   *       order.push(1);
+   *       done(null, 1);
+   *     }, 10);
+   *   },
+   *   'b': function(done) {
+   *     setTimeout(function() {
+   *       order.push(2);
+   *       done(null, 2);
+   *     }, 30);
+   *   },
+   *   'c': function(done) {
+   *     setTimeout(function() {
+   *       order.push(3);
+   *       done(null, 3);
+   *     }, 40);
+   *   },
+   *   'd': function(done) {
+   *     setTimeout(function() {
+   *       order.push(4);
+   *       done(null, 4);
+   *     }, 20);
+   *   }
+   * };
+   * async.parallel(tasks, function(err, res) {
+   *   console.log(res); // { a: 1, b: 2, c: 3, d:4 }
+   *   console.log(order); // [1, 4, 2, 3]
+   * });
+   *
+   */
+  var parallel = createParallel(arrayEachFunc, baseEachFunc);
+
+  /**
+   * @memberof async
+   * @namespace applyEach
+   */
+  var applyEach = createApplyEach(map);
+
+  /**
+   * @memberof async
+   * @namespace applyEachSeries
+   */
+  var applyEachSeries = createApplyEach(mapSeries);
+
+  /**
+   * @memberof async
+   * @namespace log
+   */
+  var log = createLogger('log');
+
+  /**
+   * @memberof async
+   * @namespace dir
+   */
+  var dir = createLogger('dir');
+
+  /**
+   * @version 2.6.2
+   * @namespace async
+   */
+  var index = {
+    VERSION: '2.6.2',
+
+    // Collections
+    each: each,
+    eachSeries: eachSeries,
+    eachLimit: eachLimit,
+    forEach: each,
+    forEachSeries: eachSeries,
+    forEachLimit: eachLimit,
+    eachOf: each,
+    eachOfSeries: eachSeries,
+    eachOfLimit: eachLimit,
+    forEachOf: each,
+    forEachOfSeries: eachSeries,
+    forEachOfLimit: eachLimit,
+    map: map,
+    mapSeries: mapSeries,
+    mapLimit: mapLimit,
+    mapValues: mapValues,
+    mapValuesSeries: mapValuesSeries,
+    mapValuesLimit: mapValuesLimit,
+    filter: filter,
+    filterSeries: filterSeries,
+    filterLimit: filterLimit,
+    select: filter,
+    selectSeries: filterSeries,
+    selectLimit: filterLimit,
+    reject: reject,
+    rejectSeries: rejectSeries,
+    rejectLimit: rejectLimit,
+    detect: detect,
+    detectSeries: detectSeries,
+    detectLimit: detectLimit,
+    find: detect,
+    findSeries: detectSeries,
+    findLimit: detectLimit,
+    pick: pick,
+    pickSeries: pickSeries,
+    pickLimit: pickLimit,
+    omit: omit,
+    omitSeries: omitSeries,
+    omitLimit: omitLimit,
+    reduce: reduce,
+    inject: reduce,
+    foldl: reduce,
+    reduceRight: reduceRight,
+    foldr: reduceRight,
+    transform: transform,
+    transformSeries: transformSeries,
+    transformLimit: transformLimit,
+    sortBy: sortBy,
+    sortBySeries: sortBySeries,
+    sortByLimit: sortByLimit,
+    some: some,
+    someSeries: someSeries,
+    someLimit: someLimit,
+    any: some,
+    anySeries: someSeries,
+    anyLimit: someLimit,
+    every: every,
+    everySeries: everySeries,
+    everyLimit: everyLimit,
+    all: every,
+    allSeries: everySeries,
+    allLimit: everyLimit,
+    concat: concat,
+    concatSeries: concatSeries,
+    concatLimit: concatLimit,
+    groupBy: groupBy,
+    groupBySeries: groupBySeries,
+    groupByLimit: groupByLimit,
+
+    // Control Flow
+    parallel: parallel,
+    series: series,
+    parallelLimit: parallelLimit,
+    tryEach: tryEach,
+    waterfall: waterfall,
+    angelFall: angelFall,
+    angelfall: angelFall,
+    whilst: whilst,
+    doWhilst: doWhilst,
+    until: until,
+    doUntil: doUntil,
+    during: during,
+    doDuring: doDuring,
+    forever: forever,
+    compose: compose,
+    seq: seq,
+    applyEach: applyEach,
+    applyEachSeries: applyEachSeries,
+    queue: queue,
+    priorityQueue: priorityQueue,
+    cargo: cargo,
+    auto: auto,
+    autoInject: autoInject,
+    retry: retry,
+    retryable: retryable,
+    iterator: iterator,
+    times: times,
+    timesSeries: timesSeries,
+    timesLimit: timesLimit,
+    race: race,
+
+    // Utils
+    apply: apply,
+    nextTick: asyncNextTick,
+    setImmediate: asyncSetImmediate,
+    memoize: memoize,
+    unmemoize: unmemoize,
+    ensureAsync: ensureAsync,
+    constant: constant,
+    asyncify: asyncify,
+    wrapSync: asyncify,
+    log: log,
+    dir: dir,
+    reflect: reflect,
+    reflectAll: reflectAll,
+    timeout: timeout,
+    createLogger: createLogger,
+
+    // Mode
+    safe: safe,
+    fast: fast
+  };
+
+  exports['default'] = index;
+  baseEachSync(
+    index,
+    function(func, key) {
+      exports[key] = func;
+    },
+    nativeKeys(index)
+  );
+
+  /**
+   * @private
+   */
+  function createImmediate(safeMode) {
+    var delay = function delay(fn) {
+      var args = slice(arguments, 1);
+      setTimeout(function() {
+        fn.apply(null, args);
+      });
+    };
+    asyncSetImmediate = typeof setImmediate === func ? setImmediate : delay;
+    if (typeof process === obj && typeof process.nextTick === func) {
+      nextTick = /^v0.10/.test(process.version) ? asyncSetImmediate : process.nextTick;
+      asyncNextTick = /^v0/.test(process.version) ? asyncSetImmediate : process.nextTick;
+    } else {
+      asyncNextTick = nextTick = asyncSetImmediate;
+    }
+    if (safeMode === false) {
+      nextTick = function(cb) {
+        cb();
+      };
+    }
+  }
+
+  /* sync functions based on lodash */
+
+  /**
+   * Converts `arguments` to an array.
+   *
+   * @private
+   * @param {Array} array = The array to slice.
+   */
+  function createArray(array) {
+    var index = -1;
+    var size = array.length;
+    var result = Array(size);
+
+    while (++index < size) {
+      result[index] = array[index];
+    }
+    return result;
+  }
+
+  /**
+   * Create an array from `start`
+   *
+   * @private
+   * @param {Array} array - The array to slice.
+   * @param {number} start - The start position.
+   */
+  function slice(array, start) {
+    var end = array.length;
+    var index = -1;
+    var size = end - start;
+    if (size <= 0) {
+      return [];
+    }
+    var result = Array(size);
+
+    while (++index < size) {
+      result[index] = array[index + start];
+    }
+    return result;
+  }
+
+  /**
+   * @private
+   * @param {Object} object
+   */
+  function objectClone(object) {
+    var keys = nativeKeys(object);
+    var size = keys.length;
+    var index = -1;
+    var result = {};
+
+    while (++index < size) {
+      var key = keys[index];
+      result[key] = object[key];
+    }
+    return result;
+  }
+
+  /**
+   * Create an array with all falsey values removed.
+   *
+   * @private
+   * @param {Array} array - The array to compact.
+   */
+  function compact(array) {
+    var index = -1;
+    var size = array.length;
+    var result = [];
+
+    while (++index < size) {
+      var value = array[index];
+      if (value) {
+        result[result.length] = value;
+      }
+    }
+    return result;
+  }
+
+  /**
+   * Create an array of reverse sequence.
+   *
+   * @private
+   * @param {Array} array - The array to reverse.
+   */
+  function reverse(array) {
+    var index = -1;
+    var size = array.length;
+    var result = Array(size);
+    var resIndex = size;
+
+    while (++index < size) {
+      result[--resIndex] = array[index];
+    }
+    return result;
+  }
+
+  /**
+   * Checks if key exists in object property.
+   *
+   * @private
+   * @param {Object} object - The object to inspect.
+   * @param {string} key - The key to check.
+   */
+  function has(object, key) {
+    return object.hasOwnProperty(key);
+  }
+
+  /**
+   * Check if target exists in array.
+   * @private
+   * @param {Array} array
+   * @param {*} target
+   */
+  function notInclude(array, target) {
+    var index = -1;
+    var size = array.length;
+
+    while (++index < size) {
+      if (array[index] === target) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  /**
+   * @private
+   * @param {Array} array - The array to iterate over.
+   * @param {Function} iterator - The function invoked per iteration.
+   */
+  function arrayEachSync(array, iterator) {
+    var index = -1;
+    var size = array.length;
+
+    while (++index < size) {
+      iterator(array[index], index);
+    }
+    return array;
+  }
+
+  /**
+   * @private
+   * @param {Object} object - The object to iterate over.
+   * @param {Function} iterator - The function invoked per iteration.
+   * @param {Array} keys
+   */
+  function baseEachSync(object, iterator, keys) {
+    var index = -1;
+    var size = keys.length;
+
+    while (++index < size) {
+      var key = keys[index];
+      iterator(object[key], key);
+    }
+    return object;
+  }
+
+  /**
+   * @private
+   * @param {number} n
+   * @param {Function} iterator
+   */
+  function timesSync(n, iterator) {
+    var index = -1;
+    while (++index < n) {
+      iterator(index);
+    }
+  }
+
+  /**
+   * @private
+   * @param {Array} array
+   * @param {number[]} criteria
+   */
+  function sortByCriteria(array, criteria) {
+    var l = array.length;
+    var indices = Array(l);
+    var i;
+    for (i = 0; i < l; i++) {
+      indices[i] = i;
+    }
+    quickSort(criteria, 0, l - 1, indices);
+    var result = Array(l);
+    for (var n = 0; n < l; n++) {
+      i = indices[n];
+      result[n] = i === undefined ? array[n] : array[i];
+    }
+    return result;
+  }
+
+  function partition(array, i, j, mid, indices) {
+    var l = i;
+    var r = j;
+    while (l <= r) {
+      i = l;
+      while (l < r && array[l] < mid) {
+        l++;
+      }
+      while (r >= i && array[r] >= mid) {
+        r--;
+      }
+      if (l > r) {
+        break;
+      }
+      swap(array, indices, l++, r--);
+    }
+    return l;
+  }
+
+  function swap(array, indices, l, r) {
+    var n = array[l];
+    array[l] = array[r];
+    array[r] = n;
+    var i = indices[l];
+    indices[l] = indices[r];
+    indices[r] = i;
+  }
+
+  function quickSort(array, i, j, indices) {
+    if (i === j) {
+      return;
+    }
+    var k = i;
+    while (++k <= j && array[i] === array[k]) {
+      var l = k - 1;
+      if (indices[l] > indices[k]) {
+        var index = indices[l];
+        indices[l] = indices[k];
+        indices[k] = index;
+      }
+    }
+    if (k > j) {
+      return;
+    }
+    var p = array[i] > array[k] ? i : k;
+    k = partition(array, i, j, array[p], indices);
+    quickSort(array, i, k - 1, indices);
+    quickSort(array, k, j, indices);
+  }
+
+  /**
+   * @Private
+   */
+  function makeConcatResult(array) {
+    var result = [];
+    arrayEachSync(array, function(value) {
+      if (value === noop) {
+        return;
+      }
+      if (isArray(value)) {
+        nativePush.apply(result, value);
+      } else {
+        result.push(value);
+      }
+    });
+    return result;
+  }
+
+  /* async functions */
+
+  /**
+   * @private
+   */
+  function arrayEach(array, iterator, callback) {
+    var index = -1;
+    var size = array.length;
+
+    if (iterator.length === 3) {
+      while (++index < size) {
+        iterator(array[index], index, onlyOnce(callback));
+      }
+    } else {
+      while (++index < size) {
+        iterator(array[index], onlyOnce(callback));
+      }
+    }
+  }
+
+  /**
+   * @private
+   */
+  function baseEach(object, iterator, callback, keys) {
+    var key;
+    var index = -1;
+    var size = keys.length;
+
+    if (iterator.length === 3) {
+      while (++index < size) {
+        key = keys[index];
+        iterator(object[key], key, onlyOnce(callback));
+      }
+    } else {
+      while (++index < size) {
+        iterator(object[keys[index]], onlyOnce(callback));
+      }
+    }
+  }
+
+  /**
+   * @private
+   */
+  function symbolEach(collection, iterator, callback) {
+    var iter = collection[iteratorSymbol]();
+    var index = 0;
+    var item;
+    if (iterator.length === 3) {
+      while ((item = iter.next()).done === false) {
+        iterator(item.value, index++, onlyOnce(callback));
+      }
+    } else {
+      while ((item = iter.next()).done === false) {
+        index++;
+        iterator(item.value, onlyOnce(callback));
+      }
+    }
+    return index;
+  }
+
+  /**
+   * @private
+   */
+  function arrayEachResult(array, result, iterator, callback) {
+    var index = -1;
+    var size = array.length;
+
+    if (iterator.length === 4) {
+      while (++index < size) {
+        iterator(result, array[index], index, onlyOnce(callback));
+      }
+    } else {
+      while (++index < size) {
+        iterator(result, array[index], onlyOnce(callback));
+      }
+    }
+  }
+
+  /**
+   * @private
+   */
+  function baseEachResult(object, result, iterator, callback, keys) {
+    var key;
+    var index = -1;
+    var size = keys.length;
+
+    if (iterator.length === 4) {
+      while (++index < size) {
+        key = keys[index];
+        iterator(result, object[key], key, onlyOnce(callback));
+      }
+    } else {
+      while (++index < size) {
+        iterator(result, object[keys[index]], onlyOnce(callback));
+      }
+    }
+  }
+
+  /**
+   * @private
+   */
+  function symbolEachResult(collection, result, iterator, callback) {
+    var item;
+    var index = 0;
+    var iter = collection[iteratorSymbol]();
+
+    if (iterator.length === 4) {
+      while ((item = iter.next()).done === false) {
+        iterator(result, item.value, index++, onlyOnce(callback));
+      }
+    } else {
+      while ((item = iter.next()).done === false) {
+        index++;
+        iterator(result, item.value, onlyOnce(callback));
+      }
+    }
+    return index;
+  }
+
+  /**
+   * @private
+   */
+  function arrayEachFunc(array, createCallback) {
+    var index = -1;
+    var size = array.length;
+
+    while (++index < size) {
+      array[index](createCallback(index));
+    }
+  }
+
+  /**
+   * @private
+   */
+  function baseEachFunc(object, createCallback, keys) {
+    var key;
+    var index = -1;
+    var size = keys.length;
+
+    while (++index < size) {
+      key = keys[index];
+      object[key](createCallback(key));
+    }
+  }
+
+  /**
+   * @private
+   */
+  function arrayEachIndex(array, iterator, createCallback) {
+    var index = -1;
+    var size = array.length;
+
+    if (iterator.length === 3) {
+      while (++index < size) {
+        iterator(array[index], index, createCallback(index));
+      }
+    } else {
+      while (++index < size) {
+        iterator(array[index], createCallback(index));
+      }
+    }
+  }
+
+  /**
+   * @private
+   */
+  function baseEachIndex(object, iterator, createCallback, keys) {
+    var key;
+    var index = -1;
+    var size = keys.length;
+
+    if (iterator.length === 3) {
+      while (++index < size) {
+        key = keys[index];
+        iterator(object[key], key, createCallback(index));
+      }
+    } else {
+      while (++index < size) {
+        iterator(object[keys[index]], createCallback(index));
+      }
+    }
+  }
+
+  /**
+   * @private
+   */
+  function symbolEachIndex(collection, iterator, createCallback) {
+    var item;
+    var index = 0;
+    var iter = collection[iteratorSymbol]();
+
+    if (iterator.length === 3) {
+      while ((item = iter.next()).done === false) {
+        iterator(item.value, index, createCallback(index++));
+      }
+    } else {
+      while ((item = iter.next()).done === false) {
+        iterator(item.value, createCallback(index++));
+      }
+    }
+    return index;
+  }
+
+  /**
+   * @private
+   */
+  function baseEachKey(object, iterator, createCallback, keys) {
+    var key;
+    var index = -1;
+    var size = keys.length;
+
+    if (iterator.length === 3) {
+      while (++index < size) {
+        key = keys[index];
+        iterator(object[key], key, createCallback(key));
+      }
+    } else {
+      while (++index < size) {
+        key = keys[index];
+        iterator(object[key], createCallback(key));
+      }
+    }
+  }
+
+  /**
+   * @private
+   */
+  function symbolEachKey(collection, iterator, createCallback) {
+    var item;
+    var index = 0;
+    var iter = collection[iteratorSymbol]();
+
+    if (iterator.length === 3) {
+      while ((item = iter.next()).done === false) {
+        iterator(item.value, index, createCallback(index++));
+      }
+    } else {
+      while ((item = iter.next()).done === false) {
+        iterator(item.value, createCallback(index++));
+      }
+    }
+    return index;
+  }
+
+  /**
+   * @private
+   */
+  function arrayEachValue(array, iterator, createCallback) {
+    var value;
+    var index = -1;
+    var size = array.length;
+
+    if (iterator.length === 3) {
+      while (++index < size) {
+        value = array[index];
+        iterator(value, index, createCallback(value));
+      }
+    } else {
+      while (++index < size) {
+        value = array[index];
+        iterator(value, createCallback(value));
+      }
+    }
+  }
+
+  /**
+   * @private
+   */
+  function baseEachValue(object, iterator, createCallback, keys) {
+    var key, value;
+    var index = -1;
+    var size = keys.length;
+
+    if (iterator.length === 3) {
+      while (++index < size) {
+        key = keys[index];
+        value = object[key];
+        iterator(value, key, createCallback(value));
+      }
+    } else {
+      while (++index < size) {
+        value = object[keys[index]];
+        iterator(value, createCallback(value));
+      }
+    }
+  }
+
+  /**
+   * @private
+   */
+  function symbolEachValue(collection, iterator, createCallback) {
+    var value, item;
+    var index = 0;
+    var iter = collection[iteratorSymbol]();
+
+    if (iterator.length === 3) {
+      while ((item = iter.next()).done === false) {
+        value = item.value;
+        iterator(value, index++, createCallback(value));
+      }
+    } else {
+      while ((item = iter.next()).done === false) {
+        index++;
+        value = item.value;
+        iterator(value, createCallback(value));
+      }
+    }
+    return index;
+  }
+
+  /**
+   * @private
+   */
+  function arrayEachIndexValue(array, iterator, createCallback) {
+    var value;
+    var index = -1;
+    var size = array.length;
+
+    if (iterator.length === 3) {
+      while (++index < size) {
+        value = array[index];
+        iterator(value, index, createCallback(index, value));
+      }
+    } else {
+      while (++index < size) {
+        value = array[index];
+        iterator(value, createCallback(index, value));
+      }
+    }
+  }
+
+  /**
+   * @private
+   */
+  function baseEachIndexValue(object, iterator, createCallback, keys) {
+    var key, value;
+    var index = -1;
+    var size = keys.length;
+
+    if (iterator.length === 3) {
+      while (++index < size) {
+        key = keys[index];
+        value = object[key];
+        iterator(value, key, createCallback(index, value));
+      }
+    } else {
+      while (++index < size) {
+        value = object[keys[index]];
+        iterator(value, createCallback(index, value));
+      }
+    }
+  }
+
+  /**
+   * @private
+   */
+  function symbolEachIndexValue(collection, iterator, createCallback) {
+    var value, item;
+    var index = 0;
+    var iter = collection[iteratorSymbol]();
+
+    if (iterator.length === 3) {
+      while ((item = iter.next()).done === false) {
+        value = item.value;
+        iterator(value, index, createCallback(index++, value));
+      }
+    } else {
+      while ((item = iter.next()).done === false) {
+        value = item.value;
+        iterator(value, createCallback(index++, value));
+      }
+    }
+    return index;
+  }
+
+  /**
+   * @private
+   */
+  function baseEachKeyValue(object, iterator, createCallback, keys) {
+    var key, value;
+    var index = -1;
+    var size = keys.length;
+
+    if (iterator.length === 3) {
+      while (++index < size) {
+        key = keys[index];
+        value = object[key];
+        iterator(value, key, createCallback(key, value));
+      }
+    } else {
+      while (++index < size) {
+        key = keys[index];
+        value = object[key];
+        iterator(value, createCallback(key, value));
+      }
+    }
+  }
+
+  /**
+   * @private
+   */
+  function symbolEachKeyValue(collection, iterator, createCallback) {
+    var value, item;
+    var index = 0;
+    var iter = collection[iteratorSymbol]();
+
+    if (iterator.length === 3) {
+      while ((item = iter.next()).done === false) {
+        value = item.value;
+        iterator(value, index, createCallback(index++, value));
+      }
+    } else {
+      while ((item = iter.next()).done === false) {
+        value = item.value;
+        iterator(value, createCallback(index++, value));
+      }
+    }
+    return index;
+  }
+
+  /**
+   * @private
+   * @param {Function} func
+   */
+  function onlyOnce(func) {
+    return function(err, res) {
+      var fn = func;
+      func = throwError;
+      fn(err, res);
+    };
+  }
+
+  /**
+   * @private
+   * @param {Function} func
+   */
+  function once(func) {
+    return function(err, res) {
+      var fn = func;
+      func = noop;
+      fn(err, res);
+    };
+  }
+
+  /**
+   * @private
+   * @param {Function} arrayEach
+   * @param {Function} baseEach
+   */
+  function createEach(arrayEach, baseEach, symbolEach) {
+    return function each(collection, iterator, callback) {
+      callback = once(callback || noop);
+      var size, keys;
+      var completed = 0;
+      if (isArray(collection)) {
+        size = collection.length;
+        arrayEach(collection, iterator, done);
+      } else if (!collection) {
+      } else if (iteratorSymbol && collection[iteratorSymbol]) {
+        size = symbolEach(collection, iterator, done);
+        size && size === completed && callback(null);
+      } else if (typeof collection === obj) {
+        keys = nativeKeys(collection);
+        size = keys.length;
+        baseEach(collection, iterator, done, keys);
+      }
+      if (!size) {
+        callback(null);
+      }
+
+      function done(err, bool) {
+        if (err) {
+          callback = once(callback);
+          callback(err);
+        } else if (++completed === size) {
+          callback(null);
+        } else if (bool === false) {
+          callback = once(callback);
+          callback(null);
+        }
+      }
+    };
+  }
+
+  /**
+   * @private
+   * @param {Function} arrayEach
+   * @param {Function} baseEach
+   * @param {Function} symbolEach
+   */
+  function createMap(arrayEach, baseEach, symbolEach, useArray) {
+    var init, clone;
+    if (useArray) {
+      init = Array;
+      clone = createArray;
+    } else {
+      init = function() {
+        return {};
+      };
+      clone = objectClone;
+    }
+
+    return function(collection, iterator, callback) {
+      callback = callback || noop;
+      var size, keys, result;
+      var completed = 0;
+
+      if (isArray(collection)) {
+        size = collection.length;
+        result = init(size);
+        arrayEach(collection, iterator, createCallback);
+      } else if (!collection) {
+      } else if (iteratorSymbol && collection[iteratorSymbol]) {
+        // TODO: size could be changed
+        result = init(0);
+        size = symbolEach(collection, iterator, createCallback);
+        size && size === completed && callback(null, result);
+      } else if (typeof collection === obj) {
+        keys = nativeKeys(collection);
+        size = keys.length;
+        result = init(size);
+        baseEach(collection, iterator, createCallback, keys);
+      }
+      if (!size) {
+        callback(null, init());
+      }
+
+      function createCallback(key) {
+        return function done(err, res) {
+          if (key === null) {
+            throwError();
+          }
+          if (err) {
+            key = null;
+            callback = once(callback);
+            callback(err, clone(result));
+            return;
+          }
+          result[key] = res;
+          key = null;
+          if (++completed === size) {
+            callback(null, result);
+          }
+        };
+      }
+    };
+  }
+
+  /**
+   * @private
+   * @param {Function} arrayEach
+   * @param {Function} baseEach
+   * @param {Function} symbolEach
+   * @param {boolean} bool
+   */
+  function createFilter(arrayEach, baseEach, symbolEach, bool) {
+    return function(collection, iterator, callback) {
+      callback = callback || noop;
+      var size, keys, result;
+      var completed = 0;
+
+      if (isArray(collection)) {
+        size = collection.length;
+        result = Array(size);
+        arrayEach(collection, iterator, createCallback);
+      } else if (!collection) {
+      } else if (iteratorSymbol && collection[iteratorSymbol]) {
+        result = [];
+        size = symbolEach(collection, iterator, createCallback);
+        size && size === completed && callback(null, compact(result));
+      } else if (typeof collection === obj) {
+        keys = nativeKeys(collection);
+        size = keys.length;
+        result = Array(size);
+        baseEach(collection, iterator, createCallback, keys);
+      }
+      if (!size) {
+        return callback(null, []);
+      }
+
+      function createCallback(index, value) {
+        return function done(err, res) {
+          if (index === null) {
+            throwError();
+          }
+          if (err) {
+            index = null;
+            callback = once(callback);
+            callback(err);
+            return;
+          }
+          if (!!res === bool) {
+            result[index] = value;
+          }
+          index = null;
+          if (++completed === size) {
+            callback(null, compact(result));
+          }
+        };
+      }
+    };
+  }
+
+  /**
+   * @private
+   * @param {boolean} bool
+   */
+  function createFilterSeries(bool) {
+    return function(collection, iterator, callback) {
+      callback = onlyOnce(callback || noop);
+      var size, key, value, keys, iter, item, iterate;
+      var sync = false;
+      var completed = 0;
+      var result = [];
+
+      if (isArray(collection)) {
+        size = collection.length;
+        iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator;
+      } else if (!collection) {
+      } else if (iteratorSymbol && collection[iteratorSymbol]) {
+        size = Infinity;
+        iter = collection[iteratorSymbol]();
+        iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator;
+      } else if (typeof collection === obj) {
+        keys = nativeKeys(collection);
+        size = keys.length;
+        iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator;
+      }
+      if (!size) {
+        return callback(null, []);
+      }
+      iterate();
+
+      function arrayIterator() {
+        value = collection[completed];
+        iterator(value, done);
+      }
+
+      function arrayIteratorWithIndex() {
+        value = collection[completed];
+        iterator(value, completed, done);
+      }
+
+      function symbolIterator() {
+        item = iter.next();
+        value = item.value;
+        item.done ? callback(null, result) : iterator(value, done);
+      }
+
+      function symbolIteratorWithKey() {
+        item = iter.next();
+        value = item.value;
+        item.done ? callback(null, result) : iterator(value, completed, done);
+      }
+
+      function objectIterator() {
+        key = keys[completed];
+        value = collection[key];
+        iterator(value, done);
+      }
+
+      function objectIteratorWithKey() {
+        key = keys[completed];
+        value = collection[key];
+        iterator(value, key, done);
+      }
+
+      function done(err, res) {
+        if (err) {
+          callback(err);
+          return;
+        }
+        if (!!res === bool) {
+          result[result.length] = value;
+        }
+        if (++completed === size) {
+          iterate = throwError;
+          callback(null, result);
+        } else if (sync) {
+          nextTick(iterate);
+        } else {
+          sync = true;
+          iterate();
+        }
+        sync = false;
+      }
+    };
+  }
+
+  /**
+   * @private
+   * @param {boolean} bool
+   */
+  function createFilterLimit(bool) {
+    return function(collection, limit, iterator, callback) {
+      callback = callback || noop;
+      var size, index, key, value, keys, iter, item, iterate, result;
+      var sync = false;
+      var started = 0;
+      var completed = 0;
+
+      if (isArray(collection)) {
+        size = collection.length;
+        iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator;
+      } else if (!collection) {
+      } else if (iteratorSymbol && collection[iteratorSymbol]) {
+        size = Infinity;
+        result = [];
+        iter = collection[iteratorSymbol]();
+        iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator;
+      } else if (typeof collection === obj) {
+        keys = nativeKeys(collection);
+        size = keys.length;
+        iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator;
+      }
+      if (!size || isNaN(limit) || limit < 1) {
+        return callback(null, []);
+      }
+      result = result || Array(size);
+      timesSync(limit > size ? size : limit, iterate);
+
+      function arrayIterator() {
+        index = started++;
+        if (index < size) {
+          value = collection[index];
+          iterator(value, createCallback(value, index));
+        }
+      }
+
+      function arrayIteratorWithIndex() {
+        index = started++;
+        if (index < size) {
+          value = collection[index];
+          iterator(value, index, createCallback(value, index));
+        }
+      }
+
+      function symbolIterator() {
+        item = iter.next();
+        if (item.done === false) {
+          value = item.value;
+          iterator(value, createCallback(value, started++));
+        } else if (completed === started && iterator !== noop) {
+          iterator = noop;
+          callback(null, compact(result));
+        }
+      }
+
+      function symbolIteratorWithKey() {
+        item = iter.next();
+        if (item.done === false) {
+          value = item.value;
+          iterator(value, started, createCallback(value, started++));
+        } else if (completed === started && iterator !== noop) {
+          iterator = noop;
+          callback(null, compact(result));
+        }
+      }
+
+      function objectIterator() {
+        index = started++;
+        if (index < size) {
+          value = collection[keys[index]];
+          iterator(value, createCallback(value, index));
+        }
+      }
+
+      function objectIteratorWithKey() {
+        index = started++;
+        if (index < size) {
+          key = keys[index];
+          value = collection[key];
+          iterator(value, key, createCallback(value, index));
+        }
+      }
+
+      function createCallback(value, index) {
+        return function(err, res) {
+          if (index === null) {
+            throwError();
+          }
+          if (err) {
+            index = null;
+            iterate = noop;
+            callback = once(callback);
+            callback(err);
+            return;
+          }
+          if (!!res === bool) {
+            result[index] = value;
+          }
+          index = null;
+          if (++completed === size) {
+            callback = onlyOnce(callback);
+            callback(null, compact(result));
+          } else if (sync) {
+            nextTick(iterate);
+          } else {
+            sync = true;
+            iterate();
+          }
+          sync = false;
+        };
+      }
+    };
+  }
+
+  /**
+   * @memberof async
+   * @namespace eachSeries
+   * @param {Array|Object} collection
+   * @param {Function} iterator
+   * @param {Function} callback
+   * @example
+   *
+   * // array
+   * var order = [];
+   * var array = [1, 3, 2];
+   * var iterator = function(num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     done();
+   *   }, num * 10);
+   * };
+   * async.eachSeries(array, iterator, function(err, res) {
+   *   console.log(res); // undefined
+   *   console.log(order); // [1, 3, 2]
+   * });
+   *
+   * @example
+   *
+   * // array with index
+   * var order = [];
+   * var array = [1, 3, 2];
+   * var iterator = function(num, index, done) {
+   *   setTimeout(function() {
+   *     order.push([num, index]);
+   *     done();
+   *   }, num * 10);
+   * };
+   * async.eachSeries(array, iterator, function(err, res) {
+   *   console.log(res); // undefined
+   *   console.log(order); // [[1, 0], [3, 1], [2, 2]]
+   * });
+   *
+   * @example
+   *
+   * // object
+   * var order = [];
+   * var object = { a: 1, b: 3, c: 2 };
+   * var iterator = function(num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     done();
+   *   }, num * 10);
+   * };
+   * async.eachSeries(object, iterator, function(err, res) {
+   *   console.log(res); // undefined
+   *   console.log(order); // [1, 3, 2]
+   * });
+   *
+   * @example
+   *
+   * // object with key
+   * var order = [];
+   * var object = { a: 1, b: 3, c: 2 };
+   * var iterator = function(num, key, done) {
+   *   setTimeout(function() {
+   *     order.push([num, key]);
+   *     done();
+   *   }, num * 10);
+   * };
+   * async.eachSeries(object, iterator, function(err, res) {
+   *   console.log(res); // undefined
+   *   console.log(order); // [[1, 'a'], [3, 'b'], [2, 'b']]
+   * });
+   *
+   * @example
+   *
+   * // break
+   * var order = [];
+   * var array = [1, 3, 2];
+   * var iterator = function(num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     done(null, num !== 3);
+   *   }, num * 10);
+   * };
+   * async.eachSeries(array, iterator, function(err, res) {
+   *   console.log(res); // undefined
+   *   console.log(order); // [1, 3]
+   * });
+   */
+  function eachSeries(collection, iterator, callback) {
+    callback = onlyOnce(callback || noop);
+    var size, key, keys, iter, item, iterate;
+    var sync = false;
+    var completed = 0;
+
+    if (isArray(collection)) {
+      size = collection.length;
+      iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator;
+    } else if (!collection) {
+    } else if (iteratorSymbol && collection[iteratorSymbol]) {
+      size = Infinity;
+      iter = collection[iteratorSymbol]();
+      iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator;
+    } else if (typeof collection === obj) {
+      keys = nativeKeys(collection);
+      size = keys.length;
+      iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator;
+    }
+    if (!size) {
+      return callback(null);
+    }
+    iterate();
+
+    function arrayIterator() {
+      iterator(collection[completed], done);
+    }
+
+    function arrayIteratorWithIndex() {
+      iterator(collection[completed], completed, done);
+    }
+
+    function symbolIterator() {
+      item = iter.next();
+      item.done ? callback(null) : iterator(item.value, done);
+    }
+
+    function symbolIteratorWithKey() {
+      item = iter.next();
+      item.done ? callback(null) : iterator(item.value, completed, done);
+    }
+
+    function objectIterator() {
+      iterator(collection[keys[completed]], done);
+    }
+
+    function objectIteratorWithKey() {
+      key = keys[completed];
+      iterator(collection[key], key, done);
+    }
+
+    function done(err, bool) {
+      if (err) {
+        callback(err);
+      } else if (++completed === size || bool === false) {
+        iterate = throwError;
+        callback(null);
+      } else if (sync) {
+        nextTick(iterate);
+      } else {
+        sync = true;
+        iterate();
+      }
+      sync = false;
+    }
+  }
+
+  /**
+   * @memberof async
+   * @namespace eachLimit
+   * @param {Array|Object} collection
+   * @param {number} limit - limit >= 1
+   * @param {Function} iterator
+   * @param {Function} callback
+   * @example
+   *
+   * // array
+   * var order = [];
+   * var array = [1, 5, 3, 4, 2];
+   * var iterator = function(num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     done();
+   *   }, num * 10);
+   * };
+   * async.eachLimit(array, 2, iterator, function(err, res) {
+   *   console.log(res); // undefined
+   *   console.log(order); // [1, 3, 5, 2, 4]
+   * });
+   *
+   * @example
+   *
+   * // array with index
+   * var order = [];
+   * var array = [1, 5, 3, 4, 2];
+   * var iterator = function(num, index, done) {
+   *   setTimeout(function() {
+   *     order.push([num, index]);
+   *     done();
+   *   }, num * 10);
+   * };
+   * async.eachLimit(array, 2, iterator, function(err, res) {
+   *   console.log(res); // undefined
+   *   console.log(order); // [[1, 0], [3, 2], [5, 1], [2, 4], [4, 3]]
+   * });
+   *
+   * @example
+   *
+   * // object
+   * var order = [];
+   * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 };
+   * var iterator = function(num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     done();
+   *   }, num * 10);
+   * };
+   * async.eachLimit(object, 2, iterator, function(err, res) {
+   *   console.log(res); // undefined
+   *   console.log(order); // [1, 3, 5, 2, 4]
+   * });
+   *
+   * @example
+   *
+   * // object with key
+   * var order = [];
+   * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 };
+   * var iterator = function(num, key, done) {
+   *   setTimeout(function() {
+   *     order.push([num, key]);
+   *     done();
+   *   }, num * 10);
+   * };
+   * async.eachLimit(object, 2, iterator, function(err, res) {
+   *   console.log(res); // undefined
+   *   console.log(order); // [[1, 'a'], [3, 'c'], [5, 'b'], [2, 'e'], [4, 'd']]
+   * });
+   *
+   * @example
+   *
+   * // break
+   * var order = [];
+   * var array = [1, 5, 3, 4, 2];
+   * var iterator = function(num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     done(null, num !== 5);
+   *   }, num * 10);
+   * };
+   * async.eachLimit(array, 2, iterator, function(err, res) {
+   *   console.log(res); // undefined
+   *   console.log(order); // [1, 3, 5]
+   * });
+   *
+   */
+  function eachLimit(collection, limit, iterator, callback) {
+    callback = callback || noop;
+    var size, index, key, keys, iter, item, iterate;
+    var sync = false;
+    var started = 0;
+    var completed = 0;
+
+    if (isArray(collection)) {
+      size = collection.length;
+      iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator;
+    } else if (!collection) {
+    } else if (iteratorSymbol && collection[iteratorSymbol]) {
+      size = Infinity;
+      iter = collection[iteratorSymbol]();
+      iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator;
+    } else if (typeof collection === obj) {
+      keys = nativeKeys(collection);
+      size = keys.length;
+      iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator;
+    } else {
+      return callback(null);
+    }
+    if (!size || isNaN(limit) || limit < 1) {
+      return callback(null);
+    }
+    timesSync(limit > size ? size : limit, iterate);
+
+    function arrayIterator() {
+      if (started < size) {
+        iterator(collection[started++], done);
+      }
+    }
+
+    function arrayIteratorWithIndex() {
+      index = started++;
+      if (index < size) {
+        iterator(collection[index], index, done);
+      }
+    }
+
+    function symbolIterator() {
+      item = iter.next();
+      if (item.done === false) {
+        started++;
+        iterator(item.value, done);
+      } else if (completed === started && iterator !== noop) {
+        iterator = noop;
+        callback(null);
+      }
+    }
+
+    function symbolIteratorWithKey() {
+      item = iter.next();
+      if (item.done === false) {
+        iterator(item.value, started++, done);
+      } else if (completed === started && iterator !== noop) {
+        iterator = noop;
+        callback(null);
+      }
+    }
+
+    function objectIterator() {
+      if (started < size) {
+        iterator(collection[keys[started++]], done);
+      }
+    }
+
+    function objectIteratorWithKey() {
+      index = started++;
+      if (index < size) {
+        key = keys[index];
+        iterator(collection[key], key, done);
+      }
+    }
+
+    function done(err, bool) {
+      if (err || bool === false) {
+        iterate = noop;
+        callback = once(callback);
+        callback(err);
+      } else if (++completed === size) {
+        iterator = noop;
+        iterate = throwError;
+        callback = onlyOnce(callback);
+        callback(null);
+      } else if (sync) {
+        nextTick(iterate);
+      } else {
+        sync = true;
+        iterate();
+      }
+      sync = false;
+    }
+  }
+
+  /**
+   * @memberof async
+   * @namespace mapSeries
+   * @param {Array|Object} collection
+   * @param {Function} iterator
+   * @param {Function} callback
+   * @example
+   *
+   * // array
+   * var order = [];
+   * var array = [1, 3, 2];
+   * var iterator = function(num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     done(null, num);
+   *   }, num * 10);
+   * };
+   * async.mapSeries(array, iterator, function(err, res) {
+   *   console.log(res); // [1, 3, 2];
+   *   console.log(order); // [1, 3, 2]
+   * });
+   *
+   * @example
+   *
+   * // array with index
+   * var order = [];
+   * var array = [1, 3, 2];
+   * var iterator = function(num, index, done) {
+   *   setTimeout(function() {
+   *     order.push([num, index]);
+   *     done(null, num);
+   *   }, num * 10);
+   * };
+   * async.mapSeries(array, iterator, function(err, res) {
+   *   console.log(res); // [1, 3, 2]
+   *   console.log(order); // [[1, 0], [3, 1], [2, 2]]
+   * });
+   *
+   * @example
+   *
+   * // object
+   * var order = [];
+   * var object = { a: 1, b: 3, c: 2 };
+   * var iterator = function(num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     done(null, num);
+   *   }, num * 10);
+   * };
+   * async.mapSeries(object, iterator, function(err, res) {
+   *   console.log(res); // [1, 3, 2]
+   *   console.log(order); // [1, 3, 2]
+   * });
+   *
+   * @example
+   *
+   * // object with key
+   * var order = [];
+   * var object = { a: 1, b: 3, c: 2 };
+   * var iterator = function(num, key, done) {
+   *   setTimeout(function() {
+   *     order.push([num, key]);
+   *     done(null, num);
+   *   }, num * 10);
+   * };
+   * async.mapSeries(object, iterator, function(err, res) {
+   *   console.log(res); // [1, 3, 2]
+   *   console.log(order); // [[1, 'a'], [3, 'b'], [2, 'c']]
+   * });
+   *
+   */
+  function mapSeries(collection, iterator, callback) {
+    callback = callback || noop;
+    var size, key, keys, iter, item, result, iterate;
+    var sync = false;
+    var completed = 0;
+
+    if (isArray(collection)) {
+      size = collection.length;
+      iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator;
+    } else if (!collection) {
+    } else if (iteratorSymbol && collection[iteratorSymbol]) {
+      size = Infinity;
+      result = [];
+      iter = collection[iteratorSymbol]();
+      iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator;
+    } else if (typeof collection === obj) {
+      keys = nativeKeys(collection);
+      size = keys.length;
+      iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator;
+    }
+    if (!size) {
+      return callback(null, []);
+    }
+    result = result || Array(size);
+    iterate();
+
+    function arrayIterator() {
+      iterator(collection[completed], done);
+    }
+
+    function arrayIteratorWithIndex() {
+      iterator(collection[completed], completed, done);
+    }
+
+    function symbolIterator() {
+      item = iter.next();
+      item.done ? callback(null, result) : iterator(item.value, done);
+    }
+
+    function symbolIteratorWithKey() {
+      item = iter.next();
+      item.done ? callback(null, result) : iterator(item.value, completed, done);
+    }
+
+    function objectIterator() {
+      iterator(collection[keys[completed]], done);
+    }
+
+    function objectIteratorWithKey() {
+      key = keys[completed];
+      iterator(collection[key], key, done);
+    }
+
+    function done(err, res) {
+      if (err) {
+        iterate = throwError;
+        callback = onlyOnce(callback);
+        callback(err, createArray(result));
+        return;
+      }
+      result[completed] = res;
+      if (++completed === size) {
+        iterate = throwError;
+        callback(null, result);
+        callback = throwError;
+      } else if (sync) {
+        nextTick(iterate);
+      } else {
+        sync = true;
+        iterate();
+      }
+      sync = false;
+    }
+  }
+
+  /**
+   * @memberof async
+   * @namespace mapLimit
+   * @param {Array|Object} collection
+   * @param {number} limit - limit >= 1
+   * @param {Function} iterator
+   * @param {Function} callback
+   * @example
+   *
+   * // array
+   * var order = [];
+   * var array = [1, 5, 3, 4, 2];
+   * var iterator = function(num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     done(null, num);
+   *   }, num * 10);
+   * };
+   * async.mapLimit(array, 2, iterator, function(err, res) {
+   *   console.log(res); // [1, 5, 3, 4, 2]
+   *   console.log(order); // [1, 3, 5, 2, 4]
+   * });
+   *
+   * @example
+   *
+   * // array with index
+   * var order = [];
+   * var array = [1, 5, 3, 4, 2];
+   * var iterator = function(num, index, done) {
+   *   setTimeout(function() {
+   *     order.push([num, index]);
+   *     done(null, num);
+   *   }, num * 10);
+   * };
+   * async.mapLimit(array, 2, iterator, function(err, res) {
+   *   console.log(res); // [1, 5, 3, 4, 2]
+   *   console.log(order); // [[1, 0], [3, 2], [5, 1], [2, 4], [4, 3]]
+   * });
+   *
+   * @example
+   *
+   * // object
+   * var order = [];
+   * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 };
+   * var iterator = function(num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     done(null, num);
+   *   }, num * 10);
+   * };
+   * async.mapLimit(object, 2, iterator, function(err, res) {
+   *   console.log(res); // [1, 5, 3, 4, 2]
+   *   console.log(order); // [1, 3, 5, 2, 4]
+   * });
+   *
+   * @example
+   *
+   * // object with key
+   * var order = [];
+   * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 };
+   * var iterator = function(num, key, done) {
+   *   setTimeout(function() {
+   *     order.push([num, key]);
+   *     done(null, num);
+   *   }, num * 10);
+   * };
+   * async.mapLimit(object, 2, iterator, function(err, res) {
+   *   console.log(res); // [1, 5, 3, 4, 2]
+   *   console.log(order); // [[1, 'a'], [3, 'c'], [5, 'b'], [2, 'e'], [4, 'd']]
+   * });
+   *
+   */
+  function mapLimit(collection, limit, iterator, callback) {
+    callback = callback || noop;
+    var size, index, key, keys, iter, item, result, iterate;
+    var sync = false;
+    var started = 0;
+    var completed = 0;
+
+    if (isArray(collection)) {
+      size = collection.length;
+      iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator;
+    } else if (!collection) {
+    } else if (iteratorSymbol && collection[iteratorSymbol]) {
+      size = Infinity;
+      result = [];
+      iter = collection[iteratorSymbol]();
+      iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator;
+    } else if (typeof collection === obj) {
+      keys = nativeKeys(collection);
+      size = keys.length;
+      iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator;
+    }
+    if (!size || isNaN(limit) || limit < 1) {
+      return callback(null, []);
+    }
+    result = result || Array(size);
+    timesSync(limit > size ? size : limit, iterate);
+
+    function arrayIterator() {
+      index = started++;
+      if (index < size) {
+        iterator(collection[index], createCallback(index));
+      }
+    }
+
+    function arrayIteratorWithIndex() {
+      index = started++;
+      if (index < size) {
+        iterator(collection[index], index, createCallback(index));
+      }
+    }
+
+    function symbolIterator() {
+      item = iter.next();
+      if (item.done === false) {
+        iterator(item.value, createCallback(started++));
+      } else if (completed === started && iterator !== noop) {
+        iterator = noop;
+        callback(null, result);
+      }
+    }
+
+    function symbolIteratorWithKey() {
+      item = iter.next();
+      if (item.done === false) {
+        iterator(item.value, started, createCallback(started++));
+      } else if (completed === started && iterator !== noop) {
+        iterator = noop;
+        callback(null, result);
+      }
+    }
+
+    function objectIterator() {
+      index = started++;
+      if (index < size) {
+        iterator(collection[keys[index]], createCallback(index));
+      }
+    }
+
+    function objectIteratorWithKey() {
+      index = started++;
+      if (index < size) {
+        key = keys[index];
+        iterator(collection[key], key, createCallback(index));
+      }
+    }
+
+    function createCallback(index) {
+      return function(err, res) {
+        if (index === null) {
+          throwError();
+        }
+        if (err) {
+          index = null;
+          iterate = noop;
+          callback = once(callback);
+          callback(err, createArray(result));
+          return;
+        }
+        result[index] = res;
+        index = null;
+        if (++completed === size) {
+          iterate = throwError;
+          callback(null, result);
+          callback = throwError;
+        } else if (sync) {
+          nextTick(iterate);
+        } else {
+          sync = true;
+          iterate();
+        }
+        sync = false;
+      };
+    }
+  }
+
+  /**
+   * @memberof async
+   * @namespace mapValuesSeries
+   * @param {Array|Object} collection
+   * @param {Function} iterator
+   * @param {Function} callback
+   * @example
+   *
+   * // array
+   * var order = [];
+   * var array = [1, 3, 2];
+   * var iterator = function(num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     done(null, num);
+   *   }, num * 10);
+   * };
+   * async.mapValuesSeries(array, iterator, function(err, res) {
+   *   console.log(res); // { '0': 1, '1': 3, '2': 2 }
+   *   console.log(order); // [1, 3, 2]
+   * });
+   *
+   * @example
+   *
+   * // array with index
+   * var order = [];
+   * var array = [1, 3, 2];
+   * var iterator = function(num, index, done) {
+   *   setTimeout(function() {
+   *     order.push([num, index]);
+   *     done(null, num);
+   *   }, num * 10);
+   * };
+   * async.mapValuesSeries(array, iterator, function(err, res) {
+   *   console.log(res); // { '0': 1, '1': 3, '2': 2 }
+   *   console.log(order); // [[1, 0], [3, 1], [2, 2]]
+   * });
+   *
+   * @example
+   *
+   * // object
+   * var order = [];
+   * var object = { a: 1, b: 3, c: 2 };
+   * var iterator = function(num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     done(null, num);
+   *   }, num * 10);
+   * };
+   * async.mapValuesSeries(object, iterator, function(err, res) {
+   *   console.log(res); // { a: 1, b: 3, c: 2 }
+   *   console.log(order); // [1, 3, 2]
+   * });
+   *
+   * @example
+   *
+   * // object with key
+   * var order = [];
+   * var object = { a: 1, b: 3, c: 2 };
+   * var iterator = function(num, key, done) {
+   *   setTimeout(function() {
+   *     order.push([num, key]);
+   *     done(null, num);
+   *   }, num * 10);
+   * };
+   * async.mapValuesSeries(object, iterator, function(err, res) {
+   *   console.log(res); // { a: 1, b: 3, c: 2 }
+   *   console.log(order); // [[1, 'a'], [3, 'b'], [2, 'c']]
+   * });
+   *
+   */
+  function mapValuesSeries(collection, iterator, callback) {
+    callback = callback || noop;
+    var size, key, keys, iter, item, iterate;
+    var sync = false;
+    var result = {};
+    var completed = 0;
+
+    if (isArray(collection)) {
+      size = collection.length;
+      iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator;
+    } else if (!collection) {
+    } else if (iteratorSymbol && collection[iteratorSymbol]) {
+      size = Infinity;
+      iter = collection[iteratorSymbol]();
+      iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator;
+    } else if (typeof collection === obj) {
+      keys = nativeKeys(collection);
+      size = keys.length;
+      iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator;
+    }
+    if (!size) {
+      return callback(null, result);
+    }
+    iterate();
+
+    function arrayIterator() {
+      key = completed;
+      iterator(collection[completed], done);
+    }
+
+    function arrayIteratorWithIndex() {
+      key = completed;
+      iterator(collection[completed], completed, done);
+    }
+
+    function symbolIterator() {
+      key = completed;
+      item = iter.next();
+      item.done ? callback(null, result) : iterator(item.value, done);
+    }
+
+    function symbolIteratorWithKey() {
+      key = completed;
+      item = iter.next();
+      item.done ? callback(null, result) : iterator(item.value, completed, done);
+    }
+
+    function objectIterator() {
+      key = keys[completed];
+      iterator(collection[key], done);
+    }
+
+    function objectIteratorWithKey() {
+      key = keys[completed];
+      iterator(collection[key], key, done);
+    }
+
+    function done(err, res) {
+      if (err) {
+        iterate = throwError;
+        callback = onlyOnce(callback);
+        callback(err, objectClone(result));
+        return;
+      }
+      result[key] = res;
+      if (++completed === size) {
+        iterate = throwError;
+        callback(null, result);
+        callback = throwError;
+      } else if (sync) {
+        nextTick(iterate);
+      } else {
+        sync = true;
+        iterate();
+      }
+      sync = false;
+    }
+  }
+
+  /**
+   * @memberof async
+   * @namespace mapValuesLimit
+   * @param {Array|Object} collection
+   * @param {number} limit - limit >= 1
+   * @param {Function} iterator
+   * @param {Function} callback
+   * @example
+   *
+   * // array
+   * var order = [];
+   * var array = [1, 5, 3, 4, 2];
+   * var iterator = function(num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     done(null, num);
+   *   }, num * 10);
+   * };
+   * async.mapValuesLimit(array, 2, iterator, function(err, res) {
+   *   console.log(res); // { '0': 1, '1': 5, '2': 3, '3': 4, '4': 2 }
+   *   console.log(order); // [1, 3, 5, 2, 4]
+   * });
+   *
+   * @example
+   *
+   * // array with index
+   * var order = [];
+   * var array = [1, 5, 3, 4, 2];
+   * var iterator = function(num, index, done) {
+   *   setTimeout(function() {
+   *     order.push([num, index]);
+   *     done(null, num);
+   *   }, num * 10);
+   * };
+   * async.mapValuesLimit(array, 2, iterator, function(err, res) {
+   *   console.log(res); // { '0': 1, '1': 5, '2': 3, '3': 4, '4': 2 }
+   *   console.log(order); // [[1, 0], [3, 2], [5, 1], [2, 4], [4, 3]]
+   * });
+   *
+   * @example
+   *
+   * // object
+   * var order = [];
+   * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 };
+   * var iterator = function(num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     done(null, num);
+   *   }, num * 10);
+   * };
+   * async.mapValuesLimit(object, 2, iterator, function(err, res) {
+   *   console.log(res); // { a: 1, b: 5, c: 3, d: 4, e: 2 }
+   *   console.log(order); // [1, 3, 5, 2, 4]
+   * });
+   *
+   * @example
+   *
+   * // object with key
+   * var order = [];
+   * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 };
+   * var iterator = function(num, key, done) {
+   *   setTimeout(function() {
+   *     order.push([num, key]);
+   *     done(null, num);
+   *   }, num * 10);
+   * };
+   * async.mapValuesLimit(object, 2, iterator, function(err, res) {
+   *   console.log(res); // { a: 1, b: 5, c: 3, d: 4, e: 2 }
+   *   console.log(order); // [[1, 'a'], [3, 'c'], [5, 'b'], [2, 'e'], [4, 'd']]
+   * });
+   *
+   */
+  function mapValuesLimit(collection, limit, iterator, callback) {
+    callback = callback || noop;
+    var size, index, key, keys, iter, item, iterate;
+    var sync = false;
+    var result = {};
+    var started = 0;
+    var completed = 0;
+
+    if (isArray(collection)) {
+      size = collection.length;
+      iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator;
+    } else if (!collection) {
+    } else if (iteratorSymbol && collection[iteratorSymbol]) {
+      size = Infinity;
+      iter = collection[iteratorSymbol]();
+      iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator;
+    } else if (typeof collection === obj) {
+      keys = nativeKeys(collection);
+      size = keys.length;
+      iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator;
+    }
+    if (!size || isNaN(limit) || limit < 1) {
+      return callback(null, result);
+    }
+    timesSync(limit > size ? size : limit, iterate);
+
+    function arrayIterator() {
+      index = started++;
+      if (index < size) {
+        iterator(collection[index], createCallback(index));
+      }
+    }
+
+    function arrayIteratorWithIndex() {
+      index = started++;
+      if (index < size) {
+        iterator(collection[index], index, createCallback(index));
+      }
+    }
+
+    function symbolIterator() {
+      item = iter.next();
+      if (item.done === false) {
+        iterator(item.value, createCallback(started++));
+      } else if (completed === started && iterator !== noop) {
+        iterator = noop;
+        callback(null, result);
+      }
+    }
+
+    function symbolIteratorWithKey() {
+      item = iter.next();
+      if (item.done === false) {
+        iterator(item.value, started, createCallback(started++));
+      } else if (completed === started && iterator !== noop) {
+        iterator = noop;
+        callback(null, result);
+      }
+    }
+
+    function objectIterator() {
+      index = started++;
+      if (index < size) {
+        key = keys[index];
+        iterator(collection[key], createCallback(key));
+      }
+    }
+
+    function objectIteratorWithKey() {
+      index = started++;
+      if (index < size) {
+        key = keys[index];
+        iterator(collection[key], key, createCallback(key));
+      }
+    }
+
+    function createCallback(key) {
+      return function(err, res) {
+        if (key === null) {
+          throwError();
+        }
+        if (err) {
+          key = null;
+          iterate = noop;
+          callback = once(callback);
+          callback(err, objectClone(result));
+          return;
+        }
+        result[key] = res;
+        key = null;
+        if (++completed === size) {
+          callback(null, result);
+        } else if (sync) {
+          nextTick(iterate);
+        } else {
+          sync = true;
+          iterate();
+        }
+        sync = false;
+      };
+    }
+  }
+
+  /**
+   * @private
+   * @param {Function} arrayEach
+   * @param {Function} baseEach
+   * @param {Function} symbolEach
+   * @param {boolean} bool
+   */
+  function createDetect(arrayEach, baseEach, symbolEach, bool) {
+    return function(collection, iterator, callback) {
+      callback = callback || noop;
+      var size, keys;
+      var completed = 0;
+
+      if (isArray(collection)) {
+        size = collection.length;
+        arrayEach(collection, iterator, createCallback);
+      } else if (!collection) {
+      } else if (iteratorSymbol && collection[iteratorSymbol]) {
+        size = symbolEach(collection, iterator, createCallback);
+        size && size === completed && callback(null);
+      } else if (typeof collection === obj) {
+        keys = nativeKeys(collection);
+        size = keys.length;
+        baseEach(collection, iterator, createCallback, keys);
+      }
+      if (!size) {
+        callback(null);
+      }
+
+      function createCallback(value) {
+        var called = false;
+        return function done(err, res) {
+          if (called) {
+            throwError();
+          }
+          called = true;
+          if (err) {
+            callback = once(callback);
+            callback(err);
+          } else if (!!res === bool) {
+            callback = once(callback);
+            callback(null, value);
+          } else if (++completed === size) {
+            callback(null);
+          }
+        };
+      }
+    };
+  }
+
+  /**
+   * @private
+   * @param {boolean} bool
+   */
+  function createDetectSeries(bool) {
+    return function(collection, iterator, callback) {
+      callback = onlyOnce(callback || noop);
+      var size, key, value, keys, iter, item, iterate;
+      var sync = false;
+      var completed = 0;
+
+      if (isArray(collection)) {
+        size = collection.length;
+        iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator;
+      } else if (!collection) {
+      } else if (iteratorSymbol && collection[iteratorSymbol]) {
+        size = Infinity;
+        iter = collection[iteratorSymbol]();
+        iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator;
+      } else if (typeof collection === obj) {
+        keys = nativeKeys(collection);
+        size = keys.length;
+        iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator;
+      }
+      if (!size) {
+        return callback(null);
+      }
+      iterate();
+
+      function arrayIterator() {
+        value = collection[completed];
+        iterator(value, done);
+      }
+
+      function arrayIteratorWithIndex() {
+        value = collection[completed];
+        iterator(value, completed, done);
+      }
+
+      function symbolIterator() {
+        item = iter.next();
+        value = item.value;
+        item.done ? callback(null) : iterator(value, done);
+      }
+
+      function symbolIteratorWithKey() {
+        item = iter.next();
+        value = item.value;
+        item.done ? callback(null) : iterator(value, completed, done);
+      }
+
+      function objectIterator() {
+        value = collection[keys[completed]];
+        iterator(value, done);
+      }
+
+      function objectIteratorWithKey() {
+        key = keys[completed];
+        value = collection[key];
+        iterator(value, key, done);
+      }
+
+      function done(err, res) {
+        if (err) {
+          callback(err);
+        } else if (!!res === bool) {
+          iterate = throwError;
+          callback(null, value);
+        } else if (++completed === size) {
+          iterate = throwError;
+          callback(null);
+        } else if (sync) {
+          nextTick(iterate);
+        } else {
+          sync = true;
+          iterate();
+        }
+        sync = false;
+      }
+    };
+  }
+
+  /**
+   * @private
+   * @param {boolean} bool
+   */
+  function createDetectLimit(bool) {
+    return function(collection, limit, iterator, callback) {
+      callback = callback || noop;
+      var size, index, key, value, keys, iter, item, iterate;
+      var sync = false;
+      var started = 0;
+      var completed = 0;
+
+      if (isArray(collection)) {
+        size = collection.length;
+        iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator;
+      } else if (!collection) {
+      } else if (iteratorSymbol && collection[iteratorSymbol]) {
+        size = Infinity;
+        iter = collection[iteratorSymbol]();
+        iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator;
+      } else if (typeof collection === obj) {
+        keys = nativeKeys(collection);
+        size = keys.length;
+        iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator;
+      }
+      if (!size || isNaN(limit) || limit < 1) {
+        return callback(null);
+      }
+      timesSync(limit > size ? size : limit, iterate);
+
+      function arrayIterator() {
+        index = started++;
+        if (index < size) {
+          value = collection[index];
+          iterator(value, createCallback(value));
+        }
+      }
+
+      function arrayIteratorWithIndex() {
+        index = started++;
+        if (index < size) {
+          value = collection[index];
+          iterator(value, index, createCallback(value));
+        }
+      }
+
+      function symbolIterator() {
+        item = iter.next();
+        if (item.done === false) {
+          started++;
+          value = item.value;
+          iterator(value, createCallback(value));
+        } else if (completed === started && iterator !== noop) {
+          iterator = noop;
+          callback(null);
+        }
+      }
+
+      function symbolIteratorWithKey() {
+        item = iter.next();
+        if (item.done === false) {
+          value = item.value;
+          iterator(value, started++, createCallback(value));
+        } else if (completed === started && iterator !== noop) {
+          iterator = noop;
+          callback(null);
+        }
+      }
+
+      function objectIterator() {
+        index = started++;
+        if (index < size) {
+          value = collection[keys[index]];
+          iterator(value, createCallback(value));
+        }
+      }
+
+      function objectIteratorWithKey() {
+        if (started < size) {
+          key = keys[started++];
+          value = collection[key];
+          iterator(value, key, createCallback(value));
+        }
+      }
+
+      function createCallback(value) {
+        var called = false;
+        return function(err, res) {
+          if (called) {
+            throwError();
+          }
+          called = true;
+          if (err) {
+            iterate = noop;
+            callback = once(callback);
+            callback(err);
+          } else if (!!res === bool) {
+            iterate = noop;
+            callback = once(callback);
+            callback(null, value);
+          } else if (++completed === size) {
+            callback(null);
+          } else if (sync) {
+            nextTick(iterate);
+          } else {
+            sync = true;
+            iterate();
+          }
+          sync = false;
+        };
+      }
+    };
+  }
+
+  /**
+   * @private
+   * @param {Function} arrayEach
+   * @param {Function} baseEach
+   * @param {Function} symbolEach
+   * @param {boolean} bool
+   */
+  function createPick(arrayEach, baseEach, symbolEach, bool) {
+    return function(collection, iterator, callback) {
+      callback = callback || noop;
+      var size, keys;
+      var completed = 0;
+      var result = {};
+
+      if (isArray(collection)) {
+        size = collection.length;
+        arrayEach(collection, iterator, createCallback);
+      } else if (!collection) {
+      } else if (iteratorSymbol && collection[iteratorSymbol]) {
+        size = symbolEach(collection, iterator, createCallback);
+        size && size === completed && callback(null, result);
+      } else if (typeof collection === obj) {
+        keys = nativeKeys(collection);
+        size = keys.length;
+        baseEach(collection, iterator, createCallback, keys);
+      }
+      if (!size) {
+        return callback(null, {});
+      }
+
+      function createCallback(key, value) {
+        return function done(err, res) {
+          if (key === null) {
+            throwError();
+          }
+          if (err) {
+            key = null;
+            callback = once(callback);
+            callback(err, objectClone(result));
+            return;
+          }
+          if (!!res === bool) {
+            result[key] = value;
+          }
+          key = null;
+          if (++completed === size) {
+            callback(null, result);
+          }
+        };
+      }
+    };
+  }
+
+  /**
+   * @private
+   * @param {boolean} bool
+   */
+  function createPickSeries(bool) {
+    return function(collection, iterator, callback) {
+      callback = onlyOnce(callback || noop);
+      var size, key, value, keys, iter, item, iterate;
+      var sync = false;
+      var result = {};
+      var completed = 0;
+
+      if (isArray(collection)) {
+        size = collection.length;
+        iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator;
+      } else if (!collection) {
+      } else if (iteratorSymbol && collection[iteratorSymbol]) {
+        size = Infinity;
+        iter = collection[iteratorSymbol]();
+        iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator;
+      } else if (typeof collection === obj) {
+        keys = nativeKeys(collection);
+        size = keys.length;
+        iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator;
+      }
+      if (!size) {
+        return callback(null, {});
+      }
+      iterate();
+
+      function arrayIterator() {
+        key = completed;
+        value = collection[completed];
+        iterator(value, done);
+      }
+
+      function arrayIteratorWithIndex() {
+        key = completed;
+        value = collection[completed];
+        iterator(value, completed, done);
+      }
+
+      function symbolIterator() {
+        key = completed;
+        item = iter.next();
+        value = item.value;
+        item.done ? callback(null, result) : iterator(value, done);
+      }
+
+      function symbolIteratorWithKey() {
+        key = completed;
+        item = iter.next();
+        value = item.value;
+        item.done ? callback(null, result) : iterator(value, key, done);
+      }
+
+      function objectIterator() {
+        key = keys[completed];
+        value = collection[key];
+        iterator(value, done);
+      }
+
+      function objectIteratorWithKey() {
+        key = keys[completed];
+        value = collection[key];
+        iterator(value, key, done);
+      }
+
+      function done(err, res) {
+        if (err) {
+          callback(err, result);
+          return;
+        }
+        if (!!res === bool) {
+          result[key] = value;
+        }
+        if (++completed === size) {
+          iterate = throwError;
+          callback(null, result);
+        } else if (sync) {
+          nextTick(iterate);
+        } else {
+          sync = true;
+          iterate();
+        }
+        sync = false;
+      }
+    };
+  }
+
+  /**
+   * @private
+   * @param {boolean} bool
+   */
+  function createPickLimit(bool) {
+    return function(collection, limit, iterator, callback) {
+      callback = callback || noop;
+      var size, index, key, value, keys, iter, item, iterate;
+      var sync = false;
+      var result = {};
+      var started = 0;
+      var completed = 0;
+
+      if (isArray(collection)) {
+        size = collection.length;
+        iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator;
+      } else if (!collection) {
+      } else if (iteratorSymbol && collection[iteratorSymbol]) {
+        size = Infinity;
+        iter = collection[iteratorSymbol]();
+        iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator;
+      } else if (typeof collection === obj) {
+        keys = nativeKeys(collection);
+        size = keys.length;
+        iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator;
+      }
+      if (!size || isNaN(limit) || limit < 1) {
+        return callback(null, {});
+      }
+      timesSync(limit > size ? size : limit, iterate);
+
+      function arrayIterator() {
+        index = started++;
+        if (index < size) {
+          value = collection[index];
+          iterator(value, createCallback(value, index));
+        }
+      }
+
+      function arrayIteratorWithIndex() {
+        index = started++;
+        if (index < size) {
+          value = collection[index];
+          iterator(value, index, createCallback(value, index));
+        }
+      }
+
+      function symbolIterator() {
+        item = iter.next();
+        if (item.done === false) {
+          value = item.value;
+          iterator(value, createCallback(value, started++));
+        } else if (completed === started && iterator !== noop) {
+          iterator = noop;
+          callback(null, result);
+        }
+      }
+
+      function symbolIteratorWithKey() {
+        item = iter.next();
+        if (item.done === false) {
+          value = item.value;
+          iterator(value, started, createCallback(value, started++));
+        } else if (completed === started && iterator !== noop) {
+          iterator = noop;
+          callback(null, result);
+        }
+      }
+
+      function objectIterator() {
+        if (started < size) {
+          key = keys[started++];
+          value = collection[key];
+          iterator(value, createCallback(value, key));
+        }
+      }
+
+      function objectIteratorWithKey() {
+        if (started < size) {
+          key = keys[started++];
+          value = collection[key];
+          iterator(value, key, createCallback(value, key));
+        }
+      }
+
+      function createCallback(value, key) {
+        return function(err, res) {
+          if (key === null) {
+            throwError();
+          }
+          if (err) {
+            key = null;
+            iterate = noop;
+            callback = once(callback);
+            callback(err, objectClone(result));
+            return;
+          }
+          if (!!res === bool) {
+            result[key] = value;
+          }
+          key = null;
+          if (++completed === size) {
+            iterate = throwError;
+            callback = onlyOnce(callback);
+            callback(null, result);
+          } else if (sync) {
+            nextTick(iterate);
+          } else {
+            sync = true;
+            iterate();
+          }
+          sync = false;
+        };
+      }
+    };
+  }
+
+  /**
+   * @memberof async
+   * @namespace reduce
+   * @param {Array|Object} collection
+   * @param {*} result
+   * @param {Function} iterator
+   * @param {Function} callback
+   * @example
+   *
+   * // array
+   * var order = [];
+   * var collection = [1, 3, 2, 4];
+   * var iterator = function(result, num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     done(null, result + num);
+   *   }, num * 10);
+   * };
+   * async.reduce(collection, 0, iterator, function(err, res) {
+   *   console.log(res); // 10
+   *   console.log(order); // [1, 3, 2, 4]
+   * });
+   *
+   * @example
+   *
+   * // array with index
+   * var order = [];
+   * var collection = [1, 3, 2, 4];
+   * var iterator = function(result, num, index, done) {
+   *   setTimeout(function() {
+   *     order.push([num, index]);
+   *     done(null, result + num);
+   *   }, num * 10);
+   * };
+   * async.reduce(collection, '', iterator, function(err, res) {
+   *   console.log(res); // '1324'
+   *   console.log(order); // [[1, 0], [3, 1], [2, 2], [4, 3]]
+   * });
+   *
+   * @example
+   *
+   * // object
+   * var order = [];
+   * var object = { a: 1, b: 3, c: 2, d: 4 };
+   * var iterator = function(result, num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     done(null, result + num);
+   *   }, num * 10);
+   * };
+   * async.reduce(collection, '', iterator, function(err, res) {
+   *   console.log(res); // '1324'
+   *   console.log(order); // [1, 3, 2, 4]
+   * });
+   *
+   * @example
+   *
+   * // object with key
+   * var order = [];
+   * var object = { a: 1, b: 3, c: 2, d: 4 };
+   * var iterator = function(result, num, key, done) {
+   *   setTimeout(function() {
+   *     order.push([num, key]);
+   *     done(null, result + num);
+   *   }, num * 10);
+   * };
+   * async.reduce(collection, 0, iterator, function(err, res) {
+   *   console.log(res); // 10
+   *   console.log(order); // [[1, 'a'], [3, 'b'], [2, 'b'], [4, 'd']]
+   * });
+   *
+   */
+  function reduce(collection, result, iterator, callback) {
+    callback = onlyOnce(callback || noop);
+    var size, key, keys, iter, item, iterate;
+    var sync = false;
+    var completed = 0;
+
+    if (isArray(collection)) {
+      size = collection.length;
+      iterate = iterator.length === 4 ? arrayIteratorWithIndex : arrayIterator;
+    } else if (!collection) {
+    } else if (iteratorSymbol && collection[iteratorSymbol]) {
+      size = Infinity;
+      iter = collection[iteratorSymbol]();
+      iterate = iterator.length === 4 ? symbolIteratorWithKey : symbolIterator;
+    } else if (typeof collection === obj) {
+      keys = nativeKeys(collection);
+      size = keys.length;
+      iterate = iterator.length === 4 ? objectIteratorWithKey : objectIterator;
+    }
+    if (!size) {
+      return callback(null, result);
+    }
+    iterate(result);
+
+    function arrayIterator(result) {
+      iterator(result, collection[completed], done);
+    }
+
+    function arrayIteratorWithIndex(result) {
+      iterator(result, collection[completed], completed, done);
+    }
+
+    function symbolIterator(result) {
+      item = iter.next();
+      item.done ? callback(null, result) : iterator(result, item.value, done);
+    }
+
+    function symbolIteratorWithKey(result) {
+      item = iter.next();
+      item.done ? callback(null, result) : iterator(result, item.value, completed, done);
+    }
+
+    function objectIterator(result) {
+      iterator(result, collection[keys[completed]], done);
+    }
+
+    function objectIteratorWithKey(result) {
+      key = keys[completed];
+      iterator(result, collection[key], key, done);
+    }
+
+    function done(err, result) {
+      if (err) {
+        callback(err, result);
+      } else if (++completed === size) {
+        iterator = throwError;
+        callback(null, result);
+      } else if (sync) {
+        nextTick(function() {
+          iterate(result);
+        });
+      } else {
+        sync = true;
+        iterate(result);
+      }
+      sync = false;
+    }
+  }
+
+  /**
+   * @memberof async
+   * @namespace reduceRight
+   * @param {Array|Object} collection
+   * @param {*} result
+   * @param {Function} iterator
+   * @param {Function} callback
+   * @example
+   *
+   * // array
+   * var order = [];
+   * var collection = [1, 3, 2, 4];
+   * var iterator = function(result, num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     done(null, result + num);
+   *   }, num * 10);
+   * };
+   * async.reduceRight(collection, 0, iterator, function(err, res) {
+   *   console.log(res); // 10
+   *   console.log(order); // [4, 2, 3, 1]
+   * });
+   *
+   * @example
+   *
+   * // array with index
+   * var order = [];
+   * var collection = [1, 3, 2, 4];
+   * var iterator = function(result, num, index, done) {
+   *   setTimeout(function() {
+   *     order.push([num, index]);
+   *     done(null, result + num);
+   *   }, num * 10);
+   * };
+   * async.reduceRight(collection, '', iterator, function(err, res) {
+   *   console.log(res); // '4231'
+   *   console.log(order); // [[4, 3], [2, 2], [3, 1], [1, 0]]
+   * });
+   *
+   * @example
+   *
+   * // object
+   * var order = [];
+   * var object = { a: 1, b: 3, c: 2, d: 4 };
+   * var iterator = function(result, num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     done(null, result + num);
+   *   }, num * 10);
+   * };
+   * async.reduceRight(collection, '', iterator, function(err, res) {
+   *   console.log(res); // '4231'
+   *   console.log(order); // [4, 2, 3, 1]
+   * });
+   *
+   * @example
+   *
+   * // object with key
+   * var order = [];
+   * var object = { a: 1, b: 3, c: 2, d: 4 };
+   * var iterator = function(result, num, key, done) {
+   *   setTimeout(function() {
+   *     order.push([num, key]);
+   *     done(null, result + num);
+   *   }, num * 10);
+   * };
+   * async.reduceRight(collection, 0, iterator, function(err, res) {
+   *   console.log(res); // 10
+   *   console.log(order); // [[4, 3], [2, 2], [3, 1], [1, 0]]
+   * });
+   *
+   */
+  function reduceRight(collection, result, iterator, callback) {
+    callback = onlyOnce(callback || noop);
+    var resIndex, index, key, keys, iter, item, col, iterate;
+    var sync = false;
+
+    if (isArray(collection)) {
+      resIndex = collection.length;
+      iterate = iterator.length === 4 ? arrayIteratorWithIndex : arrayIterator;
+    } else if (!collection) {
+    } else if (iteratorSymbol && collection[iteratorSymbol]) {
+      col = [];
+      iter = collection[iteratorSymbol]();
+      index = -1;
+      while ((item = iter.next()).done === false) {
+        col[++index] = item.value;
+      }
+      collection = col;
+      resIndex = col.length;
+      iterate = iterator.length === 4 ? arrayIteratorWithIndex : arrayIterator;
+    } else if (typeof collection === obj) {
+      keys = nativeKeys(collection);
+      resIndex = keys.length;
+      iterate = iterator.length === 4 ? objectIteratorWithKey : objectIterator;
+    }
+    if (!resIndex) {
+      return callback(null, result);
+    }
+    iterate(result);
+
+    function arrayIterator(result) {
+      iterator(result, collection[--resIndex], done);
+    }
+
+    function arrayIteratorWithIndex(result) {
+      iterator(result, collection[--resIndex], resIndex, done);
+    }
+
+    function objectIterator(result) {
+      iterator(result, collection[keys[--resIndex]], done);
+    }
+
+    function objectIteratorWithKey(result) {
+      key = keys[--resIndex];
+      iterator(result, collection[key], key, done);
+    }
+
+    function done(err, result) {
+      if (err) {
+        callback(err, result);
+      } else if (resIndex === 0) {
+        iterate = throwError;
+        callback(null, result);
+      } else if (sync) {
+        nextTick(function() {
+          iterate(result);
+        });
+      } else {
+        sync = true;
+        iterate(result);
+      }
+      sync = false;
+    }
+  }
+
+  /**
+   * @private
+   * @param {Function} arrayEach
+   * @param {Function} baseEach
+   * @param {Function} symbolEach
+   */
+  function createTransform(arrayEach, baseEach, symbolEach) {
+    return function transform(collection, accumulator, iterator, callback) {
+      if (arguments.length === 3) {
+        callback = iterator;
+        iterator = accumulator;
+        accumulator = undefined;
+      }
+      callback = callback || noop;
+      var size, keys, result;
+      var completed = 0;
+
+      if (isArray(collection)) {
+        size = collection.length;
+        result = accumulator !== undefined ? accumulator : [];
+        arrayEach(collection, result, iterator, done);
+      } else if (!collection) {
+      } else if (iteratorSymbol && collection[iteratorSymbol]) {
+        result = accumulator !== undefined ? accumulator : {};
+        size = symbolEach(collection, result, iterator, done);
+        size && size === completed && callback(null, result);
+      } else if (typeof collection === obj) {
+        keys = nativeKeys(collection);
+        size = keys.length;
+        result = accumulator !== undefined ? accumulator : {};
+        baseEach(collection, result, iterator, done, keys);
+      }
+      if (!size) {
+        callback(null, accumulator !== undefined ? accumulator : result || {});
+      }
+
+      function done(err, bool) {
+        if (err) {
+          callback = once(callback);
+          callback(err, isArray(result) ? createArray(result) : objectClone(result));
+        } else if (++completed === size) {
+          callback(null, result);
+        } else if (bool === false) {
+          callback = once(callback);
+          callback(null, isArray(result) ? createArray(result) : objectClone(result));
+        }
+      }
+    };
+  }
+
+  /**
+   * @memberof async
+   * @namespace transformSeries
+   * @param {Array|Object} collection
+   * @param {Array|Object|Function} [accumulator]
+   * @param {Function} [iterator]
+   * @param {Function} [callback]
+   * @example
+   *
+   * // array
+   * var order = [];
+   * var collection = [1, 3, 2, 4];
+   * var iterator = function(result, num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     result.push(num)
+   *     done();
+   *   }, num * 10);
+   * };
+   * async.transformSeries(collection, iterator, function(err, res) {
+   *   console.log(res); // [1, 3, 2, 4]
+   *   console.log(order); // [1, 3, 2, 4]
+   * });
+   *
+   * @example
+   *
+   * // array with index and accumulator
+   * var order = [];
+   * var collection = [1, 3, 2, 4];
+   * var iterator = function(result, num, index, done) {
+   *   setTimeout(function() {
+   *     order.push([num, index]);
+   *     result[index] = num;
+   *     done();
+   *   }, num * 10);
+   * };
+   * async.transformSeries(collection, {}, iterator, function(err, res) {
+   *   console.log(res); // { '0': 1, '1': 3, '2': 2, '3': 4 }
+   *   console.log(order); // [[1, 0], [3, 1], [2, 2], [4, 3]]
+   * });
+   *
+   * @example
+   *
+   * // object with accumulator
+   * var order = [];
+   * var object = { a: 1, b: 3, c: 2, d: 4 };
+   * var iterator = function(result, num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     result.push(num);
+   *     done();
+   *   }, num * 10);
+   * };
+   * async.transformSeries(collection, [], iterator, function(err, res) {
+   *   console.log(res); // [1, 3, 2, 4]
+   *   console.log(order); // [1, 3, 2, 4]
+   * });
+   *
+   * @example
+   *
+   * // object with key
+   * var order = [];
+   * var object = { a: 1, b: 3, c: 2, d: 4 };
+   * var iterator = function(result, num, key, done) {
+   *   setTimeout(function() {
+   *     order.push([num, key]);
+   *     result[key] = num;
+   *     done();
+   *   }, num * 10);
+   * };
+   * async.transformSeries(collection, iterator, function(err, res) {
+   *   console.log(res); //  { a: 1, b: 3, c: 2, d: 4 }
+   *   console.log(order); // [[1, 'a'], [3, 'b'], [2, 'b'], [4, 'd']]
+   * });
+   *
+   */
+  function transformSeries(collection, accumulator, iterator, callback) {
+    if (arguments.length === 3) {
+      callback = iterator;
+      iterator = accumulator;
+      accumulator = undefined;
+    }
+    callback = onlyOnce(callback || noop);
+    var size, key, keys, iter, item, iterate, result;
+    var sync = false;
+    var completed = 0;
+
+    if (isArray(collection)) {
+      size = collection.length;
+      result = accumulator !== undefined ? accumulator : [];
+      iterate = iterator.length === 4 ? arrayIteratorWithIndex : arrayIterator;
+    } else if (!collection) {
+    } else if (iteratorSymbol && collection[iteratorSymbol]) {
+      size = Infinity;
+      iter = collection[iteratorSymbol]();
+      result = accumulator !== undefined ? accumulator : {};
+      iterate = iterator.length === 4 ? symbolIteratorWithKey : symbolIterator;
+    } else if (typeof collection === obj) {
+      keys = nativeKeys(collection);
+      size = keys.length;
+      result = accumulator !== undefined ? accumulator : {};
+      iterate = iterator.length === 4 ? objectIteratorWithKey : objectIterator;
+    }
+    if (!size) {
+      return callback(null, accumulator !== undefined ? accumulator : result || {});
+    }
+    iterate();
+
+    function arrayIterator() {
+      iterator(result, collection[completed], done);
+    }
+
+    function arrayIteratorWithIndex() {
+      iterator(result, collection[completed], completed, done);
+    }
+
+    function symbolIterator() {
+      item = iter.next();
+      item.done ? callback(null, result) : iterator(result, item.value, done);
+    }
+
+    function symbolIteratorWithKey() {
+      item = iter.next();
+      item.done ? callback(null, result) : iterator(result, item.value, completed, done);
+    }
+
+    function objectIterator() {
+      iterator(result, collection[keys[completed]], done);
+    }
+
+    function objectIteratorWithKey() {
+      key = keys[completed];
+      iterator(result, collection[key], key, done);
+    }
+
+    function done(err, bool) {
+      if (err) {
+        callback(err, result);
+      } else if (++completed === size || bool === false) {
+        iterate = throwError;
+        callback(null, result);
+      } else if (sync) {
+        nextTick(iterate);
+      } else {
+        sync = true;
+        iterate();
+      }
+      sync = false;
+    }
+  }
+
+  /**
+   * @memberof async
+   * @namespace transformLimit
+   * @param {Array|Object} collection
+   * @param {number} limit - limit >= 1
+   * @param {Array|Object|Function} [accumulator]
+   * @param {Function} [iterator]
+   * @param {Function} [callback]
+   * @example
+   *
+   * // array
+   * var order = [];
+   * var array = [1, 5, 3, 4, 2];
+   * var iterator = function(result, num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     result.push(num);
+   *     done();
+   *   }, num * 10);
+   * };
+   * async.transformLimit(array, 2, iterator, function(err, res) {
+   *   console.log(res); // [1, 3, 5, 2, 4]
+   *   console.log(order); // [1, 3, 5, 2, 4]
+   * });
+   *
+   * @example
+   *
+   * // array with index and accumulator
+   * var order = [];
+   * var array = [1, 5, 3, 4, 2];
+   * var iterator = function(result, num, index, done) {
+   *   setTimeout(function() {
+   *     order.push([num, index]);
+   *     result[index] = key;
+   *     done();
+   *   }, num * 10);
+   * };
+   * async.transformLimit(array, 2, {}, iterator, function(err, res) {
+   *   console.log(res); // { '0': 1, '1': 5, '2': 3, '3': 4, '4': 2 }
+   *   console.log(order); // [[1, 0], [3, 2], [5, 1], [2, 4], [4, 3]]
+   * });
+   *
+   * @example
+   *
+   * // object with accumulator
+   * var order = [];
+   * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 };
+   * var iterator = function(result, num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     result.push(num);
+   *     done();
+   *   }, num * 10);
+   * };
+   * async.transformLimit(object, 2, [], iterator, function(err, res) {
+   *   console.log(res); // [1, 3, 5, 2, 4]
+   *   console.log(order); // [1, 3, 5, 2, 4]
+   * });
+   *
+   * @example
+   *
+   * // object with key
+   * var order = [];
+   * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 };
+   * var iterator = function(result, num, key, done) {
+   *   setTimeout(function() {
+   *     order.push([num, key]);
+   *     result[key] = num;
+   *     done();
+   *   }, num * 10);
+   * };
+   * async.transformLimit(object, 2, iterator, function(err, res) {
+   *   console.log(res); // { a: 1, b: 5, c: 3, d: 4, e: 2 };
+   *   console.log(order); // [[1, 'a'], [3, 'c'], [5, 'b'], [2, 'e'], [4, 'd']]
+   * });
+   *
+   */
+  function transformLimit(collection, limit, accumulator, iterator, callback) {
+    if (arguments.length === 4) {
+      callback = iterator;
+      iterator = accumulator;
+      accumulator = undefined;
+    }
+    callback = callback || noop;
+    var size, index, key, keys, iter, item, iterate, result;
+    var sync = false;
+    var started = 0;
+    var completed = 0;
+
+    if (isArray(collection)) {
+      size = collection.length;
+      result = accumulator !== undefined ? accumulator : [];
+      iterate = iterator.length === 4 ? arrayIteratorWithIndex : arrayIterator;
+    } else if (!collection) {
+    } else if (iteratorSymbol && collection[iteratorSymbol]) {
+      size = Infinity;
+      iter = collection[iteratorSymbol]();
+      result = accumulator !== undefined ? accumulator : {};
+      iterate = iterator.length === 4 ? symbolIteratorWithKey : symbolIterator;
+    } else if (typeof collection === obj) {
+      keys = nativeKeys(collection);
+      size = keys.length;
+      result = accumulator !== undefined ? accumulator : {};
+      iterate = iterator.length === 4 ? objectIteratorWithKey : objectIterator;
+    }
+    if (!size || isNaN(limit) || limit < 1) {
+      return callback(null, accumulator !== undefined ? accumulator : result || {});
+    }
+    timesSync(limit > size ? size : limit, iterate);
+
+    function arrayIterator() {
+      index = started++;
+      if (index < size) {
+        iterator(result, collection[index], onlyOnce(done));
+      }
+    }
+
+    function arrayIteratorWithIndex() {
+      index = started++;
+      if (index < size) {
+        iterator(result, collection[index], index, onlyOnce(done));
+      }
+    }
+
+    function symbolIterator() {
+      item = iter.next();
+      if (item.done === false) {
+        started++;
+        iterator(result, item.value, onlyOnce(done));
+      } else if (completed === started && iterator !== noop) {
+        iterator = noop;
+        callback(null, result);
+      }
+    }
+
+    function symbolIteratorWithKey() {
+      item = iter.next();
+      if (item.done === false) {
+        iterator(result, item.value, started++, onlyOnce(done));
+      } else if (completed === started && iterator !== noop) {
+        iterator = noop;
+        callback(null, result);
+      }
+    }
+
+    function objectIterator() {
+      index = started++;
+      if (index < size) {
+        iterator(result, collection[keys[index]], onlyOnce(done));
+      }
+    }
+
+    function objectIteratorWithKey() {
+      index = started++;
+      if (index < size) {
+        key = keys[index];
+        iterator(result, collection[key], key, onlyOnce(done));
+      }
+    }
+
+    function done(err, bool) {
+      if (err || bool === false) {
+        iterate = noop;
+        callback(err || null, isArray(result) ? createArray(result) : objectClone(result));
+        callback = noop;
+      } else if (++completed === size) {
+        iterator = noop;
+        callback(null, result);
+      } else if (sync) {
+        nextTick(iterate);
+      } else {
+        sync = true;
+        iterate();
+      }
+      sync = false;
+    }
+  }
+
+  /**
+   * @private
+   * @param {function} arrayEach
+   * @param {function} baseEach
+   * @param {function} symbolEach
+   */
+  function createSortBy(arrayEach, baseEach, symbolEach) {
+    return function sortBy(collection, iterator, callback) {
+      callback = callback || noop;
+      var size, array, criteria;
+      var completed = 0;
+
+      if (isArray(collection)) {
+        size = collection.length;
+        array = Array(size);
+        criteria = Array(size);
+        arrayEach(collection, iterator, createCallback);
+      } else if (!collection) {
+      } else if (iteratorSymbol && collection[iteratorSymbol]) {
+        array = [];
+        criteria = [];
+        size = symbolEach(collection, iterator, createCallback);
+        size && size === completed && callback(null, sortByCriteria(array, criteria));
+      } else if (typeof collection === obj) {
+        var keys = nativeKeys(collection);
+        size = keys.length;
+        array = Array(size);
+        criteria = Array(size);
+        baseEach(collection, iterator, createCallback, keys);
+      }
+      if (!size) {
+        callback(null, []);
+      }
+
+      function createCallback(index, value) {
+        var called = false;
+        array[index] = value;
+        return function done(err, criterion) {
+          if (called) {
+            throwError();
+          }
+          called = true;
+          criteria[index] = criterion;
+          if (err) {
+            callback = once(callback);
+            callback(err);
+          } else if (++completed === size) {
+            callback(null, sortByCriteria(array, criteria));
+          }
+        };
+      }
+    };
+  }
+
+  /**
+   * @memberof async
+   * @namespace sortBySeries
+   * @param {Array|Object} collection
+   * @param {Function} iterator
+   * @param {Function} callback
+   * @example
+   *
+   * // array
+   * var order = [];
+   * var array = [1, 3, 2];
+   * var iterator = function(num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     done(null, num);
+   *   }, num * 10);
+   * };
+   * async.sortBySeries(array, iterator, function(err, res) {
+   *   console.log(res); // [1, 2, 3];
+   *   console.log(order); // [1, 3, 2]
+   * });
+   *
+   * @example
+   *
+   * // array with index
+   * var order = [];
+   * var array = [1, 3, 2];
+   * var iterator = function(num, index, done) {
+   *   setTimeout(function() {
+   *     order.push([num, index]);
+   *     done(null, num);
+   *   }, num * 10);
+   * };
+   * async.sortBySeries(array, iterator, function(err, res) {
+   *   console.log(res); // [1, 2, 3]
+   *   console.log(order); // [[1, 0], [3, 1], [2, 2]]
+   * });
+   *
+   * @example
+   *
+   * // object
+   * var order = [];
+   * var object = { a: 1, b: 3, c: 2 };
+   * var iterator = function(num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     done(null, num);
+   *   }, num * 10);
+   * };
+   * async.sortBySeries(object, iterator, function(err, res) {
+   *   console.log(res); // [1, 2, 3]
+   *   console.log(order); // [1, 3, 2]
+   * });
+   *
+   * @example
+   *
+   * // object with key
+   * var order = [];
+   * var object = { a: 1, b: 3, c: 2 };
+   * var iterator = function(num, key, done) {
+   *   setTimeout(function() {
+   *     order.push([num, key]);
+   *     done(null, num);
+   *   }, num * 10);
+   * };
+   * async.sortBySeries(object, iterator, function(err, res) {
+   *   console.log(res); // [1, 2, 3]
+   *   console.log(order); // [[1, 'a'], [3, 'b'], [2, 'c']]
+   * });
+   *
+   */
+  function sortBySeries(collection, iterator, callback) {
+    callback = onlyOnce(callback || noop);
+    var size, key, value, keys, iter, item, array, criteria, iterate;
+    var sync = false;
+    var completed = 0;
+
+    if (isArray(collection)) {
+      size = collection.length;
+      array = collection;
+      criteria = Array(size);
+      iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator;
+    } else if (!collection) {
+    } else if (iteratorSymbol && collection[iteratorSymbol]) {
+      size = Infinity;
+      array = [];
+      criteria = [];
+      iter = collection[iteratorSymbol]();
+      iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator;
+    } else if (typeof collection === obj) {
+      keys = nativeKeys(collection);
+      size = keys.length;
+      array = Array(size);
+      criteria = Array(size);
+      iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator;
+    }
+    if (!size) {
+      return callback(null, []);
+    }
+    iterate();
+
+    function arrayIterator() {
+      value = collection[completed];
+      iterator(value, done);
+    }
+
+    function arrayIteratorWithIndex() {
+      value = collection[completed];
+      iterator(value, completed, done);
+    }
+
+    function symbolIterator() {
+      item = iter.next();
+      if (item.done) {
+        return callback(null, sortByCriteria(array, criteria));
+      }
+      value = item.value;
+      array[completed] = value;
+      iterator(value, done);
+    }
+
+    function symbolIteratorWithKey() {
+      item = iter.next();
+      if (item.done) {
+        return callback(null, sortByCriteria(array, criteria));
+      }
+      value = item.value;
+      array[completed] = value;
+      iterator(value, completed, done);
+    }
+
+    function objectIterator() {
+      value = collection[keys[completed]];
+      array[completed] = value;
+      iterator(value, done);
+    }
+
+    function objectIteratorWithKey() {
+      key = keys[completed];
+      value = collection[key];
+      array[completed] = value;
+      iterator(value, key, done);
+    }
+
+    function done(err, criterion) {
+      criteria[completed] = criterion;
+      if (err) {
+        callback(err);
+      } else if (++completed === size) {
+        iterate = throwError;
+        callback(null, sortByCriteria(array, criteria));
+      } else if (sync) {
+        nextTick(iterate);
+      } else {
+        sync = true;
+        iterate();
+      }
+      sync = false;
+    }
+  }
+
+  /**
+   * @memberof async
+   * @namespace sortByLimit
+   * @param {Array|Object} collection
+   * @param {number} limit - limit >= 1
+   * @param {Function} iterator
+   * @param {Function} callback
+   * @example
+   *
+   * // array
+   * var order = [];
+   * var array = [1, 5, 3, 4, 2];
+   * var iterator = function(num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     done(null, num);
+   *   }, num * 10);
+   * };
+   * async.sortByLimit(array, 2, iterator, function(err, res) {
+   *   console.log(res); // [1, 2, 3, 4, 5]
+   *   console.log(order); // [1, 3, 5, 2, 4]
+   * });
+   *
+   * @example
+   *
+   * // array with index
+   * var order = [];
+   * var array = [1, 5, 3, 4, 2];
+   * var iterator = function(num, index, done) {
+   *   setTimeout(function() {
+   *     order.push([num, index]);
+   *     done(null, num);
+   *   }, num * 10);
+   * };
+   * async.sortByLimit(array, 2, iterator, function(err, res) {
+   *   console.log(res); // [1, 2, 3, 4, 5]
+   *   console.log(order); // [[1, 0], [3, 2], [5, 1], [2, 4], [4, 3]]
+   * });
+   *
+   * @example
+   *
+   * // object
+   * var order = [];
+   * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 };
+   * var iterator = function(num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     done(null, num);
+   *   }, num * 10);
+   * };
+   * async.sortByLimit(object, 2, iterator, function(err, res) {
+   *   console.log(res); // [1, 2, 3, 4, 5]
+   *   console.log(order); // [1, 3, 5, 2, 4]
+   * });
+   *
+   * @example
+   *
+   * // object with key
+   * var order = [];
+   * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 };
+   * var iterator = function(num, key, done) {
+   *   setTimeout(function() {
+   *     order.push([num, key]);
+   *     done(null, num);
+   *   }, num * 10);
+   * };
+   * async.sortByLimit(object, 2, iterator, function(err, res) {
+   *   console.log(res); // [1, 2, 3, 4, 5]
+   *   console.log(order); // [[1, 'a'], [3, 'c'], [5, 'b'], [2, 'e'], [4, 'd']]
+   * });
+   *
+   */
+  function sortByLimit(collection, limit, iterator, callback) {
+    callback = callback || noop;
+    var size, index, key, value, array, keys, iter, item, criteria, iterate;
+    var sync = false;
+    var started = 0;
+    var completed = 0;
+
+    if (isArray(collection)) {
+      size = collection.length;
+      array = collection;
+      iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator;
+    } else if (!collection) {
+    } else if (iteratorSymbol && collection[iteratorSymbol]) {
+      size = Infinity;
+      iter = collection[iteratorSymbol]();
+      array = [];
+      criteria = [];
+      iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator;
+    } else if (typeof collection === obj) {
+      keys = nativeKeys(collection);
+      size = keys.length;
+      array = Array(size);
+      iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator;
+    }
+    if (!size || isNaN(limit) || limit < 1) {
+      return callback(null, []);
+    }
+    criteria = criteria || Array(size);
+    timesSync(limit > size ? size : limit, iterate);
+
+    function arrayIterator() {
+      if (started < size) {
+        value = collection[started];
+        iterator(value, createCallback(value, started++));
+      }
+    }
+
+    function arrayIteratorWithIndex() {
+      index = started++;
+      if (index < size) {
+        value = collection[index];
+        iterator(value, index, createCallback(value, index));
+      }
+    }
+
+    function symbolIterator() {
+      item = iter.next();
+      if (item.done === false) {
+        value = item.value;
+        array[started] = value;
+        iterator(value, createCallback(value, started++));
+      } else if (completed === started && iterator !== noop) {
+        iterator = noop;
+        callback(null, sortByCriteria(array, criteria));
+      }
+    }
+
+    function symbolIteratorWithKey() {
+      item = iter.next();
+      if (item.done === false) {
+        value = item.value;
+        array[started] = value;
+        iterator(value, started, createCallback(value, started++));
+      } else if (completed === started && iterator !== noop) {
+        iterator = noop;
+        callback(null, sortByCriteria(array, criteria));
+      }
+    }
+
+    function objectIterator() {
+      if (started < size) {
+        value = collection[keys[started]];
+        array[started] = value;
+        iterator(value, createCallback(value, started++));
+      }
+    }
+
+    function objectIteratorWithKey() {
+      if (started < size) {
+        key = keys[started];
+        value = collection[key];
+        array[started] = value;
+        iterator(value, key, createCallback(value, started++));
+      }
+    }
+
+    function createCallback(value, index) {
+      var called = false;
+      return function(err, criterion) {
+        if (called) {
+          throwError();
+        }
+        called = true;
+        criteria[index] = criterion;
+        if (err) {
+          iterate = noop;
+          callback(err);
+          callback = noop;
+        } else if (++completed === size) {
+          callback(null, sortByCriteria(array, criteria));
+        } else if (sync) {
+          nextTick(iterate);
+        } else {
+          sync = true;
+          iterate();
+        }
+        sync = false;
+      };
+    }
+  }
+
+  /**
+   * @memberof async
+   * @namespace some
+   * @param {Array|Object} collection
+   * @param {Function} iterator
+   * @param {Function} callback
+   * @example
+   *
+   * // array
+   * var order = [];
+   * var array = [1, 3, 2];
+   * var iterator = function(num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     done(null, num % 2);
+   *   }, num * 10);
+   * };
+   * async.some(array, iterator, function(err, res) {
+   *   console.log(res); // true
+   *   console.log(order); // [1]
+   * });
+   *
+   * @example
+   *
+   * // array with index
+   * var order = [];
+   * var array = [1, 3, 2];
+   * var iterator = function(num, index, done) {
+   *   setTimeout(function() {
+   *     order.push([num, index]);
+   *     done(null, num % 2);
+   *   }, num * 10);
+   * };
+   * async.some(array, iterator, function(err, res) {
+   *   console.log(res); // true
+   *   console.log(order); // [[1, 0]]
+   * });
+   *
+   * @example
+   *
+   * // object
+   * var order = [];
+   * var object = { a: 1, b: 3, c: 2 };
+   * var iterator = function(num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     done(null, num % 2);
+   *   }, num * 10);
+   * };
+   * async.some(object, iterator, function(err, res) {
+   *   console.log(res); // true
+   *   console.log(order); // [1]
+   * });
+   *
+   * @example
+   *
+   * // object with key
+   * var order = [];
+   * var object = { a: 1, b: 3, c: 2 };
+   * var iterator = function(num, key, done) {
+   *   setTimeout(function() {
+   *     order.push([num, key]);
+   *     done(null, num % 2);
+   *   }, num * 10);
+   * };
+   * async.some(object, iterator, function(err, res) {
+   *   console.log(res); // true
+   *   console.log(order); // [[1, 'a']]
+   * });
+   *
+   */
+  function some(collection, iterator, callback) {
+    callback = callback || noop;
+    detect(collection, iterator, done);
+
+    function done(err, res) {
+      if (err) {
+        return callback(err);
+      }
+      callback(null, !!res);
+    }
+  }
+
+  /**
+   * @memberof async
+   * @namespace someSeries
+   * @param {Array|Object} collection
+   * @param {Function} iterator
+   * @param {Function} callback
+   * @example
+   *
+   * // array
+   * var order = [];
+   * var array = [1, 3, 2];
+   * var iterator = function(num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     done(null, num % 2);
+   *   }, num * 10);
+   * };
+   * async.someSeries(array, iterator, function(err, res) {
+   *   console.log(res); // true
+   *   console.log(order); // [1]
+   * });
+   *
+   * @example
+   *
+   * // array with index
+   * var order = [];
+   * var array = [1, 3, 2];
+   * var iterator = function(num, index, done) {
+   *   setTimeout(function() {
+   *     order.push([num, index]);
+   *     done(null, num % 2);
+   *   }, num * 10);
+   * };
+   * async.someSeries(array, iterator, function(err, res) {
+   *   console.log(res); // true
+   *   console.log(order); // [[1, 0]]
+   * });
+   *
+   * @example
+   *
+   * // object
+   * var order = [];
+   * var object = { a: 1, b: 3, c: 2 };
+   * var iterator = function(num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     done(null, num % 2);
+   *   }, num * 10);
+   * };
+   * async.someSeries(object, iterator, function(err, res) {
+   *   console.log(res); // true
+   *   console.log(order); // [1]
+   * });
+   *
+   * @example
+   *
+   * // object with key
+   * var order = [];
+   * var object = { a: 1, b: 3, c: 2 };
+   * var iterator = function(num, key, done) {
+   *   setTimeout(function() {
+   *     order.push([num, key]);
+   *     done(null, num % 2);
+   *   }, num * 10);
+   * };
+   * async.someSeries(object, iterator, function(err, res) {
+   *   console.log(res); // true
+   *   console.log(order); // [[1, 'a']]
+   * });
+   *
+   */
+  function someSeries(collection, iterator, callback) {
+    callback = callback || noop;
+    detectSeries(collection, iterator, done);
+
+    function done(err, res) {
+      if (err) {
+        return callback(err);
+      }
+      callback(null, !!res);
+    }
+  }
+
+  /**
+   * @memberof async
+   * @namespace someLimit
+   * @param {Array|Object} collection
+   * @param {number} limit - limit >= 1
+   * @param {Function} iterator
+   * @param {Function} callback
+   * @example
+   *
+   * // array
+   * var order = [];
+   * var array = [1, 5, 3, 4, 2];
+   * var iterator = function(num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     done(null, num % 2);
+   *   }, num * 10);
+   * };
+   * async.someLimit(array, 2, iterator, function(err, res) {
+   *   console.log(res); // true
+   *   console.log(order); // [1]
+   * });
+   *
+   * @example
+   *
+   * // array with index
+   * var order = [];
+   * var array = [1, 5, 3, 4, 2];
+   * var iterator = function(num, index, done) {
+   *   setTimeout(function() {
+   *     order.push([num, index]);
+   *     done(null, num % 2);
+   *   }, num * 10);
+   * };
+   * async.someLimit(array, 2, iterator, function(err, res) {
+   *   console.log(res); // true
+   *   console.log(order); // [[1, 0]]
+   * });
+   *
+   * @example
+   *
+   * // object
+   * var order = [];
+   * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 };
+   * var iterator = function(num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     done(null, num % 2);
+   *   }, num * 10);
+   * };
+   * async.someLimit(object, 2, iterator, function(err, res) {
+   *   console.log(res); // true
+   *   console.log(order); // [1]
+   * });
+   *
+   * @example
+   *
+   * // object with key
+   * var order = [];
+   * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 };
+   * var iterator = function(num, key, done) {
+   *   setTimeout(function() {
+   *     order.push([num, key]);
+   *     done(null, num % 2);
+   *   }, num * 10);
+   * };
+   * async.someLimit(object, 2, iterator, function(err, res) {
+   *   console.log(res); // true
+   *   console.log(order); // [[1, 'a']]
+   * });
+   *
+   */
+  function someLimit(collection, limit, iterator, callback) {
+    callback = callback || noop;
+    detectLimit(collection, limit, iterator, done);
+
+    function done(err, res) {
+      if (err) {
+        return callback(err);
+      }
+      callback(null, !!res);
+    }
+  }
+
+  /**
+   * @private
+   * @param {Function} arrayEach
+   * @param {Function} baseEach
+   * @param {Function} symbolEach
+   */
+  function createEvery(arrayEach, baseEach, symbolEach) {
+    var deny = createDetect(arrayEach, baseEach, symbolEach, false);
+
+    return function every(collection, iterator, callback) {
+      callback = callback || noop;
+      deny(collection, iterator, done);
+
+      function done(err, res) {
+        if (err) {
+          return callback(err);
+        }
+        callback(null, !res);
+      }
+    };
+  }
+
+  /**
+   * @private
+   */
+  function createEverySeries() {
+    var denySeries = createDetectSeries(false);
+
+    return function everySeries(collection, iterator, callback) {
+      callback = callback || noop;
+      denySeries(collection, iterator, done);
+
+      function done(err, res) {
+        if (err) {
+          return callback(err);
+        }
+        callback(null, !res);
+      }
+    };
+  }
+
+  /**
+   * @private
+   */
+  function createEveryLimit() {
+    var denyLimit = createDetectLimit(false);
+
+    return function everyLimit(collection, limit, iterator, callback) {
+      callback = callback || noop;
+      denyLimit(collection, limit, iterator, done);
+
+      function done(err, res) {
+        if (err) {
+          return callback(err);
+        }
+        callback(null, !res);
+      }
+    };
+  }
+
+  /**
+   * @private
+   * @param {Function} arrayEach
+   * @param {Function} baseEach
+   * @param {Function} symbolEach
+   */
+  function createConcat(arrayEach, baseEach, symbolEach) {
+    return function concat(collection, iterator, callback) {
+      callback = callback || noop;
+      var size, result;
+      var completed = 0;
+
+      if (isArray(collection)) {
+        size = collection.length;
+        result = Array(size);
+        arrayEach(collection, iterator, createCallback);
+      } else if (!collection) {
+      } else if (iteratorSymbol && collection[iteratorSymbol]) {
+        result = [];
+        size = symbolEach(collection, iterator, createCallback);
+        size && size === completed && callback(null, result);
+      } else if (typeof collection === obj) {
+        var keys = nativeKeys(collection);
+        size = keys.length;
+        result = Array(size);
+        baseEach(collection, iterator, createCallback, keys);
+      }
+      if (!size) {
+        callback(null, []);
+      }
+
+      function createCallback(index) {
+        return function done(err, res) {
+          if (index === null) {
+            throwError();
+          }
+          if (err) {
+            index = null;
+            callback = once(callback);
+            arrayEachSync(result, function(array, index) {
+              if (array === undefined) {
+                result[index] = noop;
+              }
+            });
+            callback(err, makeConcatResult(result));
+            return;
+          }
+          switch (arguments.length) {
+            case 0:
+            case 1:
+              result[index] = noop;
+              break;
+            case 2:
+              result[index] = res;
+              break;
+            default:
+              result[index] = slice(arguments, 1);
+              break;
+          }
+          index = null;
+          if (++completed === size) {
+            callback(null, makeConcatResult(result));
+          }
+        };
+      }
+    };
+  }
+
+  /**
+   * @memberof async
+   * @namespace concatSeries
+   * @param {Array|Object} collection
+   * @param {Function} iterator
+   * @param {Function} callback
+   * @example
+   *
+   * // array
+   * var order = [];
+   * var array = [1, 3, 2];
+   * var iterator = function(num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     done(null, [num]);
+   *   }, num * 10);
+   * };
+   * async.concatSeries(array, iterator, function(err, res) {
+   *   console.log(res); // [1, 3, 2];
+   *   console.log(order); // [1, 3, 2]
+   * });
+   *
+   * @example
+   *
+   * // array with index
+   * var order = [];
+   * var array = [1, 3, 2];
+   * var iterator = function(num, index, done) {
+   *   setTimeout(function() {
+   *     order.push([num, index]);
+   *     done(null, [num]);
+   *   }, num * 10);
+   * };
+   * async.concatSeries(array, iterator, function(err, res) {
+   *   console.log(res); // [1, 3, 2]
+   *   console.log(order); // [[1, 0], [3, 1], [2, 2]]
+   * });
+   *
+   * @example
+   *
+   * // object
+   * var order = [];
+   * var object = { a: 1, b: 3, c: 2 };
+   * var iterator = function(num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     done(null, [num]);
+   *   }, num * 10);
+   * };
+   * async.concatSeries(object, iterator, function(err, res) {
+   *   console.log(res); // [1, 3, 2]
+   *   console.log(order); // [1, 3, 2]
+   * });
+   *
+   * @example
+   *
+   * // object with key
+   * var order = [];
+   * var object = { a: 1, b: 3, c: 2 };
+   * var iterator = function(num, key, done) {
+   *   setTimeout(function() {
+   *     order.push([num, key]);
+   *     done(null, [num]);
+   *   }, num * 10);
+   * };
+   * async.concatSeries(object, iterator, function(err, res) {
+   *   console.log(res); // [1, 3, 2]
+   *   console.log(order); // [[1, 'a'], [3, 'b'], [2, 'c']]
+   * });
+   *
+   */
+  function concatSeries(collection, iterator, callback) {
+    callback = onlyOnce(callback || noop);
+    var size, key, keys, iter, item, iterate;
+    var sync = false;
+    var result = [];
+    var completed = 0;
+
+    if (isArray(collection)) {
+      size = collection.length;
+      iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator;
+    } else if (!collection) {
+    } else if (iteratorSymbol && collection[iteratorSymbol]) {
+      size = Infinity;
+      iter = collection[iteratorSymbol]();
+      iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator;
+    } else if (typeof collection === obj) {
+      keys = nativeKeys(collection);
+      size = keys.length;
+      iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator;
+    }
+    if (!size) {
+      return callback(null, result);
+    }
+    iterate();
+
+    function arrayIterator() {
+      iterator(collection[completed], done);
+    }
+
+    function arrayIteratorWithIndex() {
+      iterator(collection[completed], completed, done);
+    }
+
+    function symbolIterator() {
+      item = iter.next();
+      item.done ? callback(null, result) : iterator(item.value, done);
+    }
+
+    function symbolIteratorWithKey() {
+      item = iter.next();
+      item.done ? callback(null, result) : iterator(item.value, completed, done);
+    }
+
+    function objectIterator() {
+      iterator(collection[keys[completed]], done);
+    }
+
+    function objectIteratorWithKey() {
+      key = keys[completed];
+      iterator(collection[key], key, done);
+    }
+
+    function done(err, array) {
+      if (isArray(array)) {
+        nativePush.apply(result, array);
+      } else if (arguments.length >= 2) {
+        nativePush.apply(result, slice(arguments, 1));
+      }
+      if (err) {
+        callback(err, result);
+      } else if (++completed === size) {
+        iterate = throwError;
+        callback(null, result);
+      } else if (sync) {
+        nextTick(iterate);
+      } else {
+        sync = true;
+        iterate();
+      }
+      sync = false;
+    }
+  }
+
+  /**
+   * @memberof async
+   * @namespace concatLimit
+   * @param {Array|Object} collection
+   * @param {number} limit - limit >= 1
+   * @param {Function} iterator
+   * @param {Function} callback
+   * @example
+   *
+   * // array
+   * var order = [];
+   * var array = [1, 5, 3, 4, 2];
+   * var iterator = function(num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     done(null, [num]);
+   *   }, num * 10);
+   * };
+   * async.concatLimit(array, 2, iterator, function(err, res) {
+   *   console.log(res); // [1, 3, 5, 2, 4]
+   *   console.log(order); // [1, 3, 5, 2, 4]
+   * });
+   *
+   * @example
+   *
+   * // array with index
+   * var order = [];
+   * var array = [1, 5, 3, 4, 2];
+   * var iterator = function(num, index, done) {
+   *   setTimeout(function() {
+   *     order.push([num, index]);
+   *     done(null, [num]);
+   *   }, num * 10);
+   * };
+   * async.cocnatLimit(array, 2, iterator, function(err, res) {
+   *   console.log(res); // [1, 3, 5, 2, 4]
+   *   console.log(order); // [[1, 0], [3, 2], [5, 1], [2, 4], [4, 3]]
+   * });
+   *
+   * @example
+   *
+   * // object
+   * var order = [];
+   * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 };
+   * var iterator = function(num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     done(null, [num]);
+   *   }, num * 10);
+   * };
+   * async.concatLimit(object, 2, iterator, function(err, res) {
+   *   console.log(res); // [1, 3, 5, 2, 4]
+   *   console.log(order); // [1, 3, 5, 2, 4]
+   * });
+   *
+   * @example
+   *
+   * // object with key
+   * var order = [];
+   * var object = { a: 1, b: 5, c: 3, d: 4, e: 2 };
+   * var iterator = function(num, key, done) {
+   *   setTimeout(function() {
+   *     order.push([num, key]);
+   *     done(null, num);
+   *   }, num * 10);
+   * };
+   * async.cocnatLimit(object, 2, iterator, function(err, res) {
+   *   console.log(res); // [1, 3, 5, 2, 4]
+   *   console.log(order); // [[1, 'a'], [3, 'c'], [5, 'b'], [2, 'e'], [4, 'd']]
+   * });
+   *
+   */
+  function concatLimit(collection, limit, iterator, callback) {
+    callback = callback || noop;
+    var size, key, iter, item, iterate, result;
+    var sync = false;
+    var started = 0;
+    var completed = 0;
+
+    if (isArray(collection)) {
+      size = collection.length;
+      iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator;
+    } else if (!collection) {
+    } else if (iteratorSymbol && collection[iteratorSymbol]) {
+      size = Infinity;
+      result = [];
+      iter = collection[iteratorSymbol]();
+      iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator;
+    } else if (typeof collection === obj) {
+      var keys = nativeKeys(collection);
+      size = keys.length;
+      iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator;
+    }
+    if (!size || isNaN(limit) || limit < 1) {
+      return callback(null, []);
+    }
+    result = result || Array(size);
+    timesSync(limit > size ? size : limit, iterate);
+
+    function arrayIterator() {
+      if (started < size) {
+        iterator(collection[started], createCallback(started++));
+      }
+    }
+
+    function arrayIteratorWithIndex() {
+      if (started < size) {
+        iterator(collection[started], started, createCallback(started++));
+      }
+    }
+
+    function symbolIterator() {
+      item = iter.next();
+      if (item.done === false) {
+        iterator(item.value, createCallback(started++));
+      } else if (completed === started && iterator !== noop) {
+        iterator = noop;
+        callback(null, makeConcatResult(result));
+      }
+    }
+
+    function symbolIteratorWithKey() {
+      item = iter.next();
+      if (item.done === false) {
+        iterator(item.value, started, createCallback(started++));
+      } else if (completed === started && iterator !== noop) {
+        iterator = noop;
+        callback(null, makeConcatResult(result));
+      }
+    }
+
+    function objectIterator() {
+      if (started < size) {
+        iterator(collection[keys[started]], createCallback(started++));
+      }
+    }
+
+    function objectIteratorWithKey() {
+      if (started < size) {
+        key = keys[started];
+        iterator(collection[key], key, createCallback(started++));
+      }
+    }
+
+    function createCallback(index) {
+      return function(err, res) {
+        if (index === null) {
+          throwError();
+        }
+        if (err) {
+          index = null;
+          iterate = noop;
+          callback = once(callback);
+          arrayEachSync(result, function(array, index) {
+            if (array === undefined) {
+              result[index] = noop;
+            }
+          });
+          callback(err, makeConcatResult(result));
+          return;
+        }
+        switch (arguments.length) {
+          case 0:
+          case 1:
+            result[index] = noop;
+            break;
+          case 2:
+            result[index] = res;
+            break;
+          default:
+            result[index] = slice(arguments, 1);
+            break;
+        }
+        index = null;
+        if (++completed === size) {
+          iterate = throwError;
+          callback(null, makeConcatResult(result));
+          callback = throwError;
+        } else if (sync) {
+          nextTick(iterate);
+        } else {
+          sync = true;
+          iterate();
+        }
+        sync = false;
+      };
+    }
+  }
+
+  /**
+   * @private
+   * @param {Function} arrayEach
+   * @param {Function} baseEach
+   * @param {Function} symbolEach
+   */
+  function createGroupBy(arrayEach, baseEach, symbolEach) {
+    return function groupBy(collection, iterator, callback) {
+      callback = callback || noop;
+      var size;
+      var completed = 0;
+      var result = {};
+
+      if (isArray(collection)) {
+        size = collection.length;
+        arrayEach(collection, iterator, createCallback);
+      } else if (!collection) {
+      } else if (iteratorSymbol && collection[iteratorSymbol]) {
+        size = symbolEach(collection, iterator, createCallback);
+        size && size === completed && callback(null, result);
+      } else if (typeof collection === obj) {
+        var keys = nativeKeys(collection);
+        size = keys.length;
+        baseEach(collection, iterator, createCallback, keys);
+      }
+      if (!size) {
+        callback(null, {});
+      }
+
+      function createCallback(value) {
+        var called = false;
+        return function done(err, key) {
+          if (called) {
+            throwError();
+          }
+          called = true;
+          if (err) {
+            callback = once(callback);
+            callback(err, objectClone(result));
+            return;
+          }
+          var array = result[key];
+          if (!array) {
+            result[key] = [value];
+          } else {
+            array.push(value);
+          }
+          if (++completed === size) {
+            callback(null, result);
+          }
+        };
+      }
+    };
+  }
+
+  /**
+   * @memberof async
+   * @namespace groupBySeries
+   * @param {Array|Object} collection
+   * @param {Function} iterator
+   * @param {Function} callback
+   * @example
+   *
+   * // array
+   * var order = [];
+   * var array = [4.2, 6.4, 6.1];
+   * var iterator = function(num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     done(null, Math.floor(num));
+   *   }, num * 10);
+   * };
+   * async.groupBySeries(array, iterator, function(err, res) {
+   *   console.log(res); // { '4': [4.2], '6': [6.4, 6.1] }
+   *   console.log(order); // [4.2, 6.4, 6.1]
+   * });
+   *
+   * @example
+   *
+   * // array with index
+   * var order = [];
+   * var array = [4.2, 6.4, 6.1];
+   * var iterator = function(num, index, done) {
+   *   setTimeout(function() {
+   *     order.push([num, index]);
+   *     done(null, Math.floor(num));
+   *   }, num * 10);
+   * };
+   * async.groupBySeries(array, iterator, function(err, res) {
+   *   console.log(res); // { '4': [4.2], '6': [6.4, 6.1] }
+   *   console.log(order); // [[4.2, 0], [6.4, 1], [6.1, 2]]
+   * });
+   *
+   * @example
+   *
+   * // object
+   * var order = [];
+   * var object = { a: 4.2, b: 6.4, c: 6.1 };
+   * var iterator = function(num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     done(null, Math.floor(num));
+   *   }, num * 10);
+   * };
+   * async.groupBySeries(object, iterator, function(err, res) {
+   *   console.log(res); // { '4': [4.2], '6': [6.4, 6.1] }
+   *   console.log(order); // [4.2, 6.4, 6.1]
+   * });
+   *
+   * @example
+   *
+   * // object with key
+   * var order = [];
+   * var object = { a: 4.2, b: 6.4, c: 6.1 };
+   * var iterator = function(num, key, done) {
+   *   setTimeout(function() {
+   *     order.push([num, key]);
+   *     done(null, Math.floor(num));
+   *   }, num * 10);
+   * };
+   * async.groupBySeries(object, iterator, function(err, res) {
+   *   console.log(res); // { '4': [4.2], '6': [6.4, 6.1] }
+   *   console.log(order); // [[4.2, 'a'], [6.4, 'b'], [6.1, 'c']]
+   * });
+   *
+   */
+  function groupBySeries(collection, iterator, callback) {
+    callback = onlyOnce(callback || noop);
+    var size, key, value, keys, iter, item, iterate;
+    var sync = false;
+    var completed = 0;
+    var result = {};
+
+    if (isArray(collection)) {
+      size = collection.length;
+      iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator;
+    } else if (!collection) {
+    } else if (iteratorSymbol && collection[iteratorSymbol]) {
+      size = Infinity;
+      iter = collection[iteratorSymbol]();
+      iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator;
+    } else if (typeof collection === obj) {
+      keys = nativeKeys(collection);
+      size = keys.length;
+      iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator;
+    }
+    if (!size) {
+      return callback(null, result);
+    }
+    iterate();
+
+    function arrayIterator() {
+      value = collection[completed];
+      iterator(value, done);
+    }
+
+    function arrayIteratorWithIndex() {
+      value = collection[completed];
+      iterator(value, completed, done);
+    }
+
+    function symbolIterator() {
+      item = iter.next();
+      value = item.value;
+      item.done ? callback(null, result) : iterator(value, done);
+    }
+
+    function symbolIteratorWithKey() {
+      item = iter.next();
+      value = item.value;
+      item.done ? callback(null, result) : iterator(value, completed, done);
+    }
+
+    function objectIterator() {
+      value = collection[keys[completed]];
+      iterator(value, done);
+    }
+
+    function objectIteratorWithKey() {
+      key = keys[completed];
+      value = collection[key];
+      iterator(value, key, done);
+    }
+
+    function done(err, key) {
+      if (err) {
+        iterate = throwError;
+        callback = onlyOnce(callback);
+        callback(err, objectClone(result));
+        return;
+      }
+      var array = result[key];
+      if (!array) {
+        result[key] = [value];
+      } else {
+        array.push(value);
+      }
+      if (++completed === size) {
+        iterate = throwError;
+        callback(null, result);
+      } else if (sync) {
+        nextTick(iterate);
+      } else {
+        sync = true;
+        iterate();
+      }
+      sync = false;
+    }
+  }
+
+  /**
+   * @memberof async
+   * @namespace groupByLimit
+   * @param {Array|Object} collection
+   * @param {Function} iterator
+   * @param {Function} callback
+   * @example
+   *
+   * // array
+   * var order = [];
+   * var array = [1.1, 5.9, 3.2, 3.9, 2.1];
+   * var iterator = function(num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     done(null, Math.floor(num));
+   *   }, num * 10);
+   * };
+   * async.groupByLimit(array, 2, iterator, function(err, res) {
+   *   console.log(res); // { '1': [1.1], '3': [3.2, 3.9], '5': [5.9], '2': [2.1] }
+   *   console.log(order); // [1.1, 3.2, 5.9, 2.1, 3.9]
+   * });
+   *
+   * @example
+   *
+   * // array with index
+   * var order = [];
+   * var array = [1.1, 5.9, 3.2, 3.9, 2.1];
+   * var iterator = function(num, index, done) {
+   *   setTimeout(function() {
+   *     order.push([num, index]);
+   *     done(null, Math.floor(num));
+   *   }, num * 10);
+   * };
+   * async.groupByLimit(array, 2, iterator, function(err, res) {
+   *   console.log(res); // { '1': [1.1], '3': [3.2, 3.9], '5': [5.9], '2': [2.1] }
+   *   console.log(order); // [[1.1, 0], [3.2, 2], [5.9, 1], [2.1, 4], [3.9, 3]]
+   * });
+   *
+   * @example
+   *
+   * // object
+   * var order = [];
+   * var object = { a: 1.1, b: 5.9, c: 3.2, d: 3.9, e: 2.1 }
+   * var iterator = function(num, done) {
+   *   setTimeout(function() {
+   *     order.push(num);
+   *     done(null, Math.floor(num));
+   *   }, num * 10);
+   * };
+   * async.groupByLimit(object, 2, iterator, function(err, res) {
+   *   console.log(res); // { '1': [1.1], '3': [3.2, 3.9], '5': [5.9], '2': [2.1] }
+   *   console.log(order); // [1.1, 3.2, 5.9, 2.1, 3.9]
+   * });
+   *
+   * @example
+   *
+   * // object with key
+   * var order = [];
+   * var object = { a: 1.1, b: 5.9, c: 3.2, d: 3.9, e: 2.1 }
+   * var iterator = function(num, key, done) {
+   *   setTimeout(function() {
+   *     order.push([num, key]);
+   *     done(null, Math.floor(num));
+   *   }, num * 10);
+   * };
+   * async.groupByLimit(object, 2, iterator, function(err, res) {
+   *   console.log(res); // { '1': [1.1], '3': [3.2, 3.9], '5': [5.9], '2': [2.1] }
+   *   console.log(order); // [[1.1, 'a'], [3.2, 'c'], [5.9, 'b'], [2.1, 'e'], [3.9, 'd']]
+   * });
+   *
+   */
+  function groupByLimit(collection, limit, iterator, callback) {
+    callback = callback || noop;
+    var size, index, key, value, keys, iter, item, iterate;
+    var sync = false;
+    var started = 0;
+    var completed = 0;
+    var result = {};
+
+    if (isArray(collection)) {
+      size = collection.length;
+      iterate = iterator.length === 3 ? arrayIteratorWithIndex : arrayIterator;
+    } else if (!collection) {
+    } else if (iteratorSymbol && collection[iteratorSymbol]) {
+      size = Infinity;
+      iter = collection[iteratorSymbol]();
+      iterate = iterator.length === 3 ? symbolIteratorWithKey : symbolIterator;
+    } else if (typeof collection === obj) {
+      keys = nativeKeys(collection);
+      size = keys.length;
+      iterate = iterator.length === 3 ? objectIteratorWithKey : objectIterator;
+    }
+    if (!size || isNaN(limit) || limit < 1) {
+      return callback(null, result);
+    }
+    timesSync(limit > size ? size : limit, iterate);
+
+    function arrayIterator() {
+      if (started < size) {
+        value = collection[started++];
+        iterator(value, createCallback(value));
+      }
+    }
+
+    function arrayIteratorWithIndex() {
+      index = started++;
+      if (index < size) {
+        value = collection[index];
+        iterator(value, index, createCallback(value));
+      }
+    }
+
+    function symbolIterator() {
+      item = iter.next();
+      if (item.done === false) {
+        started++;
+        value = item.value;
+        iterator(value, createCallback(value));
+      } else if (completed === started && iterator !== noop) {
+        iterator = noop;
+        callback(null, result);
+      }
+    }
+
+    function symbolIteratorWithKey() {
+      item = iter.next();
+      if (item.done === false) {
+        value = item.value;
+        iterator(value, started++, createCallback(value));
+      } else if (completed === started && iterator !== noop) {
+        iterator = noop;
+        callback(null, result);
+      }
+    }
+
+    function objectIterator() {
+      if (started < size) {
+        value = collection[keys[started++]];
+        iterator(value, createCallback(value));
+      }
+    }
+
+    function objectIteratorWithKey() {
+      if (started < size) {
+        key = keys[started++];
+        value = collection[key];
+        iterator(value, key, createCallback(value));
+      }
+    }
+
+    function createCallback(value) {
+      var called = false;
+      return function(err, key) {
+        if (called) {
+          throwError();
+        }
+        called = true;
+        if (err) {
+          iterate = noop;
+          callback = once(callback);
+          callback(err, objectClone(result));
+          return;
+        }
+        var array = result[key];
+        if (!array) {
+          result[key] = [value];
+        } else {
+          array.push(value);
+        }
+        if (++completed === size) {
+          callback(null, result);
+        } else if (sync) {
+          nextTick(iterate);
+        } else {
+          sync = true;
+          iterate();
+        }
+        sync = false;
+      };
+    }
+  }
+
+  /**
+   * @private
+   * @param {Function} arrayEach
+   * @param {Function} baseEach
+   */
+  function createParallel(arrayEach, baseEach) {
+    return function parallel(tasks, callback) {
+      callback = callback || noop;
+      var size, keys, result;
+      var completed = 0;
+
+      if (isArray(tasks)) {
+        size = tasks.length;
+        result = Array(size);
+        arrayEach(tasks, createCallback);
+      } else if (tasks && typeof tasks === obj) {
+        keys = nativeKeys(tasks);
+        size = keys.length;
+        result = {};
+        baseEach(tasks, createCallback, keys);
+      }
+      if (!size) {
+        callback(null, result);
+      }
+
+      function createCallback(key) {
+        return function(err, res) {
+          if (key === null) {
+            throwError();
+          }
+          if (err) {
+            key = null;
+            callback = once(callback);
+            callback(err, result);
+            return;
+          }
+          result[key] = arguments.length <= 2 ? res : slice(arguments, 1);
+          key = null;
+          if (++completed === size) {
+            callback(null, result);
+          }
+        };
+      }
+    };
+  }
+
+  /**
+   * @memberof async
+   * @namespace series
+   * @param {Array|Object} tasks - functions
+   * @param {Function} callback
+   * @example
+   *
+   * var order = [];
+   * var tasks = [
+   *  function(done) {
+   *    setTimeout(function() {
+   *      order.push(1);
+   *      done(null, 1);
+   *    }, 10);
+   *  },
+   *  function(done) {
+   *    setTimeout(function() {
+   *      order.push(2);
+   *      done(null, 2);
+   *    }, 30);
+   *  },
+   *  function(done) {
+   *    setTimeout(function() {
+   *      order.push(3);
+   *      done(null, 3);
+   *    }, 40);
+   *  },
+   *  function(done) {
+   *    setTimeout(function() {
+   *      order.push(4);
+   *      done(null, 4);
+   *    }, 20);
+   *  }
+   * ];
+   * async.series(tasks, function(err, res) {
+   *   console.log(res); // [1, 2, 3, 4];
+   *   console.log(order); // [1, 2, 3, 4]
+   * });
+   *
+   * @example
+   *
+   * var order = [];
+   * var tasks = {
+   *   'a': function(done) {
+   *     setTimeout(function() {
+   *       order.push(1);
+   *       done(null, 1);
+   *     }, 10);
+   *   },
+   *   'b': function(done) {
+   *     setTimeout(function() {
+   *       order.push(2);
+   *       done(null, 2);
+   *     }, 30);
+   *   },
+   *   'c': function(done) {
+   *     setTimeout(function() {
+   *       order.push(3);
+   *       done(null, 3);
+   *     }, 40);
+   *   },
+   *   'd': function(done) {
+   *     setTimeout(function() {
+   *       order.push(4);
+   *       done(null, 4);
+   *     }, 20);
+   *   }
+   * };
+   * async.series(tasks, function(err, res) {
+   *   console.log(res); // { a: 1, b: 2, c: 3, d:4 }
+   *   console.log(order); // [1, 4, 2, 3]
+   * });
+   *
+   */
+  function series(tasks, callback) {
+    callback = callback || noop;
+    var size, key, keys, result, iterate;
+    var sync = false;
+    var completed = 0;
+
+    if (isArray(tasks)) {
+      size = tasks.length;
+      result = Array(size);
+      iterate = arrayIterator;
+    } else if (tasks && typeof tasks === obj) {
+      keys = nativeKeys(tasks);
+      size = keys.length;
+      result = {};
+      iterate = objectIterator;
+    } else {
+      return callback(null);
+    }
+    if (!size) {
+      return callback(null, result);
+    }
+    iterate();
+
+    function arrayIterator() {
+      key = completed;
+      tasks[completed](done);
+    }
+
+    function objectIterator() {
+      key = keys[completed];
+      tasks[key](done);
+    }
+
+    function done(err, res) {
+      if (err) {
+        iterate = throwError;
+        callback = onlyOnce(callback);
+        callback(err, result);
+        return;
+      }
+      result[key] = arguments.length <= 2 ? res : slice(arguments, 1);
+      if (++completed === size) {
+        iterate = throwError;
+        callback(null, result);
+      } else if (sync) {
+        nextTick(iterate);
+      } else {
+        sync = true;
+        iterate();
+      }
+      sync = false;
+    }
+  }
+
+  /**
+   * @memberof async
+   * @namespace parallelLimit
+   * @param {Array|Object} tasks - functions
+   * @param {number} limit - limit >= 1
+   * @param {Function} callback
+   * @example
+   *
+   * var order = [];
+   * var tasks = [
+   *  function(done) {
+   *    setTimeout(function() {
+   *      order.push(1);
+   *      done(null, 1);
+   *    }, 10);
+   *  },
+   *  function(done) {
+   *    setTimeout(function() {
+   *      order.push(2);
+   *      done(null, 2);
+   *    }, 50);
+   *  },
+   *  function(done) {
+   *    setTimeout(function() {
+   *      order.push(3);
+   *      done(null, 3);
+   *    }, 30);
+   *  },
+   *  function(done) {
+   *    setTimeout(function() {
+   *      order.push(4);
+   *      done(null, 4);
+   *    }, 40);
+   *  }
+   * ];
+   * async.parallelLimit(tasks, 2, function(err, res) {
+   *   console.log(res); // [1, 2, 3, 4];
+   *   console.log(order); // [1, 3, 2, 4]
+   * });
+   *
+   * @example
+   *
+   * var order = [];
+   * var tasks = {
+   *   'a': function(done) {
+   *     setTimeout(function() {
+   *       order.push(1);
+   *       done(null, 1);
+   *     }, 10);
+   *   },
+   *   'b': function(done) {
+   *     setTimeout(function() {
+   *       order.push(2);
+   *       done(null, 2);
+   *     }, 50);
+   *   },
+   *   'c': function(done) {
+   *     setTimeout(function() {
+   *       order.push(3);
+   *       done(null, 3);
+   *     }, 20);
+   *   },
+   *   'd': function(done) {
+   *     setTimeout(function() {
+   *       order.push(4);
+   *       done(null, 4);
+   *     }, 40);
+   *   }
+   * };
+   * async.parallelLimit(tasks, 2, function(err, res) {
+   *   console.log(res); // { a: 1, b: 2, c: 3, d:4 }
+   *   console.log(order); // [1, 3, 2, 4]
+   * });
+   *
+   */
+  function parallelLimit(tasks, limit, callback) {
+    callback = callback || noop;
+    var size, index, key, keys, result, iterate;
+    var sync = false;
+    var started = 0;
+    var completed = 0;
+
+    if (isArray(tasks)) {
+      size = tasks.length;
+      result = Array(size);
+      iterate = arrayIterator;
+    } else if (tasks && typeof tasks === obj) {
+      keys = nativeKeys(tasks);
+      size = keys.length;
+      result = {};
+      iterate = objectIterator;
+    }
+    if (!size || isNaN(limit) || limit < 1) {
+      return callback(null, result);
+    }
+    timesSync(limit > size ? size : limit, iterate);
+
+    function arrayIterator() {
+      index = started++;
+      if (index < size) {
+        tasks[index](createCallback(index));
+      }
+    }
+
+    function objectIterator() {
+      if (started < size) {
+        key = keys[started++];
+        tasks[key](createCallback(key));
+      }
+    }
+
+    function createCallback(key) {
+      return function(err, res) {
+        if (key === null) {
+          throwError();
+        }
+        if (err) {
+          key = null;
+          iterate = noop;
+          callback = once(callback);
+          callback(err, result);
+          return;
+        }
+        result[key] = arguments.length <= 2 ? res : slice(arguments, 1);
+        key = null;
+        if (++completed === size) {
+          callback(null, result);
+        } else if (sync) {
+          nextTick(iterate);
+        } else {
+          sync = true;
+          iterate();
+        }
+        sync = false;
+      };
+    }
+  }
+
+  /**
+   * @memberof async
+   * @namespace tryEach
+   * @param {Array|Object} tasks - functions
+   * @param {Function} callback
+   * @example
+   *
+   * var tasks = [
+   *  function(done) {
+   *    setTimeout(function() {
+   *      done(new Error('error'));
+   *    }, 10);
+   *  },
+   *  function(done) {
+   *    setTimeout(function() {
+   *      done(null, 2);
+   *    }, 10);
+   *  }
+   * ];
+   * async.tryEach(tasks, function(err, res) {
+   *   console.log(res); // 2
+   * });
+   *
+   * @example
+   *
+   * var tasks = [
+   *  function(done) {
+   *    setTimeout(function() {
+   *      done(new Error('error1'));
+   *    }, 10);
+   *  },
+   *  function(done) {
+   *    setTimeout(function() {
+   *      done(new Error('error2');
+   *    }, 10);
+   *  }
+   * ];
+   * async.tryEach(tasks, function(err, res) {
+   *   console.log(err); // error2
+   *   console.log(res); // undefined
+   * });
+   *
+   */
+  function tryEach(tasks, callback) {
+    callback = callback || noop;
+    var size, keys, iterate;
+    var sync = false;
+    var completed = 0;
+
+    if (isArray(tasks)) {
+      size = tasks.length;
+      iterate = arrayIterator;
+    } else if (tasks && typeof tasks === obj) {
+      keys = nativeKeys(tasks);
+      size = keys.length;
+      iterate = objectIterator;
+    }
+    if (!size) {
+      return callback(null);
+    }
+    iterate();
+
+    function arrayIterator() {
+      tasks[completed](done);
+    }
+
+    function objectIterator() {
+      tasks[keys[completed]](done);
+    }
+
+    function done(err, res) {
+      if (!err) {
+        if (arguments.length <= 2) {
+          callback(null, res);
+        } else {
+          callback(null, slice(arguments, 1));
+        }
+      } else if (++completed === size) {
+        callback(err);
+      } else {
+        sync = true;
+        iterate();
+      }
+      sync = false;
+    }
+  }
+
+  /**
+   * check for waterfall tasks
+   * @private
+   * @param {Array} tasks
+   * @param {Function} callback
+   * @return {boolean}
+   */
+  function checkWaterfallTasks(tasks, callback) {
+    if (!isArray(tasks)) {
+      callback(new Error('First argument to waterfall must be an array of functions'));
+      return false;
+    }
+    if (tasks.length === 0) {
+      callback(null);
+      return false;
+    }
+    return true;
+  }
+
+  /**
+   * check for waterfall tasks
+   * @private
+   * @param {function} func
+   * @param {Array|Object} args - arguments
+   * @return {function} next
+   */
+  function waterfallIterator(func, args, next) {
+    switch (args.length) {
+      case 0:
+      case 1:
+        return func(next);
+      case 2:
+        return func(args[1], next);
+      case 3:
+        return func(args[1], args[2], next);
+      case 4:
+        return func(args[1], args[2], args[3], next);
+      case 5:
+        return func(args[1], args[2], args[3], args[4], next);
+      case 6:
+        return func(args[1], args[2], args[3], args[4], args[5], next);
+      default:
+        args = slice(args, 1);
+        args.push(next);
+        return func.apply(null, args);
+    }
+  }
+
+  /**
+   * @memberof async
+   * @namespace waterfall
+   * @param {Array} tasks - functions
+   * @param {Function} callback
+   * @example
+   *
+   * var order = [];
+   * var tasks = [
+   *   function(next) {
+   *     setTimeout(function() {
+   *       order.push(1);
+   *       next(null, 1);
+   *     }, 10);
+   *   },
+   *   function(arg1, next) {
+   *     setTimeout(function() {
+   *       order.push(2);
+   *       next(null, 1, 2);
+   *     }, 30);
+   *   },
+   *   function(arg1, arg2, next) {
+   *     setTimeout(function() {
+   *       order.push(3);
+   *       next(null, 3);
+   *     }, 20);
+   *   },
+   *   function(arg1, next) {
+   *     setTimeout(function() {
+   *       order.push(4);
+   *       next(null, 1, 2, 3, 4);
+   *     }, 40);
+   *   }
+   * ];
+   * async.waterfall(tasks, function(err, arg1, arg2, arg3, arg4) {
+   *   console.log(arg1, arg2, arg3, arg4); // 1 2 3 4
+   * });
+   *
+   */
+  function waterfall(tasks, callback) {
+    callback = callback || noop;
+    if (!checkWaterfallTasks(tasks, callback)) {
+      return;
+    }
+    var func, args, done, sync;
+    var completed = 0;
+    var size = tasks.length;
+    waterfallIterator(tasks[0], [], createCallback(0));
+
+    function iterate() {
+      waterfallIterator(func, args, createCallback(func));
+    }
+
+    function createCallback(index) {
+      return function next(err, res) {
+        if (index === undefined) {
+          callback = noop;
+          throwError();
+        }
+        index = undefined;
+        if (err) {
+          done = callback;
+          callback = throwError;
+          done(err);
+          return;
+        }
+        if (++completed === size) {
+          done = callback;
+          callback = throwError;
+          if (arguments.length <= 2) {
+            done(err, res);
+          } else {
+            done.apply(null, createArray(arguments));
+          }
+          return;
+        }
+        if (sync) {
+          args = arguments;
+          func = tasks[completed] || throwError;
+          nextTick(iterate);
+        } else {
+          sync = true;
+          waterfallIterator(tasks[completed] || throwError, arguments, createCallback(completed));
+        }
+        sync = false;
+      };
+    }
+  }
+
+  /**
+   * `angelFall` is like `waterfall` and inject callback to last argument of next task.
+   *
+   * @memberof async
+   * @namespace angelFall
+   * @param {Array} tasks - functions
+   * @param {Function} callback
+   * @example
+   *
+   * var order = [];
+   * var tasks = [
+   *   function(next) {
+   *     setTimeout(function() {
+   *       order.push(1);
+   *       next(null, 1);
+   *     }, 10);
+   *   },
+   *   function(arg1, empty, next) {
+   *     setTimeout(function() {
+   *       order.push(2);
+   *       next(null, 1, 2);
+   *     }, 30);
+   *   },
+   *   function(next) {
+   *     setTimeout(function() {
+   *       order.push(3);
+   *       next(null, 3);
+   *     }, 20);
+   *   },
+   *   function(arg1, empty1, empty2, empty3, next) {
+   *     setTimeout(function() {
+   *       order.push(4);
+   *       next(null, 1, 2, 3, 4);
+   *     }, 40);
+   *   }
+   * ];
+   * async.angelFall(tasks, function(err, arg1, arg2, arg3, arg4) {
+   *   console.log(arg1, arg2, arg3, arg4); // 1 2 3 4
+   * });
+   *
+   */
+  function angelFall(tasks, callback) {
+    callback = callback || noop;
+    if (!checkWaterfallTasks(tasks, callback)) {
+      return;
+    }
+    var completed = 0;
+    var sync = false;
+    var size = tasks.length;
+    var func = tasks[completed];
+    var args = [];
+    var iterate = function() {
+      switch (func.length) {
+        case 0:
+          try {
+            next(null, func());
+          } catch (e) {
+            next(e);
+          }
+          return;
+        case 1:
+          return func(next);
+        case 2:
+          return func(args[1], next);
+        case 3:
+          return func(args[1], args[2], next);
+        case 4:
+          return func(args[1], args[2], args[3], next);
+        case 5:
+          return func(args[1], args[2], args[3], args[4], next);
+        default:
+          args = slice(args, 1);
+          args[func.length - 1] = next;
+          return func.apply(null, args);
+      }
+    };
+    iterate();
+
+    function next(err, res) {
+      if (err) {
+        iterate = throwError;
+        callback = onlyOnce(callback);
+        callback(err);
+        return;
+      }
+      if (++completed === size) {
+        iterate = throwError;
+        var done = callback;
+        callback = throwError;
+        if (arguments.length === 2) {
+          done(err, res);
+        } else {
+          done.apply(null, createArray(arguments));
+        }
+        return;
+      }
+      func = tasks[completed];
+      args = arguments;
+      if (sync) {
+        nextTick(iterate);
+      } else {
+        sync = true;
+        iterate();
+      }
+      sync = false;
+    }
+  }
+
+  /**
+   * @memberof async
+   * @namespace whilst
+   * @param {Function} test
+   * @param {Function} iterator
+   * @param {Function} callback
+   */
+  function whilst(test, iterator, callback) {
+    callback = callback || noop;
+    var sync = false;
+    if (test()) {
+      iterate();
+    } else {
+      callback(null);
+    }
+
+    function iterate() {
+      if (sync) {
+        nextTick(next);
+      } else {
+        sync = true;
+        iterator(done);
+      }
+      sync = false;
+    }
+
+    function next() {
+      iterator(done);
+    }
+
+    function done(err, arg) {
+      if (err) {
+        return callback(err);
+      }
+      if (arguments.length <= 2) {
+        if (test(arg)) {
+          iterate();
+        } else {
+          callback(null, arg);
+        }
+        return;
+      }
+      arg = slice(arguments, 1);
+      if (test.apply(null, arg)) {
+        iterate();
+      } else {
+        callback.apply(null, [null].concat(arg));
+      }
+    }
+  }
+
+  /**
+   * @memberof async
+   * @namespace doWhilst
+   * @param {Function} iterator
+   * @param {Function} test
+   * @param {Function} callback
+   */
+  function doWhilst(iterator, test, callback) {
+    callback = callback || noop;
+    var sync = false;
+    next();
+
+    function iterate() {
+      if (sync) {
+        nextTick(next);
+      } else {
+        sync = true;
+        iterator(done);
+      }
+      sync = false;
+    }
+
+    function next() {
+      iterator(done);
+    }
+
+    function done(err, arg) {
+      if (err) {
+        return callback(err);
+      }
+      if (arguments.length <= 2) {
+        if (test(arg)) {
+          iterate();
+        } else {
+          callback(null, arg);
+        }
+        return;
+      }
+      arg = slice(arguments, 1);
+      if (test.apply(null, arg)) {
+        iterate();
+      } else {
+        callback.apply(null, [null].concat(arg));
+      }
+    }
+  }
+
+  /**
+   * @memberof async
+   * @namespace until
+   * @param {Function} test
+   * @param {Function} iterator
+   * @param {Function} callback
+   */
+  function until(test, iterator, callback) {
+    callback = callback || noop;
+    var sync = false;
+    if (!test()) {
+      iterate();
+    } else {
+      callback(null);
+    }
+
+    function iterate() {
+      if (sync) {
+        nextTick(next);
+      } else {
+        sync = true;
+        iterator(done);
+      }
+      sync = false;
+    }
+
+    function next() {
+      iterator(done);
+    }
+
+    function done(err, arg) {
+      if (err) {
+        return callback(err);
+      }
+      if (arguments.length <= 2) {
+        if (!test(arg)) {
+          iterate();
+        } else {
+          callback(null, arg);
+        }
+        return;
+      }
+      arg = slice(arguments, 1);
+      if (!test.apply(null, arg)) {
+        iterate();
+      } else {
+        callback.apply(null, [null].concat(arg));
+      }
+    }
+  }
+
+  /**
+   * @memberof async
+   * @namespace doUntil
+   * @param {Function} iterator
+   * @param {Function} test
+   * @param {Function} callback
+   */
+  function doUntil(iterator, test, callback) {
+    callback = callback || noop;
+    var sync = false;
+    next();
+
+    function iterate() {
+      if (sync) {
+        nextTick(next);
+      } else {
+        sync = true;
+        iterator(done);
+      }
+      sync = false;
+    }
+
+    function next() {
+      iterator(done);
+    }
+
+    function done(err, arg) {
+      if (err) {
+        return callback(err);
+      }
+      if (arguments.length <= 2) {
+        if (!test(arg)) {
+          iterate();
+        } else {
+          callback(null, arg);
+        }
+        return;
+      }
+      arg = slice(arguments, 1);
+      if (!test.apply(null, arg)) {
+        iterate();
+      } else {
+        callback.apply(null, [null].concat(arg));
+      }
+    }
+  }
+
+  /**
+   * @memberof async
+   * @namespace during
+   * @param {Function} test
+   * @param {Function} iterator
+   * @param {Function} callback
+   */
+  function during(test, iterator, callback) {
+    callback = callback || noop;
+    _test();
+
+    function _test() {
+      test(iterate);
+    }
+
+    function iterate(err, truth) {
+      if (err) {
+        return callback(err);
+      }
+      if (truth) {
+        iterator(done);
+      } else {
+        callback(null);
+      }
+    }
+
+    function done(err) {
+      if (err) {
+        return callback(err);
+      }
+      _test();
+    }
+  }
+
+  /**
+   * @memberof async
+   * @namespace doDuring
+   * @param {Function} test
+   * @param {Function} iterator
+   * @param {Function} callback
+   */
+  function doDuring(iterator, test, callback) {
+    callback = callback || noop;
+    iterate(null, true);
+
+    function iterate(err, truth) {
+      if (err) {
+        return callback(err);
+      }
+      if (truth) {
+        iterator(done);
+      } else {
+        callback(null);
+      }
+    }
+
+    function done(err, res) {
+      if (err) {
+        return callback(err);
+      }
+      switch (arguments.length) {
+        case 0:
+        case 1:
+          test(iterate);
+          break;
+        case 2:
+          test(res, iterate);
+          break;
+        default:
+          var args = slice(arguments, 1);
+          args.push(iterate);
+          test.apply(null, args);
+          break;
+      }
+    }
+  }
+
+  /**
+   * @memberof async
+   * @namespace forever
+   */
+  function forever(iterator, callback) {
+    var sync = false;
+    iterate();
+
+    function iterate() {
+      iterator(next);
+    }
+
+    function next(err) {
+      if (err) {
+        if (callback) {
+          return callback(err);
+        }
+        throw err;
+      }
+      if (sync) {
+        nextTick(iterate);
+      } else {
+        sync = true;
+        iterate();
+      }
+      sync = false;
+    }
+  }
+
+  /**
+   * @memberof async
+   * @namespace compose
+   */
+  function compose() {
+    return seq.apply(null, reverse(arguments));
+  }
+
+  /**
+   * @memberof async
+   * @namespace seq
+   */
+  function seq(/* functions... */) {
+    var fns = createArray(arguments);
+
+    return function() {
+      var self = this;
+      var args = createArray(arguments);
+      var callback = args[args.length - 1];
+      if (typeof callback === func) {
+        args.pop();
+      } else {
+        callback = noop;
+      }
+      reduce(fns, args, iterator, done);
+
+      function iterator(newargs, fn, callback) {
+        var func = function(err) {
+          var nextargs = slice(arguments, 1);
+          callback(err, nextargs);
+        };
+        newargs.push(func);
+        fn.apply(self, newargs);
+      }
+
+      function done(err, res) {
+        res = isArray(res) ? res : [res];
+        res.unshift(err);
+        callback.apply(self, res);
+      }
+    };
+  }
+
+  function createApplyEach(func) {
+    return function applyEach(fns /* arguments */) {
+      var go = function() {
+        var self = this;
+        var args = createArray(arguments);
+        var callback = args.pop() || noop;
+        return func(fns, iterator, callback);
+
+        function iterator(fn, done) {
+          fn.apply(self, args.concat([done]));
+        }
+      };
+      if (arguments.length > 1) {
+        var args = slice(arguments, 1);
+        return go.apply(this, args);
+      } else {
+        return go;
+      }
+    };
+  }
+
+  /**
+   * @see https://github.com/caolan/async/blob/master/lib/internal/DoublyLinkedList.js
+   */
+  function DLL() {
+    this.head = null;
+    this.tail = null;
+    this.length = 0;
+  }
+
+  DLL.prototype._removeLink = function(node) {
+    var prev = node.prev;
+    var next = node.next;
+    if (prev) {
+      prev.next = next;
+    } else {
+      this.head = next;
+    }
+    if (next) {
+      next.prev = prev;
+    } else {
+      this.tail = prev;
+    }
+    node.prev = null;
+    node.next = null;
+    this.length--;
+    return node;
+  };
+
+  DLL.prototype.empty = DLL;
+
+  DLL.prototype._setInitial = function(node) {
+    this.length = 1;
+    this.head = this.tail = node;
+  };
+
+  DLL.prototype.insertBefore = function(node, newNode) {
+    newNode.prev = node.prev;
+    newNode.next = node;
+    if (node.prev) {
+      node.prev.next = newNode;
+    } else {
+      this.head = newNode;
+    }
+    node.prev = newNode;
+    this.length++;
+  };
+
+  DLL.prototype.unshift = function(node) {
+    if (this.head) {
+      this.insertBefore(this.head, node);
+    } else {
+      this._setInitial(node);
+    }
+  };
+
+  DLL.prototype.push = function(node) {
+    var tail = this.tail;
+    if (tail) {
+      node.prev = tail;
+      node.next = tail.next;
+      this.tail = node;
+      tail.next = node;
+      this.length++;
+    } else {
+      this._setInitial(node);
+    }
+  };
+
+  DLL.prototype.shift = function() {
+    return this.head && this._removeLink(this.head);
+  };
+
+  DLL.prototype.splice = function(end) {
+    var task;
+    var tasks = [];
+    while (end-- && (task = this.shift())) {
+      tasks.push(task);
+    }
+    return tasks;
+  };
+
+  DLL.prototype.remove = function(test) {
+    var node = this.head;
+    while (node) {
+      if (test(node)) {
+        this._removeLink(node);
+      }
+      node = node.next;
+    }
+    return this;
+  };
+
+  /**
+   * @private
+   */
+  function baseQueue(isQueue, worker, concurrency, payload) {
+    if (concurrency === undefined) {
+      concurrency = 1;
+    } else if (isNaN(concurrency) || concurrency < 1) {
+      throw new Error('Concurrency must not be zero');
+    }
+
+    var workers = 0;
+    var workersList = [];
+    var _callback, _unshift;
+
+    var q = {
+      _tasks: new DLL(),
+      concurrency: concurrency,
+      payload: payload,
+      saturated: noop,
+      unsaturated: noop,
+      buffer: concurrency / 4,
+      empty: noop,
+      drain: noop,
+      error: noop,
+      started: false,
+      paused: false,
+      push: push,
+      kill: kill,
+      unshift: unshift,
+      remove: remove,
+      process: isQueue ? runQueue : runCargo,
+      length: getLength,
+      running: running,
+      workersList: getWorkersList,
+      idle: idle,
+      pause: pause,
+      resume: resume,
+      _worker: worker
+    };
+    return q;
+
+    function push(tasks, callback) {
+      _insert(tasks, callback);
+    }
+
+    function unshift(tasks, callback) {
+      _insert(tasks, callback, true);
+    }
+
+    function _exec(task) {
+      var item = {
+        data: task,
+        callback: _callback
+      };
+      if (_unshift) {
+        q._tasks.unshift(item);
+      } else {
+        q._tasks.push(item);
+      }
+      nextTick(q.process);
+    }
+
+    function _insert(tasks, callback, unshift) {
+      if (callback == null) {
+        callback = noop;
+      } else if (typeof callback !== 'function') {
+        throw new Error('task callback must be a function');
+      }
+      q.started = true;
+      var _tasks = isArray(tasks) ? tasks : [tasks];
+
+      if (tasks === undefined || !_tasks.length) {
+        if (q.idle()) {
+          nextTick(q.drain);
+        }
+        return;
+      }
+
+      _unshift = unshift;
+      _callback = callback;
+      arrayEachSync(_tasks, _exec);
+      // Avoid leaking the callback
+      _callback = undefined;
+    }
+
+    function kill() {
+      q.drain = noop;
+      q._tasks.empty();
+    }
+
+    function _next(q, tasks) {
+      var called = false;
+      return function done(err, res) {
+        if (called) {
+          throwError();
+        }
+        called = true;
+
+        workers--;
+        var task;
+        var index = -1;
+        var size = workersList.length;
+        var taskIndex = -1;
+        var taskSize = tasks.length;
+        var useApply = arguments.length > 2;
+        var args = useApply && createArray(arguments);
+        while (++taskIndex < taskSize) {
+          task = tasks[taskIndex];
+          while (++index < size) {
+            if (workersList[index] === task) {
+              if (index === 0) {
+                workersList.shift();
+              } else {
+                workersList.splice(index, 1);
+              }
+              index = size;
+              size--;
+            }
+          }
+          index = -1;
+          if (useApply) {
+            task.callback.apply(task, args);
+          } else {
+            task.callback(err, res);
+          }
+          if (err) {
+            q.error(err, task.data);
+          }
+        }
+
+        if (workers <= q.concurrency - q.buffer) {
+          q.unsaturated();
+        }
+
+        if (q._tasks.length + workers === 0) {
+          q.drain();
+        }
+        q.process();
+      };
+    }
+
+    function runQueue() {
+      while (!q.paused && workers < q.concurrency && q._tasks.length) {
+        var task = q._tasks.shift();
+        workers++;
+        workersList.push(task);
+        if (q._tasks.length === 0) {
+          q.empty();
+        }
+        if (workers === q.concurrency) {
+          q.saturated();
+        }
+        var done = _next(q, [task]);
+        worker(task.data, done);
+      }
+    }
+
+    function runCargo() {
+      while (!q.paused && workers < q.concurrency && q._tasks.length) {
+        var tasks = q._tasks.splice(q.payload || q._tasks.length);
+        var index = -1;
+        var size = tasks.length;
+        var data = Array(size);
+        while (++index < size) {
+          data[index] = tasks[index].data;
+        }
+        workers++;
+        nativePush.apply(workersList, tasks);
+        if (q._tasks.length === 0) {
+          q.empty();
+        }
+        if (workers === q.concurrency) {
+          q.saturated();
+        }
+        var done = _next(q, tasks);
+        worker(data, done);
+      }
+    }
+
+    function getLength() {
+      return q._tasks.length;
+    }
+
+    function running() {
+      return workers;
+    }
+
+    function getWorkersList() {
+      return workersList;
+    }
+
+    function idle() {
+      return q.length() + workers === 0;
+    }
+
+    function pause() {
+      q.paused = true;
+    }
+
+    function _resume() {
+      nextTick(q.process);
+    }
+
+    function resume() {
+      if (q.paused === false) {
+        return;
+      }
+      q.paused = false;
+      var count = q.concurrency < q._tasks.length ? q.concurrency : q._tasks.length;
+      timesSync(count, _resume);
+    }
+
+    /**
+     * @param {Function} test
+     */
+    function remove(test) {
+      q._tasks.remove(test);
+    }
+  }
+
+  /**
+   * @memberof async
+   * @namespace queue
+   */
+  function queue(worker, concurrency) {
+    return baseQueue(true, worker, concurrency);
+  }
+
+  /**
+   * @memberof async
+   * @namespace priorityQueue
+   */
+  function priorityQueue(worker, concurrency) {
+    var q = baseQueue(true, worker, concurrency);
+    q.push = push;
+    delete q.unshift;
+    return q;
+
+    function push(tasks, priority, callback) {
+      q.started = true;
+      priority = priority || 0;
+      var _tasks = isArray(tasks) ? tasks : [tasks];
+      var taskSize = _tasks.length;
+
+      if (tasks === undefined || taskSize === 0) {
+        if (q.idle()) {
+          nextTick(q.drain);
+        }
+        return;
+      }
+
+      callback = typeof callback === func ? callback : noop;
+      var nextNode = q._tasks.head;
+      while (nextNode && priority >= nextNode.priority) {
+        nextNode = nextNode.next;
+      }
+      while (taskSize--) {
+        var item = {
+          data: _tasks[taskSize],
+          priority: priority,
+          callback: callback
+        };
+        if (nextNode) {
+          q._tasks.insertBefore(nextNode, item);
+        } else {
+          q._tasks.push(item);
+        }
+        nextTick(q.process);
+      }
+    }
+  }
+
+  /**
+   * @memberof async
+   * @namespace cargo
+   */
+  function cargo(worker, payload) {
+    return baseQueue(false, worker, 1, payload);
+  }
+
+  /**
+   * @memberof async
+   * @namespace auto
+   * @param {Object} tasks
+   * @param {number} [concurrency]
+   * @param {Function} [callback]
+   */
+  function auto(tasks, concurrency, callback) {
+    if (typeof concurrency === func) {
+      callback = concurrency;
+      concurrency = null;
+    }
+    var keys = nativeKeys(tasks);
+    var rest = keys.length;
+    var results = {};
+    if (rest === 0) {
+      return callback(null, results);
+    }
+    var runningTasks = 0;
+    var readyTasks = new DLL();
+    var listeners = Object.create(null);
+    callback = onlyOnce(callback || noop);
+    concurrency = concurrency || rest;
+
+    baseEachSync(tasks, iterator, keys);
+    proceedQueue();
+
+    function iterator(task, key) {
+      // no dependencies
+      var _task, _taskSize;
+      if (!isArray(task)) {
+        _task = task;
+        _taskSize = 0;
+        readyTasks.push([_task, _taskSize, done]);
+        return;
+      }
+      var dependencySize = task.length - 1;
+      _task = task[dependencySize];
+      _taskSize = dependencySize;
+      if (dependencySize === 0) {
+        readyTasks.push([_task, _taskSize, done]);
+        return;
+      }
+      // dependencies
+      var index = -1;
+      while (++index < dependencySize) {
+        var dependencyName = task[index];
+        if (notInclude(keys, dependencyName)) {
+          var msg =
+            'async.auto task `' +
+            key +
+            '` has non-existent dependency `' +
+            dependencyName +
+            '` in ' +
+            task.join(', ');
+          throw new Error(msg);
+        }
+        var taskListeners = listeners[dependencyName];
+        if (!taskListeners) {
+          taskListeners = listeners[dependencyName] = [];
+        }
+        taskListeners.push(taskListener);
+      }
+
+      function done(err, arg) {
+        if (key === null) {
+          throwError();
+        }
+        arg = arguments.length <= 2 ? arg : slice(arguments, 1);
+        if (err) {
+          rest = 0;
+          runningTasks = 0;
+          readyTasks.length = 0;
+          var safeResults = objectClone(results);
+          safeResults[key] = arg;
+          key = null;
+          var _callback = callback;
+          callback = noop;
+          _callback(err, safeResults);
+          return;
+        }
+        runningTasks--;
+        rest--;
+        results[key] = arg;
+        taskComplete(key);
+        key = null;
+      }
+
+      function taskListener() {
+        if (--dependencySize === 0) {
+          readyTasks.push([_task, _taskSize, done]);
+        }
+      }
+    }
+
+    function proceedQueue() {
+      if (readyTasks.length === 0 && runningTasks === 0) {
+        if (rest !== 0) {
+          throw new Error('async.auto task has cyclic dependencies');
+        }
+        return callback(null, results);
+      }
+      while (readyTasks.length && runningTasks < concurrency && callback !== noop) {
+        runningTasks++;
+        var array = readyTasks.shift();
+        if (array[1] === 0) {
+          array[0](array[2]);
+        } else {
+          array[0](results, array[2]);
+        }
+      }
+    }
+
+    function taskComplete(key) {
+      var taskListeners = listeners[key] || [];
+      arrayEachSync(taskListeners, function(task) {
+        task();
+      });
+      proceedQueue();
+    }
+  }
+
+  var FN_ARGS = /^(function)?\s*[^\(]*\(\s*([^\)]*)\)/m;
+  var FN_ARG_SPLIT = /,/;
+  var FN_ARG = /(=.+)?(\s*)$/;
+  var STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/gm;
+
+  /**
+   * parse function arguments for `autoInject`
+   *
+   * @private
+   */
+  function parseParams(func) {
+    func = func.toString().replace(STRIP_COMMENTS, '');
+    func = func.match(FN_ARGS)[2].replace(' ', '');
+    func = func ? func.split(FN_ARG_SPLIT) : [];
+    func = func.map(function(arg) {
+      return arg.replace(FN_ARG, '').trim();
+    });
+    return func;
+  }
+
+  /**
+   * @memberof async
+   * @namespace autoInject
+   * @param {Object} tasks
+   * @param {number} [concurrency]
+   * @param {Function} [callback]
+   */
+  function autoInject(tasks, concurrency, callback) {
+    var newTasks = {};
+    baseEachSync(tasks, iterator, nativeKeys(tasks));
+    auto(newTasks, concurrency, callback);
+
+    function iterator(task, key) {
+      var params;
+      var taskLength = task.length;
+
+      if (isArray(task)) {
+        if (taskLength === 0) {
+          throw new Error('autoInject task functions require explicit parameters.');
+        }
+        params = createArray(task);
+        taskLength = params.length - 1;
+        task = params[taskLength];
+        if (taskLength === 0) {
+          newTasks[key] = task;
+          return;
+        }
+      } else if (taskLength === 1) {
+        newTasks[key] = task;
+        return;
+      } else {
+        params = parseParams(task);
+        if (taskLength === 0 && params.length === 0) {
+          throw new Error('autoInject task functions require explicit parameters.');
+        }
+        taskLength = params.length - 1;
+      }
+      params[taskLength] = newTask;
+      newTasks[key] = params;
+
+      function newTask(results, done) {
+        switch (taskLength) {
+          case 1:
+            task(results[params[0]], done);
+            break;
+          case 2:
+            task(results[params[0]], results[params[1]], done);
+            break;
+          case 3:
+            task(results[params[0]], results[params[1]], results[params[2]], done);
+            break;
+          default:
+            var i = -1;
+            while (++i < taskLength) {
+              params[i] = results[params[i]];
+            }
+            params[i] = done;
+            task.apply(null, params);
+            break;
+        }
+      }
+    }
+  }
+
+  /**
+   * @memberof async
+   * @namespace retry
+   * @param {integer|Object|Function} opts
+   * @param {Function} [task]
+   * @param {Function} [callback]
+   */
+  function retry(opts, task, callback) {
+    var times, intervalFunc, errorFilter;
+    var count = 0;
+    if (arguments.length < 3 && typeof opts === func) {
+      callback = task || noop;
+      task = opts;
+      opts = null;
+      times = DEFAULT_TIMES;
+    } else {
+      callback = callback || noop;
+      switch (typeof opts) {
+        case 'object':
+          if (typeof opts.errorFilter === func) {
+            errorFilter = opts.errorFilter;
+          }
+          var interval = opts.interval;
+          switch (typeof interval) {
+            case func:
+              intervalFunc = interval;
+              break;
+            case 'string':
+            case 'number':
+              interval = +interval;
+              intervalFunc = interval
+                ? function() {
+                    return interval;
+                  }
+                : function() {
+                    return DEFAULT_INTERVAL;
+                  };
+              break;
+          }
+          times = +opts.times || DEFAULT_TIMES;
+          break;
+        case 'number':
+          times = opts || DEFAULT_TIMES;
+          break;
+        case 'string':
+          times = +opts || DEFAULT_TIMES;
+          break;
+        default:
+          throw new Error('Invalid arguments for async.retry');
+      }
+    }
+    if (typeof task !== 'function') {
+      throw new Error('Invalid arguments for async.retry');
+    }
+
+    if (intervalFunc) {
+      task(intervalCallback);
+    } else {
+      task(simpleCallback);
+    }
+
+    function simpleIterator() {
+      task(simpleCallback);
+    }
+
+    function simpleCallback(err, res) {
+      if (++count === times || !err || (errorFilter && !errorFilter(err))) {
+        if (arguments.length <= 2) {
+          return callback(err, res);
+        }
+        var args = createArray(arguments);
+        return callback.apply(null, args);
+      }
+      simpleIterator();
+    }
+
+    function intervalIterator() {
+      task(intervalCallback);
+    }
+
+    function intervalCallback(err, res) {
+      if (++count === times || !err || (errorFilter && !errorFilter(err))) {
+        if (arguments.length <= 2) {
+          return callback(err, res);
+        }
+        var args = createArray(arguments);
+        return callback.apply(null, args);
+      }
+      setTimeout(intervalIterator, intervalFunc(count));
+    }
+  }
+
+  function retryable(opts, task) {
+    if (!task) {
+      task = opts;
+      opts = null;
+    }
+    return done;
+
+    function done() {
+      var taskFn;
+      var args = createArray(arguments);
+      var lastIndex = args.length - 1;
+      var callback = args[lastIndex];
+      switch (task.length) {
+        case 1:
+          taskFn = task1;
+          break;
+        case 2:
+          taskFn = task2;
+          break;
+        case 3:
+          taskFn = task3;
+          break;
+        default:
+          taskFn = task4;
+      }
+      if (opts) {
+        retry(opts, taskFn, callback);
+      } else {
+        retry(taskFn, callback);
+      }
+
+      function task1(done) {
+        task(done);
+      }
+
+      function task2(done) {
+        task(args[0], done);
+      }
+
+      function task3(done) {
+        task(args[0], args[1], done);
+      }
+
+      function task4(callback) {
+        args[lastIndex] = callback;
+        task.apply(null, args);
+      }
+    }
+  }
+
+  /**
+   * @memberof async
+   * @namespace iterator
+   */
+  function iterator(tasks) {
+    var size = 0;
+    var keys = [];
+    if (isArray(tasks)) {
+      size = tasks.length;
+    } else {
+      keys = nativeKeys(tasks);
+      size = keys.length;
+    }
+    return makeCallback(0);
+
+    function makeCallback(index) {
+      var fn = function() {
+        if (size) {
+          var key = keys[index] || index;
+          tasks[key].apply(null, createArray(arguments));
+        }
+        return fn.next();
+      };
+      fn.next = function() {
+        return index < size - 1 ? makeCallback(index + 1) : null;
+      };
+      return fn;
+    }
+  }
+
+  /**
+   * @memberof async
+   * @namespace apply
+   */
+  function apply(func) {
+    switch (arguments.length) {
+      case 0:
+      case 1:
+        return func;
+      case 2:
+        return func.bind(null, arguments[1]);
+      case 3:
+        return func.bind(null, arguments[1], arguments[2]);
+      case 4:
+        return func.bind(null, arguments[1], arguments[2], arguments[3]);
+      case 5:
+        return func.bind(null, arguments[1], arguments[2], arguments[3], arguments[4]);
+      default:
+        var size = arguments.length;
+        var index = 0;
+        var args = Array(size);
+        args[index] = null;
+        while (++index < size) {
+          args[index] = arguments[index];
+        }
+        return func.bind.apply(func, args);
+    }
+  }
+
+  /**
+   * @memberof async
+   * @namespace timeout
+   * @param {Function} func
+   * @param {number} millisec
+   * @param {*} info
+   */
+  function timeout(func, millisec, info) {
+    var callback, timer;
+    return wrappedFunc;
+
+    function wrappedFunc() {
+      timer = setTimeout(timeoutCallback, millisec);
+      var args = createArray(arguments);
+      var lastIndex = args.length - 1;
+      callback = args[lastIndex];
+      args[lastIndex] = injectedCallback;
+      simpleApply(func, args);
+    }
+
+    function timeoutCallback() {
+      var name = func.name || 'anonymous';
+      var err = new Error('Callback function "' + name + '" timed out.');
+      err.code = 'ETIMEDOUT';
+      if (info) {
+        err.info = info;
+      }
+      timer = null;
+      callback(err);
+    }
+
+    function injectedCallback() {
+      if (timer !== null) {
+        simpleApply(callback, createArray(arguments));
+        clearTimeout(timer);
+      }
+    }
+
+    function simpleApply(func, args) {
+      switch (args.length) {
+        case 0:
+          func();
+          break;
+        case 1:
+          func(args[0]);
+          break;
+        case 2:
+          func(args[0], args[1]);
+          break;
+        default:
+          func.apply(null, args);
+          break;
+      }
+    }
+  }
+
+  /**
+   * @memberof async
+   * @namespace times
+   * @param {number} n - n >= 1
+   * @param {Function} iterator
+   * @param {Function} callback
+   * @example
+   *
+   * var iterator = function(n, done) {
+   *   done(null, n);
+   * };
+   * async.times(4, iterator, function(err, res) {
+   *   console.log(res); // [0, 1, 2, 3];
+   * });
+   *
+   */
+  function times(n, iterator, callback) {
+    callback = callback || noop;
+    n = +n;
+    if (isNaN(n) || n < 1) {
+      return callback(null, []);
+    }
+    var result = Array(n);
+    timesSync(n, iterate);
+
+    function iterate(num) {
+      iterator(num, createCallback(num));
+    }
+
+    function createCallback(index) {
+      return function(err, res) {
+        if (index === null) {
+          throwError();
+        }
+        result[index] = res;
+        index = null;
+        if (err) {
+          callback(err);
+          callback = noop;
+        } else if (--n === 0) {
+          callback(null, result);
+        }
+      };
+    }
+  }
+
+  /**
+   * @memberof async
+   * @namespace timesSeries
+   * @param {number} n - n >= 1
+   * @param {Function} iterator
+   * @param {Function} callback
+   * @example
+   *
+   * var iterator = function(n, done) {
+   *   done(null, n);
+   * };
+   * async.timesSeries(4, iterator, function(err, res) {
+   *   console.log(res); // [0, 1, 2, 3];
+   * });
+   *
+   */
+  function timesSeries(n, iterator, callback) {
+    callback = callback || noop;
+    n = +n;
+    if (isNaN(n) || n < 1) {
+      return callback(null, []);
+    }
+    var result = Array(n);
+    var sync = false;
+    var completed = 0;
+    iterate();
+
+    function iterate() {
+      iterator(completed, done);
+    }
+
+    function done(err, res) {
+      result[completed] = res;
+      if (err) {
+        callback(err);
+        callback = throwError;
+      } else if (++completed >= n) {
+        callback(null, result);
+        callback = throwError;
+      } else if (sync) {
+        nextTick(iterate);
+      } else {
+        sync = true;
+        iterate();
+      }
+      sync = false;
+    }
+  }
+
+  /**
+   * @memberof async
+   * @namespace timesLimit
+   * @param {number} n - n >= 1
+   * @param {number} limit - n >= 1
+   * @param {Function} iterator
+   * @param {Function} callback
+   * @example
+   *
+   * var iterator = function(n, done) {
+   *   done(null, n);
+   * };
+   * async.timesLimit(4, 2, iterator, function(err, res) {
+   *   console.log(res); // [0, 1, 2, 3];
+   * });
+   *
+   */
+  function timesLimit(n, limit, iterator, callback) {
+    callback = callback || noop;
+    n = +n;
+    if (isNaN(n) || n < 1 || isNaN(limit) || limit < 1) {
+      return callback(null, []);
+    }
+    var result = Array(n);
+    var sync = false;
+    var started = 0;
+    var completed = 0;
+    timesSync(limit > n ? n : limit, iterate);
+
+    function iterate() {
+      var index = started++;
+      if (index < n) {
+        iterator(index, createCallback(index));
+      }
+    }
+
+    function createCallback(index) {
+      return function(err, res) {
+        if (index === null) {
+          throwError();
+        }
+        result[index] = res;
+        index = null;
+        if (err) {
+          callback(err);
+          callback = noop;
+        } else if (++completed >= n) {
+          callback(null, result);
+          callback = throwError;
+        } else if (sync) {
+          nextTick(iterate);
+        } else {
+          sync = true;
+          iterate();
+        }
+        sync = false;
+      };
+    }
+  }
+
+  /**
+   * @memberof async
+   * @namespace race
+   * @param {Array|Object} tasks - functions
+   * @param {Function} callback
+   * @example
+   *
+   * // array
+   * var called = 0;
+   * var tasks = [
+   *   function(done) {
+   *     setTimeout(function() {
+   *       called++;
+   *       done(null, '1');
+   *     }, 30);
+   *   },
+   *   function(done) {
+   *     setTimeout(function() {
+   *       called++;
+   *       done(null, '2');
+   *     }, 20);
+   *   },
+   *   function(done) {
+   *     setTimeout(function() {
+   *       called++;
+   *       done(null, '3');
+   *     }, 10);
+   *   }
+   * ];
+   * async.race(tasks, function(err, res) {
+   *   console.log(res); // '3'
+   *   console.log(called); // 1
+   *   setTimeout(function() {
+   *     console.log(called); // 3
+   *   }, 50);
+   * });
+   *
+   * @example
+   *
+   * // object
+   * var called = 0;
+   * var tasks = {
+   *   'test1': function(done) {
+   *     setTimeout(function() {
+   *       called++;
+   *       done(null, '1');
+   *     }, 30);
+   *   },
+   *   'test2': function(done) {
+   *     setTimeout(function() {
+   *       called++;
+   *       done(null, '2');
+   *     }, 20);
+   *   },
+   *   'test3': function(done) {
+   *     setTimeout(function() {
+   *       called++;
+   *       done(null, '3');
+   *     }, 10);
+   *   }
+   * };
+   * async.race(tasks, function(err, res) {
+   *   console.log(res); // '3'
+   *   console.log(called); // 1
+   *   setTimeout(function() {
+   *     console.log(called); // 3
+   *     done();
+   *   }, 50);
+   * });
+   *
+   */
+  function race(tasks, callback) {
+    callback = once(callback || noop);
+    var size, keys;
+    var index = -1;
+    if (isArray(tasks)) {
+      size = tasks.length;
+      while (++index < size) {
+        tasks[index](callback);
+      }
+    } else if (tasks && typeof tasks === obj) {
+      keys = nativeKeys(tasks);
+      size = keys.length;
+      while (++index < size) {
+        tasks[keys[index]](callback);
+      }
+    } else {
+      return callback(new TypeError('First argument to race must be a collection of functions'));
+    }
+    if (!size) {
+      callback(null);
+    }
+  }
+
+  /**
+   * @memberof async
+   * @namespace memoize
+   */
+  function memoize(fn, hasher) {
+    hasher =
+      hasher ||
+      function(hash) {
+        return hash;
+      };
+
+    var memo = {};
+    var queues = {};
+    var memoized = function() {
+      var args = createArray(arguments);
+      var callback = args.pop();
+      var key = hasher.apply(null, args);
+      if (has(memo, key)) {
+        nextTick(function() {
+          callback.apply(null, memo[key]);
+        });
+        return;
+      }
+      if (has(queues, key)) {
+        return queues[key].push(callback);
+      }
+
+      queues[key] = [callback];
+      args.push(done);
+      fn.apply(null, args);
+
+      function done(err) {
+        var args = createArray(arguments);
+        if (!err) {
+          memo[key] = args;
+        }
+        var q = queues[key];
+        delete queues[key];
+
+        var i = -1;
+        var size = q.length;
+        while (++i < size) {
+          q[i].apply(null, args);
+        }
+      }
+    };
+    memoized.memo = memo;
+    memoized.unmemoized = fn;
+    return memoized;
+  }
+
+  /**
+   * @memberof async
+   * @namespace unmemoize
+   */
+  function unmemoize(fn) {
+    return function() {
+      return (fn.unmemoized || fn).apply(null, arguments);
+    };
+  }
+
+  /**
+   * @memberof async
+   * @namespace ensureAsync
+   */
+  function ensureAsync(fn) {
+    return function(/* ...args, callback */) {
+      var args = createArray(arguments);
+      var lastIndex = args.length - 1;
+      var callback = args[lastIndex];
+      var sync = true;
+      args[lastIndex] = done;
+      fn.apply(this, args);
+      sync = false;
+
+      function done() {
+        var innerArgs = createArray(arguments);
+        if (sync) {
+          nextTick(function() {
+            callback.apply(null, innerArgs);
+          });
+        } else {
+          callback.apply(null, innerArgs);
+        }
+      }
+    };
+  }
+
+  /**
+   * @memberof async
+   * @namespace constant
+   */
+  function constant(/* values... */) {
+    var args = [null].concat(createArray(arguments));
+    return function(callback) {
+      callback = arguments[arguments.length - 1];
+      callback.apply(this, args);
+    };
+  }
+
+  function asyncify(fn) {
+    return function(/* args..., callback */) {
+      var args = createArray(arguments);
+      var callback = args.pop();
+      var result;
+      try {
+        result = fn.apply(this, args);
+      } catch (e) {
+        return callback(e);
+      }
+      if (result && typeof result.then === func) {
+        result.then(
+          function(value) {
+            invokeCallback(callback, null, value);
+          },
+          function(err) {
+            invokeCallback(callback, err && err.message ? err : new Error(err));
+          }
+        );
+      } else {
+        callback(null, result);
+      }
+    };
+  }
+
+  function invokeCallback(callback, err, value) {
+    try {
+      callback(err, value);
+    } catch (e) {
+      nextTick(rethrow, e);
+    }
+  }
+
+  function rethrow(error) {
+    throw error;
+  }
+
+  /**
+   * @memberof async
+   * @namespace reflect
+   * @param {Function} func
+   * @return {Function}
+   */
+  function reflect(func) {
+    return function(/* args..., callback */) {
+      var callback;
+      switch (arguments.length) {
+        case 1:
+          callback = arguments[0];
+          return func(done);
+        case 2:
+          callback = arguments[1];
+          return func(arguments[0], done);
+        default:
+          var args = createArray(arguments);
+          var lastIndex = args.length - 1;
+          callback = args[lastIndex];
+          args[lastIndex] = done;
+          func.apply(this, args);
+      }
+
+      function done(err, res) {
+        if (err) {
+          return callback(null, {
+            error: err
+          });
+        }
+        if (arguments.length > 2) {
+          res = slice(arguments, 1);
+        }
+        callback(null, {
+          value: res
+        });
+      }
+    };
+  }
+
+  /**
+   * @memberof async
+   * @namespace reflectAll
+   * @param {Array[]|Object} tasks
+   * @return {Function}
+   */
+  function reflectAll(tasks) {
+    var newTasks, keys;
+    if (isArray(tasks)) {
+      newTasks = Array(tasks.length);
+      arrayEachSync(tasks, iterate);
+    } else if (tasks && typeof tasks === obj) {
+      keys = nativeKeys(tasks);
+      newTasks = {};
+      baseEachSync(tasks, iterate, keys);
+    }
+    return newTasks;
+
+    function iterate(func, key) {
+      newTasks[key] = reflect(func);
+    }
+  }
+
+  /**
+   * @memberof async
+   * @namespace createLogger
+   */
+  function createLogger(name) {
+    return function(fn) {
+      var args = slice(arguments, 1);
+      args.push(done);
+      fn.apply(null, args);
+    };
+
+    function done(err) {
+      if (typeof console === obj) {
+        if (err) {
+          if (console.error) {
+            console.error(err);
+          }
+          return;
+        }
+        if (console[name]) {
+          var args = slice(arguments, 1);
+          arrayEachSync(args, function(arg) {
+            console[name](arg);
+          });
+        }
+      }
+    }
+  }
+
+  /**
+   * @memberof async
+   * @namespace safe
+   */
+  function safe() {
+    createImmediate();
+    return exports;
+  }
+
+  /**
+   * @memberof async
+   * @namespace fast
+   */
+  function fast() {
+    createImmediate(false);
+    return exports;
+  }
+});
Index: frontend/node_modules/neo-async/async.min.js
===================================================================
--- frontend/node_modules/neo-async/async.min.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/async.min.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,80 @@
+(function(N,O){"object"===typeof exports&&"undefined"!==typeof module?O(exports):"function"===typeof define&&define.amd?define(["exports"],O):N.async?O(N.neo_async=N.neo_async||{}):O(N.async=N.async||{})})(this,function(N){function O(a){var c=function(a){var d=J(arguments,1);setTimeout(function(){a.apply(null,d)})};T="function"===typeof setImmediate?setImmediate:c;"object"===typeof process&&"function"===typeof process.nextTick?(D=/^v0.10/.test(process.version)?T:process.nextTick,ba=/^v0/.test(process.version)?
+T:process.nextTick):ba=D=T;!1===a&&(D=function(a){a()})}function H(a){for(var c=-1,b=a.length,d=Array(b);++c<b;)d[c]=a[c];return d}function J(a,c){var b=-1,d=a.length-c;if(0>=d)return[];for(var e=Array(d);++b<d;)e[b]=a[b+c];return e}function L(a){for(var c=F(a),b=c.length,d=-1,e={};++d<b;){var f=c[d];e[f]=a[f]}return e}function U(a){for(var c=-1,b=a.length,d=[];++c<b;){var e=a[c];e&&(d[d.length]=e)}return d}function Za(a){for(var c=-1,b=a.length,d=Array(b),e=b;++c<b;)d[--e]=a[c];return d}function $a(a,
+c){for(var b=-1,d=a.length;++b<d;)if(a[b]===c)return!1;return!0}function Q(a,c){for(var b=-1,d=a.length;++b<d;)c(a[b],b);return a}function W(a,c,b){for(var d=-1,e=b.length;++d<e;){var f=b[d];c(a[f],f)}return a}function K(a,c){for(var b=-1;++b<a;)c(b)}function P(a,c){var b=a.length,d=Array(b),e;for(e=0;e<b;e++)d[e]=e;ca(c,0,b-1,d);for(var f=Array(b),g=0;g<b;g++)e=d[g],f[g]=void 0===e?a[g]:a[e];return f}function ca(a,c,b,d){if(c!==b){for(var e=c;++e<=b&&a[c]===a[e];){var f=e-1;if(d[f]>d[e]){var g=d[f];
+d[f]=d[e];d[e]=g}}if(!(e>b)){for(var l,e=a[a[c]>a[e]?c:e],f=c,g=b;f<=g;){for(l=f;f<g&&a[f]<e;)f++;for(;g>=l&&a[g]>=e;)g--;if(f>g)break;var q=a;l=d;var s=f++,h=g--,k=q[s];q[s]=q[h];q[h]=k;q=l[s];l[s]=l[h];l[h]=q}e=f;ca(a,c,e-1,d);ca(a,e,b,d)}}}function S(a){var c=[];Q(a,function(a){a!==w&&(C(a)?X.apply(c,a):c.push(a))});return c}function da(a,c,b){var d=-1,e=a.length;if(3===c.length)for(;++d<e;)c(a[d],d,b(d));else for(;++d<e;)c(a[d],b(d))}function ra(a,c,b,d){var e,f=-1,g=d.length;if(3===c.length)for(;++f<
+g;)e=d[f],c(a[e],e,b(f));else for(;++f<g;)c(a[d[f]],b(f))}function sa(a,c,b){var d=0,e=a[z]();if(3===c.length)for(;!1===(a=e.next()).done;)c(a.value,d,b(d++));else for(;!1===(a=e.next()).done;)c(a.value,b(d++));return d}function ea(a,c,b){var d,e=-1,f=a.length;if(3===c.length)for(;++e<f;)d=a[e],c(d,e,b(d));else for(;++e<f;)d=a[e],c(d,b(d))}function fa(a,c,b,d){var e,f,g=-1,l=d.length;if(3===c.length)for(;++g<l;)e=d[g],f=a[e],c(f,e,b(f));else for(;++g<l;)f=a[d[g]],c(f,b(f))}function ga(a,c,b){var d,
+e=0;a=a[z]();if(3===c.length)for(;!1===(d=a.next()).done;)d=d.value,c(d,e++,b(d));else for(;!1===(d=a.next()).done;)e++,d=d.value,c(d,b(d));return e}function V(a,c,b){var d,e=-1,f=a.length;if(3===c.length)for(;++e<f;)d=a[e],c(d,e,b(e,d));else for(;++e<f;)d=a[e],c(d,b(e,d))}function ha(a,c,b,d){var e,f,g=-1,l=d.length;if(3===c.length)for(;++g<l;)e=d[g],f=a[e],c(f,e,b(g,f));else for(;++g<l;)f=a[d[g]],c(f,b(g,f))}function ia(a,c,b){var d,e=0;a=a[z]();if(3===c.length)for(;!1===(d=a.next()).done;)d=d.value,
+c(d,e,b(e++,d));else for(;!1===(d=a.next()).done;)d=d.value,c(d,b(e++,d));return e}function ta(a,c,b,d){var e,f,g=-1,l=d.length;if(3===c.length)for(;++g<l;)e=d[g],f=a[e],c(f,e,b(e,f));else for(;++g<l;)e=d[g],f=a[e],c(f,b(e,f))}function ua(a,c,b){var d,e=0;a=a[z]();if(3===c.length)for(;!1===(d=a.next()).done;)d=d.value,c(d,e,b(e++,d));else for(;!1===(d=a.next()).done;)d=d.value,c(d,b(e++,d));return e}function E(a){return function(c,b){var d=a;a=A;d(c,b)}}function I(a){return function(c,b){var d=a;
+a=w;d(c,b)}}function va(a,c,b,d){var e,f;d?(e=Array,f=H):(e=function(){return{}},f=L);return function(d,l,q){function s(a){return function(b,d){null===a&&A();b?(a=null,q=I(q),q(b,f(m))):(m[a]=d,a=null,++r===h&&q(null,m))}}q=q||w;var h,k,m,r=0;C(d)?(h=d.length,m=e(h),a(d,l,s)):d&&(z&&d[z]?(m=e(0),(h=b(d,l,s))&&h===r&&q(null,m)):"object"===typeof d&&(k=F(d),h=k.length,m=e(h),c(d,l,s,k)));h||q(null,e())}}function wa(a,c,b,d){return function(e,f,g){function l(a,b){return function(c,e){null===a&&A();c?
+(a=null,g=I(g),g(c)):(!!e===d&&(h[a]=b),a=null,++k===q&&g(null,U(h)))}}g=g||w;var q,s,h,k=0;C(e)?(q=e.length,h=Array(q),a(e,f,l)):e&&(z&&e[z]?(h=[],(q=b(e,f,l))&&q===k&&g(null,U(h))):"object"===typeof e&&(s=F(e),q=s.length,h=Array(q),c(e,f,l,s)));if(!q)return g(null,[])}}function xa(a){return function(c,b,d){function e(){r=c[x];b(r,h)}function f(){r=c[x];b(r,x,h)}function g(){u=p.next();r=u.value;u.done?d(null,y):b(r,h)}function l(){u=p.next();r=u.value;u.done?d(null,y):b(r,x,h)}function q(){m=n[x];
+r=c[m];b(r,h)}function s(){m=n[x];r=c[m];b(r,m,h)}function h(b,c){b?d(b):(!!c===a&&(y[y.length]=r),++x===k?(v=A,d(null,y)):t?D(v):(t=!0,v()),t=!1)}d=E(d||w);var k,m,r,n,p,u,v,t=!1,x=0,y=[];C(c)?(k=c.length,v=3===b.length?f:e):c&&(z&&c[z]?(k=Infinity,p=c[z](),v=3===b.length?l:g):"object"===typeof c&&(n=F(c),k=n.length,v=3===b.length?s:q));if(!k)return d(null,[]);v()}}function ya(a){return function(c,b,d,e){function f(){r=B++;r<m&&(p=c[r],d(p,k(p,r)))}function g(){r=B++;r<m&&(p=c[r],d(p,r,k(p,r)))}
+function l(){t=v.next();!1===t.done?(p=t.value,d(p,k(p,B++))):R===B&&d!==w&&(d=w,e(null,U(y)))}function q(){t=v.next();!1===t.done?(p=t.value,d(p,B,k(p,B++))):R===B&&d!==w&&(d=w,e(null,U(y)))}function s(){r=B++;r<m&&(p=c[u[r]],d(p,k(p,r)))}function h(){r=B++;r<m&&(n=u[r],p=c[n],d(p,n,k(p,r)))}function k(b,d){return function(c,f){null===d&&A();c?(d=null,x=w,e=I(e),e(c)):(!!f===a&&(y[d]=b),d=null,++R===m?(e=E(e),e(null,U(y))):G?D(x):(G=!0,x()),G=!1)}}e=e||w;var m,r,n,p,u,v,t,x,y,G=!1,B=0,R=0;C(c)?(m=
+c.length,x=3===d.length?g:f):c&&(z&&c[z]?(m=Infinity,y=[],v=c[z](),x=3===d.length?q:l):"object"===typeof c&&(u=F(c),m=u.length,x=3===d.length?h:s));if(!m||isNaN(b)||1>b)return e(null,[]);y=y||Array(m);K(b>m?m:b,x)}}function Y(a,c,b){function d(){c(a[v],s)}function e(){c(a[v],v,s)}function f(){n=r.next();n.done?b(null):c(n.value,s)}function g(){n=r.next();n.done?b(null):c(n.value,v,s)}function l(){c(a[m[v]],s)}function q(){k=m[v];c(a[k],k,s)}function s(a,d){a?b(a):++v===h||!1===d?(p=A,b(null)):u?D(p):
+(u=!0,p());u=!1}b=E(b||w);var h,k,m,r,n,p,u=!1,v=0;C(a)?(h=a.length,p=3===c.length?e:d):a&&(z&&a[z]?(h=Infinity,r=a[z](),p=3===c.length?g:f):"object"===typeof a&&(m=F(a),h=m.length,p=3===c.length?q:l));if(!h)return b(null);p()}function Z(a,c,b,d){function e(){x<k&&b(a[x++],h)}function f(){m=x++;m<k&&b(a[m],m,h)}function g(){u=p.next();!1===u.done?(x++,b(u.value,h)):y===x&&b!==w&&(b=w,d(null))}function l(){u=p.next();!1===u.done?b(u.value,x++,h):y===x&&b!==w&&(b=w,d(null))}function q(){x<k&&b(a[n[x++]],
+h)}function s(){m=x++;m<k&&(r=n[m],b(a[r],r,h))}function h(a,c){a||!1===c?(v=w,d=I(d),d(a)):++y===k?(b=w,v=A,d=E(d),d(null)):t?D(v):(t=!0,v());t=!1}d=d||w;var k,m,r,n,p,u,v,t=!1,x=0,y=0;if(C(a))k=a.length,v=3===b.length?f:e;else if(a)if(z&&a[z])k=Infinity,p=a[z](),v=3===b.length?l:g;else if("object"===typeof a)n=F(a),k=n.length,v=3===b.length?s:q;else return d(null);if(!k||isNaN(c)||1>c)return d(null);K(c>k?k:c,v)}function za(a,c,b){function d(){c(a[t],s)}function e(){c(a[t],t,s)}function f(){n=r.next();
+n.done?b(null,p):c(n.value,s)}function g(){n=r.next();n.done?b(null,p):c(n.value,t,s)}function l(){c(a[m[t]],s)}function q(){k=m[t];c(a[k],k,s)}function s(a,d){a?(u=A,b=E(b),b(a,H(p))):(p[t]=d,++t===h?(u=A,b(null,p),b=A):v?D(u):(v=!0,u()),v=!1)}b=b||w;var h,k,m,r,n,p,u,v=!1,t=0;C(a)?(h=a.length,u=3===c.length?e:d):a&&(z&&a[z]?(h=Infinity,p=[],r=a[z](),u=3===c.length?g:f):"object"===typeof a&&(m=F(a),h=m.length,u=3===c.length?q:l));if(!h)return b(null,[]);p=p||Array(h);u()}function Aa(a,c,b,d){return function(e,
+f,g){function l(a){var b=!1;return function(c,e){b&&A();b=!0;c?(g=I(g),g(c)):!!e===d?(g=I(g),g(null,a)):++h===q&&g(null)}}g=g||w;var q,s,h=0;C(e)?(q=e.length,a(e,f,l)):e&&(z&&e[z]?(q=b(e,f,l))&&q===h&&g(null):"object"===typeof e&&(s=F(e),q=s.length,c(e,f,l,s)));q||g(null)}}function Ba(a){return function(c,b,d){function e(){r=c[x];b(r,h)}function f(){r=c[x];b(r,x,h)}function g(){u=p.next();r=u.value;u.done?d(null):b(r,h)}function l(){u=p.next();r=u.value;u.done?d(null):b(r,x,h)}function q(){r=c[n[x]];
+b(r,h)}function s(){m=n[x];r=c[m];b(r,m,h)}function h(b,c){b?d(b):!!c===a?(v=A,d(null,r)):++x===k?(v=A,d(null)):t?D(v):(t=!0,v());t=!1}d=E(d||w);var k,m,r,n,p,u,v,t=!1,x=0;C(c)?(k=c.length,v=3===b.length?f:e):c&&(z&&c[z]?(k=Infinity,p=c[z](),v=3===b.length?l:g):"object"===typeof c&&(n=F(c),k=n.length,v=3===b.length?s:q));if(!k)return d(null);v()}}function Ca(a){return function(c,b,d,e){function f(){r=G++;r<m&&(p=c[r],d(p,k(p)))}function g(){r=G++;r<m&&(p=c[r],d(p,r,k(p)))}function l(){t=v.next();
+!1===t.done?(G++,p=t.value,d(p,k(p))):B===G&&d!==w&&(d=w,e(null))}function q(){t=v.next();!1===t.done?(p=t.value,d(p,G++,k(p))):B===G&&d!==w&&(d=w,e(null))}function s(){r=G++;r<m&&(p=c[u[r]],d(p,k(p)))}function h(){G<m&&(n=u[G++],p=c[n],d(p,n,k(p)))}function k(b){var d=!1;return function(c,f){d&&A();d=!0;c?(x=w,e=I(e),e(c)):!!f===a?(x=w,e=I(e),e(null,b)):++B===m?e(null):y?D(x):(y=!0,x());y=!1}}e=e||w;var m,r,n,p,u,v,t,x,y=!1,G=0,B=0;C(c)?(m=c.length,x=3===d.length?g:f):c&&(z&&c[z]?(m=Infinity,v=c[z](),
+x=3===d.length?q:l):"object"===typeof c&&(u=F(c),m=u.length,x=3===d.length?h:s));if(!m||isNaN(b)||1>b)return e(null);K(b>m?m:b,x)}}function Da(a,c,b,d){return function(e,f,g){function l(a,b){return function(c,e){null===a&&A();c?(a=null,g=I(g),g(c,L(k))):(!!e===d&&(k[a]=b),a=null,++h===q&&g(null,k))}}g=g||w;var q,s,h=0,k={};C(e)?(q=e.length,a(e,f,l)):e&&(z&&e[z]?(q=b(e,f,l))&&q===h&&g(null,k):"object"===typeof e&&(s=F(e),q=s.length,c(e,f,l,s)));if(!q)return g(null,{})}}function Ea(a){return function(c,
+b,d){function e(){m=y;r=c[y];b(r,h)}function f(){m=y;r=c[y];b(r,y,h)}function g(){m=y;u=p.next();r=u.value;u.done?d(null,x):b(r,h)}function l(){m=y;u=p.next();r=u.value;u.done?d(null,x):b(r,m,h)}function q(){m=n[y];r=c[m];b(r,h)}function s(){m=n[y];r=c[m];b(r,m,h)}function h(b,c){b?d(b,x):(!!c===a&&(x[m]=r),++y===k?(v=A,d(null,x)):t?D(v):(t=!0,v()),t=!1)}d=E(d||w);var k,m,r,n,p,u,v,t=!1,x={},y=0;C(c)?(k=c.length,v=3===b.length?f:e):c&&(z&&c[z]?(k=Infinity,p=c[z](),v=3===b.length?l:g):"object"===typeof c&&
+(n=F(c),k=n.length,v=3===b.length?s:q));if(!k)return d(null,{});v()}}function Fa(a){return function(c,b,d,e){function f(){r=B++;r<m&&(p=c[r],d(p,k(p,r)))}function g(){r=B++;r<m&&(p=c[r],d(p,r,k(p,r)))}function l(){t=v.next();!1===t.done?(p=t.value,d(p,k(p,B++))):R===B&&d!==w&&(d=w,e(null,G))}function q(){t=v.next();!1===t.done?(p=t.value,d(p,B,k(p,B++))):R===B&&d!==w&&(d=w,e(null,G))}function s(){B<m&&(n=u[B++],p=c[n],d(p,k(p,n)))}function h(){B<m&&(n=u[B++],p=c[n],d(p,n,k(p,n)))}function k(b,d){return function(c,
+f){null===d&&A();c?(d=null,x=w,e=I(e),e(c,L(G))):(!!f===a&&(G[d]=b),d=null,++R===m?(x=A,e=E(e),e(null,G)):y?D(x):(y=!0,x()),y=!1)}}e=e||w;var m,r,n,p,u,v,t,x,y=!1,G={},B=0,R=0;C(c)?(m=c.length,x=3===d.length?g:f):c&&(z&&c[z]?(m=Infinity,v=c[z](),x=3===d.length?q:l):"object"===typeof c&&(u=F(c),m=u.length,x=3===d.length?h:s));if(!m||isNaN(b)||1>b)return e(null,{});K(b>m?m:b,x)}}function $(a,c,b,d){function e(d){b(d,a[t],h)}function f(d){b(d,a[t],t,h)}function g(a){p=n.next();p.done?d(null,a):b(a,p.value,
+h)}function l(a){p=n.next();p.done?d(null,a):b(a,p.value,t,h)}function q(d){b(d,a[r[t]],h)}function s(d){m=r[t];b(d,a[m],m,h)}function h(a,c){a?d(a,c):++t===k?(b=A,d(null,c)):v?D(function(){u(c)}):(v=!0,u(c));v=!1}d=E(d||w);var k,m,r,n,p,u,v=!1,t=0;C(a)?(k=a.length,u=4===b.length?f:e):a&&(z&&a[z]?(k=Infinity,n=a[z](),u=4===b.length?l:g):"object"===typeof a&&(r=F(a),k=r.length,u=4===b.length?s:q));if(!k)return d(null,c);u(c)}function Ga(a,c,b,d){function e(d){b(d,a[--s],q)}function f(d){b(d,a[--s],
+s,q)}function g(d){b(d,a[m[--s]],q)}function l(d){k=m[--s];b(d,a[k],k,q)}function q(a,b){a?d(a,b):0===s?(u=A,d(null,b)):v?D(function(){u(b)}):(v=!0,u(b));v=!1}d=E(d||w);var s,h,k,m,r,n,p,u,v=!1;if(C(a))s=a.length,u=4===b.length?f:e;else if(a)if(z&&a[z]){p=[];r=a[z]();for(h=-1;!1===(n=r.next()).done;)p[++h]=n.value;a=p;s=p.length;u=4===b.length?f:e}else"object"===typeof a&&(m=F(a),s=m.length,u=4===b.length?l:g);if(!s)return d(null,c);u(c)}function Ha(a,c,b){b=b||w;ja(a,c,function(a,c){if(a)return b(a);
+b(null,!!c)})}function Ia(a,c,b){b=b||w;ka(a,c,function(a,c){if(a)return b(a);b(null,!!c)})}function Ja(a,c,b,d){d=d||w;la(a,c,b,function(a,b){if(a)return d(a);d(null,!!b)})}function Ka(a,c){return C(a)?0===a.length?(c(null),!1):!0:(c(Error("First argument to waterfall must be an array of functions")),!1)}function ma(a,c,b){switch(c.length){case 0:case 1:return a(b);case 2:return a(c[1],b);case 3:return a(c[1],c[2],b);case 4:return a(c[1],c[2],c[3],b);case 5:return a(c[1],c[2],c[3],c[4],b);case 6:return a(c[1],
+c[2],c[3],c[4],c[5],b);default:return c=J(c,1),c.push(b),a.apply(null,c)}}function La(a,c){function b(b,h){if(b)q=A,c=E(c),c(b);else if(++d===f){q=A;var k=c;c=A;2===arguments.length?k(b,h):k.apply(null,H(arguments))}else g=a[d],l=arguments,e?D(q):(e=!0,q()),e=!1}c=c||w;if(Ka(a,c)){var d=0,e=!1,f=a.length,g=a[d],l=[],q=function(){switch(g.length){case 0:try{b(null,g())}catch(a){b(a)}break;case 1:return g(b);case 2:return g(l[1],b);case 3:return g(l[1],l[2],b);case 4:return g(l[1],l[2],l[3],b);case 5:return g(l[1],
+l[2],l[3],l[4],b);default:return l=J(l,1),l[g.length-1]=b,g.apply(null,l)}};q()}}function Ma(){var a=H(arguments);return function(){var c=this,b=H(arguments),d=b[b.length-1];"function"===typeof d?b.pop():d=w;$(a,b,function(a,b,d){a.push(function(a){var b=J(arguments,1);d(a,b)});b.apply(c,a)},function(a,b){b=C(b)?b:[b];b.unshift(a);d.apply(c,b)})}}function Na(a){return function(c){var b=function(){var b=this,d=H(arguments),g=d.pop()||w;return a(c,function(a,c){a.apply(b,d.concat([c]))},g)};if(1<arguments.length){var d=
+J(arguments,1);return b.apply(this,d)}return b}}function M(){this.tail=this.head=null;this.length=0}function na(a,c,b,d){function e(a){a={data:a,callback:m};r?n._tasks.unshift(a):n._tasks.push(a);D(n.process)}function f(a,b,d){if(null==b)b=w;else if("function"!==typeof b)throw Error("task callback must be a function");n.started=!0;var c=C(a)?a:[a];void 0!==a&&c.length?(r=d,m=b,Q(c,e),m=void 0):n.idle()&&D(n.drain)}function g(a,b){var d=!1;return function(c,e){d&&A();d=!0;h--;for(var f,g=-1,m=k.length,
+q=-1,l=b.length,n=2<arguments.length,r=n&&H(arguments);++q<l;){for(f=b[q];++g<m;)k[g]===f&&(0===g?k.shift():k.splice(g,1),g=m,m--);g=-1;n?f.callback.apply(f,r):f.callback(c,e);c&&a.error(c,f.data)}h<=a.concurrency-a.buffer&&a.unsaturated();0===a._tasks.length+h&&a.drain();a.process()}}function l(){for(;!n.paused&&h<n.concurrency&&n._tasks.length;){var a=n._tasks.shift();h++;k.push(a);0===n._tasks.length&&n.empty();h===n.concurrency&&n.saturated();var b=g(n,[a]);c(a.data,b)}}function q(){for(;!n.paused&&
+h<n.concurrency&&n._tasks.length;){for(var a=n._tasks.splice(n.payload||n._tasks.length),b=-1,d=a.length,e=Array(d);++b<d;)e[b]=a[b].data;h++;X.apply(k,a);0===n._tasks.length&&n.empty();h===n.concurrency&&n.saturated();a=g(n,a);c(e,a)}}function s(){D(n.process)}if(void 0===b)b=1;else if(isNaN(b)||1>b)throw Error("Concurrency must not be zero");var h=0,k=[],m,r,n={_tasks:new M,concurrency:b,payload:d,saturated:w,unsaturated:w,buffer:b/4,empty:w,drain:w,error:w,started:!1,paused:!1,push:function(a,
+b){f(a,b)},kill:function(){n.drain=w;n._tasks.empty()},unshift:function(a,b){f(a,b,!0)},remove:function(a){n._tasks.remove(a)},process:a?l:q,length:function(){return n._tasks.length},running:function(){return h},workersList:function(){return k},idle:function(){return 0===n.length()+h},pause:function(){n.paused=!0},resume:function(){!1!==n.paused&&(n.paused=!1,K(n.concurrency<n._tasks.length?n.concurrency:n._tasks.length,s))},_worker:c};return n}function Oa(a,c,b){function d(){if(0===s.length&&0===
+q){if(0!==g)throw Error("async.auto task has cyclic dependencies");return b(null,l)}for(;s.length&&q<c&&b!==w;){q++;var a=s.shift();if(0===a[1])a[0](a[2]);else a[0](l,a[2])}}function e(a){Q(h[a]||[],function(a){a()});d()}"function"===typeof c&&(b=c,c=null);var f=F(a),g=f.length,l={};if(0===g)return b(null,l);var q=0,s=new M,h=Object.create(null);b=E(b||w);c=c||g;W(a,function(a,d){function c(a,f){null===d&&A();f=2>=arguments.length?f:J(arguments,1);if(a){q=g=0;s.length=0;var k=L(l);k[d]=f;d=null;var h=
+b;b=w;h(a,k)}else q--,g--,l[d]=f,e(d),d=null}function n(){0===--v&&s.push([p,u,c])}var p,u;if(C(a)){var v=a.length-1;p=a[v];u=v;if(0===v)s.push([p,u,c]);else for(var t=-1;++t<v;){var x=a[t];if($a(f,x))throw t="async.auto task `"+d+"` has non-existent dependency `"+x+"` in "+a.join(", "),Error(t);var y=h[x];y||(y=h[x]=[]);y.push(n)}}else p=a,u=0,s.push([p,u,c])},f);d()}function ab(a){a=a.toString().replace(bb,"");a=(a=a.match(cb)[2].replace(" ",""))?a.split(db):[];return a=a.map(function(a){return a.replace(eb,
+"").trim()})}function oa(a,c,b){function d(a,e){if(++s===g||!a||q&&!q(a)){if(2>=arguments.length)return b(a,e);var f=H(arguments);return b.apply(null,f)}c(d)}function e(){c(f)}function f(a,d){if(++s===g||!a||q&&!q(a)){if(2>=arguments.length)return b(a,d);var c=H(arguments);return b.apply(null,c)}setTimeout(e,l(s))}var g,l,q,s=0;if(3>arguments.length&&"function"===typeof a)b=c||w,c=a,a=null,g=5;else switch(b=b||w,typeof a){case "object":"function"===typeof a.errorFilter&&(q=a.errorFilter);var h=a.interval;
+switch(typeof h){case "function":l=h;break;case "string":case "number":l=(h=+h)?function(){return h}:function(){return 0}}g=+a.times||5;break;case "number":g=a||5;break;case "string":g=+a||5;break;default:throw Error("Invalid arguments for async.retry");}if("function"!==typeof c)throw Error("Invalid arguments for async.retry");l?c(f):c(d)}function Pa(a){return function(){var c=H(arguments),b=c.pop(),d;try{d=a.apply(this,c)}catch(e){return b(e)}d&&"function"===typeof d.then?d.then(function(a){try{b(null,
+a)}catch(d){D(Qa,d)}},function(a){a=a&&a.message?a:Error(a);try{b(a,void 0)}catch(d){D(Qa,d)}}):b(null,d)}}function Qa(a){throw a;}function Ra(a){return function(){function c(a,d){if(a)return b(null,{error:a});2<arguments.length&&(d=J(arguments,1));b(null,{value:d})}var b;switch(arguments.length){case 1:return b=arguments[0],a(c);case 2:return b=arguments[1],a(arguments[0],c);default:var d=H(arguments),e=d.length-1;b=d[e];d[e]=c;a.apply(this,d)}}}function pa(a){function c(b){if("object"===typeof console)if(b)console.error&&
+console.error(b);else if(console[a]){var d=J(arguments,1);Q(d,function(b){console[a](b)})}}return function(a){var d=J(arguments,1);d.push(c);a.apply(null,d)}}var w=function(){},A=function(){throw Error("Callback was already called.");},C=Array.isArray,F=Object.keys,X=Array.prototype.push,z="function"===typeof Symbol&&Symbol.iterator,D,ba,T;O();var aa=function(a,c,b){return function(d,e,f){function g(a,b){a?(f=I(f),f(a)):++s===l?f(null):!1===b&&(f=I(f),f(null))}f=I(f||w);var l,q,s=0;C(d)?(l=d.length,
+a(d,e,g)):d&&(z&&d[z]?(l=b(d,e,g))&&l===s&&f(null):"object"===typeof d&&(q=F(d),l=q.length,c(d,e,g,q)));l||f(null)}}(function(a,c,b){var d=-1,e=a.length;if(3===c.length)for(;++d<e;)c(a[d],d,E(b));else for(;++d<e;)c(a[d],E(b))},function(a,c,b,d){var e,f=-1,g=d.length;if(3===c.length)for(;++f<g;)e=d[f],c(a[e],e,E(b));else for(;++f<g;)c(a[d[f]],E(b))},function(a,c,b){a=a[z]();var d=0,e;if(3===c.length)for(;!1===(e=a.next()).done;)c(e.value,d++,E(b));else for(;!1===(e=a.next()).done;)d++,c(e.value,E(b));
+return d}),Sa=va(da,ra,sa,!0),fb=va(da,function(a,c,b,d){var e,f=-1,g=d.length;if(3===c.length)for(;++f<g;)e=d[f],c(a[e],e,b(e));else for(;++f<g;)e=d[f],c(a[e],b(e))},function(a,c,b){var d=0,e=a[z]();if(3===c.length)for(;!1===(a=e.next()).done;)c(a.value,d,b(d++));else for(;!1===(a=e.next()).done;)c(a.value,b(d++));return d},!1),Ta=wa(V,ha,ia,!0),Ua=xa(!0),Va=ya(!0),gb=wa(V,ha,ia,!1),hb=xa(!1),ib=ya(!1),ja=Aa(ea,fa,ga,!0),ka=Ba(!0),la=Ca(!0),Wa=function(a,c,b){var d=Aa(a,c,b,!1);return function(a,
+b,c){c=c||w;d(a,b,function(a,b){if(a)return c(a);c(null,!b)})}}(ea,fa,ga),Xa=function(){var a=Ba(!1);return function(c,b,d){d=d||w;a(c,b,function(a,b){if(a)return d(a);d(null,!b)})}}(),Ya=function(){var a=Ca(!1);return function(c,b,d,e){e=e||w;a(c,b,d,function(a,b){if(a)return e(a);e(null,!b)})}}(),jb=Da(V,ta,ua,!0),kb=Ea(!0),lb=Fa(!0),mb=Da(V,ta,ua,!1),nb=Ea(!1),ob=Fa(!1),pb=function(a,c,b){return function(d,e,f,g){function l(a,b){a?(g=I(g),g(a,C(h)?H(h):L(h))):++k===q?g(null,h):!1===b&&(g=I(g),
+g(null,C(h)?H(h):L(h)))}3===arguments.length&&(g=f,f=e,e=void 0);g=g||w;var q,s,h,k=0;C(d)?(q=d.length,h=void 0!==e?e:[],a(d,h,f,l)):d&&(z&&d[z]?(h=void 0!==e?e:{},(q=b(d,h,f,l))&&q===k&&g(null,h)):"object"===typeof d&&(s=F(d),q=s.length,h=void 0!==e?e:{},c(d,h,f,l,s)));q||g(null,void 0!==e?e:h||{})}}(function(a,c,b,d){var e=-1,f=a.length;if(4===b.length)for(;++e<f;)b(c,a[e],e,E(d));else for(;++e<f;)b(c,a[e],E(d))},function(a,c,b,d,e){var f,g=-1,l=e.length;if(4===b.length)for(;++g<l;)f=e[g],b(c,a[f],
+f,E(d));else for(;++g<l;)b(c,a[e[g]],E(d))},function(a,c,b,d){var e=0,f=a[z]();if(4===b.length)for(;!1===(a=f.next()).done;)b(c,a.value,e++,E(d));else for(;!1===(a=f.next()).done;)e++,b(c,a.value,E(d));return e}),qb=function(a,c,b){return function(d,e,f){function g(a,b){var d=!1;q[a]=b;return function(b,c){d&&A();d=!0;s[a]=c;b?(f=I(f),f(b)):++h===l&&f(null,P(q,s))}}f=f||w;var l,q,s,h=0;if(C(d))l=d.length,q=Array(l),s=Array(l),a(d,e,g);else if(d)if(z&&d[z])q=[],s=[],(l=b(d,e,g))&&l===h&&f(null,P(q,
+s));else if("object"===typeof d){var k=F(d);l=k.length;q=Array(l);s=Array(l);c(d,e,g,k)}l||f(null,[])}}(V,ha,ia),rb=function(a,c,b){return function(d,e,f){function g(a){return function(b,d){null===a&&A();if(b)a=null,f=I(f),Q(q,function(a,b){void 0===a&&(q[b]=w)}),f(b,S(q));else{switch(arguments.length){case 0:case 1:q[a]=w;break;case 2:q[a]=d;break;default:q[a]=J(arguments,1)}a=null;++s===l&&f(null,S(q))}}}f=f||w;var l,q,s=0;if(C(d))l=d.length,q=Array(l),a(d,e,g);else if(d)if(z&&d[z])q=[],(l=b(d,
+e,g))&&l===s&&f(null,q);else if("object"===typeof d){var h=F(d);l=h.length;q=Array(l);c(d,e,g,h)}l||f(null,[])}}(da,ra,sa),sb=function(a,c,b){return function(d,e,f){function g(a){var b=!1;return function(d,c){b&&A();b=!0;if(d)f=I(f),f(d,L(s));else{var e=s[c];e?e.push(a):s[c]=[a];++q===l&&f(null,s)}}}f=f||w;var l,q=0,s={};if(C(d))l=d.length,a(d,e,g);else if(d)if(z&&d[z])(l=b(d,e,g))&&l===q&&f(null,s);else if("object"===typeof d){var h=F(d);l=h.length;c(d,e,g,h)}l||f(null,{})}}(ea,fa,ga),tb=function(a,
+c){return function(b,d){function e(a){return function(b,c){null===a&&A();b?(a=null,d=I(d),d(b,l)):(l[a]=2>=arguments.length?c:J(arguments,1),a=null,++q===f&&d(null,l))}}d=d||w;var f,g,l,q=0;C(b)?(f=b.length,l=Array(f),a(b,e)):b&&"object"===typeof b&&(g=F(b),f=g.length,l={},c(b,e,g));f||d(null,l)}}(function(a,c){for(var b=-1,d=a.length;++b<d;)a[b](c(b))},function(a,c,b){for(var d,e=-1,f=b.length;++e<f;)d=b[e],a[d](c(d))}),ub=Na(Sa),vb=Na(za),wb=pa("log"),xb=pa("dir"),qa={VERSION:"2.6.2",each:aa,eachSeries:Y,
+eachLimit:Z,forEach:aa,forEachSeries:Y,forEachLimit:Z,eachOf:aa,eachOfSeries:Y,eachOfLimit:Z,forEachOf:aa,forEachOfSeries:Y,forEachOfLimit:Z,map:Sa,mapSeries:za,mapLimit:function(a,c,b,d){function e(){m=y++;m<k&&b(a[m],h(m))}function f(){m=y++;m<k&&b(a[m],m,h(m))}function g(){u=p.next();!1===u.done?b(u.value,h(y++)):G===y&&b!==w&&(b=w,d(null,v))}function l(){u=p.next();!1===u.done?b(u.value,y,h(y++)):G===y&&b!==w&&(b=w,d(null,v))}function q(){m=y++;m<k&&b(a[n[m]],h(m))}function s(){m=y++;m<k&&(r=
+n[m],b(a[r],r,h(m)))}function h(a){return function(b,c){null===a&&A();b?(a=null,t=w,d=I(d),d(b,H(v))):(v[a]=c,a=null,++G===k?(t=A,d(null,v),d=A):x?D(t):(x=!0,t()),x=!1)}}d=d||w;var k,m,r,n,p,u,v,t,x=!1,y=0,G=0;C(a)?(k=a.length,t=3===b.length?f:e):a&&(z&&a[z]?(k=Infinity,v=[],p=a[z](),t=3===b.length?l:g):"object"===typeof a&&(n=F(a),k=n.length,t=3===b.length?s:q));if(!k||isNaN(c)||1>c)return d(null,[]);v=v||Array(k);K(c>k?k:c,t)},mapValues:fb,mapValuesSeries:function(a,c,b){function d(){k=t;c(a[t],
+s)}function e(){k=t;c(a[t],t,s)}function f(){k=t;n=r.next();n.done?b(null,v):c(n.value,s)}function g(){k=t;n=r.next();n.done?b(null,v):c(n.value,t,s)}function l(){k=m[t];c(a[k],s)}function q(){k=m[t];c(a[k],k,s)}function s(a,d){a?(p=A,b=E(b),b(a,L(v))):(v[k]=d,++t===h?(p=A,b(null,v),b=A):u?D(p):(u=!0,p()),u=!1)}b=b||w;var h,k,m,r,n,p,u=!1,v={},t=0;C(a)?(h=a.length,p=3===c.length?e:d):a&&(z&&a[z]?(h=Infinity,r=a[z](),p=3===c.length?g:f):"object"===typeof a&&(m=F(a),h=m.length,p=3===c.length?q:l));
+if(!h)return b(null,v);p()},mapValuesLimit:function(a,c,b,d){function e(){m=y++;m<k&&b(a[m],h(m))}function f(){m=y++;m<k&&b(a[m],m,h(m))}function g(){u=p.next();!1===u.done?b(u.value,h(y++)):G===y&&b!==w&&(b=w,d(null,x))}function l(){u=p.next();!1===u.done?b(u.value,y,h(y++)):G===y&&b!==w&&(b=w,d(null,x))}function q(){m=y++;m<k&&(r=n[m],b(a[r],h(r)))}function s(){m=y++;m<k&&(r=n[m],b(a[r],r,h(r)))}function h(a){return function(b,c){null===a&&A();b?(a=null,v=w,d=I(d),d(b,L(x))):(x[a]=c,a=null,++G===
+k?d(null,x):t?D(v):(t=!0,v()),t=!1)}}d=d||w;var k,m,r,n,p,u,v,t=!1,x={},y=0,G=0;C(a)?(k=a.length,v=3===b.length?f:e):a&&(z&&a[z]?(k=Infinity,p=a[z](),v=3===b.length?l:g):"object"===typeof a&&(n=F(a),k=n.length,v=3===b.length?s:q));if(!k||isNaN(c)||1>c)return d(null,x);K(c>k?k:c,v)},filter:Ta,filterSeries:Ua,filterLimit:Va,select:Ta,selectSeries:Ua,selectLimit:Va,reject:gb,rejectSeries:hb,rejectLimit:ib,detect:ja,detectSeries:ka,detectLimit:la,find:ja,findSeries:ka,findLimit:la,pick:jb,pickSeries:kb,
+pickLimit:lb,omit:mb,omitSeries:nb,omitLimit:ob,reduce:$,inject:$,foldl:$,reduceRight:Ga,foldr:Ga,transform:pb,transformSeries:function(a,c,b,d){function e(){b(v,a[x],h)}function f(){b(v,a[x],x,h)}function g(){p=n.next();p.done?d(null,v):b(v,p.value,h)}function l(){p=n.next();p.done?d(null,v):b(v,p.value,x,h)}function q(){b(v,a[r[x]],h)}function s(){m=r[x];b(v,a[m],m,h)}function h(a,b){a?d(a,v):++x===k||!1===b?(u=A,d(null,v)):t?D(u):(t=!0,u());t=!1}3===arguments.length&&(d=b,b=c,c=void 0);d=E(d||
+w);var k,m,r,n,p,u,v,t=!1,x=0;C(a)?(k=a.length,v=void 0!==c?c:[],u=4===b.length?f:e):a&&(z&&a[z]?(k=Infinity,n=a[z](),v=void 0!==c?c:{},u=4===b.length?l:g):"object"===typeof a&&(r=F(a),k=r.length,v=void 0!==c?c:{},u=4===b.length?s:q));if(!k)return d(null,void 0!==c?c:v||{});u()},transformLimit:function(a,c,b,d,e){function f(){r=A++;r<m&&d(x,a[r],E(k))}function g(){r=A++;r<m&&d(x,a[r],r,E(k))}function l(){v=u.next();!1===v.done?(A++,d(x,v.value,E(k))):B===A&&d!==w&&(d=w,e(null,x))}function q(){v=u.next();
+!1===v.done?d(x,v.value,A++,E(k)):B===A&&d!==w&&(d=w,e(null,x))}function s(){r=A++;r<m&&d(x,a[p[r]],E(k))}function h(){r=A++;r<m&&(n=p[r],d(x,a[n],n,E(k)))}function k(a,b){a||!1===b?(t=w,e(a||null,C(x)?H(x):L(x)),e=w):++B===m?(d=w,e(null,x)):y?D(t):(y=!0,t());y=!1}4===arguments.length&&(e=d,d=b,b=void 0);e=e||w;var m,r,n,p,u,v,t,x,y=!1,A=0,B=0;C(a)?(m=a.length,x=void 0!==b?b:[],t=4===d.length?g:f):a&&(z&&a[z]?(m=Infinity,u=a[z](),x=void 0!==b?b:{},t=4===d.length?q:l):"object"===typeof a&&(p=F(a),
+m=p.length,x=void 0!==b?b:{},t=4===d.length?h:s));if(!m||isNaN(c)||1>c)return e(null,void 0!==b?b:x||{});K(c>m?m:c,t)},sortBy:qb,sortBySeries:function(a,c,b){function d(){m=a[y];c(m,s)}function e(){m=a[y];c(m,y,s)}function f(){p=n.next();if(p.done)return b(null,P(u,v));m=p.value;u[y]=m;c(m,s)}function g(){p=n.next();if(p.done)return b(null,P(u,v));m=p.value;u[y]=m;c(m,y,s)}function l(){m=a[r[y]];u[y]=m;c(m,s)}function q(){k=r[y];m=a[k];u[y]=m;c(m,k,s)}function s(a,d){v[y]=d;a?b(a):++y===h?(t=A,b(null,
+P(u,v))):x?D(t):(x=!0,t());x=!1}b=E(b||w);var h,k,m,r,n,p,u,v,t,x=!1,y=0;C(a)?(h=a.length,u=a,v=Array(h),t=3===c.length?e:d):a&&(z&&a[z]?(h=Infinity,u=[],v=[],n=a[z](),t=3===c.length?g:f):"object"===typeof a&&(r=F(a),h=r.length,u=Array(h),v=Array(h),t=3===c.length?q:l));if(!h)return b(null,[]);t()},sortByLimit:function(a,c,b,d){function e(){B<k&&(n=a[B],b(n,h(n,B++)))}function f(){m=B++;m<k&&(n=a[m],b(n,m,h(n,m)))}function g(){t=v.next();!1===t.done?(n=t.value,p[B]=n,b(n,h(n,B++))):E===B&&b!==w&&
+(b=w,d(null,P(p,x)))}function l(){t=v.next();!1===t.done?(n=t.value,p[B]=n,b(n,B,h(n,B++))):E===B&&b!==w&&(b=w,d(null,P(p,x)))}function q(){B<k&&(n=a[u[B]],p[B]=n,b(n,h(n,B++)))}function s(){B<k&&(r=u[B],n=a[r],p[B]=n,b(n,r,h(n,B++)))}function h(a,b){var c=!1;return function(a,e){c&&A();c=!0;x[b]=e;a?(y=w,d(a),d=w):++E===k?d(null,P(p,x)):G?D(y):(G=!0,y());G=!1}}d=d||w;var k,m,r,n,p,u,v,t,x,y,G=!1,B=0,E=0;C(a)?(k=a.length,p=a,y=3===b.length?f:e):a&&(z&&a[z]?(k=Infinity,v=a[z](),p=[],x=[],y=3===b.length?
+l:g):"object"===typeof a&&(u=F(a),k=u.length,p=Array(k),y=3===b.length?s:q));if(!k||isNaN(c)||1>c)return d(null,[]);x=x||Array(k);K(c>k?k:c,y)},some:Ha,someSeries:Ia,someLimit:Ja,any:Ha,anySeries:Ia,anyLimit:Ja,every:Wa,everySeries:Xa,everyLimit:Ya,all:Wa,allSeries:Xa,allLimit:Ya,concat:rb,concatSeries:function(a,c,b){function d(){c(a[t],s)}function e(){c(a[t],t,s)}function f(){n=r.next();n.done?b(null,v):c(n.value,s)}function g(){n=r.next();n.done?b(null,v):c(n.value,t,s)}function l(){c(a[m[t]],
+s)}function q(){k=m[t];c(a[k],k,s)}function s(a,d){C(d)?X.apply(v,d):2<=arguments.length&&X.apply(v,J(arguments,1));a?b(a,v):++t===h?(p=A,b(null,v)):u?D(p):(u=!0,p());u=!1}b=E(b||w);var h,k,m,r,n,p,u=!1,v=[],t=0;C(a)?(h=a.length,p=3===c.length?e:d):a&&(z&&a[z]?(h=Infinity,r=a[z](),p=3===c.length?g:f):"object"===typeof a&&(m=F(a),h=m.length,p=3===c.length?q:l));if(!h)return b(null,v);p()},concatLimit:function(a,c,b,d){function e(){t<k&&b(a[t],h(t++))}function f(){t<k&&b(a[t],t,h(t++))}function g(){n=
+r.next();!1===n.done?b(n.value,h(t++)):x===t&&b!==w&&(b=w,d(null,S(u)))}function l(){n=r.next();!1===n.done?b(n.value,t,h(t++)):x===t&&b!==w&&(b=w,d(null,S(u)))}function q(){t<k&&b(a[y[t]],h(t++))}function s(){t<k&&(m=y[t],b(a[m],m,h(t++)))}function h(a){return function(b,c){null===a&&A();if(b)a=null,p=w,d=I(d),Q(u,function(a,b){void 0===a&&(u[b]=w)}),d(b,S(u));else{switch(arguments.length){case 0:case 1:u[a]=w;break;case 2:u[a]=c;break;default:u[a]=J(arguments,1)}a=null;++x===k?(p=A,d(null,S(u)),
+d=A):v?D(p):(v=!0,p());v=!1}}}d=d||w;var k,m,r,n,p,u,v=!1,t=0,x=0;if(C(a))k=a.length,p=3===b.length?f:e;else if(a)if(z&&a[z])k=Infinity,u=[],r=a[z](),p=3===b.length?l:g;else if("object"===typeof a){var y=F(a);k=y.length;p=3===b.length?s:q}if(!k||isNaN(c)||1>c)return d(null,[]);u=u||Array(k);K(c>k?k:c,p)},groupBy:sb,groupBySeries:function(a,c,b){function d(){m=a[t];c(m,s)}function e(){m=a[t];c(m,t,s)}function f(){p=n.next();m=p.value;p.done?b(null,x):c(m,s)}function g(){p=n.next();m=p.value;p.done?
+b(null,x):c(m,t,s)}function l(){m=a[r[t]];c(m,s)}function q(){k=r[t];m=a[k];c(m,k,s)}function s(a,d){if(a)u=A,b=E(b),b(a,L(x));else{var c=x[d];c?c.push(m):x[d]=[m];++t===h?(u=A,b(null,x)):v?D(u):(v=!0,u());v=!1}}b=E(b||w);var h,k,m,r,n,p,u,v=!1,t=0,x={};C(a)?(h=a.length,u=3===c.length?e:d):a&&(z&&a[z]?(h=Infinity,n=a[z](),u=3===c.length?g:f):"object"===typeof a&&(r=F(a),h=r.length,u=3===c.length?q:l));if(!h)return b(null,x);u()},groupByLimit:function(a,c,b,d){function e(){y<k&&(n=a[y++],b(n,h(n)))}
+function f(){m=y++;m<k&&(n=a[m],b(n,m,h(n)))}function g(){v=u.next();!1===v.done?(y++,n=v.value,b(n,h(n))):E===y&&b!==w&&(b=w,d(null,B))}function l(){v=u.next();!1===v.done?(n=v.value,b(n,y++,h(n))):E===y&&b!==w&&(b=w,d(null,B))}function q(){y<k&&(n=a[p[y++]],b(n,h(n)))}function s(){y<k&&(r=p[y++],n=a[r],b(n,r,h(n)))}function h(a){var b=!1;return function(c,e){b&&A();b=!0;if(c)t=w,d=I(d),d(c,L(B));else{var f=B[e];f?f.push(a):B[e]=[a];++E===k?d(null,B):x?D(t):(x=!0,t());x=!1}}}d=d||w;var k,m,r,n,p,
+u,v,t,x=!1,y=0,E=0,B={};C(a)?(k=a.length,t=3===b.length?f:e):a&&(z&&a[z]?(k=Infinity,u=a[z](),t=3===b.length?l:g):"object"===typeof a&&(p=F(a),k=p.length,t=3===b.length?s:q));if(!k||isNaN(c)||1>c)return d(null,B);K(c>k?k:c,t)},parallel:tb,series:function(a,c){function b(){g=k;a[k](e)}function d(){g=l[k];a[g](e)}function e(a,b){a?(s=A,c=E(c),c(a,q)):(q[g]=2>=arguments.length?b:J(arguments,1),++k===f?(s=A,c(null,q)):h?D(s):(h=!0,s()),h=!1)}c=c||w;var f,g,l,q,s,h=!1,k=0;if(C(a))f=a.length,q=Array(f),
+s=b;else if(a&&"object"===typeof a)l=F(a),f=l.length,q={},s=d;else return c(null);if(!f)return c(null,q);s()},parallelLimit:function(a,c,b){function d(){l=r++;if(l<g)a[l](f(l))}function e(){r<g&&(q=s[r++],a[q](f(q)))}function f(a){return function(d,c){null===a&&A();d?(a=null,k=w,b=I(b),b(d,h)):(h[a]=2>=arguments.length?c:J(arguments,1),a=null,++n===g?b(null,h):m?D(k):(m=!0,k()),m=!1)}}b=b||w;var g,l,q,s,h,k,m=!1,r=0,n=0;C(a)?(g=a.length,h=Array(g),k=d):a&&"object"===typeof a&&(s=F(a),g=s.length,h=
+{},k=e);if(!g||isNaN(c)||1>c)return b(null,h);K(c>g?g:c,k)},tryEach:function(a,c){function b(){a[q](e)}function d(){a[g[q]](e)}function e(a,b){a?++q===f?c(a):l():2>=arguments.length?c(null,b):c(null,J(arguments,1))}c=c||w;var f,g,l,q=0;C(a)?(f=a.length,l=b):a&&"object"===typeof a&&(g=F(a),f=g.length,l=d);if(!f)return c(null);l()},waterfall:function(a,c){function b(){ma(e,f,d(e))}function d(h){return function(k,m){void 0===h&&(c=w,A());h=void 0;k?(g=c,c=A,g(k)):++q===s?(g=c,c=A,2>=arguments.length?
+g(k,m):g.apply(null,H(arguments))):(l?(f=arguments,e=a[q]||A,D(b)):(l=!0,ma(a[q]||A,arguments,d(q))),l=!1)}}c=c||w;if(Ka(a,c)){var e,f,g,l,q=0,s=a.length;ma(a[0],[],d(0))}},angelFall:La,angelfall:La,whilst:function(a,c,b){function d(){g?D(e):(g=!0,c(f));g=!1}function e(){c(f)}function f(c,e){if(c)return b(c);2>=arguments.length?a(e)?d():b(null,e):(e=J(arguments,1),a.apply(null,e)?d():b.apply(null,[null].concat(e)))}b=b||w;var g=!1;a()?d():b(null)},doWhilst:function(a,c,b){function d(){g?D(e):(g=!0,
+a(f));g=!1}function e(){a(f)}function f(a,e){if(a)return b(a);2>=arguments.length?c(e)?d():b(null,e):(e=J(arguments,1),c.apply(null,e)?d():b.apply(null,[null].concat(e)))}b=b||w;var g=!1;e()},until:function(a,c,b){function d(){g?D(e):(g=!0,c(f));g=!1}function e(){c(f)}function f(c,e){if(c)return b(c);2>=arguments.length?a(e)?b(null,e):d():(e=J(arguments,1),a.apply(null,e)?b.apply(null,[null].concat(e)):d())}b=b||w;var g=!1;a()?b(null):d()},doUntil:function(a,c,b){function d(){g?D(e):(g=!0,a(f));g=
+!1}function e(){a(f)}function f(a,e){if(a)return b(a);2>=arguments.length?c(e)?b(null,e):d():(e=J(arguments,1),c.apply(null,e)?b.apply(null,[null].concat(e)):d())}b=b||w;var g=!1;e()},during:function(a,c,b){function d(a,d){if(a)return b(a);d?c(e):b(null)}function e(c){if(c)return b(c);a(d)}b=b||w;a(d)},doDuring:function(a,c,b){function d(d,c){if(d)return b(d);c?a(e):b(null)}function e(a,e){if(a)return b(a);switch(arguments.length){case 0:case 1:c(d);break;case 2:c(e,d);break;default:var l=J(arguments,
+1);l.push(d);c.apply(null,l)}}b=b||w;d(null,!0)},forever:function(a,c){function b(){a(d)}function d(a){if(a){if(c)return c(a);throw a;}e?D(b):(e=!0,b());e=!1}var e=!1;b()},compose:function(){return Ma.apply(null,Za(arguments))},seq:Ma,applyEach:ub,applyEachSeries:vb,queue:function(a,c){return na(!0,a,c)},priorityQueue:function(a,c){var b=na(!0,a,c);b.push=function(a,c,f){b.started=!0;c=c||0;var g=C(a)?a:[a],l=g.length;if(void 0===a||0===l)b.idle()&&D(b.drain);else{f="function"===typeof f?f:w;for(a=
+b._tasks.head;a&&c>=a.priority;)a=a.next;for(;l--;){var q={data:g[l],priority:c,callback:f};a?b._tasks.insertBefore(a,q):b._tasks.push(q);D(b.process)}}};delete b.unshift;return b},cargo:function(a,c){return na(!1,a,1,c)},auto:Oa,autoInject:function(a,c,b){var d={};W(a,function(a,b){var c,l=a.length;if(C(a)){if(0===l)throw Error("autoInject task functions require explicit parameters.");c=H(a);l=c.length-1;a=c[l];if(0===l){d[b]=a;return}}else{if(1===l){d[b]=a;return}c=ab(a);if(0===l&&0===c.length)throw Error("autoInject task functions require explicit parameters.");
+l=c.length-1}c[l]=function(b,d){switch(l){case 1:a(b[c[0]],d);break;case 2:a(b[c[0]],b[c[1]],d);break;case 3:a(b[c[0]],b[c[1]],b[c[2]],d);break;default:for(var f=-1;++f<l;)c[f]=b[c[f]];c[f]=d;a.apply(null,c)}};d[b]=c},F(a));Oa(d,c,b)},retry:oa,retryable:function(a,c){c||(c=a,a=null);return function(){function b(a){c(a)}function d(a){c(g[0],a)}function e(a){c(g[0],g[1],a)}var f,g=H(arguments),l=g.length-1,q=g[l];switch(c.length){case 1:f=b;break;case 2:f=d;break;case 3:f=e;break;default:f=function(a){g[l]=
+a;c.apply(null,g)}}a?oa(a,f,q):oa(f,q)}},iterator:function(a){function c(e){var f=function(){b&&a[d[e]||e].apply(null,H(arguments));return f.next()};f.next=function(){return e<b-1?c(e+1):null};return f}var b=0,d=[];C(a)?b=a.length:(d=F(a),b=d.length);return c(0)},times:function(a,c,b){function d(c){return function(d,l){null===c&&A();e[c]=l;c=null;d?(b(d),b=w):0===--a&&b(null,e)}}b=b||w;a=+a;if(isNaN(a)||1>a)return b(null,[]);var e=Array(a);K(a,function(a){c(a,d(a))})},timesSeries:function(a,c,b){function d(){c(l,
+e)}function e(c,e){f[l]=e;c?(b(c),b=A):++l>=a?(b(null,f),b=A):g?D(d):(g=!0,d());g=!1}b=b||w;a=+a;if(isNaN(a)||1>a)return b(null,[]);var f=Array(a),g=!1,l=0;d()},timesLimit:function(a,c,b,d){function e(){var c=q++;c<a&&b(c,f(c))}function f(b){return function(c,f){null===b&&A();g[b]=f;b=null;c?(d(c),d=w):++s>=a?(d(null,g),d=A):l?D(e):(l=!0,e());l=!1}}d=d||w;a=+a;if(isNaN(a)||1>a||isNaN(c)||1>c)return d(null,[]);var g=Array(a),l=!1,q=0,s=0;K(c>a?a:c,e)},race:function(a,c){c=I(c||w);var b,d,e=-1;if(C(a))for(b=
+a.length;++e<b;)a[e](c);else if(a&&"object"===typeof a)for(d=F(a),b=d.length;++e<b;)a[d[e]](c);else return c(new TypeError("First argument to race must be a collection of functions"));b||c(null)},apply:function(a){switch(arguments.length){case 0:case 1:return a;case 2:return a.bind(null,arguments[1]);case 3:return a.bind(null,arguments[1],arguments[2]);case 4:return a.bind(null,arguments[1],arguments[2],arguments[3]);case 5:return a.bind(null,arguments[1],arguments[2],arguments[3],arguments[4]);default:var c=
+arguments.length,b=0,d=Array(c);for(d[b]=null;++b<c;)d[b]=arguments[b];return a.bind.apply(a,d)}},nextTick:ba,setImmediate:T,memoize:function(a,c){c=c||function(a){return a};var b={},d={},e=function(){function e(a){var c=H(arguments);a||(b[q]=c);var f=d[q];delete d[q];for(var g=-1,l=f.length;++g<l;)f[g].apply(null,c)}var g=H(arguments),l=g.pop(),q=c.apply(null,g);if(b.hasOwnProperty(q))D(function(){l.apply(null,b[q])});else{if(d.hasOwnProperty(q))return d[q].push(l);d[q]=[l];g.push(e);a.apply(null,
+g)}};e.memo=b;e.unmemoized=a;return e},unmemoize:function(a){return function(){return(a.unmemoized||a).apply(null,arguments)}},ensureAsync:function(a){return function(){var c=H(arguments),b=c.length-1,d=c[b],e=!0;c[b]=function(){var a=H(arguments);e?D(function(){d.apply(null,a)}):d.apply(null,a)};a.apply(this,c);e=!1}},constant:function(){var a=[null].concat(H(arguments));return function(c){c=arguments[arguments.length-1];c.apply(this,a)}},asyncify:Pa,wrapSync:Pa,log:wb,dir:xb,reflect:Ra,reflectAll:function(a){function c(a,
+c){b[c]=Ra(a)}var b,d;C(a)?(b=Array(a.length),Q(a,c)):a&&"object"===typeof a&&(d=F(a),b={},W(a,c,d));return b},timeout:function(a,c,b){function d(){var c=Error('Callback function "'+(a.name||"anonymous")+'" timed out.');c.code="ETIMEDOUT";b&&(c.info=b);l=null;g(c)}function e(){null!==l&&(f(g,H(arguments)),clearTimeout(l))}function f(a,b){switch(b.length){case 0:a();break;case 1:a(b[0]);break;case 2:a(b[0],b[1]);break;default:a.apply(null,b)}}var g,l;return function(){l=setTimeout(d,c);var b=H(arguments),
+s=b.length-1;g=b[s];b[s]=e;f(a,b)}},createLogger:pa,safe:function(){O();return N},fast:function(){O(!1);return N}};N["default"]=qa;W(qa,function(a,c){N[c]=a},F(qa));M.prototype._removeLink=function(a){var c=a.prev,b=a.next;c?c.next=b:this.head=b;b?b.prev=c:this.tail=c;a.prev=null;a.next=null;this.length--;return a};M.prototype.empty=M;M.prototype._setInitial=function(a){this.length=1;this.head=this.tail=a};M.prototype.insertBefore=function(a,c){c.prev=a.prev;c.next=a;a.prev?a.prev.next=c:this.head=
+c;a.prev=c;this.length++};M.prototype.unshift=function(a){this.head?this.insertBefore(this.head,a):this._setInitial(a)};M.prototype.push=function(a){var c=this.tail;c?(a.prev=c,a.next=c.next,this.tail=a,c.next=a,this.length++):this._setInitial(a)};M.prototype.shift=function(){return this.head&&this._removeLink(this.head)};M.prototype.splice=function(a){for(var c,b=[];a--&&(c=this.shift());)b.push(c);return b};M.prototype.remove=function(a){for(var c=this.head;c;)a(c)&&this._removeLink(c),c=c.next;
+return this};var cb=/^(function)?\s*[^\(]*\(\s*([^\)]*)\)/m,db=/,/,eb=/(=.+)?(\s*)$/,bb=/((\/\/.*$)|(\/\*[\s\S]*?\*\/))/gm});
Index: frontend/node_modules/neo-async/asyncify.js
===================================================================
--- frontend/node_modules/neo-async/asyncify.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/asyncify.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').asyncify;
Index: frontend/node_modules/neo-async/auto.js
===================================================================
--- frontend/node_modules/neo-async/auto.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/auto.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').auto;
Index: frontend/node_modules/neo-async/autoInject.js
===================================================================
--- frontend/node_modules/neo-async/autoInject.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/autoInject.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').autoInject;
Index: frontend/node_modules/neo-async/cargo.js
===================================================================
--- frontend/node_modules/neo-async/cargo.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/cargo.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').cargo;
Index: frontend/node_modules/neo-async/compose.js
===================================================================
--- frontend/node_modules/neo-async/compose.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/compose.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').compose;
Index: frontend/node_modules/neo-async/concat.js
===================================================================
--- frontend/node_modules/neo-async/concat.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/concat.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').concat;
Index: frontend/node_modules/neo-async/concatLimit.js
===================================================================
--- frontend/node_modules/neo-async/concatLimit.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/concatLimit.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').concatLimit;
Index: frontend/node_modules/neo-async/concatSeries.js
===================================================================
--- frontend/node_modules/neo-async/concatSeries.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/concatSeries.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').concatSeries;
Index: frontend/node_modules/neo-async/constant.js
===================================================================
--- frontend/node_modules/neo-async/constant.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/constant.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').constant;
Index: frontend/node_modules/neo-async/createLogger.js
===================================================================
--- frontend/node_modules/neo-async/createLogger.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/createLogger.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').createLogger;
Index: frontend/node_modules/neo-async/detect.js
===================================================================
--- frontend/node_modules/neo-async/detect.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/detect.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').detect;
Index: frontend/node_modules/neo-async/detectLimit.js
===================================================================
--- frontend/node_modules/neo-async/detectLimit.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/detectLimit.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').detectLimit;
Index: frontend/node_modules/neo-async/detectSeries.js
===================================================================
--- frontend/node_modules/neo-async/detectSeries.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/detectSeries.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').detectSeries;
Index: frontend/node_modules/neo-async/dir.js
===================================================================
--- frontend/node_modules/neo-async/dir.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/dir.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').dir;
Index: frontend/node_modules/neo-async/doDuring.js
===================================================================
--- frontend/node_modules/neo-async/doDuring.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/doDuring.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').doDuring;
Index: frontend/node_modules/neo-async/doUntil.js
===================================================================
--- frontend/node_modules/neo-async/doUntil.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/doUntil.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').doUntil;
Index: frontend/node_modules/neo-async/doWhilst.js
===================================================================
--- frontend/node_modules/neo-async/doWhilst.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/doWhilst.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').doWhilst;
Index: frontend/node_modules/neo-async/during.js
===================================================================
--- frontend/node_modules/neo-async/during.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/during.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').during;
Index: frontend/node_modules/neo-async/each.js
===================================================================
--- frontend/node_modules/neo-async/each.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/each.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').each;
Index: frontend/node_modules/neo-async/eachLimit.js
===================================================================
--- frontend/node_modules/neo-async/eachLimit.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/eachLimit.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').eachLimit;
Index: frontend/node_modules/neo-async/eachOf.js
===================================================================
--- frontend/node_modules/neo-async/eachOf.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/eachOf.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').eachOf;
Index: frontend/node_modules/neo-async/eachOfLimit.js
===================================================================
--- frontend/node_modules/neo-async/eachOfLimit.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/eachOfLimit.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').eachOfLimit;
Index: frontend/node_modules/neo-async/eachOfSeries.js
===================================================================
--- frontend/node_modules/neo-async/eachOfSeries.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/eachOfSeries.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').eachOfSeries;
Index: frontend/node_modules/neo-async/eachSeries.js
===================================================================
--- frontend/node_modules/neo-async/eachSeries.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/eachSeries.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').eachSeries;
Index: frontend/node_modules/neo-async/ensureAsync.js
===================================================================
--- frontend/node_modules/neo-async/ensureAsync.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/ensureAsync.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').ensureAsync;
Index: frontend/node_modules/neo-async/every.js
===================================================================
--- frontend/node_modules/neo-async/every.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/every.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').every;
Index: frontend/node_modules/neo-async/everyLimit.js
===================================================================
--- frontend/node_modules/neo-async/everyLimit.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/everyLimit.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').everyLimit;
Index: frontend/node_modules/neo-async/everySeries.js
===================================================================
--- frontend/node_modules/neo-async/everySeries.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/everySeries.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').everySeries;
Index: frontend/node_modules/neo-async/fast.js
===================================================================
--- frontend/node_modules/neo-async/fast.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/fast.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').fast;
Index: frontend/node_modules/neo-async/filter.js
===================================================================
--- frontend/node_modules/neo-async/filter.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/filter.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').filter;
Index: frontend/node_modules/neo-async/filterLimit.js
===================================================================
--- frontend/node_modules/neo-async/filterLimit.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/filterLimit.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').filterLimit;
Index: frontend/node_modules/neo-async/filterSeries.js
===================================================================
--- frontend/node_modules/neo-async/filterSeries.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/filterSeries.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').filterSeries;
Index: frontend/node_modules/neo-async/find.js
===================================================================
--- frontend/node_modules/neo-async/find.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/find.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').find;
Index: frontend/node_modules/neo-async/findLimit.js
===================================================================
--- frontend/node_modules/neo-async/findLimit.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/findLimit.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').findLimit;
Index: frontend/node_modules/neo-async/findSeries.js
===================================================================
--- frontend/node_modules/neo-async/findSeries.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/findSeries.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').findSeries;
Index: frontend/node_modules/neo-async/foldl.js
===================================================================
--- frontend/node_modules/neo-async/foldl.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/foldl.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').foldl;
Index: frontend/node_modules/neo-async/foldr.js
===================================================================
--- frontend/node_modules/neo-async/foldr.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/foldr.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').foldr;
Index: frontend/node_modules/neo-async/forEach.js
===================================================================
--- frontend/node_modules/neo-async/forEach.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/forEach.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').forEach;
Index: frontend/node_modules/neo-async/forEachLimit.js
===================================================================
--- frontend/node_modules/neo-async/forEachLimit.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/forEachLimit.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').forEachLimit;
Index: frontend/node_modules/neo-async/forEachOf.js
===================================================================
--- frontend/node_modules/neo-async/forEachOf.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/forEachOf.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').forEachOf;
Index: frontend/node_modules/neo-async/forEachOfLimit.js
===================================================================
--- frontend/node_modules/neo-async/forEachOfLimit.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/forEachOfLimit.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').forEachOfLimit;
Index: frontend/node_modules/neo-async/forEachOfSeries.js
===================================================================
--- frontend/node_modules/neo-async/forEachOfSeries.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/forEachOfSeries.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').forEachOfSeries;
Index: frontend/node_modules/neo-async/forEachSeries.js
===================================================================
--- frontend/node_modules/neo-async/forEachSeries.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/forEachSeries.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').forEachSeries;
Index: frontend/node_modules/neo-async/forever.js
===================================================================
--- frontend/node_modules/neo-async/forever.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/forever.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').forever;
Index: frontend/node_modules/neo-async/groupBy.js
===================================================================
--- frontend/node_modules/neo-async/groupBy.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/groupBy.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').groupBy;
Index: frontend/node_modules/neo-async/groupByLimit.js
===================================================================
--- frontend/node_modules/neo-async/groupByLimit.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/groupByLimit.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').groupByLimit;
Index: frontend/node_modules/neo-async/groupBySeries.js
===================================================================
--- frontend/node_modules/neo-async/groupBySeries.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/groupBySeries.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').groupBySeries;
Index: frontend/node_modules/neo-async/inject.js
===================================================================
--- frontend/node_modules/neo-async/inject.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/inject.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').inject;
Index: frontend/node_modules/neo-async/iterator.js
===================================================================
--- frontend/node_modules/neo-async/iterator.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/iterator.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').iterator;
Index: frontend/node_modules/neo-async/log.js
===================================================================
--- frontend/node_modules/neo-async/log.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/log.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').log;
Index: frontend/node_modules/neo-async/map.js
===================================================================
--- frontend/node_modules/neo-async/map.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/map.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').map;
Index: frontend/node_modules/neo-async/mapLimit.js
===================================================================
--- frontend/node_modules/neo-async/mapLimit.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/mapLimit.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').mapLimit;
Index: frontend/node_modules/neo-async/mapSeries.js
===================================================================
--- frontend/node_modules/neo-async/mapSeries.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/mapSeries.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').mapSeries;
Index: frontend/node_modules/neo-async/mapValues.js
===================================================================
--- frontend/node_modules/neo-async/mapValues.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/mapValues.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').mapValues;
Index: frontend/node_modules/neo-async/mapValuesLimit.js
===================================================================
--- frontend/node_modules/neo-async/mapValuesLimit.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/mapValuesLimit.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').mapValuesLimit;
Index: frontend/node_modules/neo-async/mapValuesSeries.js
===================================================================
--- frontend/node_modules/neo-async/mapValuesSeries.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/mapValuesSeries.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').mapValuesSeries;
Index: frontend/node_modules/neo-async/memoize.js
===================================================================
--- frontend/node_modules/neo-async/memoize.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/memoize.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').memoize;
Index: frontend/node_modules/neo-async/nextTick.js
===================================================================
--- frontend/node_modules/neo-async/nextTick.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/nextTick.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').nextTick;
Index: frontend/node_modules/neo-async/omit.js
===================================================================
--- frontend/node_modules/neo-async/omit.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/omit.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').omit;
Index: frontend/node_modules/neo-async/omitLimit.js
===================================================================
--- frontend/node_modules/neo-async/omitLimit.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/omitLimit.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').omitLimit;
Index: frontend/node_modules/neo-async/omitSeries.js
===================================================================
--- frontend/node_modules/neo-async/omitSeries.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/omitSeries.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').omitSeries;
Index: frontend/node_modules/neo-async/package.json
===================================================================
--- frontend/node_modules/neo-async/package.json	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/package.json	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,57 @@
+{
+  "name": "neo-async",
+  "version": "2.6.2",
+  "description": "Neo-Async is a drop-in replacement for Async, it almost fully covers its functionality and runs faster ",
+  "main": "async.js",
+  "license": "MIT",
+  "keywords": [
+    "async",
+    "util"
+  ],
+  "repository": {
+    "type": "git",
+    "url": "git@github.com:suguru03/neo-async.git"
+  },
+  "homepage": "https://github.com/suguru03/neo-async",
+  "dependencies": {},
+  "devDependencies": {
+    "aigle": "^1.14.0",
+    "async": "^2.6.0",
+    "benchmark": "^2.1.1",
+    "bluebird": "^3.5.1",
+    "codecov.io": "^0.1.6",
+    "fs-extra": "^4.0.2",
+    "func-comparator": "^0.7.2",
+    "gulp": "^4.0.2",
+    "gulp-bump": "^2.8.0",
+    "gulp-exit": "0.0.2",
+    "gulp-git": "^2.4.2",
+    "gulp-jscs": "^4.0.0",
+    "gulp-mocha": "^4.2.0",
+    "gulp-tag-version": "^1.3.0",
+    "gulp-util": "^3.0.7",
+    "husky": "^1.2.0",
+    "istanbul": "^0.4.3",
+    "jsdoc": "^3.5.5",
+    "jshint": "^2.9.5",
+    "lint-staged": "^8.1.0",
+    "lodash": "^4.16.6",
+    "minimist": "^1.2.0",
+    "mocha": "^3.5.3",
+    "mocha-parallel-executor": "^0.3.0",
+    "mocha.parallel": "^0.15.3",
+    "prettier": "^1.15.2",
+    "require-dir": "^0.3.0"
+  },
+  "lint-staged": {
+    "*.{js,ts}": [
+      "prettier --write",
+      "git add"
+    ]
+  },
+  "prettier": {
+    "printWidth": 100,
+    "singleQuote": true
+  },
+  "browser": "async.min.js"
+}
Index: frontend/node_modules/neo-async/parallel.js
===================================================================
--- frontend/node_modules/neo-async/parallel.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/parallel.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').parallel;
Index: frontend/node_modules/neo-async/parallelLimit.js
===================================================================
--- frontend/node_modules/neo-async/parallelLimit.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/parallelLimit.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').parallelLimit;
Index: frontend/node_modules/neo-async/pick.js
===================================================================
--- frontend/node_modules/neo-async/pick.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/pick.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').pick;
Index: frontend/node_modules/neo-async/pickLimit.js
===================================================================
--- frontend/node_modules/neo-async/pickLimit.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/pickLimit.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').pickLimit;
Index: frontend/node_modules/neo-async/pickSeries.js
===================================================================
--- frontend/node_modules/neo-async/pickSeries.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/pickSeries.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').pickSeries;
Index: frontend/node_modules/neo-async/priorityQueue.js
===================================================================
--- frontend/node_modules/neo-async/priorityQueue.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/priorityQueue.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').priorityQueue;
Index: frontend/node_modules/neo-async/queue.js
===================================================================
--- frontend/node_modules/neo-async/queue.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/queue.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').queue;
Index: frontend/node_modules/neo-async/race.js
===================================================================
--- frontend/node_modules/neo-async/race.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/race.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').race;
Index: frontend/node_modules/neo-async/reduce.js
===================================================================
--- frontend/node_modules/neo-async/reduce.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/reduce.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').reduce;
Index: frontend/node_modules/neo-async/reduceRight.js
===================================================================
--- frontend/node_modules/neo-async/reduceRight.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/reduceRight.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').reduceRight;
Index: frontend/node_modules/neo-async/reflect.js
===================================================================
--- frontend/node_modules/neo-async/reflect.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/reflect.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').reflect;
Index: frontend/node_modules/neo-async/reflectAll.js
===================================================================
--- frontend/node_modules/neo-async/reflectAll.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/reflectAll.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').reflectAll;
Index: frontend/node_modules/neo-async/reject.js
===================================================================
--- frontend/node_modules/neo-async/reject.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/reject.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').reject;
Index: frontend/node_modules/neo-async/rejectLimit.js
===================================================================
--- frontend/node_modules/neo-async/rejectLimit.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/rejectLimit.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').rejectLimit;
Index: frontend/node_modules/neo-async/rejectSeries.js
===================================================================
--- frontend/node_modules/neo-async/rejectSeries.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/rejectSeries.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').rejectSeries;
Index: frontend/node_modules/neo-async/retry.js
===================================================================
--- frontend/node_modules/neo-async/retry.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/retry.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').retry;
Index: frontend/node_modules/neo-async/retryable.js
===================================================================
--- frontend/node_modules/neo-async/retryable.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/retryable.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').retryable;
Index: frontend/node_modules/neo-async/safe.js
===================================================================
--- frontend/node_modules/neo-async/safe.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/safe.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').safe;
Index: frontend/node_modules/neo-async/select.js
===================================================================
--- frontend/node_modules/neo-async/select.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/select.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').select;
Index: frontend/node_modules/neo-async/selectLimit.js
===================================================================
--- frontend/node_modules/neo-async/selectLimit.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/selectLimit.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').selectLimit;
Index: frontend/node_modules/neo-async/selectSeries.js
===================================================================
--- frontend/node_modules/neo-async/selectSeries.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/selectSeries.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').selectSeries;
Index: frontend/node_modules/neo-async/seq.js
===================================================================
--- frontend/node_modules/neo-async/seq.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/seq.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').seq;
Index: frontend/node_modules/neo-async/series.js
===================================================================
--- frontend/node_modules/neo-async/series.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/series.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').series;
Index: frontend/node_modules/neo-async/setImmediate.js
===================================================================
--- frontend/node_modules/neo-async/setImmediate.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/setImmediate.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').setImmediate;
Index: frontend/node_modules/neo-async/some.js
===================================================================
--- frontend/node_modules/neo-async/some.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/some.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').some;
Index: frontend/node_modules/neo-async/someLimit.js
===================================================================
--- frontend/node_modules/neo-async/someLimit.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/someLimit.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').someLimit;
Index: frontend/node_modules/neo-async/someSeries.js
===================================================================
--- frontend/node_modules/neo-async/someSeries.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/someSeries.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').someSeries;
Index: frontend/node_modules/neo-async/sortBy.js
===================================================================
--- frontend/node_modules/neo-async/sortBy.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/sortBy.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').sortBy;
Index: frontend/node_modules/neo-async/sortByLimit.js
===================================================================
--- frontend/node_modules/neo-async/sortByLimit.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/sortByLimit.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').sortByLimit;
Index: frontend/node_modules/neo-async/sortBySeries.js
===================================================================
--- frontend/node_modules/neo-async/sortBySeries.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/sortBySeries.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').sortBySeries;
Index: frontend/node_modules/neo-async/timeout.js
===================================================================
--- frontend/node_modules/neo-async/timeout.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/timeout.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').timeout;
Index: frontend/node_modules/neo-async/times.js
===================================================================
--- frontend/node_modules/neo-async/times.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/times.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').times;
Index: frontend/node_modules/neo-async/timesLimit.js
===================================================================
--- frontend/node_modules/neo-async/timesLimit.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/timesLimit.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').timesLimit;
Index: frontend/node_modules/neo-async/timesSeries.js
===================================================================
--- frontend/node_modules/neo-async/timesSeries.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/timesSeries.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').timesSeries;
Index: frontend/node_modules/neo-async/transform.js
===================================================================
--- frontend/node_modules/neo-async/transform.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/transform.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').transform;
Index: frontend/node_modules/neo-async/transformLimit.js
===================================================================
--- frontend/node_modules/neo-async/transformLimit.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/transformLimit.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').transformLimit;
Index: frontend/node_modules/neo-async/transformSeries.js
===================================================================
--- frontend/node_modules/neo-async/transformSeries.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/transformSeries.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').transformSeries;
Index: frontend/node_modules/neo-async/tryEach.js
===================================================================
--- frontend/node_modules/neo-async/tryEach.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/tryEach.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').tryEach;
Index: frontend/node_modules/neo-async/unmemoize.js
===================================================================
--- frontend/node_modules/neo-async/unmemoize.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/unmemoize.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').unmemoize;
Index: frontend/node_modules/neo-async/until.js
===================================================================
--- frontend/node_modules/neo-async/until.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/until.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').until;
Index: frontend/node_modules/neo-async/waterfall.js
===================================================================
--- frontend/node_modules/neo-async/waterfall.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/waterfall.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').waterfall;
Index: frontend/node_modules/neo-async/whilst.js
===================================================================
--- frontend/node_modules/neo-async/whilst.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/whilst.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').whilst;
Index: frontend/node_modules/neo-async/wrapSync.js
===================================================================
--- frontend/node_modules/neo-async/wrapSync.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/neo-async/wrapSync.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./async').wrapSync;
