corrade-nucleus-nucleons – Blame information for rev 4

Subversion Repositories:
Rev:
Rev Author Line No. Line
2 office 1 // vim:ts=4:sts=4:sw=4:
2 /*!
3 *
4 * Copyright 2009-2012 Kris Kowal under the terms of the MIT
5 * license found at http://github.com/kriskowal/q/raw/master/LICENSE
6 *
7 * With parts by Tyler Close
8 * Copyright 2007-2009 Tyler Close under the terms of the MIT X license found
9 * at http://www.opensource.org/licenses/mit-license.html
10 * Forked at ref_send.js version: 2009-05-11
11 *
12 * With parts by Mark Miller
13 * Copyright (C) 2011 Google Inc.
14 *
15 * Licensed under the Apache License, Version 2.0 (the "License");
16 * you may not use this file except in compliance with the License.
17 * You may obtain a copy of the License at
18 *
19 * http://www.apache.org/licenses/LICENSE-2.0
20 *
21 * Unless required by applicable law or agreed to in writing, software
22 * distributed under the License is distributed on an "AS IS" BASIS,
23 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
24 * See the License for the specific language governing permissions and
25 * limitations under the License.
26 *
27 */
28  
29 (function (definition) {
30 // Turn off strict mode for this function so we can assign to global.Q
31 /* jshint strict: false */
32  
33 // This file will function properly as a <script> tag, or a module
34 // using CommonJS and NodeJS or RequireJS module formats. In
35 // Common/Node/RequireJS, the module exports the Q API and when
36 // executed as a simple <script>, it creates a Q global instead.
37  
38 // Montage Require
39 if (typeof bootstrap === "function") {
40 bootstrap("promise", definition);
41  
42 // CommonJS
43 } else if (typeof exports === "object") {
44 module.exports = definition();
45  
46 // RequireJS
47 } else if (typeof define === "function" && define.amd) {
48 define(definition);
49  
50 // SES (Secure EcmaScript)
51 } else if (typeof ses !== "undefined") {
52 if (!ses.ok()) {
53 return;
54 } else {
55 ses.makeQ = definition;
56 }
57  
58 // <script>
59 } else {
60 Q = definition();
61 }
62  
63 })(function () {
64 "use strict";
65  
66 var hasStacks = false;
67 try {
68 throw new Error();
69 } catch (e) {
70 hasStacks = !!e.stack;
71 }
72  
73 // All code after this point will be filtered from stack traces reported
74 // by Q.
75 var qStartingLine = captureLine();
76 var qFileName;
77  
78 // shims
79  
80 // used for fallback in "allResolved"
81 var noop = function () {};
82  
83 // Use the fastest possible means to execute a task in a future turn
84 // of the event loop.
85 var nextTick =(function () {
86 // linked list of tasks (single, with head node)
87 var head = {task: void 0, next: null};
88 var tail = head;
89 var flushing = false;
90 var requestTick = void 0;
91 var isNodeJS = false;
92  
93 function flush() {
94 /* jshint loopfunc: true */
95  
96 while (head.next) {
97 head = head.next;
98 var task = head.task;
99 head.task = void 0;
100 var domain = head.domain;
101  
102 if (domain) {
103 head.domain = void 0;
104 domain.enter();
105 }
106  
107 try {
108 task();
109  
110 } catch (e) {
111 if (isNodeJS) {
112 // In node, uncaught exceptions are considered fatal errors.
113 // Re-throw them synchronously to interrupt flushing!
114  
115 // Ensure continuation if the uncaught exception is suppressed
116 // listening "uncaughtException" events (as domains does).
117 // Continue in next event to avoid tick recursion.
118 if (domain) {
119 domain.exit();
120 }
121 setTimeout(flush, 0);
122 if (domain) {
123 domain.enter();
124 }
125  
126 throw e;
127  
128 } else {
129 // In browsers, uncaught exceptions are not fatal.
130 // Re-throw them asynchronously to avoid slow-downs.
131 setTimeout(function() {
132 throw e;
133 }, 0);
134 }
135 }
136  
137 if (domain) {
138 domain.exit();
139 }
140 }
141  
142 flushing = false;
143 }
144  
145 nextTick = function (task) {
146 tail = tail.next = {
147 task: task,
148 domain: isNodeJS && process.domain,
149 next: null
150 };
151  
152 if (!flushing) {
153 flushing = true;
154 requestTick();
155 }
156 };
157  
158 if (typeof process !== "undefined" && process.nextTick) {
159 // Node.js before 0.9. Note that some fake-Node environments, like the
160 // Mocha test runner, introduce a `process` global without a `nextTick`.
161 isNodeJS = true;
162  
163 requestTick = function () {
164 process.nextTick(flush);
165 };
166  
167 } else if (typeof setImmediate === "function") {
168 // In IE10, Node.js 0.9+, or https://github.com/NobleJS/setImmediate
169 if (typeof window !== "undefined") {
170 requestTick = setImmediate.bind(window, flush);
171 } else {
172 requestTick = function () {
173 setImmediate(flush);
174 };
175 }
176  
177 } else if (typeof MessageChannel !== "undefined") {
178 // modern browsers
179 // http://www.nonblocking.io/2011/06/windownexttick.html
180 var channel = new MessageChannel();
181 // At least Safari Version 6.0.5 (8536.30.1) intermittently cannot create
182 // working message ports the first time a page loads.
183 channel.port1.onmessage = function () {
184 requestTick = requestPortTick;
185 channel.port1.onmessage = flush;
186 flush();
187 };
188 var requestPortTick = function () {
189 // Opera requires us to provide a message payload, regardless of
190 // whether we use it.
191 channel.port2.postMessage(0);
192 };
193 requestTick = function () {
194 setTimeout(flush, 0);
195 requestPortTick();
196 };
197  
198 } else {
199 // old browsers
200 requestTick = function () {
201 setTimeout(flush, 0);
202 };
203 }
204  
205 return nextTick;
206 })();
207  
208 // Attempt to make generics safe in the face of downstream
209 // modifications.
210 // There is no situation where this is necessary.
211 // If you need a security guarantee, these primordials need to be
212 // deeply frozen anyway, and if you don’t need a security guarantee,
213 // this is just plain paranoid.
214 // However, this **might** have the nice side-effect of reducing the size of
215 // the minified code by reducing x.call() to merely x()
216 // See Mark Miller’s explanation of what this does.
217 // http://wiki.ecmascript.org/doku.php?id=conventions:safe_meta_programming
218 var call = Function.call;
219 function uncurryThis(f) {
220 return function () {
221 return call.apply(f, arguments);
222 };
223 }
224 // This is equivalent, but slower:
225 // uncurryThis = Function_bind.bind(Function_bind.call);
226 // http://jsperf.com/uncurrythis
227  
228 var array_slice = uncurryThis(Array.prototype.slice);
229  
230 var array_reduce = uncurryThis(
231 Array.prototype.reduce || function (callback, basis) {
232 var index = 0,
233 length = this.length;
234 // concerning the initial value, if one is not provided
235 if (arguments.length === 1) {
236 // seek to the first value in the array, accounting
237 // for the possibility that is is a sparse array
238 do {
239 if (index in this) {
240 basis = this[index++];
241 break;
242 }
243 if (++index >= length) {
244 throw new TypeError();
245 }
246 } while (1);
247 }
248 // reduce
249 for (; index < length; index++) {
250 // account for the possibility that the array is sparse
251 if (index in this) {
252 basis = callback(basis, this[index], index);
253 }
254 }
255 return basis;
256 }
257 );
258  
259 var array_indexOf = uncurryThis(
260 Array.prototype.indexOf || function (value) {
261 // not a very good shim, but good enough for our one use of it
262 for (var i = 0; i < this.length; i++) {
263 if (this[i] === value) {
264 return i;
265 }
266 }
267 return -1;
268 }
269 );
270  
271 var array_map = uncurryThis(
272 Array.prototype.map || function (callback, thisp) {
273 var self = this;
274 var collect = [];
275 array_reduce(self, function (undefined, value, index) {
276 collect.push(callback.call(thisp, value, index, self));
277 }, void 0);
278 return collect;
279 }
280 );
281  
282 var object_create = Object.create || function (prototype) {
283 function Type() { }
284 Type.prototype = prototype;
285 return new Type();
286 };
287  
288 var object_hasOwnProperty = uncurryThis(Object.prototype.hasOwnProperty);
289  
290 var object_keys = Object.keys || function (object) {
291 var keys = [];
292 for (var key in object) {
293 if (object_hasOwnProperty(object, key)) {
294 keys.push(key);
295 }
296 }
297 return keys;
298 };
299  
300 var object_toString = uncurryThis(Object.prototype.toString);
301  
302 function isObject(value) {
303 return value === Object(value);
304 }
305  
306 // generator related shims
307  
308 // FIXME: Remove this function once ES6 generators are in SpiderMonkey.
309 function isStopIteration(exception) {
310 return (
311 object_toString(exception) === "[object StopIteration]" ||
312 exception instanceof QReturnValue
313 );
314 }
315  
316 // FIXME: Remove this helper and Q.return once ES6 generators are in
317 // SpiderMonkey.
318 var QReturnValue;
319 if (typeof ReturnValue !== "undefined") {
320 QReturnValue = ReturnValue;
321 } else {
322 QReturnValue = function (value) {
323 this.value = value;
324 };
325 }
326  
327 // long stack traces
328  
329 var STACK_JUMP_SEPARATOR = "From previous event:";
330  
331 function makeStackTraceLong(error, promise) {
332 // If possible, transform the error stack trace by removing Node and Q
333 // cruft, then concatenating with the stack trace of `promise`. See #57.
334 if (hasStacks &&
335 promise.stack &&
336 typeof error === "object" &&
337 error !== null &&
338 error.stack &&
339 error.stack.indexOf(STACK_JUMP_SEPARATOR) === -1
340 ) {
341 var stacks = [];
342 for (var p = promise; !!p; p = p.source) {
343 if (p.stack) {
344 stacks.unshift(p.stack);
345 }
346 }
347 stacks.unshift(error.stack);
348  
349 var concatedStacks = stacks.join("\n" + STACK_JUMP_SEPARATOR + "\n");
350 error.stack = filterStackString(concatedStacks);
351 }
352 }
353  
354 function filterStackString(stackString) {
355 var lines = stackString.split("\n");
356 var desiredLines = [];
357 for (var i = 0; i < lines.length; ++i) {
358 var line = lines[i];
359  
360 if (!isInternalFrame(line) && !isNodeFrame(line) && line) {
361 desiredLines.push(line);
362 }
363 }
364 return desiredLines.join("\n");
365 }
366  
367 function isNodeFrame(stackLine) {
368 return stackLine.indexOf("(module.js:") !== -1 ||
369 stackLine.indexOf("(node.js:") !== -1;
370 }
371  
372 function getFileNameAndLineNumber(stackLine) {
373 // Named functions: "at functionName (filename:lineNumber:columnNumber)"
374 // In IE10 function name can have spaces ("Anonymous function") O_o
375 var attempt1 = /at .+ \((.+):(\d+):(?:\d+)\)$/.exec(stackLine);
376 if (attempt1) {
377 return [attempt1[1], Number(attempt1[2])];
378 }
379  
380 // Anonymous functions: "at filename:lineNumber:columnNumber"
381 var attempt2 = /at ([^ ]+):(\d+):(?:\d+)$/.exec(stackLine);
382 if (attempt2) {
383 return [attempt2[1], Number(attempt2[2])];
384 }
385  
386 // Firefox style: "function@filename:lineNumber or @filename:lineNumber"
387 var attempt3 = /.*@(.+):(\d+)$/.exec(stackLine);
388 if (attempt3) {
389 return [attempt3[1], Number(attempt3[2])];
390 }
391 }
392  
393 function isInternalFrame(stackLine) {
394 var fileNameAndLineNumber = getFileNameAndLineNumber(stackLine);
395  
396 if (!fileNameAndLineNumber) {
397 return false;
398 }
399  
400 var fileName = fileNameAndLineNumber[0];
401 var lineNumber = fileNameAndLineNumber[1];
402  
403 return fileName === qFileName &&
404 lineNumber >= qStartingLine &&
405 lineNumber <= qEndingLine;
406 }
407  
408 // discover own file name and line number range for filtering stack
409 // traces
410 function captureLine() {
411 if (!hasStacks) {
412 return;
413 }
414  
415 try {
416 throw new Error();
417 } catch (e) {
418 var lines = e.stack.split("\n");
419 var firstLine = lines[0].indexOf("@") > 0 ? lines[1] : lines[2];
420 var fileNameAndLineNumber = getFileNameAndLineNumber(firstLine);
421 if (!fileNameAndLineNumber) {
422 return;
423 }
424  
425 qFileName = fileNameAndLineNumber[0];
426 return fileNameAndLineNumber[1];
427 }
428 }
429  
430 function deprecate(callback, name, alternative) {
431 return function () {
432 if (typeof console !== "undefined" &&
433 typeof console.warn === "function") {
434 console.warn(name + " is deprecated, use " + alternative +
435 " instead.", new Error("").stack);
436 }
437 return callback.apply(callback, arguments);
438 };
439 }
440  
441 // end of shims
442 // beginning of real work
443  
444 /**
445 * Constructs a promise for an immediate reference, passes promises through, or
446 * coerces promises from different systems.
447 * @param value immediate reference or promise
448 */
449 function Q(value) {
450 // If the object is already a Promise, return it directly. This enables
451 // the resolve function to both be used to created references from objects,
452 // but to tolerably coerce non-promises to promises.
453 if (isPromise(value)) {
454 return value;
455 }
456  
457 // assimilate thenables
458 if (isPromiseAlike(value)) {
459 return coerce(value);
460 } else {
461 return fulfill(value);
462 }
463 }
464 Q.resolve = Q;
465  
466 /**
467 * Performs a task in a future turn of the event loop.
468 * @param {Function} task
469 */
470 Q.nextTick = nextTick;
471  
472 /**
473 * Controls whether or not long stack traces will be on
474 */
475 Q.longStackSupport = false;
476  
477 /**
478 * Constructs a {promise, resolve, reject} object.
479 *
480 * `resolve` is a callback to invoke with a more resolved value for the
481 * promise. To fulfill the promise, invoke `resolve` with any value that is
482 * not a thenable. To reject the promise, invoke `resolve` with a rejected
483 * thenable, or invoke `reject` with the reason directly. To resolve the
484 * promise to another thenable, thus putting it in the same state, invoke
485 * `resolve` with that other thenable.
486 */
487 Q.defer = defer;
488 function defer() {
489 // if "messages" is an "Array", that indicates that the promise has not yet
490 // been resolved. If it is "undefined", it has been resolved. Each
491 // element of the messages array is itself an array of complete arguments to
492 // forward to the resolved promise. We coerce the resolution value to a
493 // promise using the `resolve` function because it handles both fully
494 // non-thenable values and other thenables gracefully.
495 var messages = [], progressListeners = [], resolvedPromise;
496  
497 var deferred = object_create(defer.prototype);
498 var promise = object_create(Promise.prototype);
499  
500 promise.promiseDispatch = function (resolve, op, operands) {
501 var args = array_slice(arguments);
502 if (messages) {
503 messages.push(args);
504 if (op === "when" && operands[1]) { // progress operand
505 progressListeners.push(operands[1]);
506 }
507 } else {
508 nextTick(function () {
509 resolvedPromise.promiseDispatch.apply(resolvedPromise, args);
510 });
511 }
512 };
513  
514 // XXX deprecated
515 promise.valueOf = function () {
516 if (messages) {
517 return promise;
518 }
519 var nearerValue = nearer(resolvedPromise);
520 if (isPromise(nearerValue)) {
521 resolvedPromise = nearerValue; // shorten chain
522 }
523 return nearerValue;
524 };
525  
526 promise.inspect = function () {
527 if (!resolvedPromise) {
528 return { state: "pending" };
529 }
530 return resolvedPromise.inspect();
531 };
532  
533 if (Q.longStackSupport && hasStacks) {
534 try {
535 throw new Error();
536 } catch (e) {
537 // NOTE: don't try to use `Error.captureStackTrace` or transfer the
538 // accessor around; that causes memory leaks as per GH-111. Just
539 // reify the stack trace as a string ASAP.
540 //
541 // At the same time, cut off the first line; it's always just
542 // "[object Promise]\n", as per the `toString`.
543 promise.stack = e.stack.substring(e.stack.indexOf("\n") + 1);
544 }
545 }
546  
547 // NOTE: we do the checks for `resolvedPromise` in each method, instead of
548 // consolidating them into `become`, since otherwise we'd create new
549 // promises with the lines `become(whatever(value))`. See e.g. GH-252.
550  
551 function become(newPromise) {
552 resolvedPromise = newPromise;
553 promise.source = newPromise;
554  
555 array_reduce(messages, function (undefined, message) {
556 nextTick(function () {
557 newPromise.promiseDispatch.apply(newPromise, message);
558 });
559 }, void 0);
560  
561 messages = void 0;
562 progressListeners = void 0;
563 }
564  
565 deferred.promise = promise;
566 deferred.resolve = function (value) {
567 if (resolvedPromise) {
568 return;
569 }
570  
571 become(Q(value));
572 };
573  
574 deferred.fulfill = function (value) {
575 if (resolvedPromise) {
576 return;
577 }
578  
579 become(fulfill(value));
580 };
581 deferred.reject = function (reason) {
582 if (resolvedPromise) {
583 return;
584 }
585  
586 become(reject(reason));
587 };
588 deferred.notify = function (progress) {
589 if (resolvedPromise) {
590 return;
591 }
592  
593 array_reduce(progressListeners, function (undefined, progressListener) {
594 nextTick(function () {
595 progressListener(progress);
596 });
597 }, void 0);
598 };
599  
600 return deferred;
601 }
602  
603 /**
604 * Creates a Node-style callback that will resolve or reject the deferred
605 * promise.
606 * @returns a nodeback
607 */
608 defer.prototype.makeNodeResolver = function () {
609 var self = this;
610 return function (error, value) {
611 if (error) {
612 self.reject(error);
613 } else if (arguments.length > 2) {
614 self.resolve(array_slice(arguments, 1));
615 } else {
616 self.resolve(value);
617 }
618 };
619 };
620  
621 /**
622 * @param resolver {Function} a function that returns nothing and accepts
623 * the resolve, reject, and notify functions for a deferred.
624 * @returns a promise that may be resolved with the given resolve and reject
625 * functions, or rejected by a thrown exception in resolver
626 */
627 Q.Promise = promise; // ES6
628 Q.promise = promise;
629 function promise(resolver) {
630 if (typeof resolver !== "function") {
631 throw new TypeError("resolver must be a function.");
632 }
633 var deferred = defer();
634 try {
635 resolver(deferred.resolve, deferred.reject, deferred.notify);
636 } catch (reason) {
637 deferred.reject(reason);
638 }
639 return deferred.promise;
640 }
641  
642 promise.race = race; // ES6
643 promise.all = all; // ES6
644 promise.reject = reject; // ES6
645 promise.resolve = Q; // ES6
646  
647 // XXX experimental. This method is a way to denote that a local value is
648 // serializable and should be immediately dispatched to a remote upon request,
649 // instead of passing a reference.
650 Q.passByCopy = function (object) {
651 //freeze(object);
652 //passByCopies.set(object, true);
653 return object;
654 };
655  
656 Promise.prototype.passByCopy = function () {
657 //freeze(object);
658 //passByCopies.set(object, true);
659 return this;
660 };
661  
662 /**
663 * If two promises eventually fulfill to the same value, promises that value,
664 * but otherwise rejects.
665 * @param x {Any*}
666 * @param y {Any*}
667 * @returns {Any*} a promise for x and y if they are the same, but a rejection
668 * otherwise.
669 *
670 */
671 Q.join = function (x, y) {
672 return Q(x).join(y);
673 };
674  
675 Promise.prototype.join = function (that) {
676 return Q([this, that]).spread(function (x, y) {
677 if (x === y) {
678 // TODO: "===" should be Object.is or equiv
679 return x;
680 } else {
681 throw new Error("Can't join: not the same: " + x + " " + y);
682 }
683 });
684 };
685  
686 /**
687 * Returns a promise for the first of an array of promises to become fulfilled.
688 * @param answers {Array[Any*]} promises to race
689 * @returns {Any*} the first promise to be fulfilled
690 */
691 Q.race = race;
692 function race(answerPs) {
693 return promise(function(resolve, reject) {
694 // Switch to this once we can assume at least ES5
695 // answerPs.forEach(function(answerP) {
696 // Q(answerP).then(resolve, reject);
697 // });
698 // Use this in the meantime
699 for (var i = 0, len = answerPs.length; i < len; i++) {
700 Q(answerPs[i]).then(resolve, reject);
701 }
702 });
703 }
704  
705 Promise.prototype.race = function () {
706 return this.then(Q.race);
707 };
708  
709 /**
710 * Constructs a Promise with a promise descriptor object and optional fallback
711 * function. The descriptor contains methods like when(rejected), get(name),
712 * set(name, value), post(name, args), and delete(name), which all
713 * return either a value, a promise for a value, or a rejection. The fallback
714 * accepts the operation name, a resolver, and any further arguments that would
715 * have been forwarded to the appropriate method above had a method been
716 * provided with the proper name. The API makes no guarantees about the nature
717 * of the returned object, apart from that it is usable whereever promises are
718 * bought and sold.
719 */
720 Q.makePromise = Promise;
721 function Promise(descriptor, fallback, inspect) {
722 if (fallback === void 0) {
723 fallback = function (op) {
724 return reject(new Error(
725 "Promise does not support operation: " + op
726 ));
727 };
728 }
729 if (inspect === void 0) {
730 inspect = function () {
731 return {state: "unknown"};
732 };
733 }
734  
735 var promise = object_create(Promise.prototype);
736  
737 promise.promiseDispatch = function (resolve, op, args) {
738 var result;
739 try {
740 if (descriptor[op]) {
741 result = descriptor[op].apply(promise, args);
742 } else {
743 result = fallback.call(promise, op, args);
744 }
745 } catch (exception) {
746 result = reject(exception);
747 }
748 if (resolve) {
749 resolve(result);
750 }
751 };
752  
753 promise.inspect = inspect;
754  
755 // XXX deprecated `valueOf` and `exception` support
756 if (inspect) {
757 var inspected = inspect();
758 if (inspected.state === "rejected") {
759 promise.exception = inspected.reason;
760 }
761  
762 promise.valueOf = function () {
763 var inspected = inspect();
764 if (inspected.state === "pending" ||
765 inspected.state === "rejected") {
766 return promise;
767 }
768 return inspected.value;
769 };
770 }
771  
772 return promise;
773 }
774  
775 Promise.prototype.toString = function () {
776 return "[object Promise]";
777 };
778  
779 Promise.prototype.then = function (fulfilled, rejected, progressed) {
780 var self = this;
781 var deferred = defer();
782 var done = false; // ensure the untrusted promise makes at most a
783 // single call to one of the callbacks
784  
785 function _fulfilled(value) {
786 try {
787 return typeof fulfilled === "function" ? fulfilled(value) : value;
788 } catch (exception) {
789 return reject(exception);
790 }
791 }
792  
793 function _rejected(exception) {
794 if (typeof rejected === "function") {
795 makeStackTraceLong(exception, self);
796 try {
797 return rejected(exception);
798 } catch (newException) {
799 return reject(newException);
800 }
801 }
802 return reject(exception);
803 }
804  
805 function _progressed(value) {
806 return typeof progressed === "function" ? progressed(value) : value;
807 }
808  
809 nextTick(function () {
810 self.promiseDispatch(function (value) {
811 if (done) {
812 return;
813 }
814 done = true;
815  
816 deferred.resolve(_fulfilled(value));
817 }, "when", [function (exception) {
818 if (done) {
819 return;
820 }
821 done = true;
822  
823 deferred.resolve(_rejected(exception));
824 }]);
825 });
826  
827 // Progress propagator need to be attached in the current tick.
828 self.promiseDispatch(void 0, "when", [void 0, function (value) {
829 var newValue;
830 var threw = false;
831 try {
832 newValue = _progressed(value);
833 } catch (e) {
834 threw = true;
835 if (Q.onerror) {
836 Q.onerror(e);
837 } else {
838 throw e;
839 }
840 }
841  
842 if (!threw) {
843 deferred.notify(newValue);
844 }
845 }]);
846  
847 return deferred.promise;
848 };
849  
850 /**
851 * Registers an observer on a promise.
852 *
853 * Guarantees:
854 *
855 * 1. that fulfilled and rejected will be called only once.
856 * 2. that either the fulfilled callback or the rejected callback will be
857 * called, but not both.
858 * 3. that fulfilled and rejected will not be called in this turn.
859 *
860 * @param value promise or immediate reference to observe
861 * @param fulfilled function to be called with the fulfilled value
862 * @param rejected function to be called with the rejection exception
863 * @param progressed function to be called on any progress notifications
864 * @return promise for the return value from the invoked callback
865 */
866 Q.when = when;
867 function when(value, fulfilled, rejected, progressed) {
868 return Q(value).then(fulfilled, rejected, progressed);
869 }
870  
871 Promise.prototype.thenResolve = function (value) {
872 return this.then(function () { return value; });
873 };
874  
875 Q.thenResolve = function (promise, value) {
876 return Q(promise).thenResolve(value);
877 };
878  
879 Promise.prototype.thenReject = function (reason) {
880 return this.then(function () { throw reason; });
881 };
882  
883 Q.thenReject = function (promise, reason) {
884 return Q(promise).thenReject(reason);
885 };
886  
887 /**
888 * If an object is not a promise, it is as "near" as possible.
889 * If a promise is rejected, it is as "near" as possible too.
890 * If it’s a fulfilled promise, the fulfillment value is nearer.
891 * If it’s a deferred promise and the deferred has been resolved, the
892 * resolution is "nearer".
893 * @param object
894 * @returns most resolved (nearest) form of the object
895 */
896  
897 // XXX should we re-do this?
898 Q.nearer = nearer;
899 function nearer(value) {
900 if (isPromise(value)) {
901 var inspected = value.inspect();
902 if (inspected.state === "fulfilled") {
903 return inspected.value;
904 }
905 }
906 return value;
907 }
908  
909 /**
910 * @returns whether the given object is a promise.
911 * Otherwise it is a fulfilled value.
912 */
913 Q.isPromise = isPromise;
914 function isPromise(object) {
915 return isObject(object) &&
916 typeof object.promiseDispatch === "function" &&
917 typeof object.inspect === "function";
918 }
919  
920 Q.isPromiseAlike = isPromiseAlike;
921 function isPromiseAlike(object) {
922 return isObject(object) && typeof object.then === "function";
923 }
924  
925 /**
926 * @returns whether the given object is a pending promise, meaning not
927 * fulfilled or rejected.
928 */
929 Q.isPending = isPending;
930 function isPending(object) {
931 return isPromise(object) && object.inspect().state === "pending";
932 }
933  
934 Promise.prototype.isPending = function () {
935 return this.inspect().state === "pending";
936 };
937  
938 /**
939 * @returns whether the given object is a value or fulfilled
940 * promise.
941 */
942 Q.isFulfilled = isFulfilled;
943 function isFulfilled(object) {
944 return !isPromise(object) || object.inspect().state === "fulfilled";
945 }
946  
947 Promise.prototype.isFulfilled = function () {
948 return this.inspect().state === "fulfilled";
949 };
950  
951 /**
952 * @returns whether the given object is a rejected promise.
953 */
954 Q.isRejected = isRejected;
955 function isRejected(object) {
956 return isPromise(object) && object.inspect().state === "rejected";
957 }
958  
959 Promise.prototype.isRejected = function () {
960 return this.inspect().state === "rejected";
961 };
962  
963 //// BEGIN UNHANDLED REJECTION TRACKING
964  
965 // This promise library consumes exceptions thrown in handlers so they can be
966 // handled by a subsequent promise. The exceptions get added to this array when
967 // they are created, and removed when they are handled. Note that in ES6 or
968 // shimmed environments, this would naturally be a `Set`.
969 var unhandledReasons = [];
970 var unhandledRejections = [];
971 var trackUnhandledRejections = true;
972  
973 function resetUnhandledRejections() {
974 unhandledReasons.length = 0;
975 unhandledRejections.length = 0;
976  
977 if (!trackUnhandledRejections) {
978 trackUnhandledRejections = true;
979 }
980 }
981  
982 function trackRejection(promise, reason) {
983 if (!trackUnhandledRejections) {
984 return;
985 }
986  
987 unhandledRejections.push(promise);
988 if (reason && typeof reason.stack !== "undefined") {
989 unhandledReasons.push(reason.stack);
990 } else {
991 unhandledReasons.push("(no stack) " + reason);
992 }
993 }
994  
995 function untrackRejection(promise) {
996 if (!trackUnhandledRejections) {
997 return;
998 }
999  
1000 var at = array_indexOf(unhandledRejections, promise);
1001 if (at !== -1) {
1002 unhandledRejections.splice(at, 1);
1003 unhandledReasons.splice(at, 1);
1004 }
1005 }
1006  
1007 Q.resetUnhandledRejections = resetUnhandledRejections;
1008  
1009 Q.getUnhandledReasons = function () {
1010 // Make a copy so that consumers can't interfere with our internal state.
1011 return unhandledReasons.slice();
1012 };
1013  
1014 Q.stopUnhandledRejectionTracking = function () {
1015 resetUnhandledRejections();
1016 trackUnhandledRejections = false;
1017 };
1018  
1019 resetUnhandledRejections();
1020  
1021 //// END UNHANDLED REJECTION TRACKING
1022  
1023 /**
1024 * Constructs a rejected promise.
1025 * @param reason value describing the failure
1026 */
1027 Q.reject = reject;
1028 function reject(reason) {
1029 var rejection = Promise({
1030 "when": function (rejected) {
1031 // note that the error has been handled
1032 if (rejected) {
1033 untrackRejection(this);
1034 }
1035 return rejected ? rejected(reason) : this;
1036 }
1037 }, function fallback() {
1038 return this;
1039 }, function inspect() {
1040 return { state: "rejected", reason: reason };
1041 });
1042  
1043 // Note that the reason has not been handled.
1044 trackRejection(rejection, reason);
1045  
1046 return rejection;
1047 }
1048  
1049 /**
1050 * Constructs a fulfilled promise for an immediate reference.
1051 * @param value immediate reference
1052 */
1053 Q.fulfill = fulfill;
1054 function fulfill(value) {
1055 return Promise({
1056 "when": function () {
1057 return value;
1058 },
1059 "get": function (name) {
1060 return value[name];
1061 },
1062 "set": function (name, rhs) {
1063 value[name] = rhs;
1064 },
1065 "delete": function (name) {
1066 delete value[name];
1067 },
1068 "post": function (name, args) {
1069 // Mark Miller proposes that post with no name should apply a
1070 // promised function.
1071 if (name === null || name === void 0) {
1072 return value.apply(void 0, args);
1073 } else {
1074 return value[name].apply(value, args);
1075 }
1076 },
1077 "apply": function (thisp, args) {
1078 return value.apply(thisp, args);
1079 },
1080 "keys": function () {
1081 return object_keys(value);
1082 }
1083 }, void 0, function inspect() {
1084 return { state: "fulfilled", value: value };
1085 });
1086 }
1087  
1088 /**
1089 * Converts thenables to Q promises.
1090 * @param promise thenable promise
1091 * @returns a Q promise
1092 */
1093 function coerce(promise) {
1094 var deferred = defer();
1095 nextTick(function () {
1096 try {
1097 promise.then(deferred.resolve, deferred.reject, deferred.notify);
1098 } catch (exception) {
1099 deferred.reject(exception);
1100 }
1101 });
1102 return deferred.promise;
1103 }
1104  
1105 /**
1106 * Annotates an object such that it will never be
1107 * transferred away from this process over any promise
1108 * communication channel.
1109 * @param object
1110 * @returns promise a wrapping of that object that
1111 * additionally responds to the "isDef" message
1112 * without a rejection.
1113 */
1114 Q.master = master;
1115 function master(object) {
1116 return Promise({
1117 "isDef": function () {}
1118 }, function fallback(op, args) {
1119 return dispatch(object, op, args);
1120 }, function () {
1121 return Q(object).inspect();
1122 });
1123 }
1124  
1125 /**
1126 * Spreads the values of a promised array of arguments into the
1127 * fulfillment callback.
1128 * @param fulfilled callback that receives variadic arguments from the
1129 * promised array
1130 * @param rejected callback that receives the exception if the promise
1131 * is rejected.
1132 * @returns a promise for the return value or thrown exception of
1133 * either callback.
1134 */
1135 Q.spread = spread;
1136 function spread(value, fulfilled, rejected) {
1137 return Q(value).spread(fulfilled, rejected);
1138 }
1139  
1140 Promise.prototype.spread = function (fulfilled, rejected) {
1141 return this.all().then(function (array) {
1142 return fulfilled.apply(void 0, array);
1143 }, rejected);
1144 };
1145  
1146 /**
1147 * The async function is a decorator for generator functions, turning
1148 * them into asynchronous generators. Although generators are only part
1149 * of the newest ECMAScript 6 drafts, this code does not cause syntax
1150 * errors in older engines. This code should continue to work and will
1151 * in fact improve over time as the language improves.
1152 *
1153 * ES6 generators are currently part of V8 version 3.19 with the
1154 * --harmony-generators runtime flag enabled. SpiderMonkey has had them
1155 * for longer, but under an older Python-inspired form. This function
1156 * works on both kinds of generators.
1157 *
1158 * Decorates a generator function such that:
1159 * - it may yield promises
1160 * - execution will continue when that promise is fulfilled
1161 * - the value of the yield expression will be the fulfilled value
1162 * - it returns a promise for the return value (when the generator
1163 * stops iterating)
1164 * - the decorated function returns a promise for the return value
1165 * of the generator or the first rejected promise among those
1166 * yielded.
1167 * - if an error is thrown in the generator, it propagates through
1168 * every following yield until it is caught, or until it escapes
1169 * the generator function altogether, and is translated into a
1170 * rejection for the promise returned by the decorated generator.
1171 */
1172 Q.async = async;
1173 function async(makeGenerator) {
1174 return function () {
1175 // when verb is "send", arg is a value
1176 // when verb is "throw", arg is an exception
1177 function continuer(verb, arg) {
1178 var result;
1179  
1180 // Until V8 3.19 / Chromium 29 is released, SpiderMonkey is the only
1181 // engine that has a deployed base of browsers that support generators.
1182 // However, SM's generators use the Python-inspired semantics of
1183 // outdated ES6 drafts. We would like to support ES6, but we'd also
1184 // like to make it possible to use generators in deployed browsers, so
1185 // we also support Python-style generators. At some point we can remove
1186 // this block.
1187  
1188 if (typeof StopIteration === "undefined") {
1189 // ES6 Generators
1190 try {
1191 result = generator[verb](arg);
1192 } catch (exception) {
1193 return reject(exception);
1194 }
1195 if (result.done) {
1196 return Q(result.value);
1197 } else {
1198 return when(result.value, callback, errback);
1199 }
1200 } else {
1201 // SpiderMonkey Generators
1202 // FIXME: Remove this case when SM does ES6 generators.
1203 try {
1204 result = generator[verb](arg);
1205 } catch (exception) {
1206 if (isStopIteration(exception)) {
1207 return Q(exception.value);
1208 } else {
1209 return reject(exception);
1210 }
1211 }
1212 return when(result, callback, errback);
1213 }
1214 }
1215 var generator = makeGenerator.apply(this, arguments);
1216 var callback = continuer.bind(continuer, "next");
1217 var errback = continuer.bind(continuer, "throw");
1218 return callback();
1219 };
1220 }
1221  
1222 /**
1223 * The spawn function is a small wrapper around async that immediately
1224 * calls the generator and also ends the promise chain, so that any
1225 * unhandled errors are thrown instead of forwarded to the error
1226 * handler. This is useful because it's extremely common to run
1227 * generators at the top-level to work with libraries.
1228 */
1229 Q.spawn = spawn;
1230 function spawn(makeGenerator) {
1231 Q.done(Q.async(makeGenerator)());
1232 }
1233  
1234 // FIXME: Remove this interface once ES6 generators are in SpiderMonkey.
1235 /**
1236 * Throws a ReturnValue exception to stop an asynchronous generator.
1237 *
1238 * This interface is a stop-gap measure to support generator return
1239 * values in older Firefox/SpiderMonkey. In browsers that support ES6
1240 * generators like Chromium 29, just use "return" in your generator
1241 * functions.
1242 *
1243 * @param value the return value for the surrounding generator
1244 * @throws ReturnValue exception with the value.
1245 * @example
1246 * // ES6 style
1247 * Q.async(function* () {
1248 * var foo = yield getFooPromise();
1249 * var bar = yield getBarPromise();
1250 * return foo + bar;
1251 * })
1252 * // Older SpiderMonkey style
1253 * Q.async(function () {
1254 * var foo = yield getFooPromise();
1255 * var bar = yield getBarPromise();
1256 * Q.return(foo + bar);
1257 * })
1258 */
1259 Q["return"] = _return;
1260 function _return(value) {
1261 throw new QReturnValue(value);
1262 }
1263  
1264 /**
1265 * The promised function decorator ensures that any promise arguments
1266 * are settled and passed as values (`this` is also settled and passed
1267 * as a value). It will also ensure that the result of a function is
1268 * always a promise.
1269 *
1270 * @example
1271 * var add = Q.promised(function (a, b) {
1272 * return a + b;
1273 * });
1274 * add(Q(a), Q(B));
1275 *
1276 * @param {function} callback The function to decorate
1277 * @returns {function} a function that has been decorated.
1278 */
1279 Q.promised = promised;
1280 function promised(callback) {
1281 return function () {
1282 return spread([this, all(arguments)], function (self, args) {
1283 return callback.apply(self, args);
1284 });
1285 };
1286 }
1287  
1288 /**
1289 * sends a message to a value in a future turn
1290 * @param object* the recipient
1291 * @param op the name of the message operation, e.g., "when",
1292 * @param args further arguments to be forwarded to the operation
1293 * @returns result {Promise} a promise for the result of the operation
1294 */
1295 Q.dispatch = dispatch;
1296 function dispatch(object, op, args) {
1297 return Q(object).dispatch(op, args);
1298 }
1299  
1300 Promise.prototype.dispatch = function (op, args) {
1301 var self = this;
1302 var deferred = defer();
1303 nextTick(function () {
1304 self.promiseDispatch(deferred.resolve, op, args);
1305 });
1306 return deferred.promise;
1307 };
1308  
1309 /**
1310 * Gets the value of a property in a future turn.
1311 * @param object promise or immediate reference for target object
1312 * @param name name of property to get
1313 * @return promise for the property value
1314 */
1315 Q.get = function (object, key) {
1316 return Q(object).dispatch("get", [key]);
1317 };
1318  
1319 Promise.prototype.get = function (key) {
1320 return this.dispatch("get", [key]);
1321 };
1322  
1323 /**
1324 * Sets the value of a property in a future turn.
1325 * @param object promise or immediate reference for object object
1326 * @param name name of property to set
1327 * @param value new value of property
1328 * @return promise for the return value
1329 */
1330 Q.set = function (object, key, value) {
1331 return Q(object).dispatch("set", [key, value]);
1332 };
1333  
1334 Promise.prototype.set = function (key, value) {
1335 return this.dispatch("set", [key, value]);
1336 };
1337  
1338 /**
1339 * Deletes a property in a future turn.
1340 * @param object promise or immediate reference for target object
1341 * @param name name of property to delete
1342 * @return promise for the return value
1343 */
1344 Q.del = // XXX legacy
1345 Q["delete"] = function (object, key) {
1346 return Q(object).dispatch("delete", [key]);
1347 };
1348  
1349 Promise.prototype.del = // XXX legacy
1350 Promise.prototype["delete"] = function (key) {
1351 return this.dispatch("delete", [key]);
1352 };
1353  
1354 /**
1355 * Invokes a method in a future turn.
1356 * @param object promise or immediate reference for target object
1357 * @param name name of method to invoke
1358 * @param value a value to post, typically an array of
1359 * invocation arguments for promises that
1360 * are ultimately backed with `resolve` values,
1361 * as opposed to those backed with URLs
1362 * wherein the posted value can be any
1363 * JSON serializable object.
1364 * @return promise for the return value
1365 */
1366 // bound locally because it is used by other methods
1367 Q.mapply = // XXX As proposed by "Redsandro"
1368 Q.post = function (object, name, args) {
1369 return Q(object).dispatch("post", [name, args]);
1370 };
1371  
1372 Promise.prototype.mapply = // XXX As proposed by "Redsandro"
1373 Promise.prototype.post = function (name, args) {
1374 return this.dispatch("post", [name, args]);
1375 };
1376  
1377 /**
1378 * Invokes a method in a future turn.
1379 * @param object promise or immediate reference for target object
1380 * @param name name of method to invoke
1381 * @param ...args array of invocation arguments
1382 * @return promise for the return value
1383 */
1384 Q.send = // XXX Mark Miller's proposed parlance
1385 Q.mcall = // XXX As proposed by "Redsandro"
1386 Q.invoke = function (object, name /*...args*/) {
1387 return Q(object).dispatch("post", [name, array_slice(arguments, 2)]);
1388 };
1389  
1390 Promise.prototype.send = // XXX Mark Miller's proposed parlance
1391 Promise.prototype.mcall = // XXX As proposed by "Redsandro"
1392 Promise.prototype.invoke = function (name /*...args*/) {
1393 return this.dispatch("post", [name, array_slice(arguments, 1)]);
1394 };
1395  
1396 /**
1397 * Applies the promised function in a future turn.
1398 * @param object promise or immediate reference for target function
1399 * @param args array of application arguments
1400 */
1401 Q.fapply = function (object, args) {
1402 return Q(object).dispatch("apply", [void 0, args]);
1403 };
1404  
1405 Promise.prototype.fapply = function (args) {
1406 return this.dispatch("apply", [void 0, args]);
1407 };
1408  
1409 /**
1410 * Calls the promised function in a future turn.
1411 * @param object promise or immediate reference for target function
1412 * @param ...args array of application arguments
1413 */
1414 Q["try"] =
1415 Q.fcall = function (object /* ...args*/) {
1416 return Q(object).dispatch("apply", [void 0, array_slice(arguments, 1)]);
1417 };
1418  
1419 Promise.prototype.fcall = function (/*...args*/) {
1420 return this.dispatch("apply", [void 0, array_slice(arguments)]);
1421 };
1422  
1423 /**
1424 * Binds the promised function, transforming return values into a fulfilled
1425 * promise and thrown errors into a rejected one.
1426 * @param object promise or immediate reference for target function
1427 * @param ...args array of application arguments
1428 */
1429 Q.fbind = function (object /*...args*/) {
1430 var promise = Q(object);
1431 var args = array_slice(arguments, 1);
1432 return function fbound() {
1433 return promise.dispatch("apply", [
1434 this,
1435 args.concat(array_slice(arguments))
1436 ]);
1437 };
1438 };
1439 Promise.prototype.fbind = function (/*...args*/) {
1440 var promise = this;
1441 var args = array_slice(arguments);
1442 return function fbound() {
1443 return promise.dispatch("apply", [
1444 this,
1445 args.concat(array_slice(arguments))
1446 ]);
1447 };
1448 };
1449  
1450 /**
1451 * Requests the names of the owned properties of a promised
1452 * object in a future turn.
1453 * @param object promise or immediate reference for target object
1454 * @return promise for the keys of the eventually settled object
1455 */
1456 Q.keys = function (object) {
1457 return Q(object).dispatch("keys", []);
1458 };
1459  
1460 Promise.prototype.keys = function () {
1461 return this.dispatch("keys", []);
1462 };
1463  
1464 /**
1465 * Turns an array of promises into a promise for an array. If any of
1466 * the promises gets rejected, the whole array is rejected immediately.
1467 * @param {Array*} an array (or promise for an array) of values (or
1468 * promises for values)
1469 * @returns a promise for an array of the corresponding values
1470 */
1471 // By Mark Miller
1472 // http://wiki.ecmascript.org/doku.php?id=strawman:concurrency&rev=1308776521#allfulfilled
1473 Q.all = all;
1474 function all(promises) {
1475 return when(promises, function (promises) {
1476 var countDown = 0;
1477 var deferred = defer();
1478 array_reduce(promises, function (undefined, promise, index) {
1479 var snapshot;
1480 if (
1481 isPromise(promise) &&
1482 (snapshot = promise.inspect()).state === "fulfilled"
1483 ) {
1484 promises[index] = snapshot.value;
1485 } else {
1486 ++countDown;
1487 when(
1488 promise,
1489 function (value) {
1490 promises[index] = value;
1491 if (--countDown === 0) {
1492 deferred.resolve(promises);
1493 }
1494 },
1495 deferred.reject,
1496 function (progress) {
1497 deferred.notify({ index: index, value: progress });
1498 }
1499 );
1500 }
1501 }, void 0);
1502 if (countDown === 0) {
1503 deferred.resolve(promises);
1504 }
1505 return deferred.promise;
1506 });
1507 }
1508  
1509 Promise.prototype.all = function () {
1510 return all(this);
1511 };
1512  
1513 /**
1514 * Waits for all promises to be settled, either fulfilled or
1515 * rejected. This is distinct from `all` since that would stop
1516 * waiting at the first rejection. The promise returned by
1517 * `allResolved` will never be rejected.
1518 * @param promises a promise for an array (or an array) of promises
1519 * (or values)
1520 * @return a promise for an array of promises
1521 */
1522 Q.allResolved = deprecate(allResolved, "allResolved", "allSettled");
1523 function allResolved(promises) {
1524 return when(promises, function (promises) {
1525 promises = array_map(promises, Q);
1526 return when(all(array_map(promises, function (promise) {
1527 return when(promise, noop, noop);
1528 })), function () {
1529 return promises;
1530 });
1531 });
1532 }
1533  
1534 Promise.prototype.allResolved = function () {
1535 return allResolved(this);
1536 };
1537  
1538 /**
1539 * @see Promise#allSettled
1540 */
1541 Q.allSettled = allSettled;
1542 function allSettled(promises) {
1543 return Q(promises).allSettled();
1544 }
1545  
1546 /**
1547 * Turns an array of promises into a promise for an array of their states (as
1548 * returned by `inspect`) when they have all settled.
1549 * @param {Array[Any*]} values an array (or promise for an array) of values (or
1550 * promises for values)
1551 * @returns {Array[State]} an array of states for the respective values.
1552 */
1553 Promise.prototype.allSettled = function () {
1554 return this.then(function (promises) {
1555 return all(array_map(promises, function (promise) {
1556 promise = Q(promise);
1557 function regardless() {
1558 return promise.inspect();
1559 }
1560 return promise.then(regardless, regardless);
1561 }));
1562 });
1563 };
1564  
1565 /**
1566 * Captures the failure of a promise, giving an oportunity to recover
1567 * with a callback. If the given promise is fulfilled, the returned
1568 * promise is fulfilled.
1569 * @param {Any*} promise for something
1570 * @param {Function} callback to fulfill the returned promise if the
1571 * given promise is rejected
1572 * @returns a promise for the return value of the callback
1573 */
1574 Q.fail = // XXX legacy
1575 Q["catch"] = function (object, rejected) {
1576 return Q(object).then(void 0, rejected);
1577 };
1578  
1579 Promise.prototype.fail = // XXX legacy
1580 Promise.prototype["catch"] = function (rejected) {
1581 return this.then(void 0, rejected);
1582 };
1583  
1584 /**
1585 * Attaches a listener that can respond to progress notifications from a
1586 * promise's originating deferred. This listener receives the exact arguments
1587 * passed to ``deferred.notify``.
1588 * @param {Any*} promise for something
1589 * @param {Function} callback to receive any progress notifications
1590 * @returns the given promise, unchanged
1591 */
1592 Q.progress = progress;
1593 function progress(object, progressed) {
1594 return Q(object).then(void 0, void 0, progressed);
1595 }
1596  
1597 Promise.prototype.progress = function (progressed) {
1598 return this.then(void 0, void 0, progressed);
1599 };
1600  
1601 /**
1602 * Provides an opportunity to observe the settling of a promise,
1603 * regardless of whether the promise is fulfilled or rejected. Forwards
1604 * the resolution to the returned promise when the callback is done.
1605 * The callback can return a promise to defer completion.
1606 * @param {Any*} promise
1607 * @param {Function} callback to observe the resolution of the given
1608 * promise, takes no arguments.
1609 * @returns a promise for the resolution of the given promise when
1610 * ``fin`` is done.
1611 */
1612 Q.fin = // XXX legacy
1613 Q["finally"] = function (object, callback) {
1614 return Q(object)["finally"](callback);
1615 };
1616  
1617 Promise.prototype.fin = // XXX legacy
1618 Promise.prototype["finally"] = function (callback) {
1619 callback = Q(callback);
1620 return this.then(function (value) {
1621 return callback.fcall().then(function () {
1622 return value;
1623 });
1624 }, function (reason) {
1625 // TODO attempt to recycle the rejection with "this".
1626 return callback.fcall().then(function () {
1627 throw reason;
1628 });
1629 });
1630 };
1631  
1632 /**
1633 * Terminates a chain of promises, forcing rejections to be
1634 * thrown as exceptions.
1635 * @param {Any*} promise at the end of a chain of promises
1636 * @returns nothing
1637 */
1638 Q.done = function (object, fulfilled, rejected, progress) {
1639 return Q(object).done(fulfilled, rejected, progress);
1640 };
1641  
1642 Promise.prototype.done = function (fulfilled, rejected, progress) {
1643 var onUnhandledError = function (error) {
1644 // forward to a future turn so that ``when``
1645 // does not catch it and turn it into a rejection.
1646 nextTick(function () {
1647 makeStackTraceLong(error, promise);
1648 if (Q.onerror) {
1649 Q.onerror(error);
1650 } else {
1651 throw error;
1652 }
1653 });
1654 };
1655  
1656 // Avoid unnecessary `nextTick`ing via an unnecessary `when`.
1657 var promise = fulfilled || rejected || progress ?
1658 this.then(fulfilled, rejected, progress) :
1659 this;
1660  
1661 if (typeof process === "object" && process && process.domain) {
1662 onUnhandledError = process.domain.bind(onUnhandledError);
1663 }
1664  
1665 promise.then(void 0, onUnhandledError);
1666 };
1667  
1668 /**
1669 * Causes a promise to be rejected if it does not get fulfilled before
1670 * some milliseconds time out.
1671 * @param {Any*} promise
1672 * @param {Number} milliseconds timeout
1673 * @param {Any*} custom error message or Error object (optional)
1674 * @returns a promise for the resolution of the given promise if it is
1675 * fulfilled before the timeout, otherwise rejected.
1676 */
1677 Q.timeout = function (object, ms, error) {
1678 return Q(object).timeout(ms, error);
1679 };
1680  
1681 Promise.prototype.timeout = function (ms, error) {
1682 var deferred = defer();
1683 var timeoutId = setTimeout(function () {
1684 if (!error || "string" === typeof error) {
1685 error = new Error(error || "Timed out after " + ms + " ms");
1686 error.code = "ETIMEDOUT";
1687 }
1688 deferred.reject(error);
1689 }, ms);
1690  
1691 this.then(function (value) {
1692 clearTimeout(timeoutId);
1693 deferred.resolve(value);
1694 }, function (exception) {
1695 clearTimeout(timeoutId);
1696 deferred.reject(exception);
1697 }, deferred.notify);
1698  
1699 return deferred.promise;
1700 };
1701  
1702 /**
1703 * Returns a promise for the given value (or promised value), some
1704 * milliseconds after it resolved. Passes rejections immediately.
1705 * @param {Any*} promise
1706 * @param {Number} milliseconds
1707 * @returns a promise for the resolution of the given promise after milliseconds
1708 * time has elapsed since the resolution of the given promise.
1709 * If the given promise rejects, that is passed immediately.
1710 */
1711 Q.delay = function (object, timeout) {
1712 if (timeout === void 0) {
1713 timeout = object;
1714 object = void 0;
1715 }
1716 return Q(object).delay(timeout);
1717 };
1718  
1719 Promise.prototype.delay = function (timeout) {
1720 return this.then(function (value) {
1721 var deferred = defer();
1722 setTimeout(function () {
1723 deferred.resolve(value);
1724 }, timeout);
1725 return deferred.promise;
1726 });
1727 };
1728  
1729 /**
1730 * Passes a continuation to a Node function, which is called with the given
1731 * arguments provided as an array, and returns a promise.
1732 *
1733 * Q.nfapply(FS.readFile, [__filename])
1734 * .then(function (content) {
1735 * })
1736 *
1737 */
1738 Q.nfapply = function (callback, args) {
1739 return Q(callback).nfapply(args);
1740 };
1741  
1742 Promise.prototype.nfapply = function (args) {
1743 var deferred = defer();
1744 var nodeArgs = array_slice(args);
1745 nodeArgs.push(deferred.makeNodeResolver());
1746 this.fapply(nodeArgs).fail(deferred.reject);
1747 return deferred.promise;
1748 };
1749  
1750 /**
1751 * Passes a continuation to a Node function, which is called with the given
1752 * arguments provided individually, and returns a promise.
1753 * @example
1754 * Q.nfcall(FS.readFile, __filename)
1755 * .then(function (content) {
1756 * })
1757 *
1758 */
1759 Q.nfcall = function (callback /*...args*/) {
1760 var args = array_slice(arguments, 1);
1761 return Q(callback).nfapply(args);
1762 };
1763  
1764 Promise.prototype.nfcall = function (/*...args*/) {
1765 var nodeArgs = array_slice(arguments);
1766 var deferred = defer();
1767 nodeArgs.push(deferred.makeNodeResolver());
1768 this.fapply(nodeArgs).fail(deferred.reject);
1769 return deferred.promise;
1770 };
1771  
1772 /**
1773 * Wraps a NodeJS continuation passing function and returns an equivalent
1774 * version that returns a promise.
1775 * @example
1776 * Q.nfbind(FS.readFile, __filename)("utf-8")
1777 * .then(console.log)
1778 * .done()
1779 */
1780 Q.nfbind =
1781 Q.denodeify = function (callback /*...args*/) {
1782 var baseArgs = array_slice(arguments, 1);
1783 return function () {
1784 var nodeArgs = baseArgs.concat(array_slice(arguments));
1785 var deferred = defer();
1786 nodeArgs.push(deferred.makeNodeResolver());
1787 Q(callback).fapply(nodeArgs).fail(deferred.reject);
1788 return deferred.promise;
1789 };
1790 };
1791  
1792 Promise.prototype.nfbind =
1793 Promise.prototype.denodeify = function (/*...args*/) {
1794 var args = array_slice(arguments);
1795 args.unshift(this);
1796 return Q.denodeify.apply(void 0, args);
1797 };
1798  
1799 Q.nbind = function (callback, thisp /*...args*/) {
1800 var baseArgs = array_slice(arguments, 2);
1801 return function () {
1802 var nodeArgs = baseArgs.concat(array_slice(arguments));
1803 var deferred = defer();
1804 nodeArgs.push(deferred.makeNodeResolver());
1805 function bound() {
1806 return callback.apply(thisp, arguments);
1807 }
1808 Q(bound).fapply(nodeArgs).fail(deferred.reject);
1809 return deferred.promise;
1810 };
1811 };
1812  
1813 Promise.prototype.nbind = function (/*thisp, ...args*/) {
1814 var args = array_slice(arguments, 0);
1815 args.unshift(this);
1816 return Q.nbind.apply(void 0, args);
1817 };
1818  
1819 /**
1820 * Calls a method of a Node-style object that accepts a Node-style
1821 * callback with a given array of arguments, plus a provided callback.
1822 * @param object an object that has the named method
1823 * @param {String} name name of the method of object
1824 * @param {Array} args arguments to pass to the method; the callback
1825 * will be provided by Q and appended to these arguments.
1826 * @returns a promise for the value or error
1827 */
1828 Q.nmapply = // XXX As proposed by "Redsandro"
1829 Q.npost = function (object, name, args) {
1830 return Q(object).npost(name, args);
1831 };
1832  
1833 Promise.prototype.nmapply = // XXX As proposed by "Redsandro"
1834 Promise.prototype.npost = function (name, args) {
1835 var nodeArgs = array_slice(args || []);
1836 var deferred = defer();
1837 nodeArgs.push(deferred.makeNodeResolver());
1838 this.dispatch("post", [name, nodeArgs]).fail(deferred.reject);
1839 return deferred.promise;
1840 };
1841  
1842 /**
1843 * Calls a method of a Node-style object that accepts a Node-style
1844 * callback, forwarding the given variadic arguments, plus a provided
1845 * callback argument.
1846 * @param object an object that has the named method
1847 * @param {String} name name of the method of object
1848 * @param ...args arguments to pass to the method; the callback will
1849 * be provided by Q and appended to these arguments.
1850 * @returns a promise for the value or error
1851 */
1852 Q.nsend = // XXX Based on Mark Miller's proposed "send"
1853 Q.nmcall = // XXX Based on "Redsandro's" proposal
1854 Q.ninvoke = function (object, name /*...args*/) {
1855 var nodeArgs = array_slice(arguments, 2);
1856 var deferred = defer();
1857 nodeArgs.push(deferred.makeNodeResolver());
1858 Q(object).dispatch("post", [name, nodeArgs]).fail(deferred.reject);
1859 return deferred.promise;
1860 };
1861  
1862 Promise.prototype.nsend = // XXX Based on Mark Miller's proposed "send"
1863 Promise.prototype.nmcall = // XXX Based on "Redsandro's" proposal
1864 Promise.prototype.ninvoke = function (name /*...args*/) {
1865 var nodeArgs = array_slice(arguments, 1);
1866 var deferred = defer();
1867 nodeArgs.push(deferred.makeNodeResolver());
1868 this.dispatch("post", [name, nodeArgs]).fail(deferred.reject);
1869 return deferred.promise;
1870 };
1871  
1872 /**
1873 * If a function would like to support both Node continuation-passing-style and
1874 * promise-returning-style, it can end its internal promise chain with
1875 * `nodeify(nodeback)`, forwarding the optional nodeback argument. If the user
1876 * elects to use a nodeback, the result will be sent there. If they do not
1877 * pass a nodeback, they will receive the result promise.
1878 * @param object a result (or a promise for a result)
1879 * @param {Function} nodeback a Node.js-style callback
1880 * @returns either the promise or nothing
1881 */
1882 Q.nodeify = nodeify;
1883 function nodeify(object, nodeback) {
1884 return Q(object).nodeify(nodeback);
1885 }
1886  
1887 Promise.prototype.nodeify = function (nodeback) {
1888 if (nodeback) {
1889 this.then(function (value) {
1890 nextTick(function () {
1891 nodeback(null, value);
1892 });
1893 }, function (error) {
1894 nextTick(function () {
1895 nodeback(error);
1896 });
1897 });
1898 } else {
1899 return this;
1900 }
1901 };
1902  
1903 // All code before this point will be filtered from stack traces.
1904 var qEndingLine = captureLine();
1905  
1906 return Q;
1907  
1908 });