| "use strict"; | 
| module.exports = function(Promise, | 
|                           PromiseArray, | 
|                           apiRejection, | 
|                           tryConvertToPromise, | 
|                           INTERNAL, | 
|                           debug) { | 
| var util = require("./util"); | 
| var tryCatch = util.tryCatch; | 
| var errorObj = util.errorObj; | 
| var async = Promise._async; | 
|   | 
| function MappingPromiseArray(promises, fn, limit, _filter) { | 
|     this.constructor$(promises); | 
|     this._promise._captureStackTrace(); | 
|     var context = Promise._getContext(); | 
|     this._callback = util.contextBind(context, fn); | 
|     this._preservedValues = _filter === INTERNAL | 
|         ? new Array(this.length()) | 
|         : null; | 
|     this._limit = limit; | 
|     this._inFlight = 0; | 
|     this._queue = []; | 
|     async.invoke(this._asyncInit, this, undefined); | 
|     if (util.isArray(promises)) { | 
|         for (var i = 0; i < promises.length; ++i) { | 
|             var maybePromise = promises[i]; | 
|             if (maybePromise instanceof Promise) { | 
|                 maybePromise.suppressUnhandledRejections(); | 
|             } | 
|         } | 
|     } | 
| } | 
| util.inherits(MappingPromiseArray, PromiseArray); | 
|   | 
| MappingPromiseArray.prototype._asyncInit = function() { | 
|     this._init$(undefined, -2); | 
| }; | 
|   | 
| MappingPromiseArray.prototype._init = function () {}; | 
|   | 
| MappingPromiseArray.prototype._promiseFulfilled = function (value, index) { | 
|     var values = this._values; | 
|     var length = this.length(); | 
|     var preservedValues = this._preservedValues; | 
|     var limit = this._limit; | 
|   | 
|     if (index < 0) { | 
|         index = (index * -1) - 1; | 
|         values[index] = value; | 
|         if (limit >= 1) { | 
|             this._inFlight--; | 
|             this._drainQueue(); | 
|             if (this._isResolved()) return true; | 
|         } | 
|     } else { | 
|         if (limit >= 1 && this._inFlight >= limit) { | 
|             values[index] = value; | 
|             this._queue.push(index); | 
|             return false; | 
|         } | 
|         if (preservedValues !== null) preservedValues[index] = value; | 
|   | 
|         var promise = this._promise; | 
|         var callback = this._callback; | 
|         var receiver = promise._boundValue(); | 
|         promise._pushContext(); | 
|         var ret = tryCatch(callback).call(receiver, value, index, length); | 
|         var promiseCreated = promise._popContext(); | 
|         debug.checkForgottenReturns( | 
|             ret, | 
|             promiseCreated, | 
|             preservedValues !== null ? "Promise.filter" : "Promise.map", | 
|             promise | 
|         ); | 
|         if (ret === errorObj) { | 
|             this._reject(ret.e); | 
|             return true; | 
|         } | 
|   | 
|         var maybePromise = tryConvertToPromise(ret, this._promise); | 
|         if (maybePromise instanceof Promise) { | 
|             maybePromise = maybePromise._target(); | 
|             var bitField = maybePromise._bitField; | 
|             ; | 
|             if (((bitField & 50397184) === 0)) { | 
|                 if (limit >= 1) this._inFlight++; | 
|                 values[index] = maybePromise; | 
|                 maybePromise._proxy(this, (index + 1) * -1); | 
|                 return false; | 
|             } else if (((bitField & 33554432) !== 0)) { | 
|                 ret = maybePromise._value(); | 
|             } else if (((bitField & 16777216) !== 0)) { | 
|                 this._reject(maybePromise._reason()); | 
|                 return true; | 
|             } else { | 
|                 this._cancel(); | 
|                 return true; | 
|             } | 
|         } | 
|         values[index] = ret; | 
|     } | 
|     var totalResolved = ++this._totalResolved; | 
|     if (totalResolved >= length) { | 
|         if (preservedValues !== null) { | 
|             this._filter(values, preservedValues); | 
|         } else { | 
|             this._resolve(values); | 
|         } | 
|         return true; | 
|     } | 
|     return false; | 
| }; | 
|   | 
| MappingPromiseArray.prototype._drainQueue = function () { | 
|     var queue = this._queue; | 
|     var limit = this._limit; | 
|     var values = this._values; | 
|     while (queue.length > 0 && this._inFlight < limit) { | 
|         if (this._isResolved()) return; | 
|         var index = queue.pop(); | 
|         this._promiseFulfilled(values[index], index); | 
|     } | 
| }; | 
|   | 
| MappingPromiseArray.prototype._filter = function (booleans, values) { | 
|     var len = values.length; | 
|     var ret = new Array(len); | 
|     var j = 0; | 
|     for (var i = 0; i < len; ++i) { | 
|         if (booleans[i]) ret[j++] = values[i]; | 
|     } | 
|     ret.length = j; | 
|     this._resolve(ret); | 
| }; | 
|   | 
| MappingPromiseArray.prototype.preservedValues = function () { | 
|     return this._preservedValues; | 
| }; | 
|   | 
| function map(promises, fn, options, _filter) { | 
|     if (typeof fn !== "function") { | 
|         return apiRejection("expecting a function but got " + util.classString(fn)); | 
|     } | 
|   | 
|     var limit = 0; | 
|     if (options !== undefined) { | 
|         if (typeof options === "object" && options !== null) { | 
|             if (typeof options.concurrency !== "number") { | 
|                 return Promise.reject( | 
|                     new TypeError("'concurrency' must be a number but it is " + | 
|                                     util.classString(options.concurrency))); | 
|             } | 
|             limit = options.concurrency; | 
|         } else { | 
|             return Promise.reject(new TypeError( | 
|                             "options argument must be an object but it is " + | 
|                              util.classString(options))); | 
|         } | 
|     } | 
|     limit = typeof limit === "number" && | 
|         isFinite(limit) && limit >= 1 ? limit : 0; | 
|     return new MappingPromiseArray(promises, fn, limit, _filter).promise(); | 
| } | 
|   | 
| Promise.prototype.map = function (fn, options) { | 
|     return map(this, fn, options, null); | 
| }; | 
|   | 
| Promise.map = function (promises, fn, options, _filter) { | 
|     return map(promises, fn, options, _filter); | 
| }; | 
|   | 
|   | 
| }; |