(function(){ var async = {}; // global on the server, window in the browser var root = this; var previous_async = root.async; if(typeof module !== 'undefined' && module.exports) module.exports = async; else root.async = async; async.noConflict = function(){ root.async = previous_async; return async; }; //// cross-browser compatiblity functions //// var _forEach = function(arr, iterator){ if(arr.forEach) return arr.forEach(iterator); for(var i=0; i b ? 1 : 0; }), function(x){return x.value;})); }) }; async.auto = function(tasks, callback){ callback = callback || function(){}; var keys = _keys(tasks); if(!keys.length) return callback(null); var completed = []; var listeners = []; var addListener = function(fn){ listeners.unshift(fn); }; var removeListener = function(fn){ for(var i=0; i