async.js
   1  (function (global, factory) {
   2      typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
   3      typeof define === 'function' && define.amd ? define(['exports'], factory) :
   4      (factory((global.async = {})));
   5  }(this, (function (exports) { 'use strict';
   6  
   7      /**
   8       * Creates a continuation function with some arguments already applied.
   9       *
  10       * Useful as a shorthand when combined with other control flow functions. Any
  11       * arguments passed to the returned function are added to the arguments
  12       * originally passed to apply.
  13       *
  14       * @name apply
  15       * @static
  16       * @memberOf module:Utils
  17       * @method
  18       * @category Util
  19       * @param {Function} fn - The function you want to eventually apply all
  20       * arguments to. Invokes with (arguments...).
  21       * @param {...*} arguments... - Any number of arguments to automatically apply
  22       * when the continuation is called.
  23       * @returns {Function} the partially-applied function
  24       * @example
  25       *
  26       * // using apply
  27       * async.parallel([
  28       *     async.apply(fs.writeFile, 'testfile1', 'test1'),
  29       *     async.apply(fs.writeFile, 'testfile2', 'test2')
  30       * ]);
  31       *
  32       *
  33       * // the same process without using apply
  34       * async.parallel([
  35       *     function(callback) {
  36       *         fs.writeFile('testfile1', 'test1', callback);
  37       *     },
  38       *     function(callback) {
  39       *         fs.writeFile('testfile2', 'test2', callback);
  40       *     }
  41       * ]);
  42       *
  43       * // It's possible to pass any number of additional arguments when calling the
  44       * // continuation:
  45       *
  46       * node> var fn = async.apply(sys.puts, 'one');
  47       * node> fn('two', 'three');
  48       * one
  49       * two
  50       * three
  51       */
  52      function apply(fn, ...args) {
  53          return (...callArgs) => fn(...args,...callArgs);
  54      }
  55  
  56      function initialParams (fn) {
  57          return function (...args/*, callback*/) {
  58              var callback = args.pop();
  59              return fn.call(this, args, callback);
  60          };
  61      }
  62  
  63      /* istanbul ignore file */
  64  
  65      var hasSetImmediate = typeof setImmediate === 'function' && setImmediate;
  66      var hasNextTick = typeof process === 'object' && typeof process.nextTick === 'function';
  67  
  68      function fallback(fn) {
  69          setTimeout(fn, 0);
  70      }
  71  
  72      function wrap(defer) {
  73          return (fn, ...args) => defer(() => fn(...args));
  74      }
  75  
  76      var _defer;
  77  
  78      if (hasSetImmediate) {
  79          _defer = setImmediate;
  80      } else if (hasNextTick) {
  81          _defer = process.nextTick;
  82      } else {
  83          _defer = fallback;
  84      }
  85  
  86      var setImmediate$1 = wrap(_defer);
  87  
  88      /**
  89       * Take a sync function and make it async, passing its return value to a
  90       * callback. This is useful for plugging sync functions into a waterfall,
  91       * series, or other async functions. Any arguments passed to the generated
  92       * function will be passed to the wrapped function (except for the final
  93       * callback argument). Errors thrown will be passed to the callback.
  94       *
  95       * If the function passed to `asyncify` returns a Promise, that promises's
  96       * resolved/rejected state will be used to call the callback, rather than simply
  97       * the synchronous return value.
  98       *
  99       * This also means you can asyncify ES2017 `async` functions.
 100       *
 101       * @name asyncify
 102       * @static
 103       * @memberOf module:Utils
 104       * @method
 105       * @alias wrapSync
 106       * @category Util
 107       * @param {Function} func - The synchronous function, or Promise-returning
 108       * function to convert to an {@link AsyncFunction}.
 109       * @returns {AsyncFunction} An asynchronous wrapper of the `func`. To be
 110       * invoked with `(args..., callback)`.
 111       * @example
 112       *
 113       * // passing a regular synchronous function
 114       * async.waterfall([
 115       *     async.apply(fs.readFile, filename, "utf8"),
 116       *     async.asyncify(JSON.parse),
 117       *     function (data, next) {
 118       *         // data is the result of parsing the text.
 119       *         // If there was a parsing error, it would have been caught.
 120       *     }
 121       * ], callback);
 122       *
 123       * // passing a function returning a promise
 124       * async.waterfall([
 125       *     async.apply(fs.readFile, filename, "utf8"),
 126       *     async.asyncify(function (contents) {
 127       *         return db.model.create(contents);
 128       *     }),
 129       *     function (model, next) {
 130       *         // `model` is the instantiated model object.
 131       *         // If there was an error, this function would be skipped.
 132       *     }
 133       * ], callback);
 134       *
 135       * // es2017 example, though `asyncify` is not needed if your JS environment
 136       * // supports async functions out of the box
 137       * var q = async.queue(async.asyncify(async function(file) {
 138       *     var intermediateStep = await processFile(file);
 139       *     return await somePromise(intermediateStep)
 140       * }));
 141       *
 142       * q.push(files);
 143       */
 144      function asyncify(func) {
 145          if (isAsync(func)) {
 146              return function (...args/*, callback*/) {
 147                  const callback = args.pop();
 148                  const promise = func.apply(this, args);
 149                  return handlePromise(promise, callback)
 150              }
 151          }
 152  
 153          return initialParams(function (args, callback) {
 154              var result;
 155              try {
 156                  result = func.apply(this, args);
 157              } catch (e) {
 158                  return callback(e);
 159              }
 160              // if result is Promise object
 161              if (result && typeof result.then === 'function') {
 162                  return handlePromise(result, callback)
 163              } else {
 164                  callback(null, result);
 165              }
 166          });
 167      }
 168  
 169      function handlePromise(promise, callback) {
 170          return promise.then(value => {
 171              invokeCallback(callback, null, value);
 172          }, err => {
 173              invokeCallback(callback, err && err.message ? err : new Error(err));
 174          });
 175      }
 176  
 177      function invokeCallback(callback, error, value) {
 178          try {
 179              callback(error, value);
 180          } catch (err) {
 181              setImmediate$1(e => { throw e }, err);
 182          }
 183      }
 184  
 185      function isAsync(fn) {
 186          return fn[Symbol.toStringTag] === 'AsyncFunction';
 187      }
 188  
 189      function isAsyncGenerator(fn) {
 190          return fn[Symbol.toStringTag] === 'AsyncGenerator';
 191      }
 192  
 193      function isAsyncIterable(obj) {
 194          return typeof obj[Symbol.asyncIterator] === 'function';
 195      }
 196  
 197      function wrapAsync(asyncFn) {
 198          if (typeof asyncFn !== 'function') throw new Error('expected a function')
 199          return isAsync(asyncFn) ? asyncify(asyncFn) : asyncFn;
 200      }
 201  
 202      // conditionally promisify a function.
 203      // only return a promise if a callback is omitted
 204      function awaitify (asyncFn, arity = asyncFn.length) {
 205          if (!arity) throw new Error('arity is undefined')
 206          function awaitable (...args) {
 207              if (typeof args[arity - 1] === 'function') {
 208                  return asyncFn.apply(this, args)
 209              }
 210  
 211              return new Promise((resolve, reject) => {
 212                  args[arity - 1] = (err, ...cbArgs) => {
 213                      if (err) return reject(err)
 214                      resolve(cbArgs.length > 1 ? cbArgs : cbArgs[0]);
 215                  };
 216                  asyncFn.apply(this, args);
 217              })
 218          }
 219  
 220          return awaitable
 221      }
 222  
 223      function applyEach (eachfn) {
 224          return function applyEach(fns, ...callArgs) {
 225              const go = awaitify(function (callback) {
 226                  var that = this;
 227                  return eachfn(fns, (fn, cb) => {
 228                      wrapAsync(fn).apply(that, callArgs.concat(cb));
 229                  }, callback);
 230              });
 231              return go;
 232          };
 233      }
 234  
 235      function _asyncMap(eachfn, arr, iteratee, callback) {
 236          arr = arr || [];
 237          var results = [];
 238          var counter = 0;
 239          var _iteratee = wrapAsync(iteratee);
 240  
 241          return eachfn(arr, (value, _, iterCb) => {
 242              var index = counter++;
 243              _iteratee(value, (err, v) => {
 244                  results[index] = v;
 245                  iterCb(err);
 246              });
 247          }, err => {
 248              callback(err, results);
 249          });
 250      }
 251  
 252      function isArrayLike(value) {
 253          return value &&
 254              typeof value.length === 'number' &&
 255              value.length >= 0 &&
 256              value.length % 1 === 0;
 257      }
 258  
 259      // A temporary value used to identify if the loop should be broken.
 260      // See #1064, #1293
 261      const breakLoop = {};
 262  
 263      function once(fn) {
 264          function wrapper (...args) {
 265              if (fn === null) return;
 266              var callFn = fn;
 267              fn = null;
 268              callFn.apply(this, args);
 269          }
 270          Object.assign(wrapper, fn);
 271          return wrapper
 272      }
 273  
 274      function getIterator (coll) {
 275          return coll[Symbol.iterator] && coll[Symbol.iterator]();
 276      }
 277  
 278      function createArrayIterator(coll) {
 279          var i = -1;
 280          var len = coll.length;
 281          return function next() {
 282              return ++i < len ? {value: coll[i], key: i} : null;
 283          }
 284      }
 285  
 286      function createES2015Iterator(iterator) {
 287          var i = -1;
 288          return function next() {
 289              var item = iterator.next();
 290              if (item.done)
 291                  return null;
 292              i++;
 293              return {value: item.value, key: i};
 294          }
 295      }
 296  
 297      function createObjectIterator(obj) {
 298          var okeys = obj ? Object.keys(obj) : [];
 299          var i = -1;
 300          var len = okeys.length;
 301          return function next() {
 302              var key = okeys[++i];
 303              return i < len ? {value: obj[key], key} : null;
 304          };
 305      }
 306  
 307      function createIterator(coll) {
 308          if (isArrayLike(coll)) {
 309              return createArrayIterator(coll);
 310          }
 311  
 312          var iterator = getIterator(coll);
 313          return iterator ? createES2015Iterator(iterator) : createObjectIterator(coll);
 314      }
 315  
 316      function onlyOnce(fn) {
 317          return function (...args) {
 318              if (fn === null) throw new Error("Callback was already called.");
 319              var callFn = fn;
 320              fn = null;
 321              callFn.apply(this, args);
 322          };
 323      }
 324  
 325      // for async generators
 326      function asyncEachOfLimit(generator, limit, iteratee, callback) {
 327          let done = false;
 328          let canceled = false;
 329          let awaiting = false;
 330          let running = 0;
 331          let idx = 0;
 332  
 333          function replenish() {
 334              //console.log('replenish')
 335              if (running >= limit || awaiting || done) return
 336              //console.log('replenish awaiting')
 337              awaiting = true;
 338              generator.next().then(({value, done: iterDone}) => {
 339                  //console.log('got value', value)
 340                  if (canceled || done) return
 341                  awaiting = false;
 342                  if (iterDone) {
 343                      done = true;
 344                      if (running <= 0) {
 345                          //console.log('done nextCb')
 346                          callback(null);
 347                      }
 348                      return;
 349                  }
 350                  running++;
 351                  iteratee(value, idx, iterateeCallback);
 352                  idx++;
 353                  replenish();
 354              }).catch(handleError);
 355          }
 356  
 357          function iterateeCallback(err, result) {
 358              //console.log('iterateeCallback')
 359              running -= 1;
 360              if (canceled) return
 361              if (err) return handleError(err)
 362  
 363              if (err === false) {
 364                  done = true;
 365                  canceled = true;
 366                  return
 367              }
 368  
 369              if (result === breakLoop || (done && running <= 0)) {
 370                  done = true;
 371                  //console.log('done iterCb')
 372                  return callback(null);
 373              }
 374              replenish();
 375          }
 376  
 377          function handleError(err) {
 378              if (canceled) return
 379              awaiting = false;
 380              done = true;
 381              callback(err);
 382          }
 383  
 384          replenish();
 385      }
 386  
 387      var eachOfLimit = (limit) => {
 388          return (obj, iteratee, callback) => {
 389              callback = once(callback);
 390              if (limit <= 0) {
 391                  throw new RangeError('concurrency limit cannot be less than 1')
 392              }
 393              if (!obj) {
 394                  return callback(null);
 395              }
 396              if (isAsyncGenerator(obj)) {
 397                  return asyncEachOfLimit(obj, limit, iteratee, callback)
 398              }
 399              if (isAsyncIterable(obj)) {
 400                  return asyncEachOfLimit(obj[Symbol.asyncIterator](), limit, iteratee, callback)
 401              }
 402              var nextElem = createIterator(obj);
 403              var done = false;
 404              var canceled = false;
 405              var running = 0;
 406              var looping = false;
 407  
 408              function iterateeCallback(err, value) {
 409                  if (canceled) return
 410                  running -= 1;
 411                  if (err) {
 412                      done = true;
 413                      callback(err);
 414                  }
 415                  else if (err === false) {
 416                      done = true;
 417                      canceled = true;
 418                  }
 419                  else if (value === breakLoop || (done && running <= 0)) {
 420                      done = true;
 421                      return callback(null);
 422                  }
 423                  else if (!looping) {
 424                      replenish();
 425                  }
 426              }
 427  
 428              function replenish () {
 429                  looping = true;
 430                  while (running < limit && !done) {
 431                      var elem = nextElem();
 432                      if (elem === null) {
 433                          done = true;
 434                          if (running <= 0) {
 435                              callback(null);
 436                          }
 437                          return;
 438                      }
 439                      running += 1;
 440                      iteratee(elem.value, elem.key, onlyOnce(iterateeCallback));
 441                  }
 442                  looping = false;
 443              }
 444  
 445              replenish();
 446          };
 447      };
 448  
 449      /**
 450       * The same as [`eachOf`]{@link module:Collections.eachOf} but runs a maximum of `limit` async operations at a
 451       * time.
 452       *
 453       * @name eachOfLimit
 454       * @static
 455       * @memberOf module:Collections
 456       * @method
 457       * @see [async.eachOf]{@link module:Collections.eachOf}
 458       * @alias forEachOfLimit
 459       * @category Collection
 460       * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
 461       * @param {number} limit - The maximum number of async operations at a time.
 462       * @param {AsyncFunction} iteratee - An async function to apply to each
 463       * item in `coll`. The `key` is the item's key, or index in the case of an
 464       * array.
 465       * Invoked with (item, key, callback).
 466       * @param {Function} [callback] - A callback which is called when all
 467       * `iteratee` functions have finished, or an error occurs. Invoked with (err).
 468       * @returns {Promise} a promise, if a callback is omitted
 469       */
 470      function eachOfLimit$1(coll, limit, iteratee, callback) {
 471          return eachOfLimit(limit)(coll, wrapAsync(iteratee), callback);
 472      }
 473  
 474      var eachOfLimit$2 = awaitify(eachOfLimit$1, 4);
 475  
 476      // eachOf implementation optimized for array-likes
 477      function eachOfArrayLike(coll, iteratee, callback) {
 478          callback = once(callback);
 479          var index = 0,
 480              completed = 0,
 481              {length} = coll,
 482              canceled = false;
 483          if (length === 0) {
 484              callback(null);
 485          }
 486  
 487          function iteratorCallback(err, value) {
 488              if (err === false) {
 489                  canceled = true;
 490              }
 491              if (canceled === true) return
 492              if (err) {
 493                  callback(err);
 494              } else if ((++completed === length) || value === breakLoop) {
 495                  callback(null);
 496              }
 497          }
 498  
 499          for (; index < length; index++) {
 500              iteratee(coll[index], index, onlyOnce(iteratorCallback));
 501          }
 502      }
 503  
 504      // a generic version of eachOf which can handle array, object, and iterator cases.
 505      function eachOfGeneric (coll, iteratee, callback) {
 506          return eachOfLimit$2(coll, Infinity, iteratee, callback);
 507      }
 508  
 509      /**
 510       * Like [`each`]{@link module:Collections.each}, except that it passes the key (or index) as the second argument
 511       * to the iteratee.
 512       *
 513       * @name eachOf
 514       * @static
 515       * @memberOf module:Collections
 516       * @method
 517       * @alias forEachOf
 518       * @category Collection
 519       * @see [async.each]{@link module:Collections.each}
 520       * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
 521       * @param {AsyncFunction} iteratee - A function to apply to each
 522       * item in `coll`.
 523       * The `key` is the item's key, or index in the case of an array.
 524       * Invoked with (item, key, callback).
 525       * @param {Function} [callback] - A callback which is called when all
 526       * `iteratee` functions have finished, or an error occurs. Invoked with (err).
 527       * @returns {Promise} a promise, if a callback is omitted
 528       * @example
 529       *
 530       * var obj = {dev: "/dev.json", test: "/test.json", prod: "/prod.json"};
 531       * var configs = {};
 532       *
 533       * async.forEachOf(obj, function (value, key, callback) {
 534       *     fs.readFile(__dirname + value, "utf8", function (err, data) {
 535       *         if (err) return callback(err);
 536       *         try {
 537       *             configs[key] = JSON.parse(data);
 538       *         } catch (e) {
 539       *             return callback(e);
 540       *         }
 541       *         callback();
 542       *     });
 543       * }, function (err) {
 544       *     if (err) console.error(err.message);
 545       *     // configs is now a map of JSON data
 546       *     doSomethingWith(configs);
 547       * });
 548       */
 549      function eachOf(coll, iteratee, callback) {
 550          var eachOfImplementation = isArrayLike(coll) ? eachOfArrayLike : eachOfGeneric;
 551          return eachOfImplementation(coll, wrapAsync(iteratee), callback);
 552      }
 553  
 554      var eachOf$1 = awaitify(eachOf, 3);
 555  
 556      /**
 557       * Produces a new collection of values by mapping each value in `coll` through
 558       * the `iteratee` function. The `iteratee` is called with an item from `coll`
 559       * and a callback for when it has finished processing. Each of these callback
 560       * takes 2 arguments: an `error`, and the transformed item from `coll`. If
 561       * `iteratee` passes an error to its callback, the main `callback` (for the
 562       * `map` function) is immediately called with the error.
 563       *
 564       * Note, that since this function applies the `iteratee` to each item in
 565       * parallel, there is no guarantee that the `iteratee` functions will complete
 566       * in order. However, the results array will be in the same order as the
 567       * original `coll`.
 568       *
 569       * If `map` is passed an Object, the results will be an Array.  The results
 570       * will roughly be in the order of the original Objects' keys (but this can
 571       * vary across JavaScript engines).
 572       *
 573       * @name map
 574       * @static
 575       * @memberOf module:Collections
 576       * @method
 577       * @category Collection
 578       * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
 579       * @param {AsyncFunction} iteratee - An async function to apply to each item in
 580       * `coll`.
 581       * The iteratee should complete with the transformed item.
 582       * Invoked with (item, callback).
 583       * @param {Function} [callback] - A callback which is called when all `iteratee`
 584       * functions have finished, or an error occurs. Results is an Array of the
 585       * transformed items from the `coll`. Invoked with (err, results).
 586       * @returns {Promise} a promise, if no callback is passed
 587       * @example
 588       *
 589       * async.map(['file1','file2','file3'], fs.stat, function(err, results) {
 590       *     // results is now an array of stats for each file
 591       * });
 592       */
 593      function map (coll, iteratee, callback) {
 594          return _asyncMap(eachOf$1, coll, iteratee, callback)
 595      }
 596      var map$1 = awaitify(map, 3);
 597  
 598      /**
 599       * Applies the provided arguments to each function in the array, calling
 600       * `callback` after all functions have completed. If you only provide the first
 601       * argument, `fns`, then it will return a function which lets you pass in the
 602       * arguments as if it were a single function call. If more arguments are
 603       * provided, `callback` is required while `args` is still optional. The results
 604       * for each of the applied async functions are passed to the final callback
 605       * as an array.
 606       *
 607       * @name applyEach
 608       * @static
 609       * @memberOf module:ControlFlow
 610       * @method
 611       * @category Control Flow
 612       * @param {Array|Iterable|AsyncIterable|Object} fns - A collection of {@link AsyncFunction}s
 613       * to all call with the same arguments
 614       * @param {...*} [args] - any number of separate arguments to pass to the
 615       * function.
 616       * @param {Function} [callback] - the final argument should be the callback,
 617       * called when all functions have completed processing.
 618       * @returns {AsyncFunction} - Returns a function that takes no args other than
 619       * an optional callback, that is the result of applying the `args` to each
 620       * of the functions.
 621       * @example
 622       *
 623       * const appliedFn = async.applyEach([enableSearch, updateSchema], 'bucket')
 624       *
 625       * appliedFn((err, results) => {
 626       *     // results[0] is the results for `enableSearch`
 627       *     // results[1] is the results for `updateSchema`
 628       * });
 629       *
 630       * // partial application example:
 631       * async.each(
 632       *     buckets,
 633       *     async (bucket) => async.applyEach([enableSearch, updateSchema], bucket)(),
 634       *     callback
 635       * );
 636       */
 637      var applyEach$1 = applyEach(map$1);
 638  
 639      /**
 640       * The same as [`eachOf`]{@link module:Collections.eachOf} but runs only a single async operation at a time.
 641       *
 642       * @name eachOfSeries
 643       * @static
 644       * @memberOf module:Collections
 645       * @method
 646       * @see [async.eachOf]{@link module:Collections.eachOf}
 647       * @alias forEachOfSeries
 648       * @category Collection
 649       * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
 650       * @param {AsyncFunction} iteratee - An async function to apply to each item in
 651       * `coll`.
 652       * Invoked with (item, key, callback).
 653       * @param {Function} [callback] - A callback which is called when all `iteratee`
 654       * functions have finished, or an error occurs. Invoked with (err).
 655       * @returns {Promise} a promise, if a callback is omitted
 656       */
 657      function eachOfSeries(coll, iteratee, callback) {
 658          return eachOfLimit$2(coll, 1, iteratee, callback)
 659      }
 660      var eachOfSeries$1 = awaitify(eachOfSeries, 3);
 661  
 662      /**
 663       * The same as [`map`]{@link module:Collections.map} but runs only a single async operation at a time.
 664       *
 665       * @name mapSeries
 666       * @static
 667       * @memberOf module:Collections
 668       * @method
 669       * @see [async.map]{@link module:Collections.map}
 670       * @category Collection
 671       * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
 672       * @param {AsyncFunction} iteratee - An async function to apply to each item in
 673       * `coll`.
 674       * The iteratee should complete with the transformed item.
 675       * Invoked with (item, callback).
 676       * @param {Function} [callback] - A callback which is called when all `iteratee`
 677       * functions have finished, or an error occurs. Results is an array of the
 678       * transformed items from the `coll`. Invoked with (err, results).
 679       * @returns {Promise} a promise, if no callback is passed
 680       */
 681      function mapSeries (coll, iteratee, callback) {
 682          return _asyncMap(eachOfSeries$1, coll, iteratee, callback)
 683      }
 684      var mapSeries$1 = awaitify(mapSeries, 3);
 685  
 686      /**
 687       * The same as [`applyEach`]{@link module:ControlFlow.applyEach} but runs only a single async operation at a time.
 688       *
 689       * @name applyEachSeries
 690       * @static
 691       * @memberOf module:ControlFlow
 692       * @method
 693       * @see [async.applyEach]{@link module:ControlFlow.applyEach}
 694       * @category Control Flow
 695       * @param {Array|Iterable|AsyncIterable|Object} fns - A collection of {@link AsyncFunction}s to all
 696       * call with the same arguments
 697       * @param {...*} [args] - any number of separate arguments to pass to the
 698       * function.
 699       * @param {Function} [callback] - the final argument should be the callback,
 700       * called when all functions have completed processing.
 701       * @returns {AsyncFunction} - A function, that when called, is the result of
 702       * appling the `args` to the list of functions.  It takes no args, other than
 703       * a callback.
 704       */
 705      var applyEachSeries = applyEach(mapSeries$1);
 706  
 707      const PROMISE_SYMBOL = Symbol('promiseCallback');
 708  
 709      function promiseCallback () {
 710          let resolve, reject;
 711          function callback (err, ...args) {
 712              if (err) return reject(err)
 713              resolve(args.length > 1 ? args : args[0]);
 714          }
 715  
 716          callback[PROMISE_SYMBOL] = new Promise((res, rej) => {
 717              resolve = res,
 718              reject = rej;
 719          });
 720  
 721          return callback
 722      }
 723  
 724      /**
 725       * Determines the best order for running the {@link AsyncFunction}s in `tasks`, based on
 726       * their requirements. Each function can optionally depend on other functions
 727       * being completed first, and each function is run as soon as its requirements
 728       * are satisfied.
 729       *
 730       * If any of the {@link AsyncFunction}s pass an error to their callback, the `auto` sequence
 731       * will stop. Further tasks will not execute (so any other functions depending
 732       * on it will not run), and the main `callback` is immediately called with the
 733       * error.
 734       *
 735       * {@link AsyncFunction}s also receive an object containing the results of functions which
 736       * have completed so far as the first argument, if they have dependencies. If a
 737       * task function has no dependencies, it will only be passed a callback.
 738       *
 739       * @name auto
 740       * @static
 741       * @memberOf module:ControlFlow
 742       * @method
 743       * @category Control Flow
 744       * @param {Object} tasks - An object. Each of its properties is either a
 745       * function or an array of requirements, with the {@link AsyncFunction} itself the last item
 746       * in the array. The object's key of a property serves as the name of the task
 747       * defined by that property, i.e. can be used when specifying requirements for
 748       * other tasks. The function receives one or two arguments:
 749       * * a `results` object, containing the results of the previously executed
 750       *   functions, only passed if the task has any dependencies,
 751       * * a `callback(err, result)` function, which must be called when finished,
 752       *   passing an `error` (which can be `null`) and the result of the function's
 753       *   execution.
 754       * @param {number} [concurrency=Infinity] - An optional `integer` for
 755       * determining the maximum number of tasks that can be run in parallel. By
 756       * default, as many as possible.
 757       * @param {Function} [callback] - An optional callback which is called when all
 758       * the tasks have been completed. It receives the `err` argument if any `tasks`
 759       * pass an error to their callback. Results are always returned; however, if an
 760       * error occurs, no further `tasks` will be performed, and the results object
 761       * will only contain partial results. Invoked with (err, results).
 762       * @returns {Promise} a promise, if a callback is not passed
 763       * @example
 764       *
 765       * async.auto({
 766       *     // this function will just be passed a callback
 767       *     readData: async.apply(fs.readFile, 'data.txt', 'utf-8'),
 768       *     showData: ['readData', function(results, cb) {
 769       *         // results.readData is the file's contents
 770       *         // ...
 771       *     }]
 772       * }, callback);
 773       *
 774       * async.auto({
 775       *     get_data: function(callback) {
 776       *         console.log('in get_data');
 777       *         // async code to get some data
 778       *         callback(null, 'data', 'converted to array');
 779       *     },
 780       *     make_folder: function(callback) {
 781       *         console.log('in make_folder');
 782       *         // async code to create a directory to store a file in
 783       *         // this is run at the same time as getting the data
 784       *         callback(null, 'folder');
 785       *     },
 786       *     write_file: ['get_data', 'make_folder', function(results, callback) {
 787       *         console.log('in write_file', JSON.stringify(results));
 788       *         // once there is some data and the directory exists,
 789       *         // write the data to a file in the directory
 790       *         callback(null, 'filename');
 791       *     }],
 792       *     email_link: ['write_file', function(results, callback) {
 793       *         console.log('in email_link', JSON.stringify(results));
 794       *         // once the file is written let's email a link to it...
 795       *         // results.write_file contains the filename returned by write_file.
 796       *         callback(null, {'file':results.write_file, 'email':'user@example.com'});
 797       *     }]
 798       * }, function(err, results) {
 799       *     console.log('err = ', err);
 800       *     console.log('results = ', results);
 801       * });
 802       */
 803      function auto(tasks, concurrency, callback) {
 804          if (typeof concurrency !== 'number') {
 805              // concurrency is optional, shift the args.
 806              callback = concurrency;
 807              concurrency = null;
 808          }
 809          callback = once(callback || promiseCallback());
 810          var numTasks = Object.keys(tasks).length;
 811          if (!numTasks) {
 812              return callback(null);
 813          }
 814          if (!concurrency) {
 815              concurrency = numTasks;
 816          }
 817  
 818          var results = {};
 819          var runningTasks = 0;
 820          var canceled = false;
 821          var hasError = false;
 822  
 823          var listeners = Object.create(null);
 824  
 825          var readyTasks = [];
 826  
 827          // for cycle detection:
 828          var readyToCheck = []; // tasks that have been identified as reachable
 829          // without the possibility of returning to an ancestor task
 830          var uncheckedDependencies = {};
 831  
 832          Object.keys(tasks).forEach(key => {
 833              var task = tasks[key];
 834              if (!Array.isArray(task)) {
 835                  // no dependencies
 836                  enqueueTask(key, [task]);
 837                  readyToCheck.push(key);
 838                  return;
 839              }
 840  
 841              var dependencies = task.slice(0, task.length - 1);
 842              var remainingDependencies = dependencies.length;
 843              if (remainingDependencies === 0) {
 844                  enqueueTask(key, task);
 845                  readyToCheck.push(key);
 846                  return;
 847              }
 848              uncheckedDependencies[key] = remainingDependencies;
 849  
 850              dependencies.forEach(dependencyName => {
 851                  if (!tasks[dependencyName]) {
 852                      throw new Error('async.auto task `' + key +
 853                          '` has a non-existent dependency `' +
 854                          dependencyName + '` in ' +
 855                          dependencies.join(', '));
 856                  }
 857                  addListener(dependencyName, () => {
 858                      remainingDependencies--;
 859                      if (remainingDependencies === 0) {
 860                          enqueueTask(key, task);
 861                      }
 862                  });
 863              });
 864          });
 865  
 866          checkForDeadlocks();
 867          processQueue();
 868  
 869          function enqueueTask(key, task) {
 870              readyTasks.push(() => runTask(key, task));
 871          }
 872  
 873          function processQueue() {
 874              if (canceled) return
 875              if (readyTasks.length === 0 && runningTasks === 0) {
 876                  return callback(null, results);
 877              }
 878              while(readyTasks.length && runningTasks < concurrency) {
 879                  var run = readyTasks.shift();
 880                  run();
 881              }
 882  
 883          }
 884  
 885          function addListener(taskName, fn) {
 886              var taskListeners = listeners[taskName];
 887              if (!taskListeners) {
 888                  taskListeners = listeners[taskName] = [];
 889              }
 890  
 891              taskListeners.push(fn);
 892          }
 893  
 894          function taskComplete(taskName) {
 895              var taskListeners = listeners[taskName] || [];
 896              taskListeners.forEach(fn => fn());
 897              processQueue();
 898          }
 899  
 900  
 901          function runTask(key, task) {
 902              if (hasError) return;
 903  
 904              var taskCallback = onlyOnce((err, ...result) => {
 905                  runningTasks--;
 906                  if (err === false) {
 907                      canceled = true;
 908                      return
 909                  }
 910                  if (result.length < 2) {
 911                      [result] = result;
 912                  }
 913                  if (err) {
 914                      var safeResults = {};
 915                      Object.keys(results).forEach(rkey => {
 916                          safeResults[rkey] = results[rkey];
 917                      });
 918                      safeResults[key] = result;
 919                      hasError = true;
 920                      listeners = Object.create(null);
 921                      if (canceled) return
 922                      callback(err, safeResults);
 923                  } else {
 924                      results[key] = result;
 925                      taskComplete(key);
 926                  }
 927              });
 928  
 929              runningTasks++;
 930              var taskFn = wrapAsync(task[task.length - 1]);
 931              if (task.length > 1) {
 932                  taskFn(results, taskCallback);
 933              } else {
 934                  taskFn(taskCallback);
 935              }
 936          }
 937  
 938          function checkForDeadlocks() {
 939              // Kahn's algorithm
 940              // https://en.wikipedia.org/wiki/Topological_sorting#Kahn.27s_algorithm
 941              // http://connalle.blogspot.com/2013/10/topological-sortingkahn-algorithm.html
 942              var currentTask;
 943              var counter = 0;
 944              while (readyToCheck.length) {
 945                  currentTask = readyToCheck.pop();
 946                  counter++;
 947                  getDependents(currentTask).forEach(dependent => {
 948                      if (--uncheckedDependencies[dependent] === 0) {
 949                          readyToCheck.push(dependent);
 950                      }
 951                  });
 952              }
 953  
 954              if (counter !== numTasks) {
 955                  throw new Error(
 956                      'async.auto cannot execute tasks due to a recursive dependency'
 957                  );
 958              }
 959          }
 960  
 961          function getDependents(taskName) {
 962              var result = [];
 963              Object.keys(tasks).forEach(key => {
 964                  const task = tasks[key];
 965                  if (Array.isArray(task) && task.indexOf(taskName) >= 0) {
 966                      result.push(key);
 967                  }
 968              });
 969              return result;
 970          }
 971  
 972          return callback[PROMISE_SYMBOL]
 973      }
 974  
 975      var FN_ARGS = /^(?:async\s+)?(?:function)?\s*\w*\s*\(\s*([^)]+)\s*\)(?:\s*{)/;
 976      var ARROW_FN_ARGS = /^(?:async\s+)?\(?\s*([^)=]+)\s*\)?(?:\s*=>)/;
 977      var FN_ARG_SPLIT = /,/;
 978      var FN_ARG = /(=.+)?(\s*)$/;
 979      var STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg;
 980  
 981      function parseParams(func) {
 982          const src = func.toString().replace(STRIP_COMMENTS, '');
 983          let match = src.match(FN_ARGS);
 984          if (!match) {
 985              match = src.match(ARROW_FN_ARGS);
 986          }
 987          if (!match) throw new Error('could not parse args in autoInject\nSource:\n' + src)
 988          let [, args] = match;
 989          return args
 990              .replace(/\s/g, '')
 991              .split(FN_ARG_SPLIT)
 992              .map((arg) => arg.replace(FN_ARG, '').trim());
 993      }
 994  
 995      /**
 996       * A dependency-injected version of the [async.auto]{@link module:ControlFlow.auto} function. Dependent
 997       * tasks are specified as parameters to the function, after the usual callback
 998       * parameter, with the parameter names matching the names of the tasks it
 999       * depends on. This can provide even more readable task graphs which can be
1000       * easier to maintain.
1001       *
1002       * If a final callback is specified, the task results are similarly injected,
1003       * specified as named parameters after the initial error parameter.
1004       *
1005       * The autoInject function is purely syntactic sugar and its semantics are
1006       * otherwise equivalent to [async.auto]{@link module:ControlFlow.auto}.
1007       *
1008       * @name autoInject
1009       * @static
1010       * @memberOf module:ControlFlow
1011       * @method
1012       * @see [async.auto]{@link module:ControlFlow.auto}
1013       * @category Control Flow
1014       * @param {Object} tasks - An object, each of whose properties is an {@link AsyncFunction} of
1015       * the form 'func([dependencies...], callback). The object's key of a property
1016       * serves as the name of the task defined by that property, i.e. can be used
1017       * when specifying requirements for other tasks.
1018       * * The `callback` parameter is a `callback(err, result)` which must be called
1019       *   when finished, passing an `error` (which can be `null`) and the result of
1020       *   the function's execution. The remaining parameters name other tasks on
1021       *   which the task is dependent, and the results from those tasks are the
1022       *   arguments of those parameters.
1023       * @param {Function} [callback] - An optional callback which is called when all
1024       * the tasks have been completed. It receives the `err` argument if any `tasks`
1025       * pass an error to their callback, and a `results` object with any completed
1026       * task results, similar to `auto`.
1027       * @returns {Promise} a promise, if no callback is passed
1028       * @example
1029       *
1030       * //  The example from `auto` can be rewritten as follows:
1031       * async.autoInject({
1032       *     get_data: function(callback) {
1033       *         // async code to get some data
1034       *         callback(null, 'data', 'converted to array');
1035       *     },
1036       *     make_folder: function(callback) {
1037       *         // async code to create a directory to store a file in
1038       *         // this is run at the same time as getting the data
1039       *         callback(null, 'folder');
1040       *     },
1041       *     write_file: function(get_data, make_folder, callback) {
1042       *         // once there is some data and the directory exists,
1043       *         // write the data to a file in the directory
1044       *         callback(null, 'filename');
1045       *     },
1046       *     email_link: function(write_file, callback) {
1047       *         // once the file is written let's email a link to it...
1048       *         // write_file contains the filename returned by write_file.
1049       *         callback(null, {'file':write_file, 'email':'user@example.com'});
1050       *     }
1051       * }, function(err, results) {
1052       *     console.log('err = ', err);
1053       *     console.log('email_link = ', results.email_link);
1054       * });
1055       *
1056       * // If you are using a JS minifier that mangles parameter names, `autoInject`
1057       * // will not work with plain functions, since the parameter names will be
1058       * // collapsed to a single letter identifier.  To work around this, you can
1059       * // explicitly specify the names of the parameters your task function needs
1060       * // in an array, similar to Angular.js dependency injection.
1061       *
1062       * // This still has an advantage over plain `auto`, since the results a task
1063       * // depends on are still spread into arguments.
1064       * async.autoInject({
1065       *     //...
1066       *     write_file: ['get_data', 'make_folder', function(get_data, make_folder, callback) {
1067       *         callback(null, 'filename');
1068       *     }],
1069       *     email_link: ['write_file', function(write_file, callback) {
1070       *         callback(null, {'file':write_file, 'email':'user@example.com'});
1071       *     }]
1072       *     //...
1073       * }, function(err, results) {
1074       *     console.log('err = ', err);
1075       *     console.log('email_link = ', results.email_link);
1076       * });
1077       */
1078      function autoInject(tasks, callback) {
1079          var newTasks = {};
1080  
1081          Object.keys(tasks).forEach(key => {
1082              var taskFn = tasks[key];
1083              var params;
1084              var fnIsAsync = isAsync(taskFn);
1085              var hasNoDeps =
1086                  (!fnIsAsync && taskFn.length === 1) ||
1087                  (fnIsAsync && taskFn.length === 0);
1088  
1089              if (Array.isArray(taskFn)) {
1090                  params = [...taskFn];
1091                  taskFn = params.pop();
1092  
1093                  newTasks[key] = params.concat(params.length > 0 ? newTask : taskFn);
1094              } else if (hasNoDeps) {
1095                  // no dependencies, use the function as-is
1096                  newTasks[key] = taskFn;
1097              } else {
1098                  params = parseParams(taskFn);
1099                  if ((taskFn.length === 0 && !fnIsAsync) && params.length === 0) {
1100                      throw new Error("autoInject task functions require explicit parameters.");
1101                  }
1102  
1103                  // remove callback param
1104                  if (!fnIsAsync) params.pop();
1105  
1106                  newTasks[key] = params.concat(newTask);
1107              }
1108  
1109              function newTask(results, taskCb) {
1110                  var newArgs = params.map(name => results[name]);
1111                  newArgs.push(taskCb);
1112                  wrapAsync(taskFn)(...newArgs);
1113              }
1114          });
1115  
1116          return auto(newTasks, callback);
1117      }
1118  
1119      // Simple doubly linked list (https://en.wikipedia.org/wiki/Doubly_linked_list) implementation
1120      // used for queues. This implementation assumes that the node provided by the user can be modified
1121      // to adjust the next and last properties. We implement only the minimal functionality
1122      // for queue support.
1123      class DLL {
1124          constructor() {
1125              this.head = this.tail = null;
1126              this.length = 0;
1127          }
1128  
1129          removeLink(node) {
1130              if (node.prev) node.prev.next = node.next;
1131              else this.head = node.next;
1132              if (node.next) node.next.prev = node.prev;
1133              else this.tail = node.prev;
1134  
1135              node.prev = node.next = null;
1136              this.length -= 1;
1137              return node;
1138          }
1139  
1140          empty () {
1141              while(this.head) this.shift();
1142              return this;
1143          }
1144  
1145          insertAfter(node, newNode) {
1146              newNode.prev = node;
1147              newNode.next = node.next;
1148              if (node.next) node.next.prev = newNode;
1149              else this.tail = newNode;
1150              node.next = newNode;
1151              this.length += 1;
1152          }
1153  
1154          insertBefore(node, newNode) {
1155              newNode.prev = node.prev;
1156              newNode.next = node;
1157              if (node.prev) node.prev.next = newNode;
1158              else this.head = newNode;
1159              node.prev = newNode;
1160              this.length += 1;
1161          }
1162  
1163          unshift(node) {
1164              if (this.head) this.insertBefore(this.head, node);
1165              else setInitial(this, node);
1166          }
1167  
1168          push(node) {
1169              if (this.tail) this.insertAfter(this.tail, node);
1170              else setInitial(this, node);
1171          }
1172  
1173          shift() {
1174              return this.head && this.removeLink(this.head);
1175          }
1176  
1177          pop() {
1178              return this.tail && this.removeLink(this.tail);
1179          }
1180  
1181          toArray() {
1182              return [...this]
1183          }
1184  
1185          *[Symbol.iterator] () {
1186              var cur = this.head;
1187              while (cur) {
1188                  yield cur.data;
1189                  cur = cur.next;
1190              }
1191          }
1192  
1193          remove (testFn) {
1194              var curr = this.head;
1195              while(curr) {
1196                  var {next} = curr;
1197                  if (testFn(curr)) {
1198                      this.removeLink(curr);
1199                  }
1200                  curr = next;
1201              }
1202              return this;
1203          }
1204      }
1205  
1206      function setInitial(dll, node) {
1207          dll.length = 1;
1208          dll.head = dll.tail = node;
1209      }
1210  
1211      function queue(worker, concurrency, payload) {
1212          if (concurrency == null) {
1213              concurrency = 1;
1214          }
1215          else if(concurrency === 0) {
1216              throw new RangeError('Concurrency must not be zero');
1217          }
1218  
1219          var _worker = wrapAsync(worker);
1220          var numRunning = 0;
1221          var workersList = [];
1222          const events = {
1223              error: [],
1224              drain: [],
1225              saturated: [],
1226              unsaturated: [],
1227              empty: []
1228          };
1229  
1230          function on (event, handler) {
1231              events[event].push(handler);
1232          }
1233  
1234          function once (event, handler) {
1235              const handleAndRemove = (...args) => {
1236                  off(event, handleAndRemove);
1237                  handler(...args);
1238              };
1239              events[event].push(handleAndRemove);
1240          }
1241  
1242          function off (event, handler) {
1243              if (!event) return Object.keys(events).forEach(ev => events[ev] = [])
1244              if (!handler) return events[event] = []
1245              events[event] = events[event].filter(ev => ev !== handler);
1246          }
1247  
1248          function trigger (event, ...args) {
1249              events[event].forEach(handler => handler(...args));
1250          }
1251  
1252          var processingScheduled = false;
1253          function _insert(data, insertAtFront, rejectOnError, callback) {
1254              if (callback != null && typeof callback !== 'function') {
1255                  throw new Error('task callback must be a function');
1256              }
1257              q.started = true;
1258  
1259              var res, rej;
1260              function promiseCallback (err, ...args) {
1261                  // we don't care about the error, let the global error handler
1262                  // deal with it
1263                  if (err) return rejectOnError ? rej(err) : res()
1264                  if (args.length <= 1) return res(args[0])
1265                  res(args);
1266              }
1267  
1268              var item = {
1269                  data,
1270                  callback: rejectOnError ?
1271                      promiseCallback :
1272                      (callback || promiseCallback)
1273              };
1274  
1275              if (insertAtFront) {
1276                  q._tasks.unshift(item);
1277              } else {
1278                  q._tasks.push(item);
1279              }
1280  
1281              if (!processingScheduled) {
1282                  processingScheduled = true;
1283                  setImmediate$1(() => {
1284                      processingScheduled = false;
1285                      q.process();
1286                  });
1287              }
1288  
1289              if (rejectOnError || !callback) {
1290                  return new Promise((resolve, reject) => {
1291                      res = resolve;
1292                      rej = reject;
1293                  })
1294              }
1295          }
1296  
1297          function _createCB(tasks) {
1298              return function (err, ...args) {
1299                  numRunning -= 1;
1300  
1301                  for (var i = 0, l = tasks.length; i < l; i++) {
1302                      var task = tasks[i];
1303  
1304                      var index = workersList.indexOf(task);
1305                      if (index === 0) {
1306                          workersList.shift();
1307                      } else if (index > 0) {
1308                          workersList.splice(index, 1);
1309                      }
1310  
1311                      task.callback(err, ...args);
1312  
1313                      if (err != null) {
1314                          trigger('error', err, task.data);
1315                      }
1316                  }
1317  
1318                  if (numRunning <= (q.concurrency - q.buffer) ) {
1319                      trigger('unsaturated');
1320                  }
1321  
1322                  if (q.idle()) {
1323                      trigger('drain');
1324                  }
1325                  q.process();
1326              };
1327          }
1328  
1329          function _maybeDrain(data) {
1330              if (data.length === 0 && q.idle()) {
1331                  // call drain immediately if there are no tasks
1332                  setImmediate$1(() => trigger('drain'));
1333                  return true
1334              }
1335              return false
1336          }
1337  
1338          const eventMethod = (name) => (handler) => {
1339              if (!handler) {
1340                  return new Promise((resolve, reject) => {
1341                      once(name, (err, data) => {
1342                          if (err) return reject(err)
1343                          resolve(data);
1344                      });
1345                  })
1346              }
1347              off(name);
1348              on(name, handler);
1349  
1350          };
1351  
1352          var isProcessing = false;
1353          var q = {
1354              _tasks: new DLL(),
1355              *[Symbol.iterator] () {
1356                  yield* q._tasks[Symbol.iterator]();
1357              },
1358              concurrency,
1359              payload,
1360              buffer: concurrency / 4,
1361              started: false,
1362              paused: false,
1363              push (data, callback) {
1364                  if (Array.isArray(data)) {
1365                      if (_maybeDrain(data)) return
1366                      return data.map(datum => _insert(datum, false, false, callback))
1367                  }
1368                  return _insert(data, false, false, callback);
1369              },
1370              pushAsync (data, callback) {
1371                  if (Array.isArray(data)) {
1372                      if (_maybeDrain(data)) return
1373                      return data.map(datum => _insert(datum, false, true, callback))
1374                  }
1375                  return _insert(data, false, true, callback);
1376              },
1377              kill () {
1378                  off();
1379                  q._tasks.empty();
1380              },
1381              unshift (data, callback) {
1382                  if (Array.isArray(data)) {
1383                      if (_maybeDrain(data)) return
1384                      return data.map(datum => _insert(datum, true, false, callback))
1385                  }
1386                  return _insert(data, true, false, callback);
1387              },
1388              unshiftAsync (data, callback) {
1389                  if (Array.isArray(data)) {
1390                      if (_maybeDrain(data)) return
1391                      return data.map(datum => _insert(datum, true, true, callback))
1392                  }
1393                  return _insert(data, true, true, callback);
1394              },
1395              remove (testFn) {
1396                  q._tasks.remove(testFn);
1397              },
1398              process () {
1399                  // Avoid trying to start too many processing operations. This can occur
1400                  // when callbacks resolve synchronously (#1267).
1401                  if (isProcessing) {
1402                      return;
1403                  }
1404                  isProcessing = true;
1405                  while(!q.paused && numRunning < q.concurrency && q._tasks.length){
1406                      var tasks = [], data = [];
1407                      var l = q._tasks.length;
1408                      if (q.payload) l = Math.min(l, q.payload);
1409                      for (var i = 0; i < l; i++) {
1410                          var node = q._tasks.shift();
1411                          tasks.push(node);
1412                          workersList.push(node);
1413                          data.push(node.data);
1414                      }
1415  
1416                      numRunning += 1;
1417  
1418                      if (q._tasks.length === 0) {
1419                          trigger('empty');
1420                      }
1421  
1422                      if (numRunning === q.concurrency) {
1423                          trigger('saturated');
1424                      }
1425  
1426                      var cb = onlyOnce(_createCB(tasks));
1427                      _worker(data, cb);
1428                  }
1429                  isProcessing = false;
1430              },
1431              length () {
1432                  return q._tasks.length;
1433              },
1434              running () {
1435                  return numRunning;
1436              },
1437              workersList () {
1438                  return workersList;
1439              },
1440              idle() {
1441                  return q._tasks.length + numRunning === 0;
1442              },
1443              pause () {
1444                  q.paused = true;
1445              },
1446              resume () {
1447                  if (q.paused === false) { return; }
1448                  q.paused = false;
1449                  setImmediate$1(q.process);
1450              }
1451          };
1452          // define these as fixed properties, so people get useful errors when updating
1453          Object.defineProperties(q, {
1454              saturated: {
1455                  writable: false,
1456                  value: eventMethod('saturated')
1457              },
1458              unsaturated: {
1459                  writable: false,
1460                  value: eventMethod('unsaturated')
1461              },
1462              empty: {
1463                  writable: false,
1464                  value: eventMethod('empty')
1465              },
1466              drain: {
1467                  writable: false,
1468                  value: eventMethod('drain')
1469              },
1470              error: {
1471                  writable: false,
1472                  value: eventMethod('error')
1473              },
1474          });
1475          return q;
1476      }
1477  
1478      /**
1479       * Creates a `cargo` object with the specified payload. Tasks added to the
1480       * cargo will be processed altogether (up to the `payload` limit). If the
1481       * `worker` is in progress, the task is queued until it becomes available. Once
1482       * the `worker` has completed some tasks, each callback of those tasks is
1483       * called. Check out [these](https://camo.githubusercontent.com/6bbd36f4cf5b35a0f11a96dcd2e97711ffc2fb37/68747470733a2f2f662e636c6f75642e6769746875622e636f6d2f6173736574732f313637363837312f36383130382f62626330636662302d356632392d313165322d393734662d3333393763363464633835382e676966) [animations](https://camo.githubusercontent.com/f4810e00e1c5f5f8addbe3e9f49064fd5d102699/68747470733a2f2f662e636c6f75642e6769746875622e636f6d2f6173736574732f313637363837312f36383130312f38346339323036362d356632392d313165322d383134662d3964336430323431336266642e676966)
1484       * for how `cargo` and `queue` work.
1485       *
1486       * While [`queue`]{@link module:ControlFlow.queue} passes only one task to one of a group of workers
1487       * at a time, cargo passes an array of tasks to a single worker, repeating
1488       * when the worker is finished.
1489       *
1490       * @name cargo
1491       * @static
1492       * @memberOf module:ControlFlow
1493       * @method
1494       * @see [async.queue]{@link module:ControlFlow.queue}
1495       * @category Control Flow
1496       * @param {AsyncFunction} worker - An asynchronous function for processing an array
1497       * of queued tasks. Invoked with `(tasks, callback)`.
1498       * @param {number} [payload=Infinity] - An optional `integer` for determining
1499       * how many tasks should be processed per round; if omitted, the default is
1500       * unlimited.
1501       * @returns {module:ControlFlow.QueueObject} A cargo object to manage the tasks. Callbacks can
1502       * attached as certain properties to listen for specific events during the
1503       * lifecycle of the cargo and inner queue.
1504       * @example
1505       *
1506       * // create a cargo object with payload 2
1507       * var cargo = async.cargo(function(tasks, callback) {
1508       *     for (var i=0; i<tasks.length; i++) {
1509       *         console.log('hello ' + tasks[i].name);
1510       *     }
1511       *     callback();
1512       * }, 2);
1513       *
1514       * // add some items
1515       * cargo.push({name: 'foo'}, function(err) {
1516       *     console.log('finished processing foo');
1517       * });
1518       * cargo.push({name: 'bar'}, function(err) {
1519       *     console.log('finished processing bar');
1520       * });
1521       * await cargo.push({name: 'baz'});
1522       * console.log('finished processing baz');
1523       */
1524      function cargo(worker, payload) {
1525          return queue(worker, 1, payload);
1526      }
1527  
1528      /**
1529       * Creates a `cargoQueue` object with the specified payload. Tasks added to the
1530       * cargoQueue will be processed together (up to the `payload` limit) in `concurrency` parallel workers.
1531       * If the all `workers` are in progress, the task is queued until one becomes available. Once
1532       * a `worker` has completed some tasks, each callback of those tasks is
1533       * called. Check out [these](https://camo.githubusercontent.com/6bbd36f4cf5b35a0f11a96dcd2e97711ffc2fb37/68747470733a2f2f662e636c6f75642e6769746875622e636f6d2f6173736574732f313637363837312f36383130382f62626330636662302d356632392d313165322d393734662d3333393763363464633835382e676966) [animations](https://camo.githubusercontent.com/f4810e00e1c5f5f8addbe3e9f49064fd5d102699/68747470733a2f2f662e636c6f75642e6769746875622e636f6d2f6173736574732f313637363837312f36383130312f38346339323036362d356632392d313165322d383134662d3964336430323431336266642e676966)
1534       * for how `cargo` and `queue` work.
1535       *
1536       * While [`queue`]{@link module:ControlFlow.queue} passes only one task to one of a group of workers
1537       * at a time, and [`cargo`]{@link module:ControlFlow.cargo} passes an array of tasks to a single worker,
1538       * the cargoQueue passes an array of tasks to multiple parallel workers.
1539       *
1540       * @name cargoQueue
1541       * @static
1542       * @memberOf module:ControlFlow
1543       * @method
1544       * @see [async.queue]{@link module:ControlFlow.queue}
1545       * @see [async.cargo]{@link module:ControlFLow.cargo}
1546       * @category Control Flow
1547       * @param {AsyncFunction} worker - An asynchronous function for processing an array
1548       * of queued tasks. Invoked with `(tasks, callback)`.
1549       * @param {number} [concurrency=1] - An `integer` for determining how many
1550       * `worker` functions should be run in parallel.  If omitted, the concurrency
1551       * defaults to `1`.  If the concurrency is `0`, an error is thrown.
1552       * @param {number} [payload=Infinity] - An optional `integer` for determining
1553       * how many tasks should be processed per round; if omitted, the default is
1554       * unlimited.
1555       * @returns {module:ControlFlow.QueueObject} A cargoQueue object to manage the tasks. Callbacks can
1556       * attached as certain properties to listen for specific events during the
1557       * lifecycle of the cargoQueue and inner queue.
1558       * @example
1559       *
1560       * // create a cargoQueue object with payload 2 and concurrency 2
1561       * var cargoQueue = async.cargoQueue(function(tasks, callback) {
1562       *     for (var i=0; i<tasks.length; i++) {
1563       *         console.log('hello ' + tasks[i].name);
1564       *     }
1565       *     callback();
1566       * }, 2, 2);
1567       *
1568       * // add some items
1569       * cargoQueue.push({name: 'foo'}, function(err) {
1570       *     console.log('finished processing foo');
1571       * });
1572       * cargoQueue.push({name: 'bar'}, function(err) {
1573       *     console.log('finished processing bar');
1574       * });
1575       * cargoQueue.push({name: 'baz'}, function(err) {
1576       *     console.log('finished processing baz');
1577       * });
1578       * cargoQueue.push({name: 'boo'}, function(err) {
1579       *     console.log('finished processing boo');
1580       * });
1581       */
1582      function cargo$1(worker, concurrency, payload) {
1583          return queue(worker, concurrency, payload);
1584      }
1585  
1586      /**
1587       * Reduces `coll` into a single value using an async `iteratee` to return each
1588       * successive step. `memo` is the initial state of the reduction. This function
1589       * only operates in series.
1590       *
1591       * For performance reasons, it may make sense to split a call to this function
1592       * into a parallel map, and then use the normal `Array.prototype.reduce` on the
1593       * results. This function is for situations where each step in the reduction
1594       * needs to be async; if you can get the data before reducing it, then it's
1595       * probably a good idea to do so.
1596       *
1597       * @name reduce
1598       * @static
1599       * @memberOf module:Collections
1600       * @method
1601       * @alias inject
1602       * @alias foldl
1603       * @category Collection
1604       * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
1605       * @param {*} memo - The initial state of the reduction.
1606       * @param {AsyncFunction} iteratee - A function applied to each item in the
1607       * array to produce the next step in the reduction.
1608       * The `iteratee` should complete with the next state of the reduction.
1609       * If the iteratee complete with an error, the reduction is stopped and the
1610       * main `callback` is immediately called with the error.
1611       * Invoked with (memo, item, callback).
1612       * @param {Function} [callback] - A callback which is called after all the
1613       * `iteratee` functions have finished. Result is the reduced value. Invoked with
1614       * (err, result).
1615       * @returns {Promise} a promise, if no callback is passed
1616       * @example
1617       *
1618       * async.reduce([1,2,3], 0, function(memo, item, callback) {
1619       *     // pointless async:
1620       *     process.nextTick(function() {
1621       *         callback(null, memo + item)
1622       *     });
1623       * }, function(err, result) {
1624       *     // result is now equal to the last value of memo, which is 6
1625       * });
1626       */
1627      function reduce(coll, memo, iteratee, callback) {
1628          callback = once(callback);
1629          var _iteratee = wrapAsync(iteratee);
1630          return eachOfSeries$1(coll, (x, i, iterCb) => {
1631              _iteratee(memo, x, (err, v) => {
1632                  memo = v;
1633                  iterCb(err);
1634              });
1635          }, err => callback(err, memo));
1636      }
1637      var reduce$1 = awaitify(reduce, 4);
1638  
1639      /**
1640       * Version of the compose function that is more natural to read. Each function
1641       * consumes the return value of the previous function. It is the equivalent of
1642       * [compose]{@link module:ControlFlow.compose} with the arguments reversed.
1643       *
1644       * Each function is executed with the `this` binding of the composed function.
1645       *
1646       * @name seq
1647       * @static
1648       * @memberOf module:ControlFlow
1649       * @method
1650       * @see [async.compose]{@link module:ControlFlow.compose}
1651       * @category Control Flow
1652       * @param {...AsyncFunction} functions - the asynchronous functions to compose
1653       * @returns {Function} a function that composes the `functions` in order
1654       * @example
1655       *
1656       * // Requires lodash (or underscore), express3 and dresende's orm2.
1657       * // Part of an app, that fetches cats of the logged user.
1658       * // This example uses `seq` function to avoid overnesting and error
1659       * // handling clutter.
1660       * app.get('/cats', function(request, response) {
1661       *     var User = request.models.User;
1662       *     async.seq(
1663       *         _.bind(User.get, User),  // 'User.get' has signature (id, callback(err, data))
1664       *         function(user, fn) {
1665       *             user.getCats(fn);      // 'getCats' has signature (callback(err, data))
1666       *         }
1667       *     )(req.session.user_id, function (err, cats) {
1668       *         if (err) {
1669       *             console.error(err);
1670       *             response.json({ status: 'error', message: err.message });
1671       *         } else {
1672       *             response.json({ status: 'ok', message: 'Cats found', data: cats });
1673       *         }
1674       *     });
1675       * });
1676       */
1677      function seq(...functions) {
1678          var _functions = functions.map(wrapAsync);
1679          return function (...args) {
1680              var that = this;
1681  
1682              var cb = args[args.length - 1];
1683              if (typeof cb == 'function') {
1684                  args.pop();
1685              } else {
1686                  cb = promiseCallback();
1687              }
1688  
1689              reduce$1(_functions, args, (newargs, fn, iterCb) => {
1690                  fn.apply(that, newargs.concat((err, ...nextargs) => {
1691                      iterCb(err, nextargs);
1692                  }));
1693              },
1694              (err, results) => cb(err, ...results));
1695  
1696              return cb[PROMISE_SYMBOL]
1697          };
1698      }
1699  
1700      /**
1701       * Creates a function which is a composition of the passed asynchronous
1702       * functions. Each function consumes the return value of the function that
1703       * follows. Composing functions `f()`, `g()`, and `h()` would produce the result
1704       * of `f(g(h()))`, only this version uses callbacks to obtain the return values.
1705       *
1706       * If the last argument to the composed function is not a function, a promise
1707       * is returned when you call it.
1708       *
1709       * Each function is executed with the `this` binding of the composed function.
1710       *
1711       * @name compose
1712       * @static
1713       * @memberOf module:ControlFlow
1714       * @method
1715       * @category Control Flow
1716       * @param {...AsyncFunction} functions - the asynchronous functions to compose
1717       * @returns {Function} an asynchronous function that is the composed
1718       * asynchronous `functions`
1719       * @example
1720       *
1721       * function add1(n, callback) {
1722       *     setTimeout(function () {
1723       *         callback(null, n + 1);
1724       *     }, 10);
1725       * }
1726       *
1727       * function mul3(n, callback) {
1728       *     setTimeout(function () {
1729       *         callback(null, n * 3);
1730       *     }, 10);
1731       * }
1732       *
1733       * var add1mul3 = async.compose(mul3, add1);
1734       * add1mul3(4, function (err, result) {
1735       *     // result now equals 15
1736       * });
1737       */
1738      function compose(...args) {
1739          return seq(...args.reverse());
1740      }
1741  
1742      /**
1743       * The same as [`map`]{@link module:Collections.map} but runs a maximum of `limit` async operations at a time.
1744       *
1745       * @name mapLimit
1746       * @static
1747       * @memberOf module:Collections
1748       * @method
1749       * @see [async.map]{@link module:Collections.map}
1750       * @category Collection
1751       * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
1752       * @param {number} limit - The maximum number of async operations at a time.
1753       * @param {AsyncFunction} iteratee - An async function to apply to each item in
1754       * `coll`.
1755       * The iteratee should complete with the transformed item.
1756       * Invoked with (item, callback).
1757       * @param {Function} [callback] - A callback which is called when all `iteratee`
1758       * functions have finished, or an error occurs. Results is an array of the
1759       * transformed items from the `coll`. Invoked with (err, results).
1760       * @returns {Promise} a promise, if no callback is passed
1761       */
1762      function mapLimit (coll, limit, iteratee, callback) {
1763          return _asyncMap(eachOfLimit(limit), coll, iteratee, callback)
1764      }
1765      var mapLimit$1 = awaitify(mapLimit, 4);
1766  
1767      /**
1768       * The same as [`concat`]{@link module:Collections.concat} but runs a maximum of `limit` async operations at a time.
1769       *
1770       * @name concatLimit
1771       * @static
1772       * @memberOf module:Collections
1773       * @method
1774       * @see [async.concat]{@link module:Collections.concat}
1775       * @category Collection
1776       * @alias flatMapLimit
1777       * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
1778       * @param {number} limit - The maximum number of async operations at a time.
1779       * @param {AsyncFunction} iteratee - A function to apply to each item in `coll`,
1780       * which should use an array as its result. Invoked with (item, callback).
1781       * @param {Function} [callback] - A callback which is called after all the
1782       * `iteratee` functions have finished, or an error occurs. Results is an array
1783       * containing the concatenated results of the `iteratee` function. Invoked with
1784       * (err, results).
1785       * @returns A Promise, if no callback is passed
1786       */
1787      function concatLimit(coll, limit, iteratee, callback) {
1788          var _iteratee = wrapAsync(iteratee);
1789          return mapLimit$1(coll, limit, (val, iterCb) => {
1790              _iteratee(val, (err, ...args) => {
1791                  if (err) return iterCb(err);
1792                  return iterCb(err, args);
1793              });
1794          }, (err, mapResults) => {
1795              var result = [];
1796              for (var i = 0; i < mapResults.length; i++) {
1797                  if (mapResults[i]) {
1798                      result = result.concat(...mapResults[i]);
1799                  }
1800              }
1801  
1802              return callback(err, result);
1803          });
1804      }
1805      var concatLimit$1 = awaitify(concatLimit, 4);
1806  
1807      /**
1808       * Applies `iteratee` to each item in `coll`, concatenating the results. Returns
1809       * the concatenated list. The `iteratee`s are called in parallel, and the
1810       * results are concatenated as they return. The results array will be returned in
1811       * the original order of `coll` passed to the `iteratee` function.
1812       *
1813       * @name concat
1814       * @static
1815       * @memberOf module:Collections
1816       * @method
1817       * @category Collection
1818       * @alias flatMap
1819       * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
1820       * @param {AsyncFunction} iteratee - A function to apply to each item in `coll`,
1821       * which should use an array as its result. Invoked with (item, callback).
1822       * @param {Function} [callback] - A callback which is called after all the
1823       * `iteratee` functions have finished, or an error occurs. Results is an array
1824       * containing the concatenated results of the `iteratee` function. Invoked with
1825       * (err, results).
1826       * @returns A Promise, if no callback is passed
1827       * @example
1828       *
1829       * async.concat(['dir1','dir2','dir3'], fs.readdir, function(err, files) {
1830       *     // files is now a list of filenames that exist in the 3 directories
1831       * });
1832       */
1833      function concat(coll, iteratee, callback) {
1834          return concatLimit$1(coll, Infinity, iteratee, callback)
1835      }
1836      var concat$1 = awaitify(concat, 3);
1837  
1838      /**
1839       * The same as [`concat`]{@link module:Collections.concat} but runs only a single async operation at a time.
1840       *
1841       * @name concatSeries
1842       * @static
1843       * @memberOf module:Collections
1844       * @method
1845       * @see [async.concat]{@link module:Collections.concat}
1846       * @category Collection
1847       * @alias flatMapSeries
1848       * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
1849       * @param {AsyncFunction} iteratee - A function to apply to each item in `coll`.
1850       * The iteratee should complete with an array an array of results.
1851       * Invoked with (item, callback).
1852       * @param {Function} [callback] - A callback which is called after all the
1853       * `iteratee` functions have finished, or an error occurs. Results is an array
1854       * containing the concatenated results of the `iteratee` function. Invoked with
1855       * (err, results).
1856       * @returns A Promise, if no callback is passed
1857       */
1858      function concatSeries(coll, iteratee, callback) {
1859          return concatLimit$1(coll, 1, iteratee, callback)
1860      }
1861      var concatSeries$1 = awaitify(concatSeries, 3);
1862  
1863      /**
1864       * Returns a function that when called, calls-back with the values provided.
1865       * Useful as the first function in a [`waterfall`]{@link module:ControlFlow.waterfall}, or for plugging values in to
1866       * [`auto`]{@link module:ControlFlow.auto}.
1867       *
1868       * @name constant
1869       * @static
1870       * @memberOf module:Utils
1871       * @method
1872       * @category Util
1873       * @param {...*} arguments... - Any number of arguments to automatically invoke
1874       * callback with.
1875       * @returns {AsyncFunction} Returns a function that when invoked, automatically
1876       * invokes the callback with the previous given arguments.
1877       * @example
1878       *
1879       * async.waterfall([
1880       *     async.constant(42),
1881       *     function (value, next) {
1882       *         // value === 42
1883       *     },
1884       *     //...
1885       * ], callback);
1886       *
1887       * async.waterfall([
1888       *     async.constant(filename, "utf8"),
1889       *     fs.readFile,
1890       *     function (fileData, next) {
1891       *         //...
1892       *     }
1893       *     //...
1894       * ], callback);
1895       *
1896       * async.auto({
1897       *     hostname: async.constant("https://server.net/"),
1898       *     port: findFreePort,
1899       *     launchServer: ["hostname", "port", function (options, cb) {
1900       *         startServer(options, cb);
1901       *     }],
1902       *     //...
1903       * }, callback);
1904       */
1905      function constant(...args) {
1906          return function (...ignoredArgs/*, callback*/) {
1907              var callback = ignoredArgs.pop();
1908              return callback(null, ...args);
1909          };
1910      }
1911  
1912      function _createTester(check, getResult) {
1913          return (eachfn, arr, _iteratee, cb) => {
1914              var testPassed = false;
1915              var testResult;
1916              const iteratee = wrapAsync(_iteratee);
1917              eachfn(arr, (value, _, callback) => {
1918                  iteratee(value, (err, result) => {
1919                      if (err || err === false) return callback(err);
1920  
1921                      if (check(result) && !testResult) {
1922                          testPassed = true;
1923                          testResult = getResult(true, value);
1924                          return callback(null, breakLoop);
1925                      }
1926                      callback();
1927                  });
1928              }, err => {
1929                  if (err) return cb(err);
1930                  cb(null, testPassed ? testResult : getResult(false));
1931              });
1932          };
1933      }
1934  
1935      /**
1936       * Returns the first value in `coll` that passes an async truth test. The
1937       * `iteratee` is applied in parallel, meaning the first iteratee to return
1938       * `true` will fire the detect `callback` with that result. That means the
1939       * result might not be the first item in the original `coll` (in terms of order)
1940       * that passes the test.
1941  
1942       * If order within the original `coll` is important, then look at
1943       * [`detectSeries`]{@link module:Collections.detectSeries}.
1944       *
1945       * @name detect
1946       * @static
1947       * @memberOf module:Collections
1948       * @method
1949       * @alias find
1950       * @category Collections
1951       * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
1952       * @param {AsyncFunction} iteratee - A truth test to apply to each item in `coll`.
1953       * The iteratee must complete with a boolean value as its result.
1954       * Invoked with (item, callback).
1955       * @param {Function} [callback] - A callback which is called as soon as any
1956       * iteratee returns `true`, or after all the `iteratee` functions have finished.
1957       * Result will be the first item in the array that passes the truth test
1958       * (iteratee) or the value `undefined` if none passed. Invoked with
1959       * (err, result).
1960       * @returns A Promise, if no callback is passed
1961       * @example
1962       *
1963       * async.detect(['file1','file2','file3'], function(filePath, callback) {
1964       *     fs.access(filePath, function(err) {
1965       *         callback(null, !err)
1966       *     });
1967       * }, function(err, result) {
1968       *     // result now equals the first file in the list that exists
1969       * });
1970       */
1971      function detect(coll, iteratee, callback) {
1972          return _createTester(bool => bool, (res, item) => item)(eachOf$1, coll, iteratee, callback)
1973      }
1974      var detect$1 = awaitify(detect, 3);
1975  
1976      /**
1977       * The same as [`detect`]{@link module:Collections.detect} but runs a maximum of `limit` async operations at a
1978       * time.
1979       *
1980       * @name detectLimit
1981       * @static
1982       * @memberOf module:Collections
1983       * @method
1984       * @see [async.detect]{@link module:Collections.detect}
1985       * @alias findLimit
1986       * @category Collections
1987       * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
1988       * @param {number} limit - The maximum number of async operations at a time.
1989       * @param {AsyncFunction} iteratee - A truth test to apply to each item in `coll`.
1990       * The iteratee must complete with a boolean value as its result.
1991       * Invoked with (item, callback).
1992       * @param {Function} [callback] - A callback which is called as soon as any
1993       * iteratee returns `true`, or after all the `iteratee` functions have finished.
1994       * Result will be the first item in the array that passes the truth test
1995       * (iteratee) or the value `undefined` if none passed. Invoked with
1996       * (err, result).
1997       * @returns a Promise if no callback is passed
1998       */
1999      function detectLimit(coll, limit, iteratee, callback) {
2000          return _createTester(bool => bool, (res, item) => item)(eachOfLimit(limit), coll, iteratee, callback)
2001      }
2002      var detectLimit$1 = awaitify(detectLimit, 4);
2003  
2004      /**
2005       * The same as [`detect`]{@link module:Collections.detect} but runs only a single async operation at a time.
2006       *
2007       * @name detectSeries
2008       * @static
2009       * @memberOf module:Collections
2010       * @method
2011       * @see [async.detect]{@link module:Collections.detect}
2012       * @alias findSeries
2013       * @category Collections
2014       * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
2015       * @param {AsyncFunction} iteratee - A truth test to apply to each item in `coll`.
2016       * The iteratee must complete with a boolean value as its result.
2017       * Invoked with (item, callback).
2018       * @param {Function} [callback] - A callback which is called as soon as any
2019       * iteratee returns `true`, or after all the `iteratee` functions have finished.
2020       * Result will be the first item in the array that passes the truth test
2021       * (iteratee) or the value `undefined` if none passed. Invoked with
2022       * (err, result).
2023       * @returns a Promise if no callback is passed
2024       */
2025      function detectSeries(coll, iteratee, callback) {
2026          return _createTester(bool => bool, (res, item) => item)(eachOfLimit(1), coll, iteratee, callback)
2027      }
2028  
2029      var detectSeries$1 = awaitify(detectSeries, 3);
2030  
2031      function consoleFunc(name) {
2032          return (fn, ...args) => wrapAsync(fn)(...args, (err, ...resultArgs) => {
2033              if (typeof console === 'object') {
2034                  if (err) {
2035                      if (console.error) {
2036                          console.error(err);
2037                      }
2038                  } else if (console[name]) {
2039                      resultArgs.forEach(x => console[name](x));
2040                  }
2041              }
2042          })
2043      }
2044  
2045      /**
2046       * Logs the result of an [`async` function]{@link AsyncFunction} to the
2047       * `console` using `console.dir` to display the properties of the resulting object.
2048       * Only works in Node.js or in browsers that support `console.dir` and
2049       * `console.error` (such as FF and Chrome).
2050       * If multiple arguments are returned from the async function,
2051       * `console.dir` is called on each argument in order.
2052       *
2053       * @name dir
2054       * @static
2055       * @memberOf module:Utils
2056       * @method
2057       * @category Util
2058       * @param {AsyncFunction} function - The function you want to eventually apply
2059       * all arguments to.
2060       * @param {...*} arguments... - Any number of arguments to apply to the function.
2061       * @example
2062       *
2063       * // in a module
2064       * var hello = function(name, callback) {
2065       *     setTimeout(function() {
2066       *         callback(null, {hello: name});
2067       *     }, 1000);
2068       * };
2069       *
2070       * // in the node repl
2071       * node> async.dir(hello, 'world');
2072       * {hello: 'world'}
2073       */
2074      var dir = consoleFunc('dir');
2075  
2076      /**
2077       * The post-check version of [`whilst`]{@link module:ControlFlow.whilst}. To reflect the difference in
2078       * the order of operations, the arguments `test` and `iteratee` are switched.
2079       *
2080       * `doWhilst` is to `whilst` as `do while` is to `while` in plain JavaScript.
2081       *
2082       * @name doWhilst
2083       * @static
2084       * @memberOf module:ControlFlow
2085       * @method
2086       * @see [async.whilst]{@link module:ControlFlow.whilst}
2087       * @category Control Flow
2088       * @param {AsyncFunction} iteratee - A function which is called each time `test`
2089       * passes. Invoked with (callback).
2090       * @param {AsyncFunction} test - asynchronous truth test to perform after each
2091       * execution of `iteratee`. Invoked with (...args, callback), where `...args` are the
2092       * non-error args from the previous callback of `iteratee`.
2093       * @param {Function} [callback] - A callback which is called after the test
2094       * function has failed and repeated execution of `iteratee` has stopped.
2095       * `callback` will be passed an error and any arguments passed to the final
2096       * `iteratee`'s callback. Invoked with (err, [results]);
2097       * @returns {Promise} a promise, if no callback is passed
2098       */
2099      function doWhilst(iteratee, test, callback) {
2100          callback = onlyOnce(callback);
2101          var _fn = wrapAsync(iteratee);
2102          var _test = wrapAsync(test);
2103          var results;
2104  
2105          function next(err, ...args) {
2106              if (err) return callback(err);
2107              if (err === false) return;
2108              results = args;
2109              _test(...args, check);
2110          }
2111  
2112          function check(err, truth) {
2113              if (err) return callback(err);
2114              if (err === false) return;
2115              if (!truth) return callback(null, ...results);
2116              _fn(next);
2117          }
2118  
2119          return check(null, true);
2120      }
2121  
2122      var doWhilst$1 = awaitify(doWhilst, 3);
2123  
2124      /**
2125       * Like ['doWhilst']{@link module:ControlFlow.doWhilst}, except the `test` is inverted. Note the
2126       * argument ordering differs from `until`.
2127       *
2128       * @name doUntil
2129       * @static
2130       * @memberOf module:ControlFlow
2131       * @method
2132       * @see [async.doWhilst]{@link module:ControlFlow.doWhilst}
2133       * @category Control Flow
2134       * @param {AsyncFunction} iteratee - An async function which is called each time
2135       * `test` fails. Invoked with (callback).
2136       * @param {AsyncFunction} test - asynchronous truth test to perform after each
2137       * execution of `iteratee`. Invoked with (...args, callback), where `...args` are the
2138       * non-error args from the previous callback of `iteratee`
2139       * @param {Function} [callback] - A callback which is called after the test
2140       * function has passed and repeated execution of `iteratee` has stopped. `callback`
2141       * will be passed an error and any arguments passed to the final `iteratee`'s
2142       * callback. Invoked with (err, [results]);
2143       * @returns {Promise} a promise, if no callback is passed
2144       */
2145      function doUntil(iteratee, test, callback) {
2146          const _test = wrapAsync(test);
2147          return doWhilst$1(iteratee, (...args) => {
2148              const cb = args.pop();
2149              _test(...args, (err, truth) => cb (err, !truth));
2150          }, callback);
2151      }
2152  
2153      function _withoutIndex(iteratee) {
2154          return (value, index, callback) => iteratee(value, callback);
2155      }
2156  
2157      /**
2158       * Applies the function `iteratee` to each item in `coll`, in parallel.
2159       * The `iteratee` is called with an item from the list, and a callback for when
2160       * it has finished. If the `iteratee` passes an error to its `callback`, the
2161       * main `callback` (for the `each` function) is immediately called with the
2162       * error.
2163       *
2164       * Note, that since this function applies `iteratee` to each item in parallel,
2165       * there is no guarantee that the iteratee functions will complete in order.
2166       *
2167       * @name each
2168       * @static
2169       * @memberOf module:Collections
2170       * @method
2171       * @alias forEach
2172       * @category Collection
2173       * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
2174       * @param {AsyncFunction} iteratee - An async function to apply to
2175       * each item in `coll`. Invoked with (item, callback).
2176       * The array index is not passed to the iteratee.
2177       * If you need the index, use `eachOf`.
2178       * @param {Function} [callback] - A callback which is called when all
2179       * `iteratee` functions have finished, or an error occurs. Invoked with (err).
2180       * @returns {Promise} a promise, if a callback is omitted
2181       * @example
2182       *
2183       * // assuming openFiles is an array of file names and saveFile is a function
2184       * // to save the modified contents of that file:
2185       *
2186       * async.each(openFiles, saveFile, function(err){
2187       *   // if any of the saves produced an error, err would equal that error
2188       * });
2189       *
2190       * // assuming openFiles is an array of file names
2191       * async.each(openFiles, function(file, callback) {
2192       *
2193       *     // Perform operation on file here.
2194       *     console.log('Processing file ' + file);
2195       *
2196       *     if( file.length > 32 ) {
2197       *       console.log('This file name is too long');
2198       *       callback('File name too long');
2199       *     } else {
2200       *       // Do work to process file here
2201       *       console.log('File processed');
2202       *       callback();
2203       *     }
2204       * }, function(err) {
2205       *     // if any of the file processing produced an error, err would equal that error
2206       *     if( err ) {
2207       *       // One of the iterations produced an error.
2208       *       // All processing will now stop.
2209       *       console.log('A file failed to process');
2210       *     } else {
2211       *       console.log('All files have been processed successfully');
2212       *     }
2213       * });
2214       */
2215      function eachLimit(coll, iteratee, callback) {
2216          return eachOf$1(coll, _withoutIndex(wrapAsync(iteratee)), callback);
2217      }
2218  
2219      var each = awaitify(eachLimit, 3);
2220  
2221      /**
2222       * The same as [`each`]{@link module:Collections.each} but runs a maximum of `limit` async operations at a time.
2223       *
2224       * @name eachLimit
2225       * @static
2226       * @memberOf module:Collections
2227       * @method
2228       * @see [async.each]{@link module:Collections.each}
2229       * @alias forEachLimit
2230       * @category Collection
2231       * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
2232       * @param {number} limit - The maximum number of async operations at a time.
2233       * @param {AsyncFunction} iteratee - An async function to apply to each item in
2234       * `coll`.
2235       * The array index is not passed to the iteratee.
2236       * If you need the index, use `eachOfLimit`.
2237       * Invoked with (item, callback).
2238       * @param {Function} [callback] - A callback which is called when all
2239       * `iteratee` functions have finished, or an error occurs. Invoked with (err).
2240       * @returns {Promise} a promise, if a callback is omitted
2241       */
2242      function eachLimit$1(coll, limit, iteratee, callback) {
2243          return eachOfLimit(limit)(coll, _withoutIndex(wrapAsync(iteratee)), callback);
2244      }
2245      var eachLimit$2 = awaitify(eachLimit$1, 4);
2246  
2247      /**
2248       * The same as [`each`]{@link module:Collections.each} but runs only a single async operation at a time.
2249       *
2250       * Note, that unlike [`each`]{@link module:Collections.each}, this function applies iteratee to each item
2251       * in series and therefore the iteratee functions will complete in order.
2252  
2253       * @name eachSeries
2254       * @static
2255       * @memberOf module:Collections
2256       * @method
2257       * @see [async.each]{@link module:Collections.each}
2258       * @alias forEachSeries
2259       * @category Collection
2260       * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
2261       * @param {AsyncFunction} iteratee - An async function to apply to each
2262       * item in `coll`.
2263       * The array index is not passed to the iteratee.
2264       * If you need the index, use `eachOfSeries`.
2265       * Invoked with (item, callback).
2266       * @param {Function} [callback] - A callback which is called when all
2267       * `iteratee` functions have finished, or an error occurs. Invoked with (err).
2268       * @returns {Promise} a promise, if a callback is omitted
2269       */
2270      function eachSeries(coll, iteratee, callback) {
2271          return eachLimit$2(coll, 1, iteratee, callback)
2272      }
2273      var eachSeries$1 = awaitify(eachSeries, 3);
2274  
2275      /**
2276       * Wrap an async function and ensure it calls its callback on a later tick of
2277       * the event loop.  If the function already calls its callback on a next tick,
2278       * no extra deferral is added. This is useful for preventing stack overflows
2279       * (`RangeError: Maximum call stack size exceeded`) and generally keeping
2280       * [Zalgo](http://blog.izs.me/post/59142742143/designing-apis-for-asynchrony)
2281       * contained. ES2017 `async` functions are returned as-is -- they are immune
2282       * to Zalgo's corrupting influences, as they always resolve on a later tick.
2283       *
2284       * @name ensureAsync
2285       * @static
2286       * @memberOf module:Utils
2287       * @method
2288       * @category Util
2289       * @param {AsyncFunction} fn - an async function, one that expects a node-style
2290       * callback as its last argument.
2291       * @returns {AsyncFunction} Returns a wrapped function with the exact same call
2292       * signature as the function passed in.
2293       * @example
2294       *
2295       * function sometimesAsync(arg, callback) {
2296       *     if (cache[arg]) {
2297       *         return callback(null, cache[arg]); // this would be synchronous!!
2298       *     } else {
2299       *         doSomeIO(arg, callback); // this IO would be asynchronous
2300       *     }
2301       * }
2302       *
2303       * // this has a risk of stack overflows if many results are cached in a row
2304       * async.mapSeries(args, sometimesAsync, done);
2305       *
2306       * // this will defer sometimesAsync's callback if necessary,
2307       * // preventing stack overflows
2308       * async.mapSeries(args, async.ensureAsync(sometimesAsync), done);
2309       */
2310      function ensureAsync(fn) {
2311          if (isAsync(fn)) return fn;
2312          return function (...args/*, callback*/) {
2313              var callback = args.pop();
2314              var sync = true;
2315              args.push((...innerArgs) => {
2316                  if (sync) {
2317                      setImmediate$1(() => callback(...innerArgs));
2318                  } else {
2319                      callback(...innerArgs);
2320                  }
2321              });
2322              fn.apply(this, args);
2323              sync = false;
2324          };
2325      }
2326  
2327      /**
2328       * Returns `true` if every element in `coll` satisfies an async test. If any
2329       * iteratee call returns `false`, the main `callback` is immediately called.
2330       *
2331       * @name every
2332       * @static
2333       * @memberOf module:Collections
2334       * @method
2335       * @alias all
2336       * @category Collection
2337       * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
2338       * @param {AsyncFunction} iteratee - An async truth test to apply to each item
2339       * in the collection in parallel.
2340       * The iteratee must complete with a boolean result value.
2341       * Invoked with (item, callback).
2342       * @param {Function} [callback] - A callback which is called after all the
2343       * `iteratee` functions have finished. Result will be either `true` or `false`
2344       * depending on the values of the async tests. Invoked with (err, result).
2345       * @returns {Promise} a promise, if no callback provided
2346       * @example
2347       *
2348       * async.every(['file1','file2','file3'], function(filePath, callback) {
2349       *     fs.access(filePath, function(err) {
2350       *         callback(null, !err)
2351       *     });
2352       * }, function(err, result) {
2353       *     // if result is true then every file exists
2354       * });
2355       */
2356      function every(coll, iteratee, callback) {
2357          return _createTester(bool => !bool, res => !res)(eachOf$1, coll, iteratee, callback)
2358      }
2359      var every$1 = awaitify(every, 3);
2360  
2361      /**
2362       * The same as [`every`]{@link module:Collections.every} but runs a maximum of `limit` async operations at a time.
2363       *
2364       * @name everyLimit
2365       * @static
2366       * @memberOf module:Collections
2367       * @method
2368       * @see [async.every]{@link module:Collections.every}
2369       * @alias allLimit
2370       * @category Collection
2371       * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
2372       * @param {number} limit - The maximum number of async operations at a time.
2373       * @param {AsyncFunction} iteratee - An async truth test to apply to each item
2374       * in the collection in parallel.
2375       * The iteratee must complete with a boolean result value.
2376       * Invoked with (item, callback).
2377       * @param {Function} [callback] - A callback which is called after all the
2378       * `iteratee` functions have finished. Result will be either `true` or `false`
2379       * depending on the values of the async tests. Invoked with (err, result).
2380       * @returns {Promise} a promise, if no callback provided
2381       */
2382      function everyLimit(coll, limit, iteratee, callback) {
2383          return _createTester(bool => !bool, res => !res)(eachOfLimit(limit), coll, iteratee, callback)
2384      }
2385      var everyLimit$1 = awaitify(everyLimit, 4);
2386  
2387      /**
2388       * The same as [`every`]{@link module:Collections.every} but runs only a single async operation at a time.
2389       *
2390       * @name everySeries
2391       * @static
2392       * @memberOf module:Collections
2393       * @method
2394       * @see [async.every]{@link module:Collections.every}
2395       * @alias allSeries
2396       * @category Collection
2397       * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
2398       * @param {AsyncFunction} iteratee - An async truth test to apply to each item
2399       * in the collection in series.
2400       * The iteratee must complete with a boolean result value.
2401       * Invoked with (item, callback).
2402       * @param {Function} [callback] - A callback which is called after all the
2403       * `iteratee` functions have finished. Result will be either `true` or `false`
2404       * depending on the values of the async tests. Invoked with (err, result).
2405       * @returns {Promise} a promise, if no callback provided
2406       */
2407      function everySeries(coll, iteratee, callback) {
2408          return _createTester(bool => !bool, res => !res)(eachOfSeries$1, coll, iteratee, callback)
2409      }
2410      var everySeries$1 = awaitify(everySeries, 3);
2411  
2412      function filterArray(eachfn, arr, iteratee, callback) {
2413          var truthValues = new Array(arr.length);
2414          eachfn(arr, (x, index, iterCb) => {
2415              iteratee(x, (err, v) => {
2416                  truthValues[index] = !!v;
2417                  iterCb(err);
2418              });
2419          }, err => {
2420              if (err) return callback(err);
2421              var results = [];
2422              for (var i = 0; i < arr.length; i++) {
2423                  if (truthValues[i]) results.push(arr[i]);
2424              }
2425              callback(null, results);
2426          });
2427      }
2428  
2429      function filterGeneric(eachfn, coll, iteratee, callback) {
2430          var results = [];
2431          eachfn(coll, (x, index, iterCb) => {
2432              iteratee(x, (err, v) => {
2433                  if (err) return iterCb(err);
2434                  if (v) {
2435                      results.push({index, value: x});
2436                  }
2437                  iterCb(err);
2438              });
2439          }, err => {
2440              if (err) return callback(err);
2441              callback(null, results
2442                  .sort((a, b) => a.index - b.index)
2443                  .map(v => v.value));
2444          });
2445      }
2446  
2447      function _filter(eachfn, coll, iteratee, callback) {
2448          var filter = isArrayLike(coll) ? filterArray : filterGeneric;
2449          return filter(eachfn, coll, wrapAsync(iteratee), callback);
2450      }
2451  
2452      /**
2453       * Returns a new array of all the values in `coll` which pass an async truth
2454       * test. This operation is performed in parallel, but the results array will be
2455       * in the same order as the original.
2456       *
2457       * @name filter
2458       * @static
2459       * @memberOf module:Collections
2460       * @method
2461       * @alias select
2462       * @category Collection
2463       * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
2464       * @param {Function} iteratee - A truth test to apply to each item in `coll`.
2465       * The `iteratee` is passed a `callback(err, truthValue)`, which must be called
2466       * with a boolean argument once it has completed. Invoked with (item, callback).
2467       * @param {Function} [callback] - A callback which is called after all the
2468       * `iteratee` functions have finished. Invoked with (err, results).
2469       * @returns {Promise} a promise, if no callback provided
2470       * @example
2471       *
2472       * async.filter(['file1','file2','file3'], function(filePath, callback) {
2473       *     fs.access(filePath, function(err) {
2474       *         callback(null, !err)
2475       *     });
2476       * }, function(err, results) {
2477       *     // results now equals an array of the existing files
2478       * });
2479       */
2480      function filter (coll, iteratee, callback) {
2481          return _filter(eachOf$1, coll, iteratee, callback)
2482      }
2483      var filter$1 = awaitify(filter, 3);
2484  
2485      /**
2486       * The same as [`filter`]{@link module:Collections.filter} but runs a maximum of `limit` async operations at a
2487       * time.
2488       *
2489       * @name filterLimit
2490       * @static
2491       * @memberOf module:Collections
2492       * @method
2493       * @see [async.filter]{@link module:Collections.filter}
2494       * @alias selectLimit
2495       * @category Collection
2496       * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
2497       * @param {number} limit - The maximum number of async operations at a time.
2498       * @param {Function} iteratee - A truth test to apply to each item in `coll`.
2499       * The `iteratee` is passed a `callback(err, truthValue)`, which must be called
2500       * with a boolean argument once it has completed. Invoked with (item, callback).
2501       * @param {Function} [callback] - A callback which is called after all the
2502       * `iteratee` functions have finished. Invoked with (err, results).
2503       * @returns {Promise} a promise, if no callback provided
2504       */
2505      function filterLimit (coll, limit, iteratee, callback) {
2506          return _filter(eachOfLimit(limit), coll, iteratee, callback)
2507      }
2508      var filterLimit$1 = awaitify(filterLimit, 4);
2509  
2510      /**
2511       * The same as [`filter`]{@link module:Collections.filter} but runs only a single async operation at a time.
2512       *
2513       * @name filterSeries
2514       * @static
2515       * @memberOf module:Collections
2516       * @method
2517       * @see [async.filter]{@link module:Collections.filter}
2518       * @alias selectSeries
2519       * @category Collection
2520       * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
2521       * @param {Function} iteratee - A truth test to apply to each item in `coll`.
2522       * The `iteratee` is passed a `callback(err, truthValue)`, which must be called
2523       * with a boolean argument once it has completed. Invoked with (item, callback).
2524       * @param {Function} [callback] - A callback which is called after all the
2525       * `iteratee` functions have finished. Invoked with (err, results)
2526       * @returns {Promise} a promise, if no callback provided
2527       */
2528      function filterSeries (coll, iteratee, callback) {
2529          return _filter(eachOfSeries$1, coll, iteratee, callback)
2530      }
2531      var filterSeries$1 = awaitify(filterSeries, 3);
2532  
2533      /**
2534       * Calls the asynchronous function `fn` with a callback parameter that allows it
2535       * to call itself again, in series, indefinitely.
2536  
2537       * If an error is passed to the callback then `errback` is called with the
2538       * error, and execution stops, otherwise it will never be called.
2539       *
2540       * @name forever
2541       * @static
2542       * @memberOf module:ControlFlow
2543       * @method
2544       * @category Control Flow
2545       * @param {AsyncFunction} fn - an async function to call repeatedly.
2546       * Invoked with (next).
2547       * @param {Function} [errback] - when `fn` passes an error to it's callback,
2548       * this function will be called, and execution stops. Invoked with (err).
2549       * @returns {Promise} a promise that rejects if an error occurs and an errback
2550       * is not passed
2551       * @example
2552       *
2553       * async.forever(
2554       *     function(next) {
2555       *         // next is suitable for passing to things that need a callback(err [, whatever]);
2556       *         // it will result in this function being called again.
2557       *     },
2558       *     function(err) {
2559       *         // if next is called with a value in its first parameter, it will appear
2560       *         // in here as 'err', and execution will stop.
2561       *     }
2562       * );
2563       */
2564      function forever(fn, errback) {
2565          var done = onlyOnce(errback);
2566          var task = wrapAsync(ensureAsync(fn));
2567  
2568          function next(err) {
2569              if (err) return done(err);
2570              if (err === false) return;
2571              task(next);
2572          }
2573          return next();
2574      }
2575      var forever$1 = awaitify(forever, 2);
2576  
2577      /**
2578       * The same as [`groupBy`]{@link module:Collections.groupBy} but runs a maximum of `limit` async operations at a time.
2579       *
2580       * @name groupByLimit
2581       * @static
2582       * @memberOf module:Collections
2583       * @method
2584       * @see [async.groupBy]{@link module:Collections.groupBy}
2585       * @category Collection
2586       * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
2587       * @param {number} limit - The maximum number of async operations at a time.
2588       * @param {AsyncFunction} iteratee - An async function to apply to each item in
2589       * `coll`.
2590       * The iteratee should complete with a `key` to group the value under.
2591       * Invoked with (value, callback).
2592       * @param {Function} [callback] - A callback which is called when all `iteratee`
2593       * functions have finished, or an error occurs. Result is an `Object` whoses
2594       * properties are arrays of values which returned the corresponding key.
2595       * @returns {Promise} a promise, if no callback is passed
2596       */
2597      function groupByLimit(coll, limit, iteratee, callback) {
2598          var _iteratee = wrapAsync(iteratee);
2599          return mapLimit$1(coll, limit, (val, iterCb) => {
2600              _iteratee(val, (err, key) => {
2601                  if (err) return iterCb(err);
2602                  return iterCb(err, {key, val});
2603              });
2604          }, (err, mapResults) => {
2605              var result = {};
2606              // from MDN, handle object having an `hasOwnProperty` prop
2607              var {hasOwnProperty} = Object.prototype;
2608  
2609              for (var i = 0; i < mapResults.length; i++) {
2610                  if (mapResults[i]) {
2611                      var {key} = mapResults[i];
2612                      var {val} = mapResults[i];
2613  
2614                      if (hasOwnProperty.call(result, key)) {
2615                          result[key].push(val);
2616                      } else {
2617                          result[key] = [val];
2618                      }
2619                  }
2620              }
2621  
2622              return callback(err, result);
2623          });
2624      }
2625  
2626      var groupByLimit$1 = awaitify(groupByLimit, 4);
2627  
2628      /**
2629       * Returns a new object, where each value corresponds to an array of items, from
2630       * `coll`, that returned the corresponding key. That is, the keys of the object
2631       * correspond to the values passed to the `iteratee` callback.
2632       *
2633       * Note: Since this function applies the `iteratee` to each item in parallel,
2634       * there is no guarantee that the `iteratee` functions will complete in order.
2635       * However, the values for each key in the `result` will be in the same order as
2636       * the original `coll`. For Objects, the values will roughly be in the order of
2637       * the original Objects' keys (but this can vary across JavaScript engines).
2638       *
2639       * @name groupBy
2640       * @static
2641       * @memberOf module:Collections
2642       * @method
2643       * @category Collection
2644       * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
2645       * @param {AsyncFunction} iteratee - An async function to apply to each item in
2646       * `coll`.
2647       * The iteratee should complete with a `key` to group the value under.
2648       * Invoked with (value, callback).
2649       * @param {Function} [callback] - A callback which is called when all `iteratee`
2650       * functions have finished, or an error occurs. Result is an `Object` whoses
2651       * properties are arrays of values which returned the corresponding key.
2652       * @returns {Promise} a promise, if no callback is passed
2653       * @example
2654       *
2655       * async.groupBy(['userId1', 'userId2', 'userId3'], function(userId, callback) {
2656       *     db.findById(userId, function(err, user) {
2657       *         if (err) return callback(err);
2658       *         return callback(null, user.age);
2659       *     });
2660       * }, function(err, result) {
2661       *     // result is object containing the userIds grouped by age
2662       *     // e.g. { 30: ['userId1', 'userId3'], 42: ['userId2']};
2663       * });
2664       */
2665      function groupBy (coll, iteratee, callback) {
2666          return groupByLimit$1(coll, Infinity, iteratee, callback)
2667      }
2668  
2669      /**
2670       * The same as [`groupBy`]{@link module:Collections.groupBy} but runs only a single async operation at a time.
2671       *
2672       * @name groupBySeries
2673       * @static
2674       * @memberOf module:Collections
2675       * @method
2676       * @see [async.groupBy]{@link module:Collections.groupBy}
2677       * @category Collection
2678       * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
2679       * @param {AsyncFunction} iteratee - An async function to apply to each item in
2680       * `coll`.
2681       * The iteratee should complete with a `key` to group the value under.
2682       * Invoked with (value, callback).
2683       * @param {Function} [callback] - A callback which is called when all `iteratee`
2684       * functions have finished, or an error occurs. Result is an `Object` whoses
2685       * properties are arrays of values which returned the corresponding key.
2686       * @returns {Promise} a promise, if no callback is passed
2687       */
2688      function groupBySeries (coll, iteratee, callback) {
2689          return groupByLimit$1(coll, 1, iteratee, callback)
2690      }
2691  
2692      /**
2693       * Logs the result of an `async` function to the `console`. Only works in
2694       * Node.js or in browsers that support `console.log` and `console.error` (such
2695       * as FF and Chrome). If multiple arguments are returned from the async
2696       * function, `console.log` is called on each argument in order.
2697       *
2698       * @name log
2699       * @static
2700       * @memberOf module:Utils
2701       * @method
2702       * @category Util
2703       * @param {AsyncFunction} function - The function you want to eventually apply
2704       * all arguments to.
2705       * @param {...*} arguments... - Any number of arguments to apply to the function.
2706       * @example
2707       *
2708       * // in a module
2709       * var hello = function(name, callback) {
2710       *     setTimeout(function() {
2711       *         callback(null, 'hello ' + name);
2712       *     }, 1000);
2713       * };
2714       *
2715       * // in the node repl
2716       * node> async.log(hello, 'world');
2717       * 'hello world'
2718       */
2719      var log = consoleFunc('log');
2720  
2721      /**
2722       * The same as [`mapValues`]{@link module:Collections.mapValues} but runs a maximum of `limit` async operations at a
2723       * time.
2724       *
2725       * @name mapValuesLimit
2726       * @static
2727       * @memberOf module:Collections
2728       * @method
2729       * @see [async.mapValues]{@link module:Collections.mapValues}
2730       * @category Collection
2731       * @param {Object} obj - A collection to iterate over.
2732       * @param {number} limit - The maximum number of async operations at a time.
2733       * @param {AsyncFunction} iteratee - A function to apply to each value and key
2734       * in `coll`.
2735       * The iteratee should complete with the transformed value as its result.
2736       * Invoked with (value, key, callback).
2737       * @param {Function} [callback] - A callback which is called when all `iteratee`
2738       * functions have finished, or an error occurs. `result` is a new object consisting
2739       * of each key from `obj`, with each transformed value on the right-hand side.
2740       * Invoked with (err, result).
2741       * @returns {Promise} a promise, if no callback is passed
2742       */
2743      function mapValuesLimit(obj, limit, iteratee, callback) {
2744          callback = once(callback);
2745          var newObj = {};
2746          var _iteratee = wrapAsync(iteratee);
2747          return eachOfLimit(limit)(obj, (val, key, next) => {
2748              _iteratee(val, key, (err, result) => {
2749                  if (err) return next(err);
2750                  newObj[key] = result;
2751                  next(err);
2752              });
2753          }, err => callback(err, newObj));
2754      }
2755  
2756      var mapValuesLimit$1 = awaitify(mapValuesLimit, 4);
2757  
2758      /**
2759       * A relative of [`map`]{@link module:Collections.map}, designed for use with objects.
2760       *
2761       * Produces a new Object by mapping each value of `obj` through the `iteratee`
2762       * function. The `iteratee` is called each `value` and `key` from `obj` and a
2763       * callback for when it has finished processing. Each of these callbacks takes
2764       * two arguments: an `error`, and the transformed item from `obj`. If `iteratee`
2765       * passes an error to its callback, the main `callback` (for the `mapValues`
2766       * function) is immediately called with the error.
2767       *
2768       * Note, the order of the keys in the result is not guaranteed.  The keys will
2769       * be roughly in the order they complete, (but this is very engine-specific)
2770       *
2771       * @name mapValues
2772       * @static
2773       * @memberOf module:Collections
2774       * @method
2775       * @category Collection
2776       * @param {Object} obj - A collection to iterate over.
2777       * @param {AsyncFunction} iteratee - A function to apply to each value and key
2778       * in `coll`.
2779       * The iteratee should complete with the transformed value as its result.
2780       * Invoked with (value, key, callback).
2781       * @param {Function} [callback] - A callback which is called when all `iteratee`
2782       * functions have finished, or an error occurs. `result` is a new object consisting
2783       * of each key from `obj`, with each transformed value on the right-hand side.
2784       * Invoked with (err, result).
2785       * @returns {Promise} a promise, if no callback is passed
2786       * @example
2787       *
2788       * async.mapValues({
2789       *     f1: 'file1',
2790       *     f2: 'file2',
2791       *     f3: 'file3'
2792       * }, function (file, key, callback) {
2793       *   fs.stat(file, callback);
2794       * }, function(err, result) {
2795       *     // result is now a map of stats for each file, e.g.
2796       *     // {
2797       *     //     f1: [stats for file1],
2798       *     //     f2: [stats for file2],
2799       *     //     f3: [stats for file3]
2800       *     // }
2801       * });
2802       */
2803      function mapValues(obj, iteratee, callback) {
2804          return mapValuesLimit$1(obj, Infinity, iteratee, callback)
2805      }
2806  
2807      /**
2808       * The same as [`mapValues`]{@link module:Collections.mapValues} but runs only a single async operation at a time.
2809       *
2810       * @name mapValuesSeries
2811       * @static
2812       * @memberOf module:Collections
2813       * @method
2814       * @see [async.mapValues]{@link module:Collections.mapValues}
2815       * @category Collection
2816       * @param {Object} obj - A collection to iterate over.
2817       * @param {AsyncFunction} iteratee - A function to apply to each value and key
2818       * in `coll`.
2819       * The iteratee should complete with the transformed value as its result.
2820       * Invoked with (value, key, callback).
2821       * @param {Function} [callback] - A callback which is called when all `iteratee`
2822       * functions have finished, or an error occurs. `result` is a new object consisting
2823       * of each key from `obj`, with each transformed value on the right-hand side.
2824       * Invoked with (err, result).
2825       * @returns {Promise} a promise, if no callback is passed
2826       */
2827      function mapValuesSeries(obj, iteratee, callback) {
2828          return mapValuesLimit$1(obj, 1, iteratee, callback)
2829      }
2830  
2831      /**
2832       * Caches the results of an async function. When creating a hash to store
2833       * function results against, the callback is omitted from the hash and an
2834       * optional hash function can be used.
2835       *
2836       * **Note: if the async function errs, the result will not be cached and
2837       * subsequent calls will call the wrapped function.**
2838       *
2839       * If no hash function is specified, the first argument is used as a hash key,
2840       * which may work reasonably if it is a string or a data type that converts to a
2841       * distinct string. Note that objects and arrays will not behave reasonably.
2842       * Neither will cases where the other arguments are significant. In such cases,
2843       * specify your own hash function.
2844       *
2845       * The cache of results is exposed as the `memo` property of the function
2846       * returned by `memoize`.
2847       *
2848       * @name memoize
2849       * @static
2850       * @memberOf module:Utils
2851       * @method
2852       * @category Util
2853       * @param {AsyncFunction} fn - The async function to proxy and cache results from.
2854       * @param {Function} hasher - An optional function for generating a custom hash
2855       * for storing results. It has all the arguments applied to it apart from the
2856       * callback, and must be synchronous.
2857       * @returns {AsyncFunction} a memoized version of `fn`
2858       * @example
2859       *
2860       * var slow_fn = function(name, callback) {
2861       *     // do something
2862       *     callback(null, result);
2863       * };
2864       * var fn = async.memoize(slow_fn);
2865       *
2866       * // fn can now be used as if it were slow_fn
2867       * fn('some name', function() {
2868       *     // callback
2869       * });
2870       */
2871      function memoize(fn, hasher = v => v) {
2872          var memo = Object.create(null);
2873          var queues = Object.create(null);
2874          var _fn = wrapAsync(fn);
2875          var memoized = initialParams((args, callback) => {
2876              var key = hasher(...args);
2877              if (key in memo) {
2878                  setImmediate$1(() => callback(null, ...memo[key]));
2879              } else if (key in queues) {
2880                  queues[key].push(callback);
2881              } else {
2882                  queues[key] = [callback];
2883                  _fn(...args, (err, ...resultArgs) => {
2884                      // #1465 don't memoize if an error occurred
2885                      if (!err) {
2886                          memo[key] = resultArgs;
2887                      }
2888                      var q = queues[key];
2889                      delete queues[key];
2890                      for (var i = 0, l = q.length; i < l; i++) {
2891                          q[i](err, ...resultArgs);
2892                      }
2893                  });
2894              }
2895          });
2896          memoized.memo = memo;
2897          memoized.unmemoized = fn;
2898          return memoized;
2899      }
2900  
2901      /**
2902       * Calls `callback` on a later loop around the event loop. In Node.js this just
2903       * calls `process.nextTick`.  In the browser it will use `setImmediate` if
2904       * available, otherwise `setTimeout(callback, 0)`, which means other higher
2905       * priority events may precede the execution of `callback`.
2906       *
2907       * This is used internally for browser-compatibility purposes.
2908       *
2909       * @name nextTick
2910       * @static
2911       * @memberOf module:Utils
2912       * @method
2913       * @see [async.setImmediate]{@link module:Utils.setImmediate}
2914       * @category Util
2915       * @param {Function} callback - The function to call on a later loop around
2916       * the event loop. Invoked with (args...).
2917       * @param {...*} args... - any number of additional arguments to pass to the
2918       * callback on the next tick.
2919       * @example
2920       *
2921       * var call_order = [];
2922       * async.nextTick(function() {
2923       *     call_order.push('two');
2924       *     // call_order now equals ['one','two']
2925       * });
2926       * call_order.push('one');
2927       *
2928       * async.setImmediate(function (a, b, c) {
2929       *     // a, b, and c equal 1, 2, and 3
2930       * }, 1, 2, 3);
2931       */
2932      var _defer$1;
2933  
2934      if (hasNextTick) {
2935          _defer$1 = process.nextTick;
2936      } else if (hasSetImmediate) {
2937          _defer$1 = setImmediate;
2938      } else {
2939          _defer$1 = fallback;
2940      }
2941  
2942      var nextTick = wrap(_defer$1);
2943  
2944      var parallel = awaitify((eachfn, tasks, callback) => {
2945          var results = isArrayLike(tasks) ? [] : {};
2946  
2947          eachfn(tasks, (task, key, taskCb) => {
2948              wrapAsync(task)((err, ...result) => {
2949                  if (result.length < 2) {
2950                      [result] = result;
2951                  }
2952                  results[key] = result;
2953                  taskCb(err);
2954              });
2955          }, err => callback(err, results));
2956      }, 3);
2957  
2958      /**
2959       * Run the `tasks` collection of functions in parallel, without waiting until
2960       * the previous function has completed. If any of the functions pass an error to
2961       * its callback, the main `callback` is immediately called with the value of the
2962       * error. Once the `tasks` have completed, the results are passed to the final
2963       * `callback` as an array.
2964       *
2965       * **Note:** `parallel` is about kicking-off I/O tasks in parallel, not about
2966       * parallel execution of code.  If your tasks do not use any timers or perform
2967       * any I/O, they will actually be executed in series.  Any synchronous setup
2968       * sections for each task will happen one after the other.  JavaScript remains
2969       * single-threaded.
2970       *
2971       * **Hint:** Use [`reflect`]{@link module:Utils.reflect} to continue the
2972       * execution of other tasks when a task fails.
2973       *
2974       * It is also possible to use an object instead of an array. Each property will
2975       * be run as a function and the results will be passed to the final `callback`
2976       * as an object instead of an array. This can be a more readable way of handling
2977       * results from {@link async.parallel}.
2978       *
2979       * @name parallel
2980       * @static
2981       * @memberOf module:ControlFlow
2982       * @method
2983       * @category Control Flow
2984       * @param {Array|Iterable|AsyncIterable|Object} tasks - A collection of
2985       * [async functions]{@link AsyncFunction} to run.
2986       * Each async function can complete with any number of optional `result` values.
2987       * @param {Function} [callback] - An optional callback to run once all the
2988       * functions have completed successfully. This function gets a results array
2989       * (or object) containing all the result arguments passed to the task callbacks.
2990       * Invoked with (err, results).
2991       * @returns {Promise} a promise, if a callback is not passed
2992       *
2993       * @example
2994       * async.parallel([
2995       *     function(callback) {
2996       *         setTimeout(function() {
2997       *             callback(null, 'one');
2998       *         }, 200);
2999       *     },
3000       *     function(callback) {
3001       *         setTimeout(function() {
3002       *             callback(null, 'two');
3003       *         }, 100);
3004       *     }
3005       * ],
3006       * // optional callback
3007       * function(err, results) {
3008       *     // the results array will equal ['one','two'] even though
3009       *     // the second function had a shorter timeout.
3010       * });
3011       *
3012       * // an example using an object instead of an array
3013       * async.parallel({
3014       *     one: function(callback) {
3015       *         setTimeout(function() {
3016       *             callback(null, 1);
3017       *         }, 200);
3018       *     },
3019       *     two: function(callback) {
3020       *         setTimeout(function() {
3021       *             callback(null, 2);
3022       *         }, 100);
3023       *     }
3024       * }, function(err, results) {
3025       *     // results is now equals to: {one: 1, two: 2}
3026       * });
3027       */
3028      function parallel$1(tasks, callback) {
3029          return parallel(eachOf$1, tasks, callback);
3030      }
3031  
3032      /**
3033       * The same as [`parallel`]{@link module:ControlFlow.parallel} but runs a maximum of `limit` async operations at a
3034       * time.
3035       *
3036       * @name parallelLimit
3037       * @static
3038       * @memberOf module:ControlFlow
3039       * @method
3040       * @see [async.parallel]{@link module:ControlFlow.parallel}
3041       * @category Control Flow
3042       * @param {Array|Iterable|AsyncIterable|Object} tasks - A collection of
3043       * [async functions]{@link AsyncFunction} to run.
3044       * Each async function can complete with any number of optional `result` values.
3045       * @param {number} limit - The maximum number of async operations at a time.
3046       * @param {Function} [callback] - An optional callback to run once all the
3047       * functions have completed successfully. This function gets a results array
3048       * (or object) containing all the result arguments passed to the task callbacks.
3049       * Invoked with (err, results).
3050       * @returns {Promise} a promise, if a callback is not passed
3051       */
3052      function parallelLimit(tasks, limit, callback) {
3053          return parallel(eachOfLimit(limit), tasks, callback);
3054      }
3055  
3056      /**
3057       * A queue of tasks for the worker function to complete.
3058       * @typedef {Iterable} QueueObject
3059       * @memberOf module:ControlFlow
3060       * @property {Function} length - a function returning the number of items
3061       * waiting to be processed. Invoke with `queue.length()`.
3062       * @property {boolean} started - a boolean indicating whether or not any
3063       * items have been pushed and processed by the queue.
3064       * @property {Function} running - a function returning the number of items
3065       * currently being processed. Invoke with `queue.running()`.
3066       * @property {Function} workersList - a function returning the array of items
3067       * currently being processed. Invoke with `queue.workersList()`.
3068       * @property {Function} idle - a function returning false if there are items
3069       * waiting or being processed, or true if not. Invoke with `queue.idle()`.
3070       * @property {number} concurrency - an integer for determining how many `worker`
3071       * functions should be run in parallel. This property can be changed after a
3072       * `queue` is created to alter the concurrency on-the-fly.
3073       * @property {number} payload - an integer that specifies how many items are
3074       * passed to the worker function at a time. only applies if this is a
3075       * [cargo]{@link module:ControlFlow.cargo} object
3076       * @property {AsyncFunction} push - add a new task to the `queue`. Calls `callback`
3077       * once the `worker` has finished processing the task. Instead of a single task,
3078       * a `tasks` array can be submitted. The respective callback is used for every
3079       * task in the list. Invoke with `queue.push(task, [callback])`,
3080       * @property {AsyncFunction} unshift - add a new task to the front of the `queue`.
3081       * Invoke with `queue.unshift(task, [callback])`.
3082       * @property {AsyncFunction} pushAsync - the same as `q.push`, except this returns
3083       * a promise that rejects if an error occurs.
3084       * @property {AsyncFunction} unshirtAsync - the same as `q.unshift`, except this returns
3085       * a promise that rejects if an error occurs.
3086       * @property {Function} remove - remove items from the queue that match a test
3087       * function.  The test function will be passed an object with a `data` property,
3088       * and a `priority` property, if this is a
3089       * [priorityQueue]{@link module:ControlFlow.priorityQueue} object.
3090       * Invoked with `queue.remove(testFn)`, where `testFn` is of the form
3091       * `function ({data, priority}) {}` and returns a Boolean.
3092       * @property {Function} saturated - a function that sets a callback that is
3093       * called when the number of running workers hits the `concurrency` limit, and
3094       * further tasks will be queued.  If the callback is omitted, `q.saturated()`
3095       * returns a promise for the next occurrence.
3096       * @property {Function} unsaturated - a function that sets a callback that is
3097       * called when the number of running workers is less than the `concurrency` &
3098       * `buffer` limits, and further tasks will not be queued. If the callback is
3099       * omitted, `q.unsaturated()` returns a promise for the next occurrence.
3100       * @property {number} buffer - A minimum threshold buffer in order to say that
3101       * the `queue` is `unsaturated`.
3102       * @property {Function} empty - a function that sets a callback that is called
3103       * when the last item from the `queue` is given to a `worker`. If the callback
3104       * is omitted, `q.empty()` returns a promise for the next occurrence.
3105       * @property {Function} drain - a function that sets a callback that is called
3106       * when the last item from the `queue` has returned from the `worker`. If the
3107       * callback is omitted, `q.drain()` returns a promise for the next occurrence.
3108       * @property {Function} error - a function that sets a callback that is called
3109       * when a task errors. Has the signature `function(error, task)`. If the
3110       * callback is omitted, `error()` returns a promise that rejects on the next
3111       * error.
3112       * @property {boolean} paused - a boolean for determining whether the queue is
3113       * in a paused state.
3114       * @property {Function} pause - a function that pauses the processing of tasks
3115       * until `resume()` is called. Invoke with `queue.pause()`.
3116       * @property {Function} resume - a function that resumes the processing of
3117       * queued tasks when the queue is paused. Invoke with `queue.resume()`.
3118       * @property {Function} kill - a function that removes the `drain` callback and
3119       * empties remaining tasks from the queue forcing it to go idle. No more tasks
3120       * should be pushed to the queue after calling this function. Invoke with `queue.kill()`.
3121       *
3122       * @example
3123       * const q = aync.queue(worker, 2)
3124       * q.push(item1)
3125       * q.push(item2)
3126       * q.push(item3)
3127       * // queues are iterable, spread into an array to inspect
3128       * const items = [...q] // [item1, item2, item3]
3129       * // or use for of
3130       * for (let item of q) {
3131       *     console.log(item)
3132       * }
3133       *
3134       * q.drain(() => {
3135       *     console.log('all done')
3136       * })
3137       * // or
3138       * await q.drain()
3139       */
3140  
3141      /**
3142       * Creates a `queue` object with the specified `concurrency`. Tasks added to the
3143       * `queue` are processed in parallel (up to the `concurrency` limit). If all
3144       * `worker`s are in progress, the task is queued until one becomes available.
3145       * Once a `worker` completes a `task`, that `task`'s callback is called.
3146       *
3147       * @name queue
3148       * @static
3149       * @memberOf module:ControlFlow
3150       * @method
3151       * @category Control Flow
3152       * @param {AsyncFunction} worker - An async function for processing a queued task.
3153       * If you want to handle errors from an individual task, pass a callback to
3154       * `q.push()`. Invoked with (task, callback).
3155       * @param {number} [concurrency=1] - An `integer` for determining how many
3156       * `worker` functions should be run in parallel.  If omitted, the concurrency
3157       * defaults to `1`.  If the concurrency is `0`, an error is thrown.
3158       * @returns {module:ControlFlow.QueueObject} A queue object to manage the tasks. Callbacks can be
3159       * attached as certain properties to listen for specific events during the
3160       * lifecycle of the queue.
3161       * @example
3162       *
3163       * // create a queue object with concurrency 2
3164       * var q = async.queue(function(task, callback) {
3165       *     console.log('hello ' + task.name);
3166       *     callback();
3167       * }, 2);
3168       *
3169       * // assign a callback
3170       * q.drain(function() {
3171       *     console.log('all items have been processed');
3172       * });
3173       * // or await the end
3174       * await q.drain()
3175       *
3176       * // assign an error callback
3177       * q.error(function(err, task) {
3178       *     console.error('task experienced an error');
3179       * });
3180       *
3181       * // add some items to the queue
3182       * q.push({name: 'foo'}, function(err) {
3183       *     console.log('finished processing foo');
3184       * });
3185       * // callback is optional
3186       * q.push({name: 'bar'});
3187       *
3188       * // add some items to the queue (batch-wise)
3189       * q.push([{name: 'baz'},{name: 'bay'},{name: 'bax'}], function(err) {
3190       *     console.log('finished processing item');
3191       * });
3192       *
3193       * // add some items to the front of the queue
3194       * q.unshift({name: 'bar'}, function (err) {
3195       *     console.log('finished processing bar');
3196       * });
3197       */
3198      function queue$1 (worker, concurrency) {
3199          var _worker = wrapAsync(worker);
3200          return queue((items, cb) => {
3201              _worker(items[0], cb);
3202          }, concurrency, 1);
3203      }
3204  
3205      // Binary min-heap implementation used for priority queue.
3206      // Implementation is stable, i.e. push time is considered for equal priorities
3207      class Heap {
3208          constructor() {
3209              this.heap = [];
3210              this.pushCount = Number.MIN_SAFE_INTEGER;
3211          }
3212  
3213          get length() {
3214              return this.heap.length;
3215          }
3216  
3217          empty () {
3218              this.heap = [];
3219              return this;
3220          }
3221  
3222          percUp(index) {
3223              let p;
3224  
3225              while (index > 0 && smaller(this.heap[index], this.heap[p=parent(index)])) {
3226                  let t = this.heap[index];
3227                  this.heap[index] = this.heap[p];
3228                  this.heap[p] = t;
3229  
3230                  index = p;
3231              }
3232          }
3233  
3234          percDown(index) {
3235              let l;
3236  
3237              while ((l=leftChi(index)) < this.heap.length) {
3238                  if (l+1 < this.heap.length && smaller(this.heap[l+1], this.heap[l])) {
3239                      l = l+1;
3240                  }
3241  
3242                  if (smaller(this.heap[index], this.heap[l])) {
3243                      break;
3244                  }
3245  
3246                  let t = this.heap[index];
3247                  this.heap[index] = this.heap[l];
3248                  this.heap[l] = t;
3249  
3250                  index = l;
3251              }
3252          }
3253  
3254          push(node) {
3255              node.pushCount = ++this.pushCount;
3256              this.heap.push(node);
3257              this.percUp(this.heap.length-1);
3258          }
3259  
3260          unshift(node) {
3261              return this.heap.push(node);
3262          }
3263  
3264          shift() {
3265              let [top] = this.heap;
3266  
3267              this.heap[0] = this.heap[this.heap.length-1];
3268              this.heap.pop();
3269              this.percDown(0);
3270  
3271              return top;
3272          }
3273  
3274          toArray() {
3275              return [...this];
3276          }
3277  
3278          *[Symbol.iterator] () {
3279              for (let i = 0; i < this.heap.length; i++) {
3280                  yield this.heap[i].data;
3281              }
3282          }
3283  
3284          remove (testFn) {
3285              let j = 0;
3286              for (let i = 0; i < this.heap.length; i++) {
3287                  if (!testFn(this.heap[i])) {
3288                      this.heap[j] = this.heap[i];
3289                      j++;
3290                  }
3291              }
3292  
3293              this.heap.splice(j);
3294  
3295              for (let i = parent(this.heap.length-1); i >= 0; i--) {
3296                  this.percDown(i);
3297              }
3298  
3299              return this;
3300          }
3301      }
3302  
3303      function leftChi(i) {
3304          return (i<<1)+1;
3305      }
3306  
3307      function parent(i) {
3308          return ((i+1)>>1)-1;
3309      }
3310  
3311      function smaller(x, y) {
3312          if (x.priority !== y.priority) {
3313              return x.priority < y.priority;
3314          }
3315          else {
3316              return x.pushCount < y.pushCount;
3317          }
3318      }
3319  
3320      /**
3321       * The same as [async.queue]{@link module:ControlFlow.queue} only tasks are assigned a priority and
3322       * completed in ascending priority order.
3323       *
3324       * @name priorityQueue
3325       * @static
3326       * @memberOf module:ControlFlow
3327       * @method
3328       * @see [async.queue]{@link module:ControlFlow.queue}
3329       * @category Control Flow
3330       * @param {AsyncFunction} worker - An async function for processing a queued task.
3331       * If you want to handle errors from an individual task, pass a callback to
3332       * `q.push()`.
3333       * Invoked with (task, callback).
3334       * @param {number} concurrency - An `integer` for determining how many `worker`
3335       * functions should be run in parallel.  If omitted, the concurrency defaults to
3336       * `1`.  If the concurrency is `0`, an error is thrown.
3337       * @returns {module:ControlFlow.QueueObject} A priorityQueue object to manage the tasks. There are two
3338       * differences between `queue` and `priorityQueue` objects:
3339       * * `push(task, priority, [callback])` - `priority` should be a number. If an
3340       *   array of `tasks` is given, all tasks will be assigned the same priority.
3341       * * The `unshift` method was removed.
3342       */
3343      function priorityQueue(worker, concurrency) {
3344          // Start with a normal queue
3345          var q = queue$1(worker, concurrency);
3346  
3347          q._tasks = new Heap();
3348  
3349          // Override push to accept second parameter representing priority
3350          q.push = function(data, priority = 0, callback = () => {}) {
3351              if (typeof callback !== 'function') {
3352                  throw new Error('task callback must be a function');
3353              }
3354              q.started = true;
3355              if (!Array.isArray(data)) {
3356                  data = [data];
3357              }
3358              if (data.length === 0 && q.idle()) {
3359                  // call drain immediately if there are no tasks
3360                  return setImmediate$1(() => q.drain());
3361              }
3362  
3363              for (var i = 0, l = data.length; i < l; i++) {
3364                  var item = {
3365                      data: data[i],
3366                      priority,
3367                      callback
3368                  };
3369  
3370                  q._tasks.push(item);
3371              }
3372  
3373              setImmediate$1(q.process);
3374          };
3375  
3376          // Remove unshift function
3377          delete q.unshift;
3378  
3379          return q;
3380      }
3381  
3382      /**
3383       * Runs the `tasks` array of functions in parallel, without waiting until the
3384       * previous function has completed. Once any of the `tasks` complete or pass an
3385       * error to its callback, the main `callback` is immediately called. It's
3386       * equivalent to `Promise.race()`.
3387       *
3388       * @name race
3389       * @static
3390       * @memberOf module:ControlFlow
3391       * @method
3392       * @category Control Flow
3393       * @param {Array} tasks - An array containing [async functions]{@link AsyncFunction}
3394       * to run. Each function can complete with an optional `result` value.
3395       * @param {Function} callback - A callback to run once any of the functions have
3396       * completed. This function gets an error or result from the first function that
3397       * completed. Invoked with (err, result).
3398       * @returns undefined
3399       * @example
3400       *
3401       * async.race([
3402       *     function(callback) {
3403       *         setTimeout(function() {
3404       *             callback(null, 'one');
3405       *         }, 200);
3406       *     },
3407       *     function(callback) {
3408       *         setTimeout(function() {
3409       *             callback(null, 'two');
3410       *         }, 100);
3411       *     }
3412       * ],
3413       * // main callback
3414       * function(err, result) {
3415       *     // the result will be equal to 'two' as it finishes earlier
3416       * });
3417       */
3418      function race(tasks, callback) {
3419          callback = once(callback);
3420          if (!Array.isArray(tasks)) return callback(new TypeError('First argument to race must be an array of functions'));
3421          if (!tasks.length) return callback();
3422          for (var i = 0, l = tasks.length; i < l; i++) {
3423              wrapAsync(tasks[i])(callback);
3424          }
3425      }
3426  
3427      var race$1 = awaitify(race, 2);
3428  
3429      /**
3430       * Same as [`reduce`]{@link module:Collections.reduce}, only operates on `array` in reverse order.
3431       *
3432       * @name reduceRight
3433       * @static
3434       * @memberOf module:Collections
3435       * @method
3436       * @see [async.reduce]{@link module:Collections.reduce}
3437       * @alias foldr
3438       * @category Collection
3439       * @param {Array} array - A collection to iterate over.
3440       * @param {*} memo - The initial state of the reduction.
3441       * @param {AsyncFunction} iteratee - A function applied to each item in the
3442       * array to produce the next step in the reduction.
3443       * The `iteratee` should complete with the next state of the reduction.
3444       * If the iteratee complete with an error, the reduction is stopped and the
3445       * main `callback` is immediately called with the error.
3446       * Invoked with (memo, item, callback).
3447       * @param {Function} [callback] - A callback which is called after all the
3448       * `iteratee` functions have finished. Result is the reduced value. Invoked with
3449       * (err, result).
3450       * @returns {Promise} a promise, if no callback is passed
3451       */
3452      function reduceRight (array, memo, iteratee, callback) {
3453          var reversed = [...array].reverse();
3454          return reduce$1(reversed, memo, iteratee, callback);
3455      }
3456  
3457      /**
3458       * Wraps the async function in another function that always completes with a
3459       * result object, even when it errors.
3460       *
3461       * The result object has either the property `error` or `value`.
3462       *
3463       * @name reflect
3464       * @static
3465       * @memberOf module:Utils
3466       * @method
3467       * @category Util
3468       * @param {AsyncFunction} fn - The async function you want to wrap
3469       * @returns {Function} - A function that always passes null to it's callback as
3470       * the error. The second argument to the callback will be an `object` with
3471       * either an `error` or a `value` property.
3472       * @example
3473       *
3474       * async.parallel([
3475       *     async.reflect(function(callback) {
3476       *         // do some stuff ...
3477       *         callback(null, 'one');
3478       *     }),
3479       *     async.reflect(function(callback) {
3480       *         // do some more stuff but error ...
3481       *         callback('bad stuff happened');
3482       *     }),
3483       *     async.reflect(function(callback) {
3484       *         // do some more stuff ...
3485       *         callback(null, 'two');
3486       *     })
3487       * ],
3488       * // optional callback
3489       * function(err, results) {
3490       *     // values
3491       *     // results[0].value = 'one'
3492       *     // results[1].error = 'bad stuff happened'
3493       *     // results[2].value = 'two'
3494       * });
3495       */
3496      function reflect(fn) {
3497          var _fn = wrapAsync(fn);
3498          return initialParams(function reflectOn(args, reflectCallback) {
3499              args.push((error, ...cbArgs) => {
3500                  let retVal = {};
3501                  if (error) {
3502                      retVal.error = error;
3503                  }
3504                  if (cbArgs.length > 0){
3505                      var value = cbArgs;
3506                      if (cbArgs.length <= 1) {
3507                          [value] = cbArgs;
3508                      }
3509                      retVal.value = value;
3510                  }
3511                  reflectCallback(null, retVal);
3512              });
3513  
3514              return _fn.apply(this, args);
3515          });
3516      }
3517  
3518      /**
3519       * A helper function that wraps an array or an object of functions with `reflect`.
3520       *
3521       * @name reflectAll
3522       * @static
3523       * @memberOf module:Utils
3524       * @method
3525       * @see [async.reflect]{@link module:Utils.reflect}
3526       * @category Util
3527       * @param {Array|Object|Iterable} tasks - The collection of
3528       * [async functions]{@link AsyncFunction} to wrap in `async.reflect`.
3529       * @returns {Array} Returns an array of async functions, each wrapped in
3530       * `async.reflect`
3531       * @example
3532       *
3533       * let tasks = [
3534       *     function(callback) {
3535       *         setTimeout(function() {
3536       *             callback(null, 'one');
3537       *         }, 200);
3538       *     },
3539       *     function(callback) {
3540       *         // do some more stuff but error ...
3541       *         callback(new Error('bad stuff happened'));
3542       *     },
3543       *     function(callback) {
3544       *         setTimeout(function() {
3545       *             callback(null, 'two');
3546       *         }, 100);
3547       *     }
3548       * ];
3549       *
3550       * async.parallel(async.reflectAll(tasks),
3551       * // optional callback
3552       * function(err, results) {
3553       *     // values
3554       *     // results[0].value = 'one'
3555       *     // results[1].error = Error('bad stuff happened')
3556       *     // results[2].value = 'two'
3557       * });
3558       *
3559       * // an example using an object instead of an array
3560       * let tasks = {
3561       *     one: function(callback) {
3562       *         setTimeout(function() {
3563       *             callback(null, 'one');
3564       *         }, 200);
3565       *     },
3566       *     two: function(callback) {
3567       *         callback('two');
3568       *     },
3569       *     three: function(callback) {
3570       *         setTimeout(function() {
3571       *             callback(null, 'three');
3572       *         }, 100);
3573       *     }
3574       * };
3575       *
3576       * async.parallel(async.reflectAll(tasks),
3577       * // optional callback
3578       * function(err, results) {
3579       *     // values
3580       *     // results.one.value = 'one'
3581       *     // results.two.error = 'two'
3582       *     // results.three.value = 'three'
3583       * });
3584       */
3585      function reflectAll(tasks) {
3586          var results;
3587          if (Array.isArray(tasks)) {
3588              results = tasks.map(reflect);
3589          } else {
3590              results = {};
3591              Object.keys(tasks).forEach(key => {
3592                  results[key] = reflect.call(this, tasks[key]);
3593              });
3594          }
3595          return results;
3596      }
3597  
3598      function reject(eachfn, arr, _iteratee, callback) {
3599          const iteratee = wrapAsync(_iteratee);
3600          return _filter(eachfn, arr, (value, cb) => {
3601              iteratee(value, (err, v) => {
3602                  cb(err, !v);
3603              });
3604          }, callback);
3605      }
3606  
3607      /**
3608       * The opposite of [`filter`]{@link module:Collections.filter}. Removes values that pass an `async` truth test.
3609       *
3610       * @name reject
3611       * @static
3612       * @memberOf module:Collections
3613       * @method
3614       * @see [async.filter]{@link module:Collections.filter}
3615       * @category Collection
3616       * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
3617       * @param {Function} iteratee - An async truth test to apply to each item in
3618       * `coll`.
3619       * The should complete with a boolean value as its `result`.
3620       * Invoked with (item, callback).
3621       * @param {Function} [callback] - A callback which is called after all the
3622       * `iteratee` functions have finished. Invoked with (err, results).
3623       * @returns {Promise} a promise, if no callback is passed
3624       * @example
3625       *
3626       * async.reject(['file1','file2','file3'], function(filePath, callback) {
3627       *     fs.access(filePath, function(err) {
3628       *         callback(null, !err)
3629       *     });
3630       * }, function(err, results) {
3631       *     // results now equals an array of missing files
3632       *     createFiles(results);
3633       * });
3634       */
3635      function reject$1 (coll, iteratee, callback) {
3636          return reject(eachOf$1, coll, iteratee, callback)
3637      }
3638      var reject$2 = awaitify(reject$1, 3);
3639  
3640      /**
3641       * The same as [`reject`]{@link module:Collections.reject} but runs a maximum of `limit` async operations at a
3642       * time.
3643       *
3644       * @name rejectLimit
3645       * @static
3646       * @memberOf module:Collections
3647       * @method
3648       * @see [async.reject]{@link module:Collections.reject}
3649       * @category Collection
3650       * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
3651       * @param {number} limit - The maximum number of async operations at a time.
3652       * @param {Function} iteratee - An async truth test to apply to each item in
3653       * `coll`.
3654       * The should complete with a boolean value as its `result`.
3655       * Invoked with (item, callback).
3656       * @param {Function} [callback] - A callback which is called after all the
3657       * `iteratee` functions have finished. Invoked with (err, results).
3658       * @returns {Promise} a promise, if no callback is passed
3659       */
3660      function rejectLimit (coll, limit, iteratee, callback) {
3661          return reject(eachOfLimit(limit), coll, iteratee, callback)
3662      }
3663      var rejectLimit$1 = awaitify(rejectLimit, 4);
3664  
3665      /**
3666       * The same as [`reject`]{@link module:Collections.reject} but runs only a single async operation at a time.
3667       *
3668       * @name rejectSeries
3669       * @static
3670       * @memberOf module:Collections
3671       * @method
3672       * @see [async.reject]{@link module:Collections.reject}
3673       * @category Collection
3674       * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
3675       * @param {Function} iteratee - An async truth test to apply to each item in
3676       * `coll`.
3677       * The should complete with a boolean value as its `result`.
3678       * Invoked with (item, callback).
3679       * @param {Function} [callback] - A callback which is called after all the
3680       * `iteratee` functions have finished. Invoked with (err, results).
3681       * @returns {Promise} a promise, if no callback is passed
3682       */
3683      function rejectSeries (coll, iteratee, callback) {
3684          return reject(eachOfSeries$1, coll, iteratee, callback)
3685      }
3686      var rejectSeries$1 = awaitify(rejectSeries, 3);
3687  
3688      function constant$1(value) {
3689          return function () {
3690              return value;
3691          }
3692      }
3693  
3694      /**
3695       * Attempts to get a successful response from `task` no more than `times` times
3696       * before returning an error. If the task is successful, the `callback` will be
3697       * passed the result of the successful task. If all attempts fail, the callback
3698       * will be passed the error and result (if any) of the final attempt.
3699       *
3700       * @name retry
3701       * @static
3702       * @memberOf module:ControlFlow
3703       * @method
3704       * @category Control Flow
3705       * @see [async.retryable]{@link module:ControlFlow.retryable}
3706       * @param {Object|number} [opts = {times: 5, interval: 0}| 5] - Can be either an
3707       * object with `times` and `interval` or a number.
3708       * * `times` - The number of attempts to make before giving up.  The default
3709       *   is `5`.
3710       * * `interval` - The time to wait between retries, in milliseconds.  The
3711       *   default is `0`. The interval may also be specified as a function of the
3712       *   retry count (see example).
3713       * * `errorFilter` - An optional synchronous function that is invoked on
3714       *   erroneous result. If it returns `true` the retry attempts will continue;
3715       *   if the function returns `false` the retry flow is aborted with the current
3716       *   attempt's error and result being returned to the final callback.
3717       *   Invoked with (err).
3718       * * If `opts` is a number, the number specifies the number of times to retry,
3719       *   with the default interval of `0`.
3720       * @param {AsyncFunction} task - An async function to retry.
3721       * Invoked with (callback).
3722       * @param {Function} [callback] - An optional callback which is called when the
3723       * task has succeeded, or after the final failed attempt. It receives the `err`
3724       * and `result` arguments of the last attempt at completing the `task`. Invoked
3725       * with (err, results).
3726       * @returns {Promise} a promise if no callback provided
3727       *
3728       * @example
3729       *
3730       * // The `retry` function can be used as a stand-alone control flow by passing
3731       * // a callback, as shown below:
3732       *
3733       * // try calling apiMethod 3 times
3734       * async.retry(3, apiMethod, function(err, result) {
3735       *     // do something with the result
3736       * });
3737       *
3738       * // try calling apiMethod 3 times, waiting 200 ms between each retry
3739       * async.retry({times: 3, interval: 200}, apiMethod, function(err, result) {
3740       *     // do something with the result
3741       * });
3742       *
3743       * // try calling apiMethod 10 times with exponential backoff
3744       * // (i.e. intervals of 100, 200, 400, 800, 1600, ... milliseconds)
3745       * async.retry({
3746       *   times: 10,
3747       *   interval: function(retryCount) {
3748       *     return 50 * Math.pow(2, retryCount);
3749       *   }
3750       * }, apiMethod, function(err, result) {
3751       *     // do something with the result
3752       * });
3753       *
3754       * // try calling apiMethod the default 5 times no delay between each retry
3755       * async.retry(apiMethod, function(err, result) {
3756       *     // do something with the result
3757       * });
3758       *
3759       * // try calling apiMethod only when error condition satisfies, all other
3760       * // errors will abort the retry control flow and return to final callback
3761       * async.retry({
3762       *   errorFilter: function(err) {
3763       *     return err.message === 'Temporary error'; // only retry on a specific error
3764       *   }
3765       * }, apiMethod, function(err, result) {
3766       *     // do something with the result
3767       * });
3768       *
3769       * // to retry individual methods that are not as reliable within other
3770       * // control flow functions, use the `retryable` wrapper:
3771       * async.auto({
3772       *     users: api.getUsers.bind(api),
3773       *     payments: async.retryable(3, api.getPayments.bind(api))
3774       * }, function(err, results) {
3775       *     // do something with the results
3776       * });
3777       *
3778       */
3779      const DEFAULT_TIMES = 5;
3780      const DEFAULT_INTERVAL = 0;
3781  
3782      function retry(opts, task, callback) {
3783          var options = {
3784              times: DEFAULT_TIMES,
3785              intervalFunc: constant$1(DEFAULT_INTERVAL)
3786          };
3787  
3788          if (arguments.length < 3 && typeof opts === 'function') {
3789              callback = task || promiseCallback();
3790              task = opts;
3791          } else {
3792              parseTimes(options, opts);
3793              callback = callback || promiseCallback();
3794          }
3795  
3796          if (typeof task !== 'function') {
3797              throw new Error("Invalid arguments for async.retry");
3798          }
3799  
3800          var _task = wrapAsync(task);
3801  
3802          var attempt = 1;
3803          function retryAttempt() {
3804              _task((err, ...args) => {
3805                  if (err === false) return
3806                  if (err && attempt++ < options.times &&
3807                      (typeof options.errorFilter != 'function' ||
3808                          options.errorFilter(err))) {
3809                      setTimeout(retryAttempt, options.intervalFunc(attempt - 1));
3810                  } else {
3811                      callback(err, ...args);
3812                  }
3813              });
3814          }
3815  
3816          retryAttempt();
3817          return callback[PROMISE_SYMBOL]
3818      }
3819  
3820      function parseTimes(acc, t) {
3821          if (typeof t === 'object') {
3822              acc.times = +t.times || DEFAULT_TIMES;
3823  
3824              acc.intervalFunc = typeof t.interval === 'function' ?
3825                  t.interval :
3826                  constant$1(+t.interval || DEFAULT_INTERVAL);
3827  
3828              acc.errorFilter = t.errorFilter;
3829          } else if (typeof t === 'number' || typeof t === 'string') {
3830              acc.times = +t || DEFAULT_TIMES;
3831          } else {
3832              throw new Error("Invalid arguments for async.retry");
3833          }
3834      }
3835  
3836      /**
3837       * A close relative of [`retry`]{@link module:ControlFlow.retry}.  This method
3838       * wraps a task and makes it retryable, rather than immediately calling it
3839       * with retries.
3840       *
3841       * @name retryable
3842       * @static
3843       * @memberOf module:ControlFlow
3844       * @method
3845       * @see [async.retry]{@link module:ControlFlow.retry}
3846       * @category Control Flow
3847       * @param {Object|number} [opts = {times: 5, interval: 0}| 5] - optional
3848       * options, exactly the same as from `retry`, except for a `opts.arity` that
3849       * is the arity of the `task` function, defaulting to `task.length`
3850       * @param {AsyncFunction} task - the asynchronous function to wrap.
3851       * This function will be passed any arguments passed to the returned wrapper.
3852       * Invoked with (...args, callback).
3853       * @returns {AsyncFunction} The wrapped function, which when invoked, will
3854       * retry on an error, based on the parameters specified in `opts`.
3855       * This function will accept the same parameters as `task`.
3856       * @example
3857       *
3858       * async.auto({
3859       *     dep1: async.retryable(3, getFromFlakyService),
3860       *     process: ["dep1", async.retryable(3, function (results, cb) {
3861       *         maybeProcessData(results.dep1, cb);
3862       *     })]
3863       * }, callback);
3864       */
3865      function retryable (opts, task) {
3866          if (!task) {
3867              task = opts;
3868              opts = null;
3869          }
3870          let arity = (opts && opts.arity) || task.length;
3871          if (isAsync(task)) {
3872              arity += 1;
3873          }
3874          var _task = wrapAsync(task);
3875          return initialParams((args, callback) => {
3876              if (args.length < arity - 1 || callback == null) {
3877                  args.push(callback);
3878                  callback = promiseCallback();
3879              }
3880              function taskFn(cb) {
3881                  _task(...args, cb);
3882              }
3883  
3884              if (opts) retry(opts, taskFn, callback);
3885              else retry(taskFn, callback);
3886  
3887              return callback[PROMISE_SYMBOL]
3888          });
3889      }
3890  
3891      /**
3892       * Run the functions in the `tasks` collection in series, each one running once
3893       * the previous function has completed. If any functions in the series pass an
3894       * error to its callback, no more functions are run, and `callback` is
3895       * immediately called with the value of the error. Otherwise, `callback`
3896       * receives an array of results when `tasks` have completed.
3897       *
3898       * It is also possible to use an object instead of an array. Each property will
3899       * be run as a function, and the results will be passed to the final `callback`
3900       * as an object instead of an array. This can be a more readable way of handling
3901       *  results from {@link async.series}.
3902       *
3903       * **Note** that while many implementations preserve the order of object
3904       * properties, the [ECMAScript Language Specification](http://www.ecma-international.org/ecma-262/5.1/#sec-8.6)
3905       * explicitly states that
3906       *
3907       * > The mechanics and order of enumerating the properties is not specified.
3908       *
3909       * So if you rely on the order in which your series of functions are executed,
3910       * and want this to work on all platforms, consider using an array.
3911       *
3912       * @name series
3913       * @static
3914       * @memberOf module:ControlFlow
3915       * @method
3916       * @category Control Flow
3917       * @param {Array|Iterable|AsyncIterable|Object} tasks - A collection containing
3918       * [async functions]{@link AsyncFunction} to run in series.
3919       * Each function can complete with any number of optional `result` values.
3920       * @param {Function} [callback] - An optional callback to run once all the
3921       * functions have completed. This function gets a results array (or object)
3922       * containing all the result arguments passed to the `task` callbacks. Invoked
3923       * with (err, result).
3924       * @return {Promise} a promise, if no callback is passed
3925       * @example
3926       * async.series([
3927       *     function(callback) {
3928       *         // do some stuff ...
3929       *         callback(null, 'one');
3930       *     },
3931       *     function(callback) {
3932       *         // do some more stuff ...
3933       *         callback(null, 'two');
3934       *     }
3935       * ],
3936       * // optional callback
3937       * function(err, results) {
3938       *     // results is now equal to ['one', 'two']
3939       * });
3940       *
3941       * async.series({
3942       *     one: function(callback) {
3943       *         setTimeout(function() {
3944       *             callback(null, 1);
3945       *         }, 200);
3946       *     },
3947       *     two: function(callback){
3948       *         setTimeout(function() {
3949       *             callback(null, 2);
3950       *         }, 100);
3951       *     }
3952       * }, function(err, results) {
3953       *     // results is now equal to: {one: 1, two: 2}
3954       * });
3955       */
3956      function series(tasks, callback) {
3957          return parallel(eachOfSeries$1, tasks, callback);
3958      }
3959  
3960      /**
3961       * Returns `true` if at least one element in the `coll` satisfies an async test.
3962       * If any iteratee call returns `true`, the main `callback` is immediately
3963       * called.
3964       *
3965       * @name some
3966       * @static
3967       * @memberOf module:Collections
3968       * @method
3969       * @alias any
3970       * @category Collection
3971       * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
3972       * @param {AsyncFunction} iteratee - An async truth test to apply to each item
3973       * in the collections in parallel.
3974       * The iteratee should complete with a boolean `result` value.
3975       * Invoked with (item, callback).
3976       * @param {Function} [callback] - A callback which is called as soon as any
3977       * iteratee returns `true`, or after all the iteratee functions have finished.
3978       * Result will be either `true` or `false` depending on the values of the async
3979       * tests. Invoked with (err, result).
3980       * @returns {Promise} a promise, if no callback provided
3981       * @example
3982       *
3983       * async.some(['file1','file2','file3'], function(filePath, callback) {
3984       *     fs.access(filePath, function(err) {
3985       *         callback(null, !err)
3986       *     });
3987       * }, function(err, result) {
3988       *     // if result is true then at least one of the files exists
3989       * });
3990       */
3991      function some(coll, iteratee, callback) {
3992          return _createTester(Boolean, res => res)(eachOf$1, coll, iteratee, callback)
3993      }
3994      var some$1 = awaitify(some, 3);
3995  
3996      /**
3997       * The same as [`some`]{@link module:Collections.some} but runs a maximum of `limit` async operations at a time.
3998       *
3999       * @name someLimit
4000       * @static
4001       * @memberOf module:Collections
4002       * @method
4003       * @see [async.some]{@link module:Collections.some}
4004       * @alias anyLimit
4005       * @category Collection
4006       * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
4007       * @param {number} limit - The maximum number of async operations at a time.
4008       * @param {AsyncFunction} iteratee - An async truth test to apply to each item
4009       * in the collections in parallel.
4010       * The iteratee should complete with a boolean `result` value.
4011       * Invoked with (item, callback).
4012       * @param {Function} [callback] - A callback which is called as soon as any
4013       * iteratee returns `true`, or after all the iteratee functions have finished.
4014       * Result will be either `true` or `false` depending on the values of the async
4015       * tests. Invoked with (err, result).
4016       * @returns {Promise} a promise, if no callback provided
4017       */
4018      function someLimit(coll, limit, iteratee, callback) {
4019          return _createTester(Boolean, res => res)(eachOfLimit(limit), coll, iteratee, callback)
4020      }
4021      var someLimit$1 = awaitify(someLimit, 4);
4022  
4023      /**
4024       * The same as [`some`]{@link module:Collections.some} but runs only a single async operation at a time.
4025       *
4026       * @name someSeries
4027       * @static
4028       * @memberOf module:Collections
4029       * @method
4030       * @see [async.some]{@link module:Collections.some}
4031       * @alias anySeries
4032       * @category Collection
4033       * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
4034       * @param {AsyncFunction} iteratee - An async truth test to apply to each item
4035       * in the collections in series.
4036       * The iteratee should complete with a boolean `result` value.
4037       * Invoked with (item, callback).
4038       * @param {Function} [callback] - A callback which is called as soon as any
4039       * iteratee returns `true`, or after all the iteratee functions have finished.
4040       * Result will be either `true` or `false` depending on the values of the async
4041       * tests. Invoked with (err, result).
4042       * @returns {Promise} a promise, if no callback provided
4043       */
4044      function someSeries(coll, iteratee, callback) {
4045          return _createTester(Boolean, res => res)(eachOfSeries$1, coll, iteratee, callback)
4046      }
4047      var someSeries$1 = awaitify(someSeries, 3);
4048  
4049      /**
4050       * Sorts a list by the results of running each `coll` value through an async
4051       * `iteratee`.
4052       *
4053       * @name sortBy
4054       * @static
4055       * @memberOf module:Collections
4056       * @method
4057       * @category Collection
4058       * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
4059       * @param {AsyncFunction} iteratee - An async function to apply to each item in
4060       * `coll`.
4061       * The iteratee should complete with a value to use as the sort criteria as
4062       * its `result`.
4063       * Invoked with (item, callback).
4064       * @param {Function} callback - A callback which is called after all the
4065       * `iteratee` functions have finished, or an error occurs. Results is the items
4066       * from the original `coll` sorted by the values returned by the `iteratee`
4067       * calls. Invoked with (err, results).
4068       * @returns {Promise} a promise, if no callback passed
4069       * @example
4070       *
4071       * async.sortBy(['file1','file2','file3'], function(file, callback) {
4072       *     fs.stat(file, function(err, stats) {
4073       *         callback(err, stats.mtime);
4074       *     });
4075       * }, function(err, results) {
4076       *     // results is now the original array of files sorted by
4077       *     // modified date
4078       * });
4079       *
4080       * // By modifying the callback parameter the
4081       * // sorting order can be influenced:
4082       *
4083       * // ascending order
4084       * async.sortBy([1,9,3,5], function(x, callback) {
4085       *     callback(null, x);
4086       * }, function(err,result) {
4087       *     // result callback
4088       * });
4089       *
4090       * // descending order
4091       * async.sortBy([1,9,3,5], function(x, callback) {
4092       *     callback(null, x*-1);    //<- x*-1 instead of x, turns the order around
4093       * }, function(err,result) {
4094       *     // result callback
4095       * });
4096       */
4097      function sortBy (coll, iteratee, callback) {
4098          var _iteratee = wrapAsync(iteratee);
4099          return map$1(coll, (x, iterCb) => {
4100              _iteratee(x, (err, criteria) => {
4101                  if (err) return iterCb(err);
4102                  iterCb(err, {value: x, criteria});
4103              });
4104          }, (err, results) => {
4105              if (err) return callback(err);
4106              callback(null, results.sort(comparator).map(v => v.value));
4107          });
4108  
4109          function comparator(left, right) {
4110              var a = left.criteria, b = right.criteria;
4111              return a < b ? -1 : a > b ? 1 : 0;
4112          }
4113      }
4114      var sortBy$1 = awaitify(sortBy, 3);
4115  
4116      /**
4117       * Sets a time limit on an asynchronous function. If the function does not call
4118       * its callback within the specified milliseconds, it will be called with a
4119       * timeout error. The code property for the error object will be `'ETIMEDOUT'`.
4120       *
4121       * @name timeout
4122       * @static
4123       * @memberOf module:Utils
4124       * @method
4125       * @category Util
4126       * @param {AsyncFunction} asyncFn - The async function to limit in time.
4127       * @param {number} milliseconds - The specified time limit.
4128       * @param {*} [info] - Any variable you want attached (`string`, `object`, etc)
4129       * to timeout Error for more information..
4130       * @returns {AsyncFunction} Returns a wrapped function that can be used with any
4131       * of the control flow functions.
4132       * Invoke this function with the same parameters as you would `asyncFunc`.
4133       * @example
4134       *
4135       * function myFunction(foo, callback) {
4136       *     doAsyncTask(foo, function(err, data) {
4137       *         // handle errors
4138       *         if (err) return callback(err);
4139       *
4140       *         // do some stuff ...
4141       *
4142       *         // return processed data
4143       *         return callback(null, data);
4144       *     });
4145       * }
4146       *
4147       * var wrapped = async.timeout(myFunction, 1000);
4148       *
4149       * // call `wrapped` as you would `myFunction`
4150       * wrapped({ bar: 'bar' }, function(err, data) {
4151       *     // if `myFunction` takes < 1000 ms to execute, `err`
4152       *     // and `data` will have their expected values
4153       *
4154       *     // else `err` will be an Error with the code 'ETIMEDOUT'
4155       * });
4156       */
4157      function timeout(asyncFn, milliseconds, info) {
4158          var fn = wrapAsync(asyncFn);
4159  
4160          return initialParams((args, callback) => {
4161              var timedOut = false;
4162              var timer;
4163  
4164              function timeoutCallback() {
4165                  var name = asyncFn.name || 'anonymous';
4166                  var error  = new Error('Callback function "' + name + '" timed out.');
4167                  error.code = 'ETIMEDOUT';
4168                  if (info) {
4169                      error.info = info;
4170                  }
4171                  timedOut = true;
4172                  callback(error);
4173              }
4174  
4175              args.push((...cbArgs) => {
4176                  if (!timedOut) {
4177                      callback(...cbArgs);
4178                      clearTimeout(timer);
4179                  }
4180              });
4181  
4182              // setup timer and call original function
4183              timer = setTimeout(timeoutCallback, milliseconds);
4184              fn(...args);
4185          });
4186      }
4187  
4188      function range(size) {
4189          var result = Array(size);
4190          while (size--) {
4191              result[size] = size;
4192          }
4193          return result;
4194      }
4195  
4196      /**
4197       * The same as [times]{@link module:ControlFlow.times} but runs a maximum of `limit` async operations at a
4198       * time.
4199       *
4200       * @name timesLimit
4201       * @static
4202       * @memberOf module:ControlFlow
4203       * @method
4204       * @see [async.times]{@link module:ControlFlow.times}
4205       * @category Control Flow
4206       * @param {number} count - The number of times to run the function.
4207       * @param {number} limit - The maximum number of async operations at a time.
4208       * @param {AsyncFunction} iteratee - The async function to call `n` times.
4209       * Invoked with the iteration index and a callback: (n, next).
4210       * @param {Function} callback - see [async.map]{@link module:Collections.map}.
4211       * @returns {Promise} a promise, if no callback is provided
4212       */
4213      function timesLimit(count, limit, iteratee, callback) {
4214          var _iteratee = wrapAsync(iteratee);
4215          return mapLimit$1(range(count), limit, _iteratee, callback);
4216      }
4217  
4218      /**
4219       * Calls the `iteratee` function `n` times, and accumulates results in the same
4220       * manner you would use with [map]{@link module:Collections.map}.
4221       *
4222       * @name times
4223       * @static
4224       * @memberOf module:ControlFlow
4225       * @method
4226       * @see [async.map]{@link module:Collections.map}
4227       * @category Control Flow
4228       * @param {number} n - The number of times to run the function.
4229       * @param {AsyncFunction} iteratee - The async function to call `n` times.
4230       * Invoked with the iteration index and a callback: (n, next).
4231       * @param {Function} callback - see {@link module:Collections.map}.
4232       * @returns {Promise} a promise, if no callback is provided
4233       * @example
4234       *
4235       * // Pretend this is some complicated async factory
4236       * var createUser = function(id, callback) {
4237       *     callback(null, {
4238       *         id: 'user' + id
4239       *     });
4240       * };
4241       *
4242       * // generate 5 users
4243       * async.times(5, function(n, next) {
4244       *     createUser(n, function(err, user) {
4245       *         next(err, user);
4246       *     });
4247       * }, function(err, users) {
4248       *     // we should now have 5 users
4249       * });
4250       */
4251      function times (n, iteratee, callback) {
4252          return timesLimit(n, Infinity, iteratee, callback)
4253      }
4254  
4255      /**
4256       * The same as [times]{@link module:ControlFlow.times} but runs only a single async operation at a time.
4257       *
4258       * @name timesSeries
4259       * @static
4260       * @memberOf module:ControlFlow
4261       * @method
4262       * @see [async.times]{@link module:ControlFlow.times}
4263       * @category Control Flow
4264       * @param {number} n - The number of times to run the function.
4265       * @param {AsyncFunction} iteratee - The async function to call `n` times.
4266       * Invoked with the iteration index and a callback: (n, next).
4267       * @param {Function} callback - see {@link module:Collections.map}.
4268       * @returns {Promise} a promise, if no callback is provided
4269       */
4270      function timesSeries (n, iteratee, callback) {
4271          return timesLimit(n, 1, iteratee, callback)
4272      }
4273  
4274      /**
4275       * A relative of `reduce`.  Takes an Object or Array, and iterates over each
4276       * element in parallel, each step potentially mutating an `accumulator` value.
4277       * The type of the accumulator defaults to the type of collection passed in.
4278       *
4279       * @name transform
4280       * @static
4281       * @memberOf module:Collections
4282       * @method
4283       * @category Collection
4284       * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
4285       * @param {*} [accumulator] - The initial state of the transform.  If omitted,
4286       * it will default to an empty Object or Array, depending on the type of `coll`
4287       * @param {AsyncFunction} iteratee - A function applied to each item in the
4288       * collection that potentially modifies the accumulator.
4289       * Invoked with (accumulator, item, key, callback).
4290       * @param {Function} [callback] - A callback which is called after all the
4291       * `iteratee` functions have finished. Result is the transformed accumulator.
4292       * Invoked with (err, result).
4293       * @returns {Promise} a promise, if no callback provided
4294       * @example
4295       *
4296       * async.transform([1,2,3], function(acc, item, index, callback) {
4297       *     // pointless async:
4298       *     process.nextTick(function() {
4299       *         acc[index] = item * 2
4300       *         callback(null)
4301       *     });
4302       * }, function(err, result) {
4303       *     // result is now equal to [2, 4, 6]
4304       * });
4305       *
4306       * @example
4307       *
4308       * async.transform({a: 1, b: 2, c: 3}, function (obj, val, key, callback) {
4309       *     setImmediate(function () {
4310       *         obj[key] = val * 2;
4311       *         callback();
4312       *     })
4313       * }, function (err, result) {
4314       *     // result is equal to {a: 2, b: 4, c: 6}
4315       * })
4316       */
4317      function transform (coll, accumulator, iteratee, callback) {
4318          if (arguments.length <= 3 && typeof accumulator === 'function') {
4319              callback = iteratee;
4320              iteratee = accumulator;
4321              accumulator = Array.isArray(coll) ? [] : {};
4322          }
4323          callback = once(callback || promiseCallback());
4324          var _iteratee = wrapAsync(iteratee);
4325  
4326          eachOf$1(coll, (v, k, cb) => {
4327              _iteratee(accumulator, v, k, cb);
4328          }, err => callback(err, accumulator));
4329          return callback[PROMISE_SYMBOL]
4330      }
4331  
4332      /**
4333       * It runs each task in series but stops whenever any of the functions were
4334       * successful. If one of the tasks were successful, the `callback` will be
4335       * passed the result of the successful task. If all tasks fail, the callback
4336       * will be passed the error and result (if any) of the final attempt.
4337       *
4338       * @name tryEach
4339       * @static
4340       * @memberOf module:ControlFlow
4341       * @method
4342       * @category Control Flow
4343       * @param {Array|Iterable|AsyncIterable|Object} tasks - A collection containing functions to
4344       * run, each function is passed a `callback(err, result)` it must call on
4345       * completion with an error `err` (which can be `null`) and an optional `result`
4346       * value.
4347       * @param {Function} [callback] - An optional callback which is called when one
4348       * of the tasks has succeeded, or all have failed. It receives the `err` and
4349       * `result` arguments of the last attempt at completing the `task`. Invoked with
4350       * (err, results).
4351       * @returns {Promise} a promise, if no callback is passed
4352       * @example
4353       * async.tryEach([
4354       *     function getDataFromFirstWebsite(callback) {
4355       *         // Try getting the data from the first website
4356       *         callback(err, data);
4357       *     },
4358       *     function getDataFromSecondWebsite(callback) {
4359       *         // First website failed,
4360       *         // Try getting the data from the backup website
4361       *         callback(err, data);
4362       *     }
4363       * ],
4364       * // optional callback
4365       * function(err, results) {
4366       *     Now do something with the data.
4367       * });
4368       *
4369       */
4370      function tryEach(tasks, callback) {
4371          var error = null;
4372          var result;
4373          return eachSeries$1(tasks, (task, taskCb) => {
4374              wrapAsync(task)((err, ...args) => {
4375                  if (err === false) return taskCb(err);
4376  
4377                  if (args.length < 2) {
4378                      [result] = args;
4379                  } else {
4380                      result = args;
4381                  }
4382                  error = err;
4383                  taskCb(err ? null : {});
4384              });
4385          }, () => callback(error, result));
4386      }
4387  
4388      var tryEach$1 = awaitify(tryEach);
4389  
4390      /**
4391       * Undoes a [memoize]{@link module:Utils.memoize}d function, reverting it to the original,
4392       * unmemoized form. Handy for testing.
4393       *
4394       * @name unmemoize
4395       * @static
4396       * @memberOf module:Utils
4397       * @method
4398       * @see [async.memoize]{@link module:Utils.memoize}
4399       * @category Util
4400       * @param {AsyncFunction} fn - the memoized function
4401       * @returns {AsyncFunction} a function that calls the original unmemoized function
4402       */
4403      function unmemoize(fn) {
4404          return (...args) => {
4405              return (fn.unmemoized || fn)(...args);
4406          };
4407      }
4408  
4409      /**
4410       * Repeatedly call `iteratee`, while `test` returns `true`. Calls `callback` when
4411       * stopped, or an error occurs.
4412       *
4413       * @name whilst
4414       * @static
4415       * @memberOf module:ControlFlow
4416       * @method
4417       * @category Control Flow
4418       * @param {AsyncFunction} test - asynchronous truth test to perform before each
4419       * execution of `iteratee`. Invoked with ().
4420       * @param {AsyncFunction} iteratee - An async function which is called each time
4421       * `test` passes. Invoked with (callback).
4422       * @param {Function} [callback] - A callback which is called after the test
4423       * function has failed and repeated execution of `iteratee` has stopped. `callback`
4424       * will be passed an error and any arguments passed to the final `iteratee`'s
4425       * callback. Invoked with (err, [results]);
4426       * @returns {Promise} a promise, if no callback is passed
4427       * @example
4428       *
4429       * var count = 0;
4430       * async.whilst(
4431       *     function test(cb) { cb(null, count < 5); },
4432       *     function iter(callback) {
4433       *         count++;
4434       *         setTimeout(function() {
4435       *             callback(null, count);
4436       *         }, 1000);
4437       *     },
4438       *     function (err, n) {
4439       *         // 5 seconds have passed, n = 5
4440       *     }
4441       * );
4442       */
4443      function whilst(test, iteratee, callback) {
4444          callback = onlyOnce(callback);
4445          var _fn = wrapAsync(iteratee);
4446          var _test = wrapAsync(test);
4447          var results = [];
4448  
4449          function next(err, ...rest) {
4450              if (err) return callback(err);
4451              results = rest;
4452              if (err === false) return;
4453              _test(check);
4454          }
4455  
4456          function check(err, truth) {
4457              if (err) return callback(err);
4458              if (err === false) return;
4459              if (!truth) return callback(null, ...results);
4460              _fn(next);
4461          }
4462  
4463          return _test(check);
4464      }
4465      var whilst$1 = awaitify(whilst, 3);
4466  
4467      /**
4468       * Repeatedly call `iteratee` until `test` returns `true`. Calls `callback` when
4469       * stopped, or an error occurs. `callback` will be passed an error and any
4470       * arguments passed to the final `iteratee`'s callback.
4471       *
4472       * The inverse of [whilst]{@link module:ControlFlow.whilst}.
4473       *
4474       * @name until
4475       * @static
4476       * @memberOf module:ControlFlow
4477       * @method
4478       * @see [async.whilst]{@link module:ControlFlow.whilst}
4479       * @category Control Flow
4480       * @param {AsyncFunction} test - asynchronous truth test to perform before each
4481       * execution of `iteratee`. Invoked with (callback).
4482       * @param {AsyncFunction} iteratee - An async function which is called each time
4483       * `test` fails. Invoked with (callback).
4484       * @param {Function} [callback] - A callback which is called after the test
4485       * function has passed and repeated execution of `iteratee` has stopped. `callback`
4486       * will be passed an error and any arguments passed to the final `iteratee`'s
4487       * callback. Invoked with (err, [results]);
4488       * @returns {Promise} a promise, if a callback is not passed
4489       *
4490       * @example
4491       * const results = []
4492       * let finished = false
4493       * async.until(function test(page, cb) {
4494       *     cb(null, finished)
4495       * }, function iter(next) {
4496       *     fetchPage(url, (err, body) => {
4497       *         if (err) return next(err)
4498       *         results = results.concat(body.objects)
4499       *         finished = !!body.next
4500       *         next(err)
4501       *     })
4502       * }, function done (err) {
4503       *     // all pages have been fetched
4504       * })
4505       */
4506      function until(test, iteratee, callback) {
4507          const _test = wrapAsync(test);
4508          return whilst$1((cb) => _test((err, truth) => cb (err, !truth)), iteratee, callback);
4509      }
4510  
4511      /**
4512       * Runs the `tasks` array of functions in series, each passing their results to
4513       * the next in the array. However, if any of the `tasks` pass an error to their
4514       * own callback, the next function is not executed, and the main `callback` is
4515       * immediately called with the error.
4516       *
4517       * @name waterfall
4518       * @static
4519       * @memberOf module:ControlFlow
4520       * @method
4521       * @category Control Flow
4522       * @param {Array} tasks - An array of [async functions]{@link AsyncFunction}
4523       * to run.
4524       * Each function should complete with any number of `result` values.
4525       * The `result` values will be passed as arguments, in order, to the next task.
4526       * @param {Function} [callback] - An optional callback to run once all the
4527       * functions have completed. This will be passed the results of the last task's
4528       * callback. Invoked with (err, [results]).
4529       * @returns undefined
4530       * @example
4531       *
4532       * async.waterfall([
4533       *     function(callback) {
4534       *         callback(null, 'one', 'two');
4535       *     },
4536       *     function(arg1, arg2, callback) {
4537       *         // arg1 now equals 'one' and arg2 now equals 'two'
4538       *         callback(null, 'three');
4539       *     },
4540       *     function(arg1, callback) {
4541       *         // arg1 now equals 'three'
4542       *         callback(null, 'done');
4543       *     }
4544       * ], function (err, result) {
4545       *     // result now equals 'done'
4546       * });
4547       *
4548       * // Or, with named functions:
4549       * async.waterfall([
4550       *     myFirstFunction,
4551       *     mySecondFunction,
4552       *     myLastFunction,
4553       * ], function (err, result) {
4554       *     // result now equals 'done'
4555       * });
4556       * function myFirstFunction(callback) {
4557       *     callback(null, 'one', 'two');
4558       * }
4559       * function mySecondFunction(arg1, arg2, callback) {
4560       *     // arg1 now equals 'one' and arg2 now equals 'two'
4561       *     callback(null, 'three');
4562       * }
4563       * function myLastFunction(arg1, callback) {
4564       *     // arg1 now equals 'three'
4565       *     callback(null, 'done');
4566       * }
4567       */
4568      function waterfall (tasks, callback) {
4569          callback = once(callback);
4570          if (!Array.isArray(tasks)) return callback(new Error('First argument to waterfall must be an array of functions'));
4571          if (!tasks.length) return callback();
4572          var taskIndex = 0;
4573  
4574          function nextTask(args) {
4575              var task = wrapAsync(tasks[taskIndex++]);
4576              task(...args, onlyOnce(next));
4577          }
4578  
4579          function next(err, ...args) {
4580              if (err === false) return
4581              if (err || taskIndex === tasks.length) {
4582                  return callback(err, ...args);
4583              }
4584              nextTask(args);
4585          }
4586  
4587          nextTask([]);
4588      }
4589  
4590      var waterfall$1 = awaitify(waterfall);
4591  
4592      /**
4593       * An "async function" in the context of Async is an asynchronous function with
4594       * a variable number of parameters, with the final parameter being a callback.
4595       * (`function (arg1, arg2, ..., callback) {}`)
4596       * The final callback is of the form `callback(err, results...)`, which must be
4597       * called once the function is completed.  The callback should be called with a
4598       * Error as its first argument to signal that an error occurred.
4599       * Otherwise, if no error occurred, it should be called with `null` as the first
4600       * argument, and any additional `result` arguments that may apply, to signal
4601       * successful completion.
4602       * The callback must be called exactly once, ideally on a later tick of the
4603       * JavaScript event loop.
4604       *
4605       * This type of function is also referred to as a "Node-style async function",
4606       * or a "continuation passing-style function" (CPS). Most of the methods of this
4607       * library are themselves CPS/Node-style async functions, or functions that
4608       * return CPS/Node-style async functions.
4609       *
4610       * Wherever we accept a Node-style async function, we also directly accept an
4611       * [ES2017 `async` function]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function}.
4612       * In this case, the `async` function will not be passed a final callback
4613       * argument, and any thrown error will be used as the `err` argument of the
4614       * implicit callback, and the return value will be used as the `result` value.
4615       * (i.e. a `rejected` of the returned Promise becomes the `err` callback
4616       * argument, and a `resolved` value becomes the `result`.)
4617       *
4618       * Note, due to JavaScript limitations, we can only detect native `async`
4619       * functions and not transpilied implementations.
4620       * Your environment must have `async`/`await` support for this to work.
4621       * (e.g. Node > v7.6, or a recent version of a modern browser).
4622       * If you are using `async` functions through a transpiler (e.g. Babel), you
4623       * must still wrap the function with [asyncify]{@link module:Utils.asyncify},
4624       * because the `async function` will be compiled to an ordinary function that
4625       * returns a promise.
4626       *
4627       * @typedef {Function} AsyncFunction
4628       * @static
4629       */
4630  
4631      var index = {
4632          apply,
4633          applyEach: applyEach$1,
4634          applyEachSeries,
4635          asyncify,
4636          auto,
4637          autoInject,
4638          cargo,
4639          cargoQueue: cargo$1,
4640          compose,
4641          concat: concat$1,
4642          concatLimit: concatLimit$1,
4643          concatSeries: concatSeries$1,
4644          constant,
4645          detect: detect$1,
4646          detectLimit: detectLimit$1,
4647          detectSeries: detectSeries$1,
4648          dir,
4649          doUntil,
4650          doWhilst: doWhilst$1,
4651          each,
4652          eachLimit: eachLimit$2,
4653          eachOf: eachOf$1,
4654          eachOfLimit: eachOfLimit$2,
4655          eachOfSeries: eachOfSeries$1,
4656          eachSeries: eachSeries$1,
4657          ensureAsync,
4658          every: every$1,
4659          everyLimit: everyLimit$1,
4660          everySeries: everySeries$1,
4661          filter: filter$1,
4662          filterLimit: filterLimit$1,
4663          filterSeries: filterSeries$1,
4664          forever: forever$1,
4665          groupBy,
4666          groupByLimit: groupByLimit$1,
4667          groupBySeries,
4668          log,
4669          map: map$1,
4670          mapLimit: mapLimit$1,
4671          mapSeries: mapSeries$1,
4672          mapValues,
4673          mapValuesLimit: mapValuesLimit$1,
4674          mapValuesSeries,
4675          memoize,
4676          nextTick,
4677          parallel: parallel$1,
4678          parallelLimit,
4679          priorityQueue,
4680          queue: queue$1,
4681          race: race$1,
4682          reduce: reduce$1,
4683          reduceRight,
4684          reflect,
4685          reflectAll,
4686          reject: reject$2,
4687          rejectLimit: rejectLimit$1,
4688          rejectSeries: rejectSeries$1,
4689          retry,
4690          retryable,
4691          seq,
4692          series,
4693          setImmediate: setImmediate$1,
4694          some: some$1,
4695          someLimit: someLimit$1,
4696          someSeries: someSeries$1,
4697          sortBy: sortBy$1,
4698          timeout,
4699          times,
4700          timesLimit,
4701          timesSeries,
4702          transform,
4703          tryEach: tryEach$1,
4704          unmemoize,
4705          until,
4706          waterfall: waterfall$1,
4707          whilst: whilst$1,
4708  
4709          // aliases
4710          all: every$1,
4711          allLimit: everyLimit$1,
4712          allSeries: everySeries$1,
4713          any: some$1,
4714          anyLimit: someLimit$1,
4715          anySeries: someSeries$1,
4716          find: detect$1,
4717          findLimit: detectLimit$1,
4718          findSeries: detectSeries$1,
4719          flatMap: concat$1,
4720          flatMapLimit: concatLimit$1,
4721          flatMapSeries: concatSeries$1,
4722          forEach: each,
4723          forEachSeries: eachSeries$1,
4724          forEachLimit: eachLimit$2,
4725          forEachOf: eachOf$1,
4726          forEachOfSeries: eachOfSeries$1,
4727          forEachOfLimit: eachOfLimit$2,
4728          inject: reduce$1,
4729          foldl: reduce$1,
4730          foldr: reduceRight,
4731          select: filter$1,
4732          selectLimit: filterLimit$1,
4733          selectSeries: filterSeries$1,
4734          wrapSync: asyncify,
4735          during: whilst$1,
4736          doDuring: doWhilst$1
4737      };
4738  
4739      exports.default = index;
4740      exports.apply = apply;
4741      exports.applyEach = applyEach$1;
4742      exports.applyEachSeries = applyEachSeries;
4743      exports.asyncify = asyncify;
4744      exports.auto = auto;
4745      exports.autoInject = autoInject;
4746      exports.cargo = cargo;
4747      exports.cargoQueue = cargo$1;
4748      exports.compose = compose;
4749      exports.concat = concat$1;
4750      exports.concatLimit = concatLimit$1;
4751      exports.concatSeries = concatSeries$1;
4752      exports.constant = constant;
4753      exports.detect = detect$1;
4754      exports.detectLimit = detectLimit$1;
4755      exports.detectSeries = detectSeries$1;
4756      exports.dir = dir;
4757      exports.doUntil = doUntil;
4758      exports.doWhilst = doWhilst$1;
4759      exports.each = each;
4760      exports.eachLimit = eachLimit$2;
4761      exports.eachOf = eachOf$1;
4762      exports.eachOfLimit = eachOfLimit$2;
4763      exports.eachOfSeries = eachOfSeries$1;
4764      exports.eachSeries = eachSeries$1;
4765      exports.ensureAsync = ensureAsync;
4766      exports.every = every$1;
4767      exports.everyLimit = everyLimit$1;
4768      exports.everySeries = everySeries$1;
4769      exports.filter = filter$1;
4770      exports.filterLimit = filterLimit$1;
4771      exports.filterSeries = filterSeries$1;
4772      exports.forever = forever$1;
4773      exports.groupBy = groupBy;
4774      exports.groupByLimit = groupByLimit$1;
4775      exports.groupBySeries = groupBySeries;
4776      exports.log = log;
4777      exports.map = map$1;
4778      exports.mapLimit = mapLimit$1;
4779      exports.mapSeries = mapSeries$1;
4780      exports.mapValues = mapValues;
4781      exports.mapValuesLimit = mapValuesLimit$1;
4782      exports.mapValuesSeries = mapValuesSeries;
4783      exports.memoize = memoize;
4784      exports.nextTick = nextTick;
4785      exports.parallel = parallel$1;
4786      exports.parallelLimit = parallelLimit;
4787      exports.priorityQueue = priorityQueue;
4788      exports.queue = queue$1;
4789      exports.race = race$1;
4790      exports.reduce = reduce$1;
4791      exports.reduceRight = reduceRight;
4792      exports.reflect = reflect;
4793      exports.reflectAll = reflectAll;
4794      exports.reject = reject$2;
4795      exports.rejectLimit = rejectLimit$1;
4796      exports.rejectSeries = rejectSeries$1;
4797      exports.retry = retry;
4798      exports.retryable = retryable;
4799      exports.seq = seq;
4800      exports.series = series;
4801      exports.setImmediate = setImmediate$1;
4802      exports.some = some$1;
4803      exports.someLimit = someLimit$1;
4804      exports.someSeries = someSeries$1;
4805      exports.sortBy = sortBy$1;
4806      exports.timeout = timeout;
4807      exports.times = times;
4808      exports.timesLimit = timesLimit;
4809      exports.timesSeries = timesSeries;
4810      exports.transform = transform;
4811      exports.tryEach = tryEach$1;
4812      exports.unmemoize = unmemoize;
4813      exports.until = until;
4814      exports.waterfall = waterfall$1;
4815      exports.whilst = whilst$1;
4816      exports.all = every$1;
4817      exports.allLimit = everyLimit$1;
4818      exports.allSeries = everySeries$1;
4819      exports.any = some$1;
4820      exports.anyLimit = someLimit$1;
4821      exports.anySeries = someSeries$1;
4822      exports.find = detect$1;
4823      exports.findLimit = detectLimit$1;
4824      exports.findSeries = detectSeries$1;
4825      exports.flatMap = concat$1;
4826      exports.flatMapLimit = concatLimit$1;
4827      exports.flatMapSeries = concatSeries$1;
4828      exports.forEach = each;
4829      exports.forEachSeries = eachSeries$1;
4830      exports.forEachLimit = eachLimit$2;
4831      exports.forEachOf = eachOf$1;
4832      exports.forEachOfSeries = eachOfSeries$1;
4833      exports.forEachOfLimit = eachOfLimit$2;
4834      exports.inject = reduce$1;
4835      exports.foldl = reduce$1;
4836      exports.foldr = reduceRight;
4837      exports.select = filter$1;
4838      exports.selectLimit = filterLimit$1;
4839      exports.selectSeries = filterSeries$1;
4840      exports.wrapSync = asyncify;
4841      exports.during = whilst$1;
4842      exports.doDuring = doWhilst$1;
4843  
4844      Object.defineProperty(exports, '__esModule', { value: true });
4845  
4846  })));