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