Name: js-handler/node_modules/nodeunit/deps/async.js 
1:
/*global setTimeout: false, console: false */
2:
(function () {
3:
 
4:
    var async = {};
5:
 
6:
    // global on the server, window in the browser
7:
    var root = this,
8:
        previous_async = root.async;
9:
 
10:
    if (typeof module !== 'undefined' && module.exports) {
11:
        module.exports = async;
12:
    }
13:
    else {
14:
        root.async = async;
15:
    }
16:
 
17:
    async.noConflict = function () {
18:
        root.async = previous_async;
19:
        return async;
20:
    };
21:
 
22:
    //// cross-browser compatiblity functions ////
23:
 
24:
    var _forEach = function (arr, iterator) {
25:
        if (arr.forEach) {
26:
            return arr.forEach(iterator);
27:
        }
28:
        for (var i = 0; i < arr.length; i += 1) {
29:
            iterator(arr[i], i, arr);
30:
        }
31:
    };
32:
 
33:
    var _map = function (arr, iterator) {
34:
        if (arr.map) {
35:
            return arr.map(iterator);
36:
        }
37:
        var results = [];
38:
        _forEach(arr, function (x, i, a) {
39:
            results.push(iterator(x, i, a));
40:
        });
41:
        return results;
42:
    };
43:
 
44:
    var _reduce = function (arr, iterator, memo) {
45:
        if (arr.reduce) {
46:
            return arr.reduce(iterator, memo);
47:
        }
48:
        _forEach(arr, function (x, i, a) {
49:
            memo = iterator(memo, x, i, a);
50:
        });
51:
        return memo;
52:
    };
53:
 
54:
    var _keys = function (obj) {
55:
        if (Object.keys) {
56:
            return Object.keys(obj);
57:
        }
58:
        var keys = [];
59:
        for (var k in obj) {
60:
            if (obj.hasOwnProperty(k)) {
61:
                keys.push(k);
62:
            }
63:
        }
64:
        return keys;
65:
    };
66:
 
67:
    var _indexOf = function (arr, item) {
68:
        if (arr.indexOf) {
69:
            return arr.indexOf(item);
70:
        }
71:
        for (var i = 0; i < arr.length; i += 1) {
72:
            if (arr[i] === item) {
73:
                return i;
74:
            }
75:
        }
76:
        return -1;
77:
    };
78:
 
79:
    //// exported async module functions ////
80:
 
81:
    //// nextTick implementation with browser-compatible fallback ////
82:
    if (typeof setImmediate === 'function') {
83:
        async.nextTick = function (fn) {
84:
            setImmediate(fn);
85:
        };
86:
    }
87:
    else if (typeof process !== 'undefined' && process.nextTick) {
88:
        async.nextTick = process.nextTick;
89:
    }
90:
    else {
91:
        async.nextTick = function (fn) {
92:
            setTimeout(fn, 0);
93:
        };
94:
    }
95:
 
96:
    async.forEach = function (arr, iterator, callback) {
97:
        if (!arr.length) {
98:
            return callback();
99:
        }
100:
        var completed = 0;
101:
        _forEach(arr, function (x) {
102:
            iterator(x, function (err) {
103:
                if (err) {
104:
                    callback(err);
105:
                    callback = function () {};
106:
                }
107:
                else {
108:
                    completed += 1;
109:
                    if (completed === arr.length) {
110:
                        callback();
111:
                    }
112:
                }
113:
            });
114:
        });
115:
    };
116:
 
117:
    async.forEachSeries = function (arr, iterator, callback) {
118:
        if (!arr.length) {
119:
            return callback();
120:
        }
121:
        var completed = 0;
122:
        var iterate = function () {
123:
            iterator(arr[completed], function (err) {
124:
                if (err) {
125:
                    callback(err);
126:
                    callback = function () {};
127:
                }
128:
                else {
129:
                    completed += 1;
130:
                    if (completed === arr.length) {
131:
                        callback();
132:
                    }
133:
                    else {
134:
                        iterate();
135:
                    }
136:
                }
137:
            });
138:
        };
139:
        iterate();
140:
    };
141:
 
142:
 
143:
    var doParallel = function (fn) {
144:
        return function () {
145:
            var args = Array.prototype.slice.call(arguments);
146:
            return fn.apply(null, [async.forEach].concat(args));
147:
        };
148:
    };
149:
    var doSeries = function (fn) {
150:
        return function () {
151:
            var args = Array.prototype.slice.call(arguments);
152:
            return fn.apply(null, [async.forEachSeries].concat(args));
153:
        };
154:
    };
155:
 
156:
 
157:
    var _asyncMap = function (eachfn, arr, iterator, callback) {
158:
        var results = [];
159:
        arr = _map(arr, function (x, i) {
160:
            return {index: i, value: x};
161:
        });
162:
        eachfn(arr, function (x, callback) {
163:
            iterator(x.value, function (err, v) {
164:
                results[x.index] = v;
165:
                callback(err);
166:
            });
167:
        }, function (err) {
168:
            callback(err, results);
169:
        });
170:
    };
171:
    async.map = doParallel(_asyncMap);
172:
    async.mapSeries = doSeries(_asyncMap);
173:
 
174:
 
175:
    // reduce only has a series version, as doing reduce in parallel won't
176:
    // work in many situations.
177:
    async.reduce = function (arr, memo, iterator, callback) {
178:
        async.forEachSeries(arr, function (x, callback) {
179:
            iterator(memo, x, function (err, v) {
180:
                memo = v;
181:
                callback(err);
182:
            });
183:
        }, function (err) {
184:
            callback(err, memo);
185:
        });
186:
    };
187:
    // inject alias
188:
    async.inject = async.reduce;
189:
    // foldl alias
190:
    async.foldl = async.reduce;
191:
 
192:
    async.reduceRight = function (arr, memo, iterator, callback) {
193:
        var reversed = _map(arr, function (x) {
194:
            return x;
195:
        }).reverse();
196:
        async.reduce(reversed, memo, iterator, callback);
197:
    };
198:
    // foldr alias
199:
    async.foldr = async.reduceRight;
200:
 
201:
    var _filter = function (eachfn, arr, iterator, callback) {
202:
        var results = [];
203:
        arr = _map(arr, function (x, i) {
204:
            return {index: i, value: x};
205:
        });
206:
        eachfn(arr, function (x, callback) {
207:
            iterator(x.value, function (v) {
208:
                if (v) {
209:
                    results.push(x);
210:
                }
211:
                callback();
212:
            });
213:
        }, function (err) {
214:
            callback(_map(results.sort(function (a, b) {
215:
                return a.index - b.index;
216:
            }), function (x) {
217:
                return x.value;
218:
            }));
219:
        });
220:
    };
221:
    async.filter = doParallel(_filter);
222:
    async.filterSeries = doSeries(_filter);
223:
    // select alias
224:
    async.select = async.filter;
225:
    async.selectSeries = async.filterSeries;
226:
 
227:
    var _reject = function (eachfn, arr, iterator, callback) {
228:
        var results = [];
229:
        arr = _map(arr, function (x, i) {
230:
            return {index: i, value: x};
231:
        });
232:
        eachfn(arr, function (x, callback) {
233:
            iterator(x.value, function (v) {
234:
                if (!v) {
235:
                    results.push(x);
236:
                }
237:
                callback();
238:
            });
239:
        }, function (err) {
240:
            callback(_map(results.sort(function (a, b) {
241:
                return a.index - b.index;
242:
            }), function (x) {
243:
                return x.value;
244:
            }));
245:
        });
246:
    };
247:
    async.reject = doParallel(_reject);
248:
    async.rejectSeries = doSeries(_reject);
249:
 
250:
    var _detect = function (eachfn, arr, iterator, main_callback) {
251:
        eachfn(arr, function (x, callback) {
252:
            iterator(x, function (result) {
253:
                if (result) {
254:
                    main_callback(x);
255:
                }
256:
                else {
257:
                    callback();
258:
                }
259:
            });
260:
        }, function (err) {
261:
            main_callback();
262:
        });
263:
    };
264:
    async.detect = doParallel(_detect);
265:
    async.detectSeries = doSeries(_detect);
266:
 
267:
    async.some = function (arr, iterator, main_callback) {
268:
        async.forEach(arr, function (x, callback) {
269:
            iterator(x, function (v) {
270:
                if (v) {
271:
                    main_callback(true);
272:
                    main_callback = function () {};
273:
                }
274:
                callback();
275:
            });
276:
        }, function (err) {
277:
            main_callback(false);
278:
        });
279:
    };
280:
    // any alias
281:
    async.any = async.some;
282:
 
283:
    async.every = function (arr, iterator, main_callback) {
284:
        async.forEach(arr, function (x, callback) {
285:
            iterator(x, function (v) {
286:
                if (!v) {
287:
                    main_callback(false);
288:
                    main_callback = function () {};
289:
                }
290:
                callback();
291:
            });
292:
        }, function (err) {
293:
            main_callback(true);
294:
        });
295:
    };
296:
    // all alias
297:
    async.all = async.every;
298:
 
299:
    async.sortBy = function (arr, iterator, callback) {
300:
        async.map(arr, function (x, callback) {
301:
            iterator(x, function (err, criteria) {
302:
                if (err) {
303:
                    callback(err);
304:
                }
305:
                else {
306:
                    callback(null, {value: x, criteria: criteria});
307:
                }
308:
            });
309:
        }, function (err, results) {
310:
            if (err) {
311:
                return callback(err);
312:
            }
313:
            else {
314:
                var fn = function (left, right) {
315:
                    var a = left.criteria, b = right.criteria;
316:
                    return a < b ? -1 : a > b ? 1 : 0;
317:
                };
318:
                callback(null, _map(results.sort(fn), function (x) {
319:
                    return x.value;
320:
                }));
321:
            }
322:
        });
323:
    };
324:
 
325:
    async.auto = function (tasks, callback) {
326:
        callback = callback || function () {};
327:
        var keys = _keys(tasks);
328:
        if (!keys.length) {
329:
            return callback(null);
330:
        }
331:
 
332:
        var completed = [];
333:
 
334:
        var listeners = [];
335:
        var addListener = function (fn) {
336:
            listeners.unshift(fn);
337:
        };
338:
        var removeListener = function (fn) {
339:
            for (var i = 0; i < listeners.length; i += 1) {
340:
                if (listeners[i] === fn) {
341:
                    listeners.splice(i, 1);
342:
                    return;
343:
                }
344:
            }
345:
        };
346:
        var taskComplete = function () {
347:
            _forEach(listeners, function (fn) {
348:
                fn();
349:
            });
350:
        };
351:
 
352:
        addListener(function () {
353:
            if (completed.length === keys.length) {
354:
                callback(null);
355:
            }
356:
        });
357:
 
358:
        _forEach(keys, function (k) {
359:
            var task = (tasks[k] instanceof Function) ? [tasks[k]]: tasks[k];
360:
            var taskCallback = function (err) {
361:
                if (err) {
362:
                    callback(err);
363:
                    // stop subsequent errors hitting callback multiple times
364:
                    callback = function () {};
365:
                }
366:
                else {
367:
                    completed.push(k);
368:
                    taskComplete();
369:
                }
370:
            };
371:
            var requires = task.slice(0, Math.abs(task.length - 1)) || [];
372:
            var ready = function () {
373:
                return _reduce(requires, function (a, x) {
374:
                    return (a && _indexOf(completed, x) !== -1);
375:
                }, true);
376:
            };
377:
            if (ready()) {
378:
                task[task.length - 1](taskCallback);
379:
            }
380:
            else {
381:
                var listener = function () {
382:
                    if (ready()) {
383:
                        removeListener(listener);
384:
                        task[task.length - 1](taskCallback);
385:
                    }
386:
                };
387:
                addListener(listener);
388:
            }
389:
        });
390:
    };
391:
 
392:
    async.waterfall = function (tasks, callback) {
393:
        if (!tasks.length) {
394:
            return callback();
395:
        }
396:
        callback = callback || function () {};
397:
        var wrapIterator = function (iterator) {
398:
            return function (err) {
399:
                if (err) {
400:
                    callback(err);
401:
                    callback = function () {};
402:
                }
403:
                else {
404:
                    var args = Array.prototype.slice.call(arguments, 1);
405:
                    var next = iterator.next();
406:
                    if (next) {
407:
                        args.push(wrapIterator(next));
408:
                    }
409:
                    else {
410:
                        args.push(callback);
411:
                    }
412:
                    async.nextTick(function () {
413:
                        iterator.apply(null, args);
414:
                    });
415:
                }
416:
            };
417:
        };
418:
        wrapIterator(async.iterator(tasks))();
419:
    };
420:
 
421:
    async.parallel = function (tasks, callback) {
422:
        callback = callback || function () {};
423:
        if (tasks.constructor === Array) {
424:
            async.map(tasks, function (fn, callback) {
425:
                if (fn) {
426:
                    fn(function (err) {
427:
                        var args = Array.prototype.slice.call(arguments, 1);
428:
                        if (args.length <= 1) {
429:
                            args = args[0];
430:
                        }
431:
                        callback.call(null, err, args || null);
432:
                    });
433:
                }
434:
            }, callback);
435:
        }
436:
        else {
437:
            var results = {};
438:
            async.forEach(_keys(tasks), function (k, callback) {
439:
                tasks[k](function (err) {
440:
                    var args = Array.prototype.slice.call(arguments, 1);
441:
                    if (args.length <= 1) {
442:
                        args = args[0];
443:
                    }
444:
                    results[k] = args;
445:
                    callback(err);
446:
                });
447:
            }, function (err) {
448:
                callback(err, results);
449:
            });
450:
        }
451:
    };
452:
 
453:
    async.series = function (tasks, callback) {
454:
        callback = callback || function () {};
455:
        if (tasks.constructor === Array) {
456:
            async.mapSeries(tasks, function (fn, callback) {
457:
                if (fn) {
458:
                    fn(function (err) {
459:
                        var args = Array.prototype.slice.call(arguments, 1);
460:
                        if (args.length <= 1) {
461:
                            args = args[0];
462:
                        }
463:
                        callback.call(null, err, args || null);
464:
                    });
465:
                }
466:
            }, callback);
467:
        }
468:
        else {
469:
            var results = {};
470:
            async.forEachSeries(_keys(tasks), function (k, callback) {
471:
                tasks[k](function (err) {
472:
                    var args = Array.prototype.slice.call(arguments, 1);
473:
                    if (args.length <= 1) {
474:
                        args = args[0];
475:
                    }
476:
                    results[k] = args;
477:
                    callback(err);
478:
                });
479:
            }, function (err) {
480:
                callback(err, results);
481:
            });
482:
        }
483:
    };
484:
 
485:
    async.iterator = function (tasks) {
486:
        var makeCallback = function (index) {
487:
            var fn = function () {
488:
                if (tasks.length) {
489:
                    tasks[index].apply(null, arguments);
490:
                }
491:
                return fn.next();
492:
            };
493:
            fn.next = function () {
494:
                return (index < tasks.length - 1) ? makeCallback(index + 1): null;
495:
            };
496:
            return fn;
497:
        };
498:
        return makeCallback(0);
499:
    };
500:
 
501:
    async.apply = function (fn) {
502:
        var args = Array.prototype.slice.call(arguments, 1);
503:
        return function () {
504:
            return fn.apply(
505:
                null, args.concat(Array.prototype.slice.call(arguments))
506:
            );
507:
        };
508:
    };
509:
 
510:
    var _concat = function (eachfn, arr, fn, callback) {
511:
        var r = [];
512:
        eachfn(arr, function (x, cb) {
513:
            fn(x, function (err, y) {
514:
                r = r.concat(y || []);
515:
                cb(err);
516:
            });
517:
        }, function (err) {
518:
            callback(err, r);
519:
        });
520:
    };
521:
    async.concat = doParallel(_concat);
522:
    async.concatSeries = doSeries(_concat);
523:
 
524:
    async.whilst = function (test, iterator, callback) {
525:
        if (test()) {
526:
            iterator(function (err) {
527:
                if (err) {
528:
                    return callback(err);
529:
                }
530:
                async.whilst(test, iterator, callback);
531:
            });
532:
        }
533:
        else {
534:
            callback();
535:
        }
536:
    };
537:
 
538:
    async.until = function (test, iterator, callback) {
539:
        if (!test()) {
540:
            iterator(function (err) {
541:
                if (err) {
542:
                    return callback(err);
543:
                }
544:
                async.until(test, iterator, callback);
545:
            });
546:
        }
547:
        else {
548:
            callback();
549:
        }
550:
    };
551:
 
552:
    async.queue = function (worker, concurrency) {
553:
        var workers = 0;
554:
        var tasks = [];
555:
        var q = {
556:
            concurrency: concurrency,
557:
            push: function (data, callback) {
558:
                tasks.push({data: data, callback: callback});
559:
                async.nextTick(q.process);
560:
            },
561:
            process: function () {
562:
                if (workers < q.concurrency && tasks.length) {
563:
                    var task = tasks.splice(0, 1)[0];
564:
                    workers += 1;
565:
                    worker(task.data, function () {
566:
                        workers -= 1;
567:
                        if (task.callback) {
568:
                            task.callback.apply(task, arguments);
569:
                        }
570:
                        q.process();
571:
                    });
572:
                }
573:
            },
574:
            length: function () {
575:
                return tasks.length;
576:
            }
577:
        };
578:
        return q;
579:
    };
580:
 
581:
    var _console_fn = function (name) {
582:
        return function (fn) {
583:
            var args = Array.prototype.slice.call(arguments, 1);
584:
            fn.apply(null, args.concat([function (err) {
585:
                var args = Array.prototype.slice.call(arguments, 1);
586:
                if (typeof console !== 'undefined') {
587:
                    if (err) {
588:
                        if (console.error) {
589:
                            console.error(err);
590:
                        }
591:
                    }
592:
                    else if (console[name]) {
593:
                        _forEach(args, function (x) {
594:
                            console[name](x);
595:
                        });
596:
                    }
597:
                }
598:
            }]));
599:
        };
600:
    };
601:
    async.log = _console_fn('log');
602:
    async.dir = _console_fn('dir');
603:
    /*async.info = _console_fn('info');
604:
    async.warn = _console_fn('warn');
605:
    async.error = _console_fn('error');*/
606:
 
607:
    async.memoize = function (fn, hasher) {
608:
        var memo = {};
609:
        hasher = hasher || function (x) {
610:
            return x;
611:
        };
612:
        return function () {
613:
            var args = Array.prototype.slice.call(arguments);
614:
            var callback = args.pop();
615:
            var key = hasher.apply(null, args);
616:
            if (key in memo) {
617:
                callback.apply(null, memo[key]);
618:
            }
619:
            else {
620:
                fn.apply(null, args.concat([function () {
621:
                    memo[key] = arguments;
622:
                    callback.apply(null, arguments);
623:
                }]));
624:
            }
625:
        };
626:
    };
627:
 
628:
}());