text: /** @license MIT License (c) copyright 2010-2014 original author or authors */
  /** @author Brian Cavalier */
  /** @author John Hann */
  
  (function(define) { 'use strict';
  define(function() {
  
  	return function array(Promise) {
  
  		var arrayMap = Array.prototype.map;
  		var arrayReduce = Array.prototype.reduce;
  		var arrayReduceRight = Array.prototype.reduceRight;
  		var arrayForEach = Array.prototype.forEach;
  
  		var toPromise = Promise.resolve;
  		var all = Promise.all;
  
  		// Additional array combinators
  
  		Promise.any = any;
  		Promise.some = some;
  		Promise.settle = settle;
  
  		Promise.map = map;
  		Promise.reduce = reduce;
  		Promise.reduceRight = reduceRight;
  
  		/**
  		 * When this promise fulfills with an array, do
  		 * onFulfilled.apply(void 0, array)
  		 * @param (function) onFulfilled function to apply
  		 * @returns {Promise} promise for the result of applying onFulfilled
  		 */
  		Promise.prototype.spread = function(onFulfilled) {
  			return this.then(all).then(function(array) {
  				return onFulfilled.apply(void 0, array);
  			});
  		};
  
  		return Promise;
  
  		/**
  		 * One-winner competitive race.
  		 * Return a promise that will fulfill when one of the promises
  		 * in the input array fulfills, or will reject when all promises
  		 * have rejected.
  		 * @param {array} promises
  		 * @returns {Promise} promise for the first fulfilled value
  		 */
  		function any(promises) {
  			return new Promise(function(resolve, reject) {
  				var pending = 0;
  				var errors = [];
  
  				arrayForEach.call(promises, function(p) {
  					++pending;
  					toPromise(p).then(resolve, handleReject);
  				});
  
  				if(pending === 0) {
  					resolve();
  				}
  
  				function handleReject(e) {
  					errors.push(e);
  					if(--pending === 0) {
  						reject(errors);
  					}
  				}
  			});
  		}
  
  		/**
  		 * N-winner competitive race
  		 * Return a promise that will fulfill when n input promises have
  		 * fulfilled, or will reject when it becomes impossible for n
  		 * input promises to fulfill (ie when promises.length - n + 1
  		 * have rejected)
  		 * @param {array} promises
  		 * @param {number} n
  		 * @returns {Promise} promise for the earliest n fulfillment values
  		 *
  		 * @deprecated
  		 */
  		function some(promises, n) {
  			return new Promise(function(resolve, reject, notify) {
  				var nFulfill = 0;
  				var nReject;
  				var results = [];
  				var errors = [];
  
  				arrayForEach.call(promises, function(p) {
  					++nFulfill;
  					toPromise(p).then(handleResolve, handleReject, notify);
  				});
  
  				n = Math.max(n, 0);
  				nReject = (nFulfill - n + 1);
  				nFulfill = Math.min(n, nFulfill);
  
  				if(nFulfill === 0) {
  					resolve(results);
  					return;
  				}
  
  				function handleResolve(x) {
  					if(nFulfill > 0) {
  						--nFulfill;
  						results.push(x);
  
  						if(nFulfill === 0) {
  							resolve(results);
  						}
  					}
  				}
  
  				function handleReject(e) {
  					if(nReject > 0) {
  						--nReject;
  						errors.push(e);
  
  						if(nReject === 0) {
  							reject(errors);
  						}
  					}
  				}
  			});
  		}
  
  		/**
  		 * Apply f to the value of each promise in a list of promises
  		 * and return a new list containing the results.
  		 * @param {array} promises
  		 * @param {function} f
  		 * @param {function} fallback
  		 * @returns {Promise}
  		 */
  		function map(promises, f, fallback) {
  			return all(arrayMap.call(promises, function(x) {
  				return toPromise(x).then(f, fallback);
  			}));
  		}
  
  		/**
  		 * Return a promise that will always fulfill with an array containing
  		 * the outcome states of all input promises.  The returned promise
  		 * will never reject.
  		 * @param {array} promises
  		 * @returns {Promise}
  		 */
  		function settle(promises) {
  			return all(arrayMap.call(promises, function(p) {
  				p = toPromise(p);
  				return p.then(inspect, inspect);
  
  				function inspect() {
  					return p.inspect();
  				}
  			}));
  		}
  
  		function reduce(promises, f) {
  			return arguments.length > 2
  				? arrayReduce.call(promises, reducer, arguments[2])
  				: arrayReduce.call(promises, reducer);
  
  			function reducer(result, x, i) {
  				return toPromise(result).then(function(r) {
  					return toPromise(x).then(function(x) {
  						return f(r, x, i);
  					});
  				});
  			}
  		}
  
  		function reduceRight(promises, f) {
  			return arguments.length > 2
  				? arrayReduceRight.call(promises, reducer, arguments[2])
  				: arrayReduceRight.call(promises, reducer);
  
  			function reducer(result, x, i) {
  				return toPromise(result).then(function(r) {
  					return toPromise(x).then(function(x) {
  						return f(r, x, i);
  					});
  				});
  			}
  		}
  	};
  
  
  });
  }(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(); }));
  