[
  {
    "path": ".coverignore",
    "content": "spec/\n"
  },
  {
    "path": ".gitignore",
    "content": "node_modules\nnpm-debug.log\nCHANGES.html\nREADME.html\n.tmp\nq.min.js\n\ncoverage/\n\n# IntelliJ IDEA project files\n.idea\n*.iml\n"
  },
  {
    "path": ".jshintrc",
    "content": "{\n    \"browser\": true,\n    \"node\": true,\n\n    \"curly\": true,\n    \"eqeqeq\": true,\n    \"es3\": true,\n    \"newcap\": false,\n    \"noarg\": true,\n    \"nonew\": true,\n    \"quotmark\": \"double\",\n    \"strict\": true,\n    \"trailing\": true,\n    \"undef\": true,\n    \"unused\": true,\n\n    \"globals\": {\n        \"self\": false,\n        \"bootstrap\": false,\n        \"cajaVM\": false,\n        \"define\": false,\n        \"ReturnValue\": false,\n        \"ses\": false,\n        \"setImmediate\": false,\n        \"Q\": true\n    }\n}\n"
  },
  {
    "path": ".mailmap",
    "content": "Domenic Denicola <domenic@domenicdenicola.com>\nKris Kowal <kris.kowal@cixar.com>\n"
  },
  {
    "path": ".travis.yml",
    "content": "language: node_js\nnode_js:\n  - \"0.10\"\nscript:\n  npm test\n"
  },
  {
    "path": "CHANGES.md",
    "content": "\n## 1.5.1\n\n - Q.any now annotates its error message to clarify that Q.any was involved and\n   includes only the last error emitted. (Ivan Etchart)\n - Avoid domain.dispose during tests in preparation for Node.js 9. (Anna\n   Henningsen)\n\n## 1.5.0\n\n - Q.any gives an error message from the last rejected promise\n - Throw if callback supplied to \"finally\" is invalid (@grahamrhay)\n - Long stack trace improvements, can now construct long stack traces\n   across rethrows.\n\n## 1.4.1\n\n - Address an issue that prevented Q from being used as a `<script>` for\n   Firefox add-ons. Q can now be used in any environment that provides `window`\n   or `self` globals, favoring `window` since add-ons have an an immutable\n   `self` that is distinct from `window`.\n\n## 1.4.0\n\n - Add `noConflict` support for use in `<script>` (@jahnjw).\n\n## 1.3.0\n\n - Add tracking for unhandled and handled rejections in Node.js (@benjamingr).\n\n## 1.2.1\n\n - Fix Node.js environment detection for modern Browserify (@kahnjw).\n\n## 1.2.0\n\n - Added Q.any(promisesArray) method (@vergara).\n   Returns a promise fulfilled with the value of the first resolved promise in\n   promisesArray. If all promises in promisesArray are rejected, it returns\n   a rejected promise.\n\n## 1.1.2\n\n - Removed extraneous files from the npm package by using the \"files\"\n   whitelist in package.json instead of the .npmignore blacklist.\n   (@anton-rudeshko)\n\n## 1.1.1\n\n - Fix a pair of regressions in bootstrapping, one which precluded\n   WebWorker support, and another that precluded support in\n   ``<script>`` usage outright. #607\n\n## 1.1.0\n\n - Adds support for enabling long stack traces in node.js by setting\n   environment variable `Q_DEBUG=1`.\n - Introduces the `tap` method to promises, which will see a value\n   pass through without alteration.\n - Use instanceof to recognize own promise instances as opposed to\n   thenables.\n - Construct timeout errors with `code === ETIMEDOUT` (Kornel Lesiński)\n - More descriminant CommonJS module environment detection.\n - Dropped continuous integration for Node.js 0.6 and 0.8 because of\n   changes to npm that preclude the use of new `^` version predicate\n   operator in any transitive dependency.\n - Users can now override `Q.nextTick`.\n\n## 1.0.1\n\n - Adds support for `Q.Promise`, which implements common usage of the\n   ES6 `Promise` constructor and its methods. `Promise` does not have\n   a valid promise constructor and a proper implementation awaits\n   version 2 of Q.\n - Removes the console stopgap for a promise inspector. This no longer\n   works with any degree of reliability.\n - Fixes support for content security policies that forbid eval. Now\n   using the `StopIteration` global to distinguish SpiderMonkey\n   generators from ES6 generators, assuming that they will never\n   coexist.\n\n## 1.0.0\n\n:cake: This is all but a re-release of version 0.9, which has settled\ninto a gentle maintenance mode and rightly deserves an official 1.0.\nAn ambitious 2.0 release is already around the corner, but 0.9/1.0\nhave been distributed far and wide and demand long term support.\n\n - Q will now attempt to post a debug message in browsers regardless\n   of whether window.Touch is defined. Chrome at least now has this\n   property regardless of whether touch is supported by the underlying\n   hardware.\n - Remove deprecation warning from `promise.valueOf`. The function is\n   called by the browser in various ways so there is no way to\n   distinguish usage that should be migrated from usage that cannot be\n   altered.\n\n## 0.9.7\n\n - :warning: `q.min.js` is no longer checked-in.  It is however still\n   created by Grunt and NPM.\n - Fixes a bug that inhibited `Q.async` with implementations of the new\n   ES6 generators.\n - Fixes a bug with `nextTick` affecting Safari 6.0.5 the first time a\n   page loads when an `iframe` is involved.\n - Introduces `passByCopy`, `join`, and `race`.\n - Shows stack traces or error messages on the console, instead of\n   `Error` objects.\n - Elimintates wrapper methods for improved performance.\n - `Q.all` now propagates progress notifications of the form you might\n   expect of ES6 iterations, `{value, index}` where the `value` is the\n   progress notification from the promise at `index`.\n\n## 0.9.6\n\n - Fixes a bug in recognizing the difference between compatible Q\n   promises, and Q promises from before the implementation of \"inspect\".\n   The latter are now coerced.\n - Fixes an infinite asynchronous coercion cycle introduced by former\n   solution, in two independently sufficient ways.  1.) All promises\n   returned by makePromise now implement \"inspect\", albeit a default\n   that reports that the promise has an \"unknown\" state.  2.) The\n   implementation of \"then/when\" is now in \"then\" instead of \"when\", so\n   that the responsibility to \"coerce\" the given promise rests solely in\n   the \"when\" method and the \"then\" method may assume that \"this\" is a\n   promise of the right type.\n - Refactors `nextTick` to use an unrolled microtask within Q regardless\n   of how new ticks a requested. #316 @rkatic\n\n## 0.9.5\n\n - Introduces `inspect` for getting the state of a promise as\n   `{state: \"fulfilled\" | \"rejected\" | \"pending\", value | reason}`.\n - Introduces `allSettled` which produces an array of promises states\n   for the input promises once they have all \"settled\".  This is in\n   accordance with a discussion on Promises/A+ that \"settled\" refers to\n   a promise that is \"fulfilled\" or \"rejected\".  \"resolved\" refers to a\n   deferred promise that has been \"resolved\" to another promise,\n   \"sealing its fate\" to the fate of the successor promise.\n - Long stack traces are now off by default.  Set `Q.longStackSupport`\n   to true to enable long stack traces.\n - Long stack traces can now follow the entire asynchronous history of a\n   promise, not just a single jump.\n - Introduces `spawn` for an immediately invoked asychronous generator.\n   @jlongster\n - Support for *experimental* synonyms `mapply`, `mcall`, `nmapply`,\n   `nmcall` for method invocation.\n\n## 0.9.4\n\n - `isPromise` and `isPromiseAlike` now always returns a boolean\n   (even for falsy values). #284 @lfac-pt\n - Support for ES6 Generators in `async` #288 @andywingo\n - Clear duplicate promise rejections from dispatch methods #238 @SLaks\n - Unhandled rejection API #296 @domenic\n   `stopUnhandledRejectionTracking`, `getUnhandledReasons`,\n   `resetUnhandledRejections`.\n\n## 0.9.3\n\n - Add the ability to give `Q.timeout`'s errors a custom error message. #270\n   @jgrenon\n - Fix Q's call-stack busting behavior in Node.js 0.10, by switching from\n   `process.nextTick` to `setImmediate`. #254 #259\n - Fix Q's behavior when used with the Mocha test runner in the browser, since\n   Mocha introduces a fake `process` global without a `nextTick` property. #267\n - Fix some, but not all, cases wherein Q would give false positives in its\n   unhandled rejection detection (#252). A fix for other cases (#238) is\n   hopefully coming soon.\n - Made `Q.promise` throw early if given a non-function.\n\n## 0.9.2\n\n - Pass through progress notifications when using `timeout`. #229 @omares\n - Pass through progress notifications when using `delay`.\n - Fix `nbind` to actually bind the `thisArg`. #232 @davidpadbury\n\n## 0.9.1\n\n - Made the AMD detection compatible with the RequireJS optimizer's `namespace`\n   option. #225 @terinjokes\n - Fix side effects from `valueOf`, and thus from `isFulfilled`, `isRejected`,\n   and `isPending`. #226 @benjamn\n\n## 0.9.0\n\nThis release removes many layers of deprecated methods and brings Q closer to\nalignment with Mark Miller’s TC39 [strawman][] for concurrency. At the same\ntime, it fixes many bugs and adds a few features around error handling. Finally,\nit comes with an updated and comprehensive [API Reference][].\n\n[strawman]: http://wiki.ecmascript.org/doku.php?id=strawman:concurrency\n[API Reference]: https://github.com/kriskowal/q/wiki/API-Reference\n\n### API Cleanup\n\nThe following deprecated or undocumented methods have been removed.\nTheir replacements are listed here:\n\n<table>\n   <thead>\n      <tr>\n         <th>0.8.x method</th>\n         <th>0.9 replacement</th>\n      </tr>\n   </thead>\n   <tbody>\n      <tr>\n         <td><code>Q.ref</code></td>\n         <td><code>Q</code></td>\n      </tr>\n      <tr>\n         <td><code>call</code>, <code>apply</code>, <code>bind</code> (*)</td>\n         <td><code>fcall</code>/<code>invoke</code>, <code>fapply</code>/<code>post</code>, <code>fbind</code></td>\n      </tr>\n      <tr>\n         <td><code>ncall</code>, <code>napply</code> (*)</td>\n         <td><code>nfcall</code>/<code>ninvoke</code>, <code>nfapply</code>/<code>npost</code></td>\n      </tr>\n      <tr>\n         <td><code>end</code></td>\n         <td><code>done</code></td>\n      </tr>\n      <tr>\n         <td><code>put</code></td>\n         <td><code>set</code></td>\n      </tr>\n      <tr>\n         <td><code>node</code></td>\n         <td><code>nbind</code></td>\n      </tr>\n      <tr>\n         <td><code>nend</code></td>\n         <td><code>nodeify</code></td>\n      </tr>\n      <tr>\n         <td><code>isResolved</code></td>\n         <td><code>isPending</code></td>\n      </tr>\n      <tr>\n         <td><code>deferred.node</code></td>\n         <td><code>deferred.makeNodeResolver</code></td>\n      </tr>\n      <tr>\n         <td><code>Method</code>, <code>sender</code></td>\n         <td><code>dispatcher</code></td>\n      </tr>\n      <tr>\n         <td><code>send</code></td>\n         <td><code>dispatch</code></td>\n      </tr>\n      <tr>\n         <td><code>view</code>, <code>viewInfo</code></td>\n         <td>(none)</td>\n      </tr>\n   </tbody>\n</table>\n\n\n(*) Use of ``thisp`` is discouraged. For calling methods, use ``post`` or\n``invoke``.\n\n### Alignment with the Concurrency Strawman\n\n-   Q now exports a `Q(value)` function, an alias for `resolve`.\n    `Q.call`, `Q.apply`, and `Q.bind` were removed to make room for the\n    same methods on the function prototype.\n-   `invoke` has been aliased to `send` in all its forms.\n-   `post` with no method name acts like `fapply`.\n\n### Error Handling\n\n-   Long stack traces can be turned off by setting `Q.stackJumpLimit` to zero.\n    In the future, this property will be used to fine tune how many stack jumps\n    are retained in long stack traces; for now, anything nonzero is treated as\n    one (since Q only tracks one stack jump at the moment, see #144). #168\n-   In Node.js, if there are unhandled rejections when the process exits, they\n    are output to the console. #115\n\n### Other\n\n-   `delete` and `set` (née `put`) no longer have a fulfillment value.\n-   Q promises are no longer frozen, which\n    [helps with performance](http://code.google.com/p/v8/issues/detail?id=1858).\n-   `thenReject` is now included, as a counterpart to `thenResolve`.\n-   The included browser `nextTick` shim is now faster. #195 @rkatic.\n\n### Bug Fixes\n\n-   Q now works in Internet Explorer 10. #186 @ForbesLindesay\n-   `fbind` no longer hard-binds the returned function's `this` to `undefined`.\n    #202\n-   `Q.reject` no longer leaks memory. #148\n-   `npost` with no arguments now works. #207\n-   `allResolved` now works with non-Q promises (\"thenables\"). #179\n-   `keys` behavior is now correct even in browsers without native\n    `Object.keys`. #192 @rkatic\n-   `isRejected` and the `exception` property now work correctly if the\n    rejection reason is falsy. #198\n\n### Internals and Advanced\n\n-   The internal interface for a promise now uses\n    `dispatchPromise(resolve, op, operands)` instead of `sendPromise(op,\n    resolve, ...operands)`, which reduces the cases where Q needs to do\n    argument slicing.\n-   The internal protocol uses different operands. \"put\" is now \"set\".\n    \"del\" is now \"delete\". \"view\" and \"viewInfo\" have been removed.\n-   `Q.fulfill` has been added. It is distinct from `Q.resolve` in that\n    it does not pass promises through, nor coerces promises from other\n    systems. The promise becomes the fulfillment value. This is only\n    recommended for use when trying to fulfill a promise with an object that has\n    a `then` function that is at the same time not a promise.\n\n## 0.8.12\n- Treat foreign promises as unresolved in `Q.isFulfilled`; this lets `Q.all`\n  work on arrays containing foreign promises. #154\n- Fix minor incompliances with the [Promises/A+ spec][] and [test suite][]. #157\n  #158\n\n[Promises/A+ spec]: http://promises-aplus.github.com/promises-spec/\n[test suite]: https://github.com/promises-aplus/promises-tests\n\n## 0.8.11\n\n - Added ``nfcall``, ``nfapply``, and ``nfbind`` as ``thisp``-less versions of\n   ``ncall``, ``napply``, and ``nbind``. The latter are now deprecated. #142\n - Long stack traces no longer cause linearly-growing memory usage when chaining\n   promises together. #111\n - Inspecting ``error.stack`` in a rejection handler will now give a long stack\n   trace. #103\n - Fixed ``Q.timeout`` to clear its timeout handle when the promise is rejected;\n   previously, it kept the event loop alive until the timeout period expired.\n   #145 @dfilatov\n - Added `q/queue` module, which exports an infinite promise queue\n   constructor.\n\n## 0.8.10\n\n - Added ``done`` as a replacement for ``end``, taking the usual fulfillment,\n   rejection, and progress handlers. It's essentially equivalent to\n   ``then(f, r, p).end()``.\n - Added ``Q.onerror``, a settable error trap that you can use to get full stack\n   traces for uncaught errors. #94\n - Added ``thenResolve`` as a shortcut for returning a constant value once a\n   promise is fulfilled. #108 @ForbesLindesay\n - Various tweaks to progress notification, including propagation and\n   transformation of progress values and only forwarding a single progress\n   object.\n - Renamed ``nend`` to ``nodeify``. It no longer returns an always-fulfilled\n   promise when a Node callback is passed.\n - ``deferred.resolve`` and ``deferred.reject`` no longer (sometimes) return\n   ``deferred.promise``.\n - Fixed stack traces getting mangled if they hit ``end`` twice. #116 #121 @ef4\n - Fixed ``ninvoke`` and ``npost`` to work on promises for objects with Node\n   methods. #134\n - Fixed accidental coercion of objects with nontrivial ``valueOf`` methods,\n   like ``Date``s, by the promise's ``valueOf`` method. #135\n - Fixed ``spread`` not calling the passed rejection handler if given a rejected\n   promise.\n\n## 0.8.9\n\n - Added ``nend``\n - Added preliminary progress notification support, via\n   ``promise.then(onFulfilled, onRejected, onProgress)``,\n   ``promise.progress(onProgress)``, and ``deferred.notify(...progressData)``.\n - Made ``put`` and ``del`` return the object acted upon for easier chaining.\n   #84\n - Fixed coercion cycles with cooperating promises. #106\n\n## 0.8.7\n\n - Support [Montage Require](http://github.com/kriskowal/mr)\n\n## 0.8.6\n\n - Fixed ``npost`` and ``ninvoke`` to pass the correct ``thisp``. #74\n - Fixed various cases involving unorthodox rejection reasons. #73 #90\n   @ef4\n - Fixed double-resolving of misbehaved custom promises. #75\n - Sped up ``Q.all`` for arrays contain already-resolved promises or scalar\n   values. @ForbesLindesay\n - Made stack trace filtering work when concatenating assets. #93 @ef4\n - Added warnings for deprecated methods. @ForbesLindesay\n - Added ``.npmignore`` file so that dependent packages get a slimmer\n   ``node_modules`` directory.\n\n## 0.8.5\n\n - Added preliminary support for long traces (@domenic)\n - Added ``fapply``, ``fcall``, ``fbind`` for non-thisp\n   promised function calls.\n - Added ``return`` for async generators, where generators\n   are implemented.\n - Rejected promises now have an \"exception\" property.  If an object\n   isRejected(object), then object.valueOf().exception will\n   be the wrapped error.\n - Added Jasmine specifications\n - Support Internet Explorers 7–9 (with multiple bug fixes @domenic)\n - Support Firefox 12\n - Support Safari 5.1.5\n - Support Chrome 18\n\n## 0.8.4\n\n - WARNING: ``promise.timeout`` is now rejected with an ``Error`` object\n   and the message now includes the duration of the timeout in\n   miliseconds.  This doesn't constitute (in my opinion) a\n   backward-incompatibility since it is a change of an undocumented and\n   unspecified public behavior, but if you happened to depend on the\n   exception being a string, you will need to revise your code.\n - Added ``deferred.makeNodeResolver()`` to replace the more cryptic\n   ``deferred.node()`` method.\n - Added experimental ``Q.promise(maker(resolve, reject))`` to make a\n   promise inside a callback, such that thrown exceptions in the\n   callback are converted and the resolver and rejecter are arguments.\n   This is a shorthand for making a deferred directly and inspired by\n   @gozala’s stream constructor pattern and the Microsoft Windows Metro\n   Promise constructor interface.\n - Added experimental ``Q.begin()`` that is intended to kick off chains\n   of ``.then`` so that each of these can be reordered without having to\n   edit the new and former first step.\n\n## 0.8.3\n\n - Added ``isFulfilled``, ``isRejected``, and ``isResolved``\n   to the promise prototype.\n - Added ``allResolved`` for waiting for every promise to either be\n   fulfilled or rejected, without propagating an error. @utvara #53\n - Added ``Q.bind`` as a method to transform functions that\n   return and throw into promise-returning functions. See\n   [an example](https://gist.github.com/1782808). @domenic\n - Renamed ``node`` export to ``nbind``, and added ``napply`` to\n   complete the set. ``node`` remains as deprecated. @domenic #58\n - Renamed ``Method`` export to ``sender``.  ``Method``\n   remains as deprecated and will be removed in the next\n   major version since I expect it has very little usage.\n - Added browser console message indicating a live list of\n   unhandled errors.\n - Added support for ``msSetImmediate`` (IE10) or ``setImmediate``\n   (available via [polyfill](https://github.com/NobleJS/setImmediate))\n   as a browser-side ``nextTick`` implementation. #44 #50 #59\n - Stopped using the event-queue dependency, which was in place for\n   Narwhal support: now directly using ``process.nextTick``.\n - WARNING: EXPERIMENTAL: added ``finally`` alias for ``fin``, ``catch``\n   alias for ``fail``, ``try`` alias for ``call``, and ``delete`` alias\n   for ``del``.  These properties are enquoted in the library for\n   cross-browser compatibility, but may be used as property names in\n   modern engines.\n\n## 0.8.2\n\n - Deprecated ``ref`` in favor of ``resolve`` as recommended by\n   @domenic.\n - Update event-queue dependency.\n\n## 0.8.1\n\n - Fixed Opera bug. #35 @cadorn\n - Fixed ``Q.all([])`` #32 @domenic\n\n## 0.8.0\n\n - WARNING: ``enqueue`` removed.  Use ``nextTick`` instead.\n   This is more consistent with NodeJS and (subjectively)\n   more explicit and intuitive.\n - WARNING: ``def`` removed.  Use ``master`` instead.  The\n   term ``def`` was too confusing to new users.\n - WARNING: ``spy`` removed in favor of ``fin``.\n - WARNING: ``wait`` removed. Do ``all(args).get(0)`` instead.\n - WARNING: ``join`` removed. Do ``all(args).spread(callback)`` instead.\n - WARNING: Removed the ``Q`` function module.exports alias\n   for ``Q.ref``. It conflicts with ``Q.apply`` in weird\n   ways, making it uncallable.\n - Revised ``delay`` so that it accepts both ``(value,\n   timeout)`` and ``(timeout)`` variations based on\n   arguments length.\n - Added ``ref().spread(cb(...args))``, a variant of\n   ``then`` that spreads an array across multiple arguments.\n   Useful with ``all()``.\n - Added ``defer().node()`` Node callback generator.  The\n   callback accepts ``(error, value)`` or ``(error,\n   ...values)``.  For multiple value arguments, the\n   fulfillment value is an array, useful in conjunction with\n   ``spread``.\n - Added ``node`` and ``ncall``, both with the signature\n   ``(fun, thisp_opt, ...args)``.  The former is a decorator\n   and the latter calls immediately.  ``node`` optional\n   binds and partially applies.  ``ncall`` can bind and pass\n   arguments.\n\n## 0.7.2\n\n - Fixed thenable promise assimilation.\n\n## 0.7.1\n\n - Stopped shimming ``Array.prototype.reduce``. The\n   enumerable property has bad side-effects.  Libraries that\n   depend on this (for example, QQ) will need to be revised.\n\n## 0.7.0 - BACKWARD INCOMPATIBILITY\n\n - WARNING: Removed ``report`` and ``asap``\n - WARNING: The ``callback`` argument of the ``fin``\n   function no longer receives any arguments. Thus, it can\n   be used to call functions that should not receive\n   arguments on resolution.  Use ``when``, ``then``, or\n   ``fail`` if you need a value.\n - IMPORTANT: Fixed a bug in the use of ``MessageChannel``\n   for ``nextTick``.\n - Renamed ``enqueue`` to ``nextTick``.\n - Added experimental ``view`` and ``viewInfo`` for creating\n   views of promises either when or before they're\n   fulfilled.\n - Shims are now externally applied so subsequent scripts or\n   dependees can use them.\n - Improved minification results.\n - Improved readability.\n\n## 0.6.0 - BACKWARD INCOMPATIBILITY\n\n - WARNING: In practice, the implementation of ``spy`` and\n   the name ``fin`` were useful.  I've removed the old\n   ``fin`` implementation and renamed/aliased ``spy``.\n - The \"q\" module now exports its ``ref`` function as a \"Q\"\n   constructor, with module systems that support exports\n   assignment including NodeJS, RequireJS, and when used as\n   a ``<script>`` tag. Notably, strictly compliant CommonJS\n   does not support this, but UncommonJS does.\n - Added ``async`` decorator for generators that use yield\n   to \"trampoline\" promises. In engines that support\n   generators (SpiderMonkey), this will greatly reduce the\n   need for nested callbacks.\n - Made ``when`` chainable.\n - Made ``all`` chainable.\n\n## 0.5.3\n\n - Added ``all`` and refactored ``join`` and ``wait`` to use\n   it.  All of these will now reject at the earliest\n   rejection.\n\n## 0.5.2\n\n - Minor improvement to ``spy``; now waits for resolution of\n   callback promise.\n\n## 0.5.1\n\n - Made most Q API methods chainable on promise objects, and\n   turned the previous promise-methods of ``join``,\n   ``wait``, and ``report`` into Q API methods.\n - Added ``apply`` and ``call`` to the Q API, and ``apply``\n   as a promise handler.\n - Added ``fail``, ``fin``, and ``spy`` to Q and the promise\n   prototype for convenience when observing rejection,\n   fulfillment and rejection, or just observing without\n   affecting the resolution.\n - Renamed ``def`` (although ``def`` remains shimmed until\n   the next major release) to ``master``.\n - Switched to using ``MessageChannel`` for next tick task\n   enqueue in browsers that support it.\n\n## 0.5.0 - MINOR BACKWARD INCOMPATIBILITY\n\n - Exceptions are no longer reported when consumed.\n - Removed ``error`` from the API.  Since exceptions are\n   getting consumed, throwing them in an errback causes the\n   exception to silently disappear.  Use ``end``.\n - Added ``end`` as both an API method and a promise-chain\n   ending method.  It causes propagated rejections to be\n   thrown, which allows Node to write stack traces and\n   emit ``uncaughtException`` events, and browsers to\n   likewise emit ``onerror`` and log to the console.\n - Added ``join`` and ``wait`` as promise chain functions,\n   so you can wait for variadic promises, returning your own\n   promise back, or join variadic promises, resolving with a\n   callback that receives variadic fulfillment values.\n\n## 0.4.4\n\n - ``end`` no longer returns a promise. It is the end of the\n   promise chain.\n - Stopped reporting thrown exceptions in ``when`` callbacks\n   and errbacks.  These must be explicitly reported through\n   ``.end()``, ``.then(null, Q.error)``, or some other\n   mechanism.\n - Added ``report`` as an API method, which can be used as\n   an errback to report and propagate an error.\n - Added ``report`` as a promise-chain method, so an error\n   can be reported if it passes such a gate.\n\n## 0.4.3\n\n - Fixed ``<script>`` support that regressed with 0.4.2\n   because of \"use strict\" in the module system\n   multi-plexer.\n\n## 0.4.2\n\n - Added support for RequireJS (jburke)\n\n## 0.4.1\n\n - Added an \"end\" method to the promise prototype,\n   as a shorthand for waiting for the promise to\n   be resolved gracefully, and failing to do so,\n   to dump an error message.\n\n## 0.4.0 - BACKWARD INCOMPATIBLE*\n\n - *Removed the utility modules. NPM and Node no longer\n   expose any module except the main module.  These have\n   been moved and merged into the \"qq\" package.\n - *In a non-CommonJS browser, q.js can be used as a script.\n   It now creates a Q global variable.\n - Fixed thenable assimilation.\n - Fixed some issues with asap, when it resolves to\n   undefined, or throws an exception.\n\n## 0.3.0 - BACKWARD-INCOMPATIBLE\n\n - The `post` method has been reverted to its original\n   signature, as provided in Tyler Close's `ref_send` API.\n   That is, `post` accepts two arguments, the second of\n   which is an arbitrary object, but usually invocation\n   arguments as an `Array`.  To provide variadic arguments\n   to `post`, there is a new `invoke` function that posts\n   the variadic arguments to the value given in the first\n   argument.\n - The `defined` method has been moved from `q` to `q/util`\n   since it gets no use in practice but is still\n   theoretically useful.\n - The `Promise` constructor has been renamed to\n   `makePromise` to be consistent with the convention that\n   functions that do not require the `new` keyword to be\n   used as constructors have camelCase names.\n - The `isResolved` function has been renamed to\n   `isFulfilled`.  There is a new `isResolved` function that\n   indicates whether a value is not a promise or, if it is a\n   promise, whether it has been either fulfilled or\n   rejected.  The code has been revised to reflect this\n   nuance in terminology.\n\n## 0.2.10\n\n - Added `join` to `\"q/util\"` for variadically joining\n   multiple promises.\n\n## 0.2.9\n\n - The future-compatible `invoke` method has been added,\n   to replace `post`, since `post` will become backward-\n   incompatible in the next major release.\n - Exceptions thrown in the callbacks of a `when` call are\n   now emitted to Node's `\"uncaughtException\"` `process`\n   event in addition to being returned as a rejection reason.\n\n## 0.2.8\n\n - Exceptions thrown in the callbacks of a `when` call\n   are now consumed, warned, and transformed into\n   rejections of the promise returned by `when`.\n\n## 0.2.7\n\n - Fixed a minor bug in thenable assimilation, regressed\n   because of the change in the forwarding protocol.\n - Fixed behavior of \"q/util\" `deep` method on dates and\n   other primitives. Github issue #11.\n\n## 0.2.6\n\n - Thenables (objects with a \"then\" method) are accepted\n   and provided, bringing this implementation of Q\n   into conformance with Promises/A, B, and D.\n - Added `makePromise`, to replace the `Promise` function\n   eventually.\n - Rejections are now also duck-typed. A rejection is a\n   promise with a valueOf method that returns a rejection\n   descriptor. A rejection descriptor has a\n   \"promiseRejected\" property equal to \"true\" and a\n   \"reason\" property corresponding to the rejection reason.\n - Altered the `makePromise` API such that the `fallback`\n   method no longer receives a superfluous `resolved` method\n   after the `operator`.  The fallback method is responsible\n   only for returning a resolution.  This breaks an\n   undocumented API, so third-party API's depending on the\n   previous undocumented behavior may break.\n\n## 0.2.5\n\n - Changed promises into a duck-type such that multiple\n   instances of the Q module can exchange promise objects.\n   A promise is now defined as \"an object that implements the\n   `promiseSend(op, resolved, ...)` method and `valueOf`\".\n - Exceptions in promises are now captured and returned\n   as rejections.\n\n## 0.2.4\n\n - Fixed bug in `ref` that prevented `del` messages from\n   being received (gozala)\n - Fixed a conflict with FireFox 4; constructor property\n   is now read-only.\n\n## 0.2.3\n\n - Added `keys` message to promises and to the promise API.\n\n## 0.2.2\n\n - Added boilerplate to `q/queue` and `q/util`.\n - Fixed missing dependency to `q/queue`.\n\n## 0.2.1\n\n - The `resolve` and `reject` methods of `defer` objects now\n   return the resolution promise for convenience.\n - Added `q/util`, which provides `step`, `delay`, `shallow`,\n   `deep`, and three reduction orders.\n - Added `q/queue` module for a promise `Queue`.\n - Added `q-comm` to the list of compatible libraries.\n - Deprecated `defined` from `q`, with intent to move it to\n   `q/util`.\n\n## 0.2.0 - BACKWARD INCOMPATIBLE\n\n - Changed post(ref, name, args) to variadic\n   post(ref, name, ...args). BACKWARD INCOMPATIBLE\n - Added a def(value) method to annotate an object as being\n   necessarily a local value that cannot be serialized, such\n   that inter-process/worker/vat promise communication\n   libraries will send messages to it, but never send it\n   back.\n - Added a send(value, op, ...args) method to the public API, for\n   forwarding messages to a value or promise in a future turn.\n\n## 0.1.9\n\n - Added isRejected() for testing whether a value is a rejected\n   promise.  isResolved() retains the behavior of stating\n   that rejected promises are not resolved.\n\n## 0.1.8\n\n - Fixed isResolved(null) and isResolved(undefined) [issue #9]\n - Fixed a problem with the Object.create shim\n\n## 0.1.7\n\n - shimmed ES5 Object.create in addition to Object.freeze\n   for compatibility on non-ES5 engines (gozala)\n\n## 0.1.6\n\n - Q.isResolved added\n - promise.valueOf() now returns the value of resolved\n   and near values\n - asap retried\n - promises are frozen when possible\n\n## 0.1.5\n\n - fixed dependency list for Teleport (gozala)\n - all unit tests now pass (gozala)\n\n## 0.1.4\n\n - added support for Teleport as an engine (gozala)\n - simplified and updated methods for getting internal\n   print and enqueue functions universally (gozala)\n\n## 0.1.3\n\n - fixed erroneous link to the q module in package.json\n\n## 0.1.2\n\n - restructured for overlay style package compatibility\n\n## 0.1.0\n\n - removed asap because it was broken, probably down to the\n   philosophy.\n\n## 0.0.3\n\n - removed q-util\n - fixed asap so it returns a value if completed\n\n## 0.0.2\n\n - added q-util\n\n## 0.0.1\n\n - initial version\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "\nFor pull requests:\n\n-   Be consistent with prevalent style and design decisions.\n-   Add a Jasmine spec to `specs/q-spec.js`.\n-   Use `npm test` to avoid regressions.\n-   Run tests in `q-spec/run.html` in as many supported browsers as you\n    can find the will to deal with.\n-   Do not build minified versions; we do this each release.\n-   If you would be so kind, add a note to `CHANGES.md` in an\n    appropriate section:\n\n    -   `Next Major Version` if it introduces backward incompatibilities\n        to code in the wild using documented features.\n    -   `Next Minor Version` if it adds a new feature.\n    -   `Next Patch Version` if it fixes a bug.\n\nFor releases:\n\n-   Run `npm test`.\n-   Run tests in `q-spec/run.html` in a representative sample of every\n    browser under the sun.\n-   Run `npm run cover` and make sure you're happy with the results.\n-   Run `npm run minify` and be sure to commit the resulting `q.min.js`.\n-   Note the Gzipped size output by the previous command, and update\n    `README.md` if it has changed to 1 significant digit.\n-   Stash any local changes.\n-   Update `CHANGES.md` to reflect all changes in the differences\n    between `HEAD` and the previous tagged version.  Give credit where\n    credit is due.\n-   Update `README.md` to address all new, non-experimental features.\n-   Update the API reference on the Wiki to reflect all non-experimental\n    features.\n-   Use `npm version major|minor|patch` to update `package.json`,\n    commit, and tag the new version.\n-   Use `npm publish` to send up a new release.\n-   Send an email to the q-continuum mailing list announcing the new\n    release and the notes from the change log.  This helps folks\n    maintaining other package ecosystems.\n\n"
  },
  {
    "path": "Gruntfile.js",
    "content": "\"use strict\";\n\nmodule.exports = function (grunt) {\n    grunt.loadNpmTasks(\"grunt-contrib-uglify\");\n\n    grunt.initConfig({\n        uglify: {\n            \"q.min.js\": [\"q.js\"],\n            options: {\n                report: \"gzip\"\n            }\n        }\n    });\n\n    grunt.registerTask(\"default\", [\"uglify\"]);\n};\n"
  },
  {
    "path": "LICENSE",
    "content": "Copyright 2009–2018 Kristopher Michael Kowal. All rights reserved.\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to\ndeal in the Software without restriction, including without limitation the\nrights to use, copy, modify, merge, publish, distribute, sublicense, and/or\nsell copies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\nIN THE SOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "\n## Note\n\nPlease consider using [JavaScript promises](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) instead of Q. Native promises are faster, have better tooling support and are the future.\n\nWhen work on Q began, promises were an academic novelty in JavaScript, unlikely to be adopted much less popular, though obviously full of…promise. Callbacks dominated the landscape. Q aimed to introduce a technology to JavaScript that had been proven and vetted in languages like E and C♯. With four years of incubation, evangelism, education, and feedback, promises became part of the language. Every modern browser contains a built-in `Promise` implementation. Being able to influence the internet and working on a library used by millions of codebases was an exciting and humbling experience.\n\nQ isn't going anywhere. The code is still here and bugs will be fixed but further development has been unnecessary for many years. We encourage you to read the code and the explainers to glimpse into the history of the internet.\n\n# Q\n\n[![Build Status](https://secure.travis-ci.org/kriskowal/q.svg?branch=master)](http://travis-ci.org/kriskowal/q)\n[![CDNJS](https://img.shields.io/cdnjs/v/q.js.svg)](https://cdnjs.com/libraries/q.js)\n\n<a href=\"http://promises-aplus.github.com/promises-spec\">\n    <img src=\"http://kriskowal.github.io/q/q.png\" align=\"right\" alt=\"Q logo\" />\n</a>\n\nIf a function cannot return a value or throw an exception without\nblocking, it can return a promise instead.  A promise is an object\nthat represents the return value or the thrown exception that the\nfunction may eventually provide.  A promise can also be used as a\nproxy for a [remote object][Q-Connection] to overcome latency.\n\n[Q-Connection]: https://github.com/kriskowal/q-connection\n\nOn the first pass, promises can mitigate the “[Pyramid of\nDoom][POD]”: the situation where code marches to the right faster\nthan it marches forward.\n\n[POD]: http://calculist.org/blog/2011/12/14/why-coroutines-wont-work-on-the-web/\n\n```javascript\nstep1(function (value1) {\n    step2(value1, function(value2) {\n        step3(value2, function(value3) {\n            step4(value3, function(value4) {\n                // Do something with value4\n            });\n        });\n    });\n});\n```\n\nWith a promise library, you can flatten the pyramid.\n\n```javascript\nQ.fcall(promisedStep1)\n.then(promisedStep2)\n.then(promisedStep3)\n.then(promisedStep4)\n.then(function (value4) {\n    // Do something with value4\n})\n.catch(function (error) {\n    // Handle any error from all above steps\n})\n.done();\n```\n\nWith this approach, you also get implicit error propagation, just like `try`,\n`catch`, and `finally`.  An error in `promisedStep1` will flow all the way to\nthe `catch` function, where it’s caught and handled.  (Here `promisedStepN` is\na version of `stepN` that returns a promise.)\n\nThe callback approach is called an “inversion of control”.\nA function that accepts a callback instead of a return value\nis saying, “Don’t call me, I’ll call you.”.  Promises\n[un-invert][IOC] the inversion, cleanly separating the input\narguments from control flow arguments.  This simplifies the\nuse and creation of API’s, particularly variadic,\nrest and spread arguments.\n\n[IOC]: http://www.slideshare.net/domenicdenicola/callbacks-promises-and-coroutines-oh-my-the-evolution-of-asynchronicity-in-javascript\n\n\n## Getting Started\n\nThe Q module can be loaded as:\n\n-   A ``<script>`` tag (creating a ``Q`` global variable): ~2.5 KB minified and\n    gzipped.\n-   A Node.js and CommonJS module, available in [npm](https://npmjs.org/) as\n    the [q](https://npmjs.org/package/q) package\n-   An AMD module\n-   A [component](https://github.com/component/component) as ``microjs/q``\n-   Using [bower](http://bower.io/) as `q#^1.4.1`\n-   Using [NuGet](http://nuget.org/) as [Q](https://nuget.org/packages/q)\n\nQ can exchange promises with jQuery, Dojo, When.js, WinJS, and more.\n\n## Resources\n\nOur [wiki][] contains a number of useful resources, including:\n\n- A method-by-method [Q API reference][reference].\n- A growing [examples gallery][examples], showing how Q can be used to make\n  everything better. From XHR to database access to accessing the Flickr API,\n  Q is there for you.\n- There are many libraries that produce and consume Q promises for everything\n  from file system/database access or RPC to templating. For a list of some of\n  the more popular ones, see [Libraries][].\n- If you want materials that introduce the promise concept generally, and the\n  below tutorial isn't doing it for you, check out our collection of\n  [presentations, blog posts, and podcasts][resources].\n- A guide for those [coming from jQuery's `$.Deferred`][jquery].\n\nWe'd also love to have you join the Q-Continuum [mailing list][].\n\n[wiki]: https://github.com/kriskowal/q/wiki\n[reference]: https://github.com/kriskowal/q/wiki/API-Reference\n[examples]: https://github.com/kriskowal/q/wiki/Examples-Gallery\n[Libraries]: https://github.com/kriskowal/q/wiki/Libraries\n[resources]: https://github.com/kriskowal/q/wiki/General-Promise-Resources\n[jquery]: https://github.com/kriskowal/q/wiki/Coming-from-jQuery\n[mailing list]: https://groups.google.com/forum/#!forum/q-continuum\n\n\n## Tutorial\n\nPromises have a ``then`` method, which you can use to get the eventual\nreturn value (fulfillment) or thrown exception (rejection).\n\n```javascript\npromiseMeSomething()\n.then(function (value) {\n}, function (reason) {\n});\n```\n\nIf ``promiseMeSomething`` returns a promise that gets fulfilled later\nwith a return value, the first function (the fulfillment handler) will be\ncalled with the value.  However, if the ``promiseMeSomething`` function\ngets rejected later by a thrown exception, the second function (the\nrejection handler) will be called with the exception.\n\nNote that resolution of a promise is always asynchronous: that is, the\nfulfillment or rejection handler will always be called in the next turn of the\nevent loop (i.e. `process.nextTick` in Node). This gives you a nice\nguarantee when mentally tracing the flow of your code, namely that\n``then`` will always return before either handler is executed.\n\nIn this tutorial, we begin with how to consume and work with promises. We'll\ntalk about how to create them, and thus create functions like\n`promiseMeSomething` that return promises, [below](#the-beginning).\n\n\n### Propagation\n\nThe ``then`` method returns a promise, which in this example, I’m\nassigning to ``outputPromise``.\n\n```javascript\nvar outputPromise = getInputPromise()\n.then(function (input) {\n}, function (reason) {\n});\n```\n\nThe ``outputPromise`` variable becomes a new promise for the return\nvalue of either handler.  Since a function can only either return a\nvalue or throw an exception, only one handler will ever be called and it\nwill be responsible for resolving ``outputPromise``.\n\n-   If you return a value in a handler, ``outputPromise`` will get\n    fulfilled.\n\n-   If you throw an exception in a handler, ``outputPromise`` will get\n    rejected.\n\n-   If you return a **promise** in a handler, ``outputPromise`` will\n    “become” that promise.  Being able to become a new promise is useful\n    for managing delays, combining results, or recovering from errors.\n\nIf the ``getInputPromise()`` promise gets rejected and you omit the\nrejection handler, the **error** will go to ``outputPromise``:\n\n```javascript\nvar outputPromise = getInputPromise()\n.then(function (value) {\n});\n```\n\nIf the input promise gets fulfilled and you omit the fulfillment handler, the\n**value** will go to ``outputPromise``:\n\n```javascript\nvar outputPromise = getInputPromise()\n.then(null, function (error) {\n});\n```\n\nQ promises provide a ``fail`` shorthand for ``then`` when you are only\ninterested in handling the error:\n\n```javascript\nvar outputPromise = getInputPromise()\n.fail(function (error) {\n});\n```\n\nIf you are writing JavaScript for modern engines only or using\nCoffeeScript, you may use `catch` instead of `fail`.\n\nPromises also have a ``fin`` function that is like a ``finally`` clause.\nThe final handler gets called, with no arguments, when the promise\nreturned by ``getInputPromise()`` either returns a value or throws an\nerror.  The value returned or error thrown by ``getInputPromise()``\npasses directly to ``outputPromise`` unless the final handler fails, and\nmay be delayed if the final handler returns a promise.\n\n```javascript\nvar outputPromise = getInputPromise()\n.fin(function () {\n    // close files, database connections, stop servers, conclude tests\n});\n```\n\n-   If the handler returns a value, the value is ignored\n-   If the handler throws an error, the error passes to ``outputPromise``\n-   If the handler returns a promise, ``outputPromise`` gets postponed.  The\n    eventual value or error has the same effect as an immediate return\n    value or thrown error: a value would be ignored, an error would be\n    forwarded.\n\nIf you are writing JavaScript for modern engines only or using\nCoffeeScript, you may use `finally` instead of `fin`.\n\n### Chaining\n\nThere are two ways to chain promises.  You can chain promises either\ninside or outside handlers.  The next two examples are equivalent.\n\n```javascript\nreturn getUsername()\n.then(function (username) {\n    return getUser(username)\n    .then(function (user) {\n        // if we get here without an error,\n        // the value returned here\n        // or the exception thrown here\n        // resolves the promise returned\n        // by the first line\n    })\n});\n```\n\n```javascript\nreturn getUsername()\n.then(function (username) {\n    return getUser(username);\n})\n.then(function (user) {\n    // if we get here without an error,\n    // the value returned here\n    // or the exception thrown here\n    // resolves the promise returned\n    // by the first line\n});\n```\n\nThe only difference is nesting.  It’s useful to nest handlers if you\nneed to capture multiple input values in your closure.\n\n```javascript\nfunction authenticate() {\n    return getUsername()\n    .then(function (username) {\n        return getUser(username);\n    })\n    // chained because we will not need the user name in the next event\n    .then(function (user) {\n        return getPassword()\n        // nested because we need both user and password next\n        .then(function (password) {\n            if (user.passwordHash !== hash(password)) {\n                throw new Error(\"Can't authenticate\");\n            }\n        });\n    });\n}\n```\n\n\n### Combination\n\nYou can turn an array of promises into a promise for the whole,\nfulfilled array using ``all``.\n\n```javascript\nreturn Q.all([\n    eventualAdd(2, 2),\n    eventualAdd(10, 20)\n]);\n```\n\nIf you have a promise for an array, you can use ``spread`` as a\nreplacement for ``then``.  The ``spread`` function “spreads” the\nvalues over the arguments of the fulfillment handler.  The rejection handler\nwill get called at the first sign of failure.  That is, whichever of\nthe received promises fails first gets handled by the rejection handler.\n\n```javascript\nfunction eventualAdd(a, b) {\n    return Q.spread([a, b], function (a, b) {\n        return a + b;\n    })\n}\n```\n\nBut ``spread`` calls ``all`` initially, so you can skip it in chains.\n\n```javascript\nreturn getUsername()\n.then(function (username) {\n    return [username, getUser(username)];\n})\n.spread(function (username, user) {\n});\n```\n\nThe ``all`` function returns a promise for an array of values.  When this\npromise is fulfilled, the array contains the fulfillment values of the original\npromises, in the same order as those promises.  If one of the given promises\nis rejected, the returned promise is immediately rejected, not waiting for the\nrest of the batch.  If you want to wait for all of the promises to either be\nfulfilled or rejected, you can use ``allSettled``.\n\n```javascript\nQ.allSettled(promises)\n.then(function (results) {\n    results.forEach(function (result) {\n        if (result.state === \"fulfilled\") {\n            var value = result.value;\n        } else {\n            var reason = result.reason;\n        }\n    });\n});\n```\n\nThe ``any`` function accepts an array of promises and returns a promise that is\nfulfilled by the first given promise to be fulfilled, or rejected if all of the\ngiven promises are rejected.\n\n```javascript\nQ.any(promises)\n.then(function (first) {\n    // Any of the promises was fulfilled.\n}, function (error) {\n    // All of the promises were rejected.\n});\n```\n\n### Sequences\n\nIf you have a number of promise-producing functions that need\nto be run sequentially, you can of course do so manually:\n\n```javascript\nreturn foo(initialVal).then(bar).then(baz).then(qux);\n```\n\nHowever, if you want to run a dynamically constructed sequence of\nfunctions, you'll want something like this:\n\n```javascript\nvar funcs = [foo, bar, baz, qux];\n\nvar result = Q(initialVal);\nfuncs.forEach(function (f) {\n    result = result.then(f);\n});\nreturn result;\n```\n\nYou can make this slightly more compact using `reduce`:\n\n```javascript\nreturn funcs.reduce(function (soFar, f) {\n    return soFar.then(f);\n}, Q(initialVal));\n```\n\nOr, you could use the ultra-compact version:\n\n```javascript\nreturn funcs.reduce(Q.when, Q(initialVal));\n```\n\n### Handling Errors\n\nOne sometimes-unintuitive aspect of promises is that if you throw an\nexception in the fulfillment handler, it will not be caught by the error\nhandler.\n\n```javascript\nreturn foo()\n.then(function (value) {\n    throw new Error(\"Can't bar.\");\n}, function (error) {\n    // We only get here if \"foo\" fails\n});\n```\n\nTo see why this is, consider the parallel between promises and\n``try``/``catch``. We are ``try``-ing to execute ``foo()``: the error\nhandler represents a ``catch`` for ``foo()``, while the fulfillment handler\nrepresents code that happens *after* the ``try``/``catch`` block.\nThat code then needs its own ``try``/``catch`` block.\n\nIn terms of promises, this means chaining your rejection handler:\n\n```javascript\nreturn foo()\n.then(function (value) {\n    throw new Error(\"Can't bar.\");\n})\n.fail(function (error) {\n    // We get here with either foo's error or bar's error\n});\n```\n\n### Progress Notification\n\nIt's possible for promises to report their progress, e.g. for tasks that take a\nlong time like a file upload. Not all promises will implement progress\nnotifications, but for those that do, you can consume the progress values using\na third parameter to ``then``:\n\n```javascript\nreturn uploadFile()\n.then(function () {\n    // Success uploading the file\n}, function (err) {\n    // There was an error, and we get the reason for error\n}, function (progress) {\n    // We get notified of the upload's progress as it is executed\n});\n```\n\nLike `fail`, Q also provides a shorthand for progress callbacks\ncalled `progress`:\n\n```javascript\nreturn uploadFile().progress(function (progress) {\n    // We get notified of the upload's progress\n});\n```\n\n### The End\n\nWhen you get to the end of a chain of promises, you should either\nreturn the last promise or end the chain.  Since handlers catch\nerrors, it’s an unfortunate pattern that the exceptions can go\nunobserved.\n\nSo, either return it,\n\n```javascript\nreturn foo()\n.then(function () {\n    return \"bar\";\n});\n```\n\nOr, end it.\n\n```javascript\nfoo()\n.then(function () {\n    return \"bar\";\n})\n.done();\n```\n\nEnding a promise chain makes sure that, if an error doesn’t get\nhandled before the end, it will get rethrown and reported.\n\nThis is a stopgap. We are exploring ways to make unhandled errors\nvisible without any explicit handling.\n\n\n### The Beginning\n\nEverything above assumes you get a promise from somewhere else.  This\nis the common case.  Every once in a while, you will need to create a\npromise from scratch.\n\n#### Using ``Q.fcall``\n\nYou can create a promise from a value using ``Q.fcall``.  This returns a\npromise for 10.\n\n```javascript\nreturn Q.fcall(function () {\n    return 10;\n});\n```\n\nYou can also use ``fcall`` to get a promise for an exception.\n\n```javascript\nreturn Q.fcall(function () {\n    throw new Error(\"Can't do it\");\n});\n```\n\nAs the name implies, ``fcall`` can call functions, or even promised\nfunctions.  This uses the ``eventualAdd`` function above to add two\nnumbers.\n\n```javascript\nreturn Q.fcall(eventualAdd, 2, 2);\n```\n\n\n#### Using Deferreds\n\nIf you have to interface with asynchronous functions that are callback-based\ninstead of promise-based, Q provides a few shortcuts (like ``Q.nfcall`` and\nfriends). But much of the time, the solution will be to use *deferreds*.\n\n```javascript\nvar deferred = Q.defer();\nFS.readFile(\"foo.txt\", \"utf-8\", function (error, text) {\n    if (error) {\n        deferred.reject(new Error(error));\n    } else {\n        deferred.resolve(text);\n    }\n});\nreturn deferred.promise;\n```\n\nNote that a deferred can be resolved with a value or a promise.  The\n``reject`` function is a shorthand for resolving with a rejected\npromise.\n\n```javascript\n// this:\ndeferred.reject(new Error(\"Can't do it\"));\n\n// is shorthand for:\nvar rejection = Q.fcall(function () {\n    throw new Error(\"Can't do it\");\n});\ndeferred.resolve(rejection);\n```\n\nThis is a simplified implementation of ``Q.delay``.\n\n```javascript\nfunction delay(ms) {\n    var deferred = Q.defer();\n    setTimeout(deferred.resolve, ms);\n    return deferred.promise;\n}\n```\n\nThis is a simplified implementation of ``Q.timeout``\n\n```javascript\nfunction timeout(promise, ms) {\n    var deferred = Q.defer();\n    Q.when(promise, deferred.resolve);\n    delay(ms).then(function () {\n        deferred.reject(new Error(\"Timed out\"));\n    });\n    return deferred.promise;\n}\n```\n\nFinally, you can send a progress notification to the promise with\n``deferred.notify``.\n\nFor illustration, this is a wrapper for XML HTTP requests in the browser. Note\nthat a more [thorough][XHR] implementation would be in order in practice.\n\n[XHR]: https://github.com/montagejs/mr/blob/71e8df99bb4f0584985accd6f2801ef3015b9763/browser.js#L29-L73\n\n```javascript\nfunction requestOkText(url) {\n    var request = new XMLHttpRequest();\n    var deferred = Q.defer();\n\n    request.open(\"GET\", url, true);\n    request.onload = onload;\n    request.onerror = onerror;\n    request.onprogress = onprogress;\n    request.send();\n\n    function onload() {\n        if (request.status === 200) {\n            deferred.resolve(request.responseText);\n        } else {\n            deferred.reject(new Error(\"Status code was \" + request.status));\n        }\n    }\n\n    function onerror() {\n        deferred.reject(new Error(\"Can't XHR \" + JSON.stringify(url)));\n    }\n\n    function onprogress(event) {\n        deferred.notify(event.loaded / event.total);\n    }\n\n    return deferred.promise;\n}\n```\n\nBelow is an example of how to use this ``requestOkText`` function:\n\n```javascript\nrequestOkText(\"http://localhost:3000\")\n.then(function (responseText) {\n    // If the HTTP response returns 200 OK, log the response text.\n    console.log(responseText);\n}, function (error) {\n    // If there's an error or a non-200 status code, log the error.\n    console.error(error);\n}, function (progress) {\n    // Log the progress as it comes in.\n    console.log(\"Request progress: \" + Math.round(progress * 100) + \"%\");\n});\n```\n\n#### Using `Q.Promise`\n\nThis is an alternative promise-creation API that has the same power as\nthe deferred concept, but without introducing another conceptual entity.\n\nRewriting the `requestOkText` example above using `Q.Promise`:\n\n```javascript\nfunction requestOkText(url) {\n    return Q.Promise(function(resolve, reject, notify) {\n        var request = new XMLHttpRequest();\n\n        request.open(\"GET\", url, true);\n        request.onload = onload;\n        request.onerror = onerror;\n        request.onprogress = onprogress;\n        request.send();\n\n        function onload() {\n            if (request.status === 200) {\n                resolve(request.responseText);\n            } else {\n                reject(new Error(\"Status code was \" + request.status));\n            }\n        }\n\n        function onerror() {\n            reject(new Error(\"Can't XHR \" + JSON.stringify(url)));\n        }\n\n        function onprogress(event) {\n            notify(event.loaded / event.total);\n        }\n    });\n}\n```\n\nIf `requestOkText` were to throw an exception, the returned promise would be\nrejected with that thrown exception as the rejection reason.\n\n### The Middle\n\nIf you are using a function that may return a promise, but just might\nreturn a value if it doesn’t need to defer, you can use the “static”\nmethods of the Q library.\n\nThe ``when`` function is the static equivalent for ``then``.\n\n```javascript\nreturn Q.when(valueOrPromise, function (value) {\n}, function (error) {\n});\n```\n\nAll of the other methods on a promise have static analogs with the\nsame name.\n\nThe following are equivalent:\n\n```javascript\nreturn Q.all([a, b]);\n```\n\n```javascript\nreturn Q.fcall(function () {\n    return [a, b];\n})\n.all();\n```\n\nWhen working with promises provided by other libraries, you should\nconvert it to a Q promise.  Not all promise libraries make the same\nguarantees as Q and certainly don’t provide all of the same methods.\nMost libraries only provide a partially functional ``then`` method.\nThis thankfully is all we need to turn them into vibrant Q promises.\n\n```javascript\nreturn Q($.ajax(...))\n.then(function () {\n});\n```\n\nIf there is any chance that the promise you receive is not a Q promise\nas provided by your library, you should wrap it using a Q function.\nYou can even use ``Q.invoke`` as a shorthand.\n\n```javascript\nreturn Q.invoke($, 'ajax', ...)\n.then(function () {\n});\n```\n\n\n### Over the Wire\n\nA promise can serve as a proxy for another object, even a remote\nobject.  There are methods that allow you to optimistically manipulate\nproperties or call functions.  All of these interactions return\npromises, so they can be chained.\n\n```\ndirect manipulation         using a promise as a proxy\n--------------------------  -------------------------------\nvalue.foo                   promise.get(\"foo\")\nvalue.foo = value           promise.put(\"foo\", value)\ndelete value.foo            promise.del(\"foo\")\nvalue.foo(...args)          promise.post(\"foo\", [args])\nvalue.foo(...args)          promise.invoke(\"foo\", ...args)\nvalue(...args)              promise.fapply([args])\nvalue(...args)              promise.fcall(...args)\n```\n\nIf the promise is a proxy for a remote object, you can shave\nround-trips by using these functions instead of ``then``.  To take\nadvantage of promises for remote objects, check out [Q-Connection][].\n\n[Q-Connection]: https://github.com/kriskowal/q-connection\n\nEven in the case of non-remote objects, these methods can be used as\nshorthand for particularly-simple fulfillment handlers. For example, you\ncan replace\n\n```javascript\nreturn Q.fcall(function () {\n    return [{ foo: \"bar\" }, { foo: \"baz\" }];\n})\n.then(function (value) {\n    return value[0].foo;\n});\n```\n\nwith\n\n```javascript\nreturn Q.fcall(function () {\n    return [{ foo: \"bar\" }, { foo: \"baz\" }];\n})\n.get(0)\n.get(\"foo\");\n```\n\n\n### Adapting Node\n\nIf you're working with functions that make use of the Node.js callback pattern,\nwhere callbacks are in the form of `function(err, result)`, Q provides a few\nuseful utility functions for converting between them. The most straightforward\nare probably `Q.nfcall` and `Q.nfapply` (\"Node function call/apply\") for calling\nNode.js-style functions and getting back a promise:\n\n```javascript\nreturn Q.nfcall(FS.readFile, \"foo.txt\", \"utf-8\");\nreturn Q.nfapply(FS.readFile, [\"foo.txt\", \"utf-8\"]);\n```\n\nIf you are working with methods, instead of simple functions, you can easily\nrun in to the usual problems where passing a method to another function—like\n`Q.nfcall`—\"un-binds\" the method from its owner. To avoid this, you can either\nuse `Function.prototype.bind` or some nice shortcut methods we provide:\n\n```javascript\nreturn Q.ninvoke(redisClient, \"get\", \"user:1:id\");\nreturn Q.npost(redisClient, \"get\", [\"user:1:id\"]);\n```\n\nYou can also create reusable wrappers with `Q.denodeify` or `Q.nbind`:\n\n```javascript\nvar readFile = Q.denodeify(FS.readFile);\nreturn readFile(\"foo.txt\", \"utf-8\");\n\nvar redisClientGet = Q.nbind(redisClient.get, redisClient);\nreturn redisClientGet(\"user:1:id\");\n```\n\nFinally, if you're working with raw deferred objects, there is a\n`makeNodeResolver` method on deferreds that can be handy:\n\n```javascript\nvar deferred = Q.defer();\nFS.readFile(\"foo.txt\", \"utf-8\", deferred.makeNodeResolver());\nreturn deferred.promise;\n```\n\n### Long Stack Traces\n\nQ comes with optional support for “long stack traces,” wherein the `stack`\nproperty of `Error` rejection reasons is rewritten to be traced along\nasynchronous jumps instead of stopping at the most recent one. As an example:\n\n```js\nfunction theDepthsOfMyProgram() {\n  Q.delay(100).done(function explode() {\n    throw new Error(\"boo!\");\n  });\n}\n\ntheDepthsOfMyProgram();\n```\n\nusually would give a rather unhelpful stack trace looking something like\n\n```\nError: boo!\n    at explode (/path/to/test.js:3:11)\n    at _fulfilled (/path/to/test.js:q:54)\n    at resolvedValue.promiseDispatch.done (/path/to/q.js:823:30)\n    at makePromise.promise.promiseDispatch (/path/to/q.js:496:13)\n    at pending (/path/to/q.js:397:39)\n    at process.startup.processNextTick.process._tickCallback (node.js:244:9)\n```\n\nBut, if you turn this feature on by setting\n\n```js\nQ.longStackSupport = true;\n```\n\nthen the above code gives a nice stack trace to the tune of\n\n```\nError: boo!\n    at explode (/path/to/test.js:3:11)\nFrom previous event:\n    at theDepthsOfMyProgram (/path/to/test.js:2:16)\n    at Object.<anonymous> (/path/to/test.js:7:1)\n```\n\nNote how you can see the function that triggered the async operation in the\nstack trace! This is very helpful for debugging, as otherwise you end up getting\nonly the first line, plus a bunch of Q internals, with no sign of where the\noperation started.\n\nIn node.js, this feature can also be enabled through the Q_DEBUG environment\nvariable:\n\n```\nQ_DEBUG=1 node server.js\n```\n\nThis will enable long stack support in every instance of Q.\n\nThis feature does come with somewhat-serious performance and memory overhead,\nhowever. If you're working with lots of promises, or trying to scale a server\nto many users, you should probably keep it off. But in development, go for it!\n\n## Tests\n\nYou can view the results of the Q test suite [in your browser][tests]!\n\n[tests]: https://rawgithub.com/kriskowal/q/v1/spec/q-spec.html\n\n## License\n\nCopyright 2009–2017 Kristopher Michael Kowal and contributors\nMIT License (enclosed)\n\n"
  },
  {
    "path": "VERSIONS.md",
    "content": "<!-- vim:ts=4:sts=4:sw=4:et:tw=60 -->\n\nThis library has the following policy about versions.\n\n-   Presently, all planned versions have a major version number of 0.\n-   The minor version number increases for every backward-incompatible\n    change to a documented behavior.\n-   The patch version number increases for every added feature,\n    backward-incompatible changes to undocumented features, and\n    bug-fixes.\n\nUpon the release of a version 1.0.0, the strategy will be revised.\n\n-   The major version will increase for any backward-incompatible\n    changes.\n-   The minor version will increase for added features.\n-   The patch version will increase for bug-fixes.\n\n"
  },
  {
    "path": "benchmark/compare-with-callbacks.js",
    "content": "\"use strict\";\n\nvar Q = require(\"../q\");\nvar fs = require(\"fs\");\n\nsuite(\"A single simple async operation\", function () {\n    bench(\"with an immediately-fulfilled promise\", function (done) {\n        Q().then(done);\n    });\n\n    bench(\"with direct setImmediate usage\", function (done) {\n        setImmediate(done);\n    });\n\n    bench(\"with direct setTimeout(…, 0)\", function (done) {\n        setTimeout(done, 0);\n    });\n});\n\nsuite(\"A fs.readFile\", function () {\n    var denodeified = Q.denodeify(fs.readFile);\n\n    set(\"iterations\", 1000);\n    set(\"delay\", 1000);\n\n    bench(\"directly, with callbacks\", function (done) {\n        fs.readFile(__filename, done);\n    });\n\n    bench(\"with Q.nfcall\", function (done) {\n        Q.nfcall(fs.readFile, __filename).then(done);\n    });\n\n    bench(\"with a Q.denodeify'ed version\", function (done) {\n        denodeified(__filename).then(done);\n    });\n\n    bench(\"with manual usage of deferred.makeNodeResolver\", function (done) {\n        var deferred = Q.defer();\n        fs.readFile(__filename, deferred.makeNodeResolver());\n        deferred.promise.then(done);\n    });\n});\n\nsuite(\"1000 operations in parallel\", function () {\n    function makeCounter(desiredCount, ultimateCallback) {\n        var soFar = 0;\n        return function () {\n            if (++soFar === desiredCount) {\n                ultimateCallback();\n            }\n        };\n    }\n    var numberOfOps = 1000;\n\n    bench(\"with immediately-fulfilled promises\", function (done) {\n        var counter = makeCounter(numberOfOps, done);\n\n        for (var i = 0; i < numberOfOps; ++i) {\n            Q().then(counter);\n        }\n    });\n\n    bench(\"with direct setImmediate usage\", function (done) {\n        var counter = makeCounter(numberOfOps, done);\n\n        for (var i = 0; i < numberOfOps; ++i) {\n            setImmediate(counter);\n        }\n    });\n});\n"
  },
  {
    "path": "benchmark/scenarios.js",
    "content": "\"use strict\";\n\nvar Q = require(\"../q\");\n\nsuite(\"Chaining\", function () {\n    var numberToChain = 1000;\n\n    bench(\"Chaining many already-fulfilled promises together\", function (done) {\n        var currentPromise = Q();\n        for (var i = 0; i < numberToChain; ++i) {\n            currentPromise = currentPromise.then(function () {\n                return Q();\n            });\n        }\n\n        currentPromise.then(done);\n    });\n\n    bench(\"Chaining and then fulfilling the end of the chain\", function (done) {\n        var deferred = Q.defer();\n\n        var currentPromise = deferred.promise;\n        for (var i = 0; i < numberToChain; ++i) {\n            (function () {\n                var promiseToReturn = currentPromise;\n                currentPromise = Q().then(function () {\n                    return promiseToReturn;\n                });\n            }());\n        }\n\n        currentPromise.then(done);\n\n        deferred.resolve();\n    });\n});\n"
  },
  {
    "path": "design/README.md",
    "content": "\nThis document is intended to explain how promises work and why this\nimplementation works its particular way by building a promise library\nincrementally and reviewing all of its major design decisions.  This is\nintended to leave the reader at liberty to experiment with variations\nof this implementation that suit their own requirements, without missing\nany important details.\n\n---\n\nSuppose that you're writing a function that can't return a value immediately.\nThe most obvious API is to forward the eventual value to a callback as an\nargument instead of returning the value.\n\n```javascript\nvar oneOneSecondLater = function (callback) {\n    setTimeout(function () {\n        callback(1);\n    }, 1000);\n};\n```\n\nThis is a very simple solution to a trival problem, but there is a lot of room\nfor improvement.\n\nA more general solution would provide analogous tools for both return values\nand thrown exceptions.  There are several obvious ways to extend the callback\npattern to handle exceptions.  One is to provide both a callback and an\nerrback.\n\n```javascript\nvar maybeOneOneSecondLater = function (callback, errback) {\n    setTimeout(function () {\n        if (Math.random() < .5) {\n            callback(1);\n        } else {\n            errback(new Error(\"Can't provide one.\"));\n        }\n    }, 1000);\n};\n```\n\nThere are other approaches, variations on providing the error as an argument\nto the callback, either by position or a distinguished sentinel value.\nHowever, none of these approaches actually model thrown exceptions.  The\npurpose of exceptions and try/catch blocks is to postpone the explicit\nhandling of exceptions until the program has returned to a point where it\nmakes sense to attempt to recover.  There needs to be some mechanism for\nimplicitly propagating exceptions if they are not handled.\n\nPromises\n========\n\nConsider a more general approach, where instead of returning values or\nthrowing exceptions, functions return an object that represents the eventual\nresult of the function, either sucessful or failed.  This object is a promise,\nboth figuratively and by name, to eventually resolve.  We can call a function\non the promise to observe either its fulfillment or rejection.  If the promise\nis rejected and the rejection is not explicitly observed, any derrived\npromises will be implicitly rejected for the same reason.\n\nIn this particular iteration of the design, we'll model a promise as an object\nwith a \"then\" function that registers the callback.\n\n```javascript\nvar maybeOneOneSecondLater = function () {\n    var callback;\n    setTimeout(function () {\n        callback(1);\n    }, 1000);\n    return {\n        then: function (_callback) {\n            callback = _callback;\n        }\n    };\n};\n\nmaybeOneOneSecondLater().then(callback);\n```\n\nThis design has two weaknesses: \n\n- The last caller of the then method determines the callback that is used.\n  It would be more useful if every registered callback were notified of\n  the resolution.\n- If the callback is registered more than a second after the promise was\n  constructed, it won't be called.\n\nA more general solution would accept any number of callbacks and permit them\nto be registered either before or after the timeout, or generally, the\nresolution event.  We accomplish this by making the promise a two-state object.\n\nA promise is initially unresolved and all callbacks are added to an array of\npending observers.  When the promise is resolved, all of the observers are\nnotified.  After the promise has been resolved, new callbacks are called\nimmediately.  We distinguish the state change by whether the array of pending\ncallbacks still exists, and we throw them away after resolution.\n\n```javascript\nvar maybeOneOneSecondLater = function () {\n    var pending = [], value;\n    setTimeout(function () {\n        value = 1;\n        for (var i = 0, ii = pending.length; i < ii; i++) {\n            var callback = pending[i];\n            callback(value);\n        }\n        pending = undefined;\n    }, 1000);\n    return {\n        then: function (callback) {\n            if (pending) {\n                pending.push(callback);\n            } else {\n                callback(value);\n            }\n        }\n    };\n};\n```\n\nThis is already doing enough that it would be useful to break it into a\nutility function.  A deferred is an object with two parts: one for registering\nobservers and another for notifying observers of resolution.\n(see design/q0.js)\n\n```javascript\nvar defer = function () {\n    var pending = [], value;\n    return {\n        resolve: function (_value) {\n            value = _value;\n            for (var i = 0, ii = pending.length; i < ii; i++) {\n                var callback = pending[i];\n                callback(value);\n            }\n            pending = undefined;\n        },\n        then: function (callback) {\n            if (pending) {\n                pending.push(callback);\n            } else {\n                callback(value);\n            }\n        }\n    }\n};\n\nvar oneOneSecondLater = function () {\n    var result = defer();\n    setTimeout(function () {\n        result.resolve(1);\n    }, 1000);\n    return result;\n};\n\noneOneSecondLater().then(callback);\n```\n\nThe resolve function now has a flaw: it can be called multiple times, changing\nthe value of the promised result.  This fails to model the fact that a\nfunction only either returns one value or throws one error.  We can protect\nagainst accidental or malicious resets by only allowing only the first call to\nresolve to set the resolution.\n\n```javascript\nvar defer = function () {\n    var pending = [], value;\n    return {\n        resolve: function (_value) {\n            if (pending) {\n                value = _value;\n                for (var i = 0, ii = pending.length; i < ii; i++) {\n                    var callback = pending[i];\n                    callback(value);\n                }\n                pending = undefined;\n            } else {\n                throw new Error(\"A promise can only be resolved once.\");\n            }\n        },\n        then: function (callback) {\n            if (pending) {\n                pending.push(callback);\n            } else {\n                callback(value);\n            }\n        }\n    }\n};\n```\n\nYou can make an argument either for throwing an error or for ignoring all\nsubsequent resolutions.  One use-case is to give the resolver to a bunch of\nworkers and have a race to resolve the promise, where subsequent resolutions\nwould be ignored.  It's also possible that you do not want the workers to know\nwhich won.  Hereafter, all examples will ignore rather than fault on multiple\nresolution.\n\nAt this point, defer can handle both multiple resolution and multiple\nobservation. (see design/q1.js)\n\n--------------------------------\n\nThere are a few variations on this design which arise from two separate\ntensions.  The first tension is that it is both useful to separate or combine\nthe promise and resolver parts of the deferred.  It is also useful to have\nsome way of distinguishing promises from other values.\n\n-\n\nSeparating the promise portion from the resolver allows us to code within the\nprinciple of least authority.  Giving someone a promise should give only the\nauthority to observe the resolution and giving someone a resolver should only\ngive the authority to determine the resolution.  One should not implicitly\ngive the other.  The test of time shows that any excess authority will\ninevitably be abused and will be very difficult to redact.\n\nThe disadvantage of separation, however, is the additional burden on the\ngarbage collector to quickly dispose of used promise objects.\n\n-\n\nAlso, there are a variety of ways to distinguish a promise from other values.\nThe most obvious and strongest distinction is to use prototypical inheritance.\n(design/q2.js)\n\n```javascript\nvar Promise = function () {\n};\n\nvar isPromise = function (value) {\n    return value instanceof Promise;\n};\n\nvar defer = function () {\n    var pending = [], value;\n    var promise = new Promise();\n    promise.then = function (callback) {\n        if (pending) {\n            pending.push(callback);\n        } else {\n            callback(value);\n        }\n    };\n    return {\n        resolve: function (_value) {\n            if (pending) {\n                value = _value;\n                for (var i = 0, ii = pending.length; i < ii; i++) {\n                    var callback = pending[i];\n                    callback(value);\n                }\n                pending = undefined;\n            }\n        },\n        promise: promise\n    };\n};\n```\n\n\nUsing prototypical inheritance has the disadvantage that only one instance of\na promise library can be used in a single program.  This can be difficult to\nenforce, leading to dependency enforcement woes.\n\nAnother approach is to use duck-typing, distinguishing promises from other\nvalues by the existence of a conventionally named method.  In our case,\nCommonJS/Promises/A establishes the use of \"then\" to distinguish its brand of\npromises from other values.  This has the disadvantage of failing to\ndistinguish other objects that just happen to have a \"then\" method.  In\npractice, this is not a problem, and the minor variations in \"thenable\"\nimplementations in the wild are manageable.\n\n```javascript\nvar isPromise = function (value) {\n    return value && typeof value.then === \"function\";\n};\n\nvar defer = function () {\n    var pending = [], value;\n    return {\n        resolve: function (_value) {\n            if (pending) {\n                value = _value;\n                for (var i = 0, ii = pending.length; i < ii; i++) {\n                    var callback = pending[i];\n                    callback(value);\n                }\n                pending = undefined;\n            }\n        },\n        promise: {\n            then: function (callback) {\n                if (pending) {\n                    pending.push(callback);\n                } else {\n                    callback(value);\n                }\n            }\n        }\n    };\n};\n```\n\nThe next big step is making it easy to compose promises, to make new promises\nusing values obtained from old promises.  Supposing that you have received\npromises for two numbers from a couple function calls, we would like to be\nable to create a promise for their sum.  Consider how this is achieved with\ncallbacks.\n\n```javascript\nvar twoOneSecondLater = function (callback) {\n    var a, b;\n    var consider = function () {\n        if (a === undefined || b === undefined)\n            return;\n        callback(a + b);\n    };\n    oneOneSecondLater(function (_a) {\n        a = _a;\n        consider();\n    });\n    oneOneSecondLater(function (_b) {\n        b = _b;\n        consider();\n    });\n};\n\ntwoOneSecondLater(function (c) {\n    // c === 2\n});\n```\n\nThis approach is fragile for a number of reasons, particularly that there\nneeds to be code to explicitly notice, in this case by a sentinel value,\nwhether a callback has been called.  One must also take care to account for cases\nwhere callbacks are issued before the end of the event loop turn: the `consider`\nfunction must appear before it is used.\n\nIn a few more steps, we will be able to accomplish this using promises in less\ncode and handling error propagation implicitly.\n\n```javascript\nvar a = oneOneSecondLater();\nvar b = oneOneSecondLater();\nvar c = a.then(function (a) {\n    return b.then(function (b) {\n        return a + b;\n    });\n});\n```\n\nFor this to work, several things have to fall into place:\n\n - The \"then\" method must return a promise.\n - The returned promise must be eventually resolved with the\n   return value of the callback.\n - The return value of the callback must be either a fulfilled\n   value or a promise.\n\nConverting values into promises that have already been fulfilled\nis straightforward.  This is a promise that immediately informs\nany observers that the value has already been fulfilled.\n\n```javascript\nvar ref = function (value) {\n    return {\n        then: function (callback) {\n            callback(value);\n        }\n    };\n};\n```\n\nThis method can be altered to coerce the argument into a promise\nregardless of whether it is a value or a promise already.\n\n```javascript\nvar ref = function (value) {\n    if (value && typeof value.then === \"function\")\n        return value;\n    return {\n        then: function (callback) {\n            callback(value);\n        }\n    };\n};\n```\n\nNow, we need to start altering our \"then\" methods so that they\nreturn promises for the return value of their given callback.\nThe \"ref\" case is simple.  We'll coerce the return value of the\ncallback to a promise and return that immediately.\n\n```javascript\nvar ref = function (value) {\n    if (value && typeof value.then === \"function\")\n        return value;\n    return {\n        then: function (callback) {\n            return ref(callback(value));\n        }\n    };\n};\n```\n\nThis is more complicated for the deferred since the callback\nwill be called in a future turn.  In this case, we recur on \"defer\"\nand wrap the callback.  The value returned by the callback will\nresolve the promise returned by \"then\".\n\nFurthermore, the \"resolve\" method needs to handle the case where the\nresolution is itself a promise to resolve later.  This is accomplished by\nchanging the resolution value to a promise.  That is, it implements a \"then\"\nmethod, and can either be a promise returned by \"defer\" or a promise returned\nby \"ref\".  If it's a \"ref\" promise, the behavior is identical to before: the\ncallback is called immediately by \"then(callback)\".  If it's a \"defer\"\npromise, the callback is passed forward to the next promise by calling\n\"then(callback)\".  Thus, your callback is now observing a new promise for a\nmore fully resolved value.  Callbacks can be forwarded many times, making\n\"progress\" toward an eventual resolution with each forwarding.\n\n```javascript\nvar defer = function () {\n    var pending = [], value;\n    return {\n        resolve: function (_value) {\n            if (pending) {\n                value = ref(_value); // values wrapped in a promise\n                for (var i = 0, ii = pending.length; i < ii; i++) {\n                    var callback = pending[i];\n                    value.then(callback); // then called instead\n                }\n                pending = undefined;\n            }\n        },\n        promise: {\n            then: function (_callback) {\n                var result = defer();\n                // callback is wrapped so that its return\n                // value is captured and used to resolve the promise\n                // that \"then\" returns\n                var callback = function (value) {\n                    result.resolve(_callback(value));\n                };\n                if (pending) {\n                    pending.push(callback);\n                } else {\n                    value.then(callback);\n                }\n                return result.promise;\n            }\n        }\n    };\n};\n```\n\nThe implementation at this point uses \"thenable\" promises and separates the\n\"promise\" and \"resolve\" components of a \"deferred\".\n(see design/q4.js)\n\nError Propagation\n=================\n\nTo achieve error propagation, we need to reintroduce errbacks.  We use a new\ntype of promise, analogous to a \"ref\" promise, that instead of informing a\ncallback of the promise's fulfillment, it will inform the errback of its\nrejection and the reason why.\n\n```javascript\nvar reject = function (reason) {\n    return {\n        then: function (callback, errback) {\n            return ref(errback(reason));\n        }\n    };\n};\n```\n\nThe simplest way to see this in action is to observe the resolution of\nan immediate rejection.\n\n```javascript\nreject(\"Meh.\").then(function (value) {\n    // we never get here\n}, function (reason) {\n    // reason === \"Meh.\"\n});\n```\n\nWe can now revise our original errback use-case to use the promise\nAPI.\n\n```javascript\nvar maybeOneOneSecondLater = function (callback, errback) {\n    var result = defer();\n    setTimeout(function () {\n        if (Math.random() < .5) {\n            result.resolve(1);\n        } else {\n            result.resolve(reject(\"Can't provide one.\"));\n        }\n    }, 1000);\n    return result.promise;\n};\n```\n\nTo make this example work, the defer system needs new plumbing so that it can\nforward both the callback and errback components.  So, the array of pending\ncallbacks will be replaced with an array of arguments for \"then\" calls.\n\n```javascript\nvar defer = function () {\n    var pending = [], value;\n    return {\n        resolve: function (_value) {\n            if (pending) {\n                value = ref(_value);\n                for (var i = 0, ii = pending.length; i < ii; i++) {\n                    // apply the pending arguments to \"then\"\n                    value.then.apply(value, pending[i]);\n                }\n                pending = undefined;\n            }\n        },\n        promise: {\n            then: function (_callback, _errback) {\n                var result = defer();\n                var callback = function (value) {\n                    result.resolve(_callback(value));\n                };\n                var errback = function (reason) {\n                    result.resolve(_errback(reason));\n                };\n                if (pending) {\n                    pending.push([callback, errback]);\n                } else {\n                    value.then(callback, errback);\n                }\n                return result.promise;\n            }\n        }\n    };\n};\n```\n\nThere is, however, a subtle problem with this version of \"defer\".  It mandates\nthat an errback must be provided on all \"then\" calls, or an exception will be\nthrown when trying to call a non-existant function.  The simplest solution to\nthis problem is to provide a default errback that forwards the rejection.  It\nis also reasonable for the callback to be omitted if you're only interested in\nobserving rejections, so we provide a default callback that forwards the\nfulfilled value.\n\n```javascript\nvar defer = function () {\n    var pending = [], value;\n    return {\n        resolve: function (_value) {\n            if (pending) {\n                value = ref(_value);\n                for (var i = 0, ii = pending.length; i < ii; i++) {\n                    value.then.apply(value, pending[i]);\n                }\n                pending = undefined;\n            }\n        },\n        promise: {\n            then: function (_callback, _errback) {\n                var result = defer();\n                // provide default callbacks and errbacks\n                _callback = _callback || function (value) {\n                    // by default, forward fulfillment\n                    return value;\n                };\n                _errback = _errback || function (reason) {\n                    // by default, forward rejection\n                    return reject(reason);\n                };\n                var callback = function (value) {\n                    result.resolve(_callback(value));\n                };\n                var errback = function (reason) {\n                    result.resolve(_errback(reason));\n                };\n                if (pending) {\n                    pending.push([callback, errback]);\n                } else {\n                    value.then(callback, errback);\n                }\n                return result.promise;\n            }\n        }\n    };\n};\n```\n\nAt this point, we've achieved composition and implicit error propagation.  We\ncan now very easily create promises from other promises either in serial or in\nparallel (see design/q6.js).  This example creates a promise for the eventual\nsum of promised values.\n\n```javascript\npromises.reduce(function (accumulating, promise) {\n    return accumulating.then(function (accumulated) {\n        return promise.then(function (value) {\n            return accumulated + value;\n        });\n    });\n}, ref(0)) // start with a promise for zero, so we can call then on it\n           // just like any of the combined promises\n.then(function (sum) {\n    // the sum is here\n});\n```\n\nSafety and Invariants\n=====================\n\nAnother incremental improvement is to make sure that callbacks and errbacks\nare called in future turns of the event loop, in the same order that they\nwere registered.  This greatly reduces the number of control-flow hazards\ninherent to asynchronous programming.  Consider a brief and contrived example:\n\n```javascript\nvar blah = function () {\n    var result = foob().then(function () {\n        return barf();\n    });\n    var barf = function () {\n        return 10;\n    };\n    return result;\n};\n```\n\nThis function will either throw an exception or return a promise that will\nquickly be fulfilled with the value of 10.  It depends on whether foob()\nresolves in the same turn of the event loop (issuing its callback on the same\nstack immediately) or in a future turn.  If the callback is delayed to a\nfuture turn, it will allways succeed.\n(see design/q7.js)\n\n```javascript\nvar enqueue = function (callback) {\n    //process.nextTick(callback); // NodeJS\n    setTimeout(callback, 1); // Naïve browser solution\n};\n\nvar defer = function () {\n    var pending = [], value;\n    return {\n        resolve: function (_value) {\n            if (pending) {\n                value = ref(_value);\n                for (var i = 0, ii = pending.length; i < ii; i++) {\n                    // XXX\n                    enqueue(function () {\n                        value.then.apply(value, pending[i]);\n                    });\n                }\n                pending = undefined;\n            }\n        },\n        promise: {\n            then: function (_callback, _errback) {\n                var result = defer();\n                _callback = _callback || function (value) {\n                    return value;\n                };\n                _errback = _errback || function (reason) {\n                    return reject(reason);\n                };\n                var callback = function (value) {\n                    result.resolve(_callback(value));\n                };\n                var errback = function (reason) {\n                    result.resolve(_errback(reason));\n                };\n                if (pending) {\n                    pending.push([callback, errback]);\n                } else {\n                    // XXX\n                    enqueue(function () {\n                        value.then(callback, errback);\n                    });\n                }\n                return result.promise;\n            }\n        }\n    };\n};\n\nvar ref = function (value) {\n    if (value && value.then)\n        return value;\n    return {\n        then: function (callback) {\n            var result = defer();\n            // XXX\n            enqueue(function () {\n                result.resolve(callback(value));\n            });\n            return result.promise;\n        }\n    };\n};\n\nvar reject = function (reason) {\n    return {\n        then: function (callback, errback) {\n            var result = defer();\n            // XXX\n            enqueue(function () {\n                result.resolve(errback(reason));\n            });\n            return result.promise;\n        }\n    };\n};\n```\n\nThere remains one safty issue, though.  Given that any object that implements\n\"then\" is treated as a promise, anyone who calls \"then\" directly is at risk\nof surprise.\n\n - The callback or errback might get called in the same turn\n - The callback and errback might both be called\n - The callback or errback might be called more than once\n\nA \"when\" method wraps a promise and prevents these surprises.\n\nWe can also take the opportunity to wrap the callback and errback\nso that any exceptions thrown get transformed into rejections.\n\n```javascript\nvar when = function (value, _callback, _errback) {\n    var result = defer();\n    var done;\n\n    _callback = _callback || function (value) {\n        return value;\n    };\n    _errback = _errback || function (reason) {\n        return reject(reason);\n    };\n\n    var callback = function (value) {\n        try {\n            return _callback(value);\n        } catch (reason) {\n            return reject(reason);\n        }\n    };\n    var errback = function (reason) {\n        try {\n            return _errback(reason);\n        } catch (reason) {\n            return reject(reason);\n        }\n    };\n\n    enqueue(function () {\n        ref(value).then(function (value) {\n            if (done)\n                return;\n            done = true;\n            result.resolve(ref(value).then(callback, errback));\n        }, function (reason) {\n            if (done)\n                return;\n            done = true;\n            result.resolve(errback(reason));\n        });\n    });\n\n    return result.promise;\n};\n```\n\nAt this point, we have the means to protect ourselves against several\nsurprises including unnecessary non-deterministic control-flow in the course\nof an event and broken callback and errback control-flow invariants.\n(see design/q7.js)\n\n\nMessage Passing\n===============\n\nIf we take a step back, promises have become objects that receive \"then\"\nmessages.  Deferred promises forward those messages to their resolution\npromise.  Fulfilled promises respond to then messages by calling the callback\nwith the fulfilled value.  Rejected promises respond to then messages by\ncalling the errback with the rejection reason.\n\nWe can generalize promises to be objects that receive arbitrary messages,\nincluding \"then/when\" messages.  This is useful if there is a lot of latency\npreventing the immediate observation of a promise's resolution, as in a\npromise that is in another process or worker or another computer on a network.\n\nIf we have to wait for a message to make a full round-trip across a network to\nget a value, the round-trips can add up a lot and much time will be wasted.\nThis ammounts to \"chatty\" network protocol problems, which are the downfall\nof SOAP and RPC in general.\n\nHowever, if we can send a message to a distant promise before it resolves, the\nremote promise can send responses in rapid succession.  Consider the case\nwhere an object is housed on a remote server and cannot itself be sent across\nthe network; it has some internal state and capabilities that cannot be\nserialized, like access to a database.  Suppose we obtain a promise for\nthis object and can now send messages.  These messages would likely mostly\ncomprise method calls like \"query\", which would in turn send promises back.\n\n---\n\nWe must found a new family of promises based on a new method that sends\narbitrary messages to a promise.  \"promiseSend\" is defined by\nCommonJS/Promises/D.  Sending a \"when\" message is equivalent to calling the\n\"then\" method.\n\n\n```javascript\npromise.then(callback, errback);\npromise.promiseSend(\"when\", callback, errback);\n```\n\nWe must revisit all of our methods, building them on \"promiseSend\" instead of\n\"then\".  However, we do not abandon \"then\" entirely; we still produce and\nconsume \"thenable\" promises, routing their message through \"promiseSend\"\ninternally.\n\n```javascript\nfunction Promise() {}\nPromise.prototype.then = function (callback, errback) {\n    return when(this, callback, errback);\n};\n```\n\nIf a promise does not recognize a message type (an \"operator\" like \"when\"),\nit must return a promise that will be eventually rejected.\n\nBeing able to receive arbitrary messages means that we can also implement new\ntypes of promise that serves as a proxy for a remote promise, simply\nforwarding all messages to the remote promise and forwarding all of its\nresponses back to promises in the local worker.\n\nBetween the use-case for proxies and rejecting unrecognized messages, it\nis useful to create a promise abstraction that routes recognized messages to\na handler object, and unrecognized messages to a fallback method.\n\n\n```javascript\nvar makePromise = function (handler, fallback) {\n    var promise = new Promise();\n    handler = handler || {};\n    fallback = fallback || function (op) {\n        return reject(\"Can't \" + op);\n    };\n    promise.promiseSend = function (op, callback) {\n        var args = Array.prototype.slice.call(arguments, 2);\n        var result;\n        callback = callback || function (value) {return value};\n        if (handler[op]) {\n            result = handler[op].apply(handler, args);\n        } else {\n            result = fallback.apply(handler, [op].concat(args));\n        }\n        return callback(result);\n    };\n    return promise;\n};\n```\n\nEach of the handler methods and the fallback method are all expected to return\na value which will be forwarded to the callback.  The handlers do not receive\ntheir own name, but the fallback does receive the operator name so it can\nroute it.  Otherwise, arguments are passed through.\n\nFor the \"ref\" method, we still only coerce values that are not already\npromises.  We also coerce \"thenables\" into \"promiseSend\" promises.\nWe provide methods for basic interaction with a fulfilled value, including\nproperty manipulation and method calls.\n\n```javascript\nvar ref = function (object) {\n    if (object && typeof object.promiseSend !== \"undefined\") {\n        return object;\n    }\n    if (object && typeof object.then !== \"undefined\") {\n        return makePromise({\n            when: function () {\n                var result = defer();\n                object.then(result.resolve, result.reject);\n                return result;\n            }\n        }, function fallback(op) {\n            return Q.when(object, function (object) {\n                return Q.ref(object).promiseSend.apply(object, arguments);\n            });\n        });\n    }\n    return makePromise({\n        when: function () {\n            return object;\n        },\n        get: function (name) {\n            return object[name];\n        },\n        put: function (name, value) {\n            object[name] = value;\n        },\n        del: function (name) {\n            delete object[name];\n        }\n    }); \n};\n```\n\nRejected promises simply forward their rejection to any message.\n\n```javascript\nvar reject = function (reason) {\n    var forward = function (reason) {\n        return reject(reason);\n    };\n    return makePromise({\n        when: function (errback) {\n            errback = errback || forward;\n            return errback(reason);\n        }\n    }, forward);\n};\n```\n\nDefer sustains very little damage.  Instead of having an array of arguments to\nforward to \"then\", we have an array of arguments to forward to \"promiseSend\".\n\"makePromise\" and \"when\" absorb the responsibility for handling the callback\nand errback argument defaults and wrappers.\n\n```javascript\nvar defer = function () {\n    var pending = [], value;\n    return {\n        resolve: function (_value) {\n            if (pending) {\n                value = ref(_value);\n                for (var i = 0, ii = pending.length; i < ii; i++) {\n                    enqueue(function () {\n                        value.promiseSend.apply(value, pending[i]);\n                    });\n                }\n                pending = undefined;\n            }\n        },\n        promise: {\n            promiseSend: function () {\n                var args = Array.prototype.slice.call(arguments);\n                var result = defer();\n                if (pending) {\n                    pending.push(args);\n                } else {\n                    enqueue(function () {\n                        value.promiseSend.apply(value, args);\n                    });\n                }\n            }\n        }\n    };\n};\n```\n\nThe last step is to make it syntactically convenient to send messages to\npromises.  We create \"get\", \"put\", \"post\" and \"del\" functions that send\nthe corresponding messages and return promises for the results.  They\nall look very similar.\n\n```javascript\nvar get = function (object, name) {\n    var result = defer();\n    ref(object).promiseSend(\"get\", result.resolve, name);\n    return result.promise;\n};\n\nget({\"a\": 10}, \"a\").then(function (ten) {\n    // ten === ten\n});\n```\n\nThe last improvment to get promises up to the state-of-the-art is to rename\nall of the callbacks to \"win\" and all of the errbacks to \"fail\".  I've left\nthis as an exercise.\n\n\nFuture\n======\n\n\nAndrew Sutherland did a great exercise in creating a variation of the Q\nlibrary that supported annotations so that waterfalls of promise creation,\nresolution, and dependencies could be graphically depicited.  Optional\nannotations and a debug variation of the Q library would be a logical\nnext-step.\n\nThere remains some question about how to ideally cancel a promise.  At the\nmoment, a secondary channel would have to be used to send the abort message.\nThis requires further research.\n\nCommonJS/Promises/A also supports progress notification callbacks.  A\nvariation of this library that supports implicit composition and propagation\nof progress information would be very awesome.\n\nIt is a common pattern that remote objects have a fixed set of methods, all\nof which return promises.  For those cases, it is a common pattern to create\na local object that proxies for the remote object by forwarding all of its\nmethod calls to the remote object using \"post\".  The construction of such\nproxies could be automated.  Lazy-Arrays are certainly one use-case.\n"
  },
  {
    "path": "design/q0.js",
    "content": "\nvar defer = function () {\n    var pending = [], value;\n    return {\n        resolve: function (_value) {\n            value = _value;\n            for (var i = 0, ii = pending.length; i < ii; i++) {\n                var callback = pending[i];\n                callback(value);\n            }\n            pending = undefined;\n        },\n        then: function (callback) {\n            if (pending) {\n                pending.push(callback);\n            } else {\n                callback(value);\n            }\n        }\n    }\n};\n\n"
  },
  {
    "path": "design/q1.js",
    "content": "\nvar defer = function () {\n    var pending = [], value;\n    return {\n        resolve: function (_value) {\n            if (pending) {\n                value = _value;\n                for (var i = 0, ii = pending.length; i < ii; i++) {\n                    var callback = pending[i];\n                    callback(value);\n                }\n                pending = undefined;\n            } else {\n                throw new Error(\"A promise can only be resolved once.\");\n            }\n        },\n        then: function (callback) {\n            if (pending) {\n                pending.push(callback);\n            } else {\n                callback(value);\n            }\n        }\n    }\n};\n\n"
  },
  {
    "path": "design/q2.js",
    "content": "\nvar Promise = function () {\n};\n\nvar isPromise = function (value) {\n    return value instanceof Promise;\n};\n\nvar defer = function () {\n    var pending = [], value;\n    var promise = new Promise();\n    promise.then = function (callback) {\n        if (pending) {\n            pending.push(callback);\n        } else {\n            callback(value);\n        }\n    };\n    return {\n        resolve: function (_value) {\n            if (pending) {\n                value = _value;\n                for (var i = 0, ii = pending.length; i < ii; i++) {\n                    var callback = pending[i];\n                    callback(value);\n                }\n                pending = undefined;\n            }\n        },\n        promise: promise\n    };\n};\n\n"
  },
  {
    "path": "design/q3.js",
    "content": "\nvar isPromise = function (value) {\n    return value && typeof value.then === \"function\";\n};\n\nvar defer = function () {\n    var pending = [], value;\n    return {\n        resolve: function (_value) {\n            if (pending) {\n                value = _value;\n                for (var i = 0, ii = pending.length; i < ii; i++) {\n                    var callback = pending[i];\n                    callback(value);\n                }\n                pending = undefined;\n            }\n        },\n        promise: {\n            then: function (callback) {\n                if (pending) {\n                    pending.push(callback);\n                } else {\n                    callback(value);\n                }\n            }\n        }\n    };\n};\n\n"
  },
  {
    "path": "design/q4.js",
    "content": "\nvar isPromise = function (value) {\n    return value && typeof value.then === \"function\";\n};\n\nvar defer = function () {\n    var pending = [], value;\n    return {\n        resolve: function (_value) {\n            if (pending) {\n                value = ref(_value); // values wrapped in a promise\n                for (var i = 0, ii = pending.length; i < ii; i++) {\n                    var callback = pending[i];\n                    value.then(callback); // then called instead\n                }\n                pending = undefined;\n            }\n        },\n        promise: {\n            then: function (_callback) {\n                var result = defer();\n                // callback is wrapped so that its return\n                // value is captured and used to resolve the promise\n                // that \"then\" returns\n                var callback = function (value) {\n                    result.resolve(_callback(value));\n                };\n                if (pending) {\n                    pending.push(callback);\n                } else {\n                    value.then(callback);\n                }\n                return result.promise;\n            }\n        }\n    };\n};\n\nvar ref = function (value) {\n    if (value && typeof value.then === \"function\")\n        return value;\n    return {\n        then: function (callback) {\n            return ref(callback(value));\n        }\n    };\n};\n\n"
  },
  {
    "path": "design/q5.js",
    "content": "\nvar isPromise = function (value) {\n    return value && typeof value.then === \"function\";\n};\n\nvar defer = function () {\n    var pending = [], value;\n    return {\n        resolve: function (_value) {\n            if (pending) {\n                value = ref(_value);\n                for (var i = 0, ii = pending.length; i < ii; i++) {\n                    // apply the pending arguments to \"then\"\n                    value.then.apply(value, pending[i]);\n                }\n                pending = undefined;\n            }\n        },\n        promise: {\n            then: function (_callback, _errback) {\n                var result = defer();\n                var callback = function (value) {\n                    result.resolve(_callback(value));\n                };\n                var errback = function (reason) {\n                    result.resolve(_errback(reason));\n                };\n                if (pending) {\n                    pending.push([callback, errback]);\n                } else {\n                    value.then(callback, errback);\n                }\n                return result.promise;\n            }\n        }\n    };\n};\n\nvar ref = function (value) {\n    if (value && typeof value.then === \"function\")\n        return value;\n    return {\n        then: function (callback) {\n            return ref(callback(value));\n        }\n    };\n};\n\nvar reject = function (reason) {\n    return {\n        then: function (callback, errback) {\n            return ref(errback(reason));\n        }\n    };\n};\n\n"
  },
  {
    "path": "design/q6.js",
    "content": "\nvar isPromise = function (value) {\n    return value && typeof value.then === \"function\";\n};\n\nvar defer = function () {\n    var pending = [], value;\n    return {\n        resolve: function (_value) {\n            if (pending) {\n                value = ref(_value);\n                for (var i = 0, ii = pending.length; i < ii; i++) {\n                    value.then.apply(value, pending[i]);\n                }\n                pending = undefined;\n            }\n        },\n        promise: {\n            then: function (_callback, _errback) {\n                var result = defer();\n                // provide default callbacks and errbacks\n                _callback = _callback || function (value) {\n                    // by default, forward fulfillment\n                    return value;\n                };\n                _errback = _errback || function (reason) {\n                    // by default, forward rejection\n                    return reject(reason);\n                };\n                var callback = function (value) {\n                    result.resolve(_callback(value));\n                };\n                var errback = function (reason) {\n                    result.resolve(_errback(reason));\n                };\n                if (pending) {\n                    pending.push([callback, errback]);\n                } else {\n                    value.then(callback, errback);\n                }\n                return result.promise;\n            }\n        }\n    };\n};\n\nvar ref = function (value) {\n    if (value && typeof value.then === \"function\")\n        return value;\n    return {\n        then: function (callback) {\n            return ref(callback(value));\n        }\n    };\n};\n\nvar reject = function (reason) {\n    return {\n        then: function (callback, errback) {\n            return ref(errback(reason));\n        }\n    };\n};\n\n"
  },
  {
    "path": "design/q7.js",
    "content": "\nvar enqueue = function (callback) {\n    //process.nextTick(callback); // NodeJS\n    setTimeout(callback, 1); // Naïve browser solution\n};\n\nvar isPromise = function (value) {\n    return value && typeof value.then === \"function\";\n};\n\nvar defer = function () {\n    var pending = [], value;\n    return {\n        resolve: function (_value) {\n            if (pending) {\n                value = ref(_value);\n                for (var i = 0, ii = pending.length; i < ii; i++) {\n                    // XXX\n                    enqueue(function () {\n                        value.then.apply(value, pending[i]);\n                    });\n                }\n                pending = undefined;\n            }\n        },\n        promise: {\n            then: function (_callback, _errback) {\n                var result = defer();\n                _callback = _callback || function (value) {\n                    return value;\n                };\n                _errback = _errback || function (reason) {\n                    return reject(reason);\n                };\n                var callback = function (value) {\n                    result.resolve(_callback(value));\n                };\n                var errback = function (reason) {\n                    result.resolve(_errback(reason));\n                };\n                if (pending) {\n                    pending.push([callback, errback]);\n                } else {\n                    // XXX\n                    enqueue(function () {\n                        value.then(callback, errback);\n                    });\n                }\n                return result.promise;\n            }\n        }\n    };\n};\n\nvar ref = function (value) {\n    if (value && value.then)\n        return value;\n    return {\n        then: function (callback) {\n            var result = defer();\n            // XXX\n            enqueue(function () {\n                result.resolve(callback(value));\n            });\n            return result.promise;\n        }\n    };\n};\n\nvar reject = function (reason) {\n    return {\n        then: function (callback, errback) {\n            var result = defer();\n            // XXX\n            enqueue(function () {\n                result.resolve(errback(reason));\n            });\n            return result.promise;\n        }\n    };\n};\n\nvar when = function (value, _callback, _errback) {\n    var result = defer();\n    var done;\n\n    _callback = _callback || function (value) {\n        return value;\n    };\n    _errback = _errback || function (reason) {\n        return reject(reason);\n    };\n\n    // XXX\n    var callback = function (value) {\n        try {\n            return _callback(value);\n        } catch (reason) {\n            return reject(reason);\n        }\n    };\n    var errback = function (reason) {\n        try {\n            return _errback(reason);\n        } catch (reason) {\n            return reject(reason);\n        }\n    };\n\n    enqueue(function () {\n        ref(value).then(function (value) {\n            if (done)\n                return;\n            done = true;\n            result.resolve(ref(value).then(callback, errback));\n        }, function (reason) {\n            if (done)\n                return;\n            done = true;\n            result.resolve(errback(reason));\n        });\n    });\n\n    return result.promise;\n};\n\n"
  },
  {
    "path": "examples/all.js",
    "content": "\"use strict\";\n\nvar Q = require(\"../q\");\n\nfunction eventually(value) {\n    return Q.delay(value, 1000);\n}\n\nQ.all([1, 2, 3].map(eventually))\n.done(function (result) {\n    console.log(result);\n});\n\nQ.all([\n    eventually(10),\n    eventually(20)\n])\n.spread(function (x, y) {\n    console.log(x, y);\n})\n.done();\n"
  },
  {
    "path": "examples/async-generators/0.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n    <title>Q.async animation example</title>\n    <!--\n        Works in browsers that support ES6 geneartors, like Chromium 29 with\n        the --harmony flag.\n\n        Peter Hallam, Tom van Cutsem, Mark S. Miller, Dave Herman, Andy Wingo.\n        The animation example was taken from\n        <http://wiki.ecmascript.org/doku.php?id=strawman:deferred_functions>\n    -->\n</head>\n<body>\n    <div id=\"box\" style=\"width: 20px; height: 20px; background-color: red;\"></div>\n\n    <script src=\"../../q.js\"></script>\n    <script>\n    (function () {\n        \"use strict\";\n\n        var deferredAnimate = Q.async(function* (element) {\n            for (var i = 0; i < 100; ++i) {\n                element.style.marginLeft = i + \"px\";\n                yield Q.delay(20);\n            }\n        });\n\n        Q.spawn(function* () {\n            yield deferredAnimate(document.getElementById(\"box\"));\n            alert(\"Done!\");\n        });\n    }());\n    </script>\n</body>\n</html>\n"
  },
  {
    "path": "examples/async-generators/1-return.js",
    "content": "\"use strict\";\n\nvar Q = require(\"../../q\");\n\nvar generator = Q.async(function* () {\n    var ten = yield 10;\n    console.log(ten, 10);\n    var twenty = yield ten + 10;\n    console.log(twenty, 20);\n    var thirty = yield twenty + 10;\n    console.log(thirty, 30);\n    return thirty + 10;\n});\n\ngenerator().then(function (forty) {\n    console.log(forty, 40);\n}, function (reason) {\n    console.log(\"reason\", reason);\n});\n"
  },
  {
    "path": "examples/async-generators/2-error-propagation.js",
    "content": "\"use strict\";\n\nvar Q = require(\"../../q\");\n\nvar generator = Q.async(function* () {\n    try {\n        var ten = yield Q.reject(new Error(\"Rejected!\"));\n        console.log(\"Should not get here 1\");\n    } catch (exception) {\n        console.log(\"Should get here 1\");\n        console.log(exception.message, \"should be\", \"Rejected!\");\n        throw new Error(\"Threw!\");\n    }\n});\n\ngenerator().then(function () {\n    console.log(\"Should not get here 2\");\n}, function (reason) {\n    console.log(\"Should get here 2\");\n    console.log(reason.message, \"should be\", \"Threw!\");\n});\n"
  },
  {
    "path": "examples/async-generators/3-spawn.js",
    "content": "\"use strict\";\n\nvar Q = require(\"../../q\");\n\nfunction foo() {\n    return Q.delay(5, 1000);\n}\n\nfunction bar() {\n    return Q.delay(10, 1000);\n}\n\nQ.spawn(function* () {\n    var x = yield foo();\n    console.log(x);\n\n    var y = yield bar();\n    console.log(y);\n\n    console.log(\"result\", x + y);\n});\n"
  },
  {
    "path": "examples/async-generators/4-flow-control.js",
    "content": "\"use strict\";\n\nvar Q = require(\"../../q\");\n\n// We get back blocking semantics: can use promises with `if`, `while`, `for`,\n// etc.\nvar filter = Q.async(function* (promises, test) {\n    var results = [];\n    for (var i = 0; i < promises.length; i++) {\n        var val = yield promises[i];\n        if (test(val)) {\n            results.push(val);\n        }\n    }\n    return results;\n});\n\nvar promises = [\n    Q.delay(\"a\", 500),\n    Q.delay(\"d\", 1000),\n    Q(\"l\")\n];\n\nfilter(promises, function (letter) {\n    return \"f\" > letter;\n}).done(function (all) {\n    console.log(all); // [ \"a\", \"d\" ]\n});\n\n\n// we can use try and catch to handle rejected promises\nvar logRejections = Q.async(function* (work) {\n    try {\n        yield work;\n        console.log(\"Never end up here\");\n    } catch (e) {\n        console.log(\"Caught:\", e.message);\n    }\n});\n\nvar rejection = Q.reject(new Error(\"Oh dear\"));\nlogRejections(rejection); // Caught: Oh dear\n"
  },
  {
    "path": "examples/async-generators/README.md",
    "content": ":warning: Warning: The behavior described here is likely to be quickly\nobseleted by developments in standardization and implementation.  Tread with\ncare.\n\nQ has an `async` function.  This can be used to decorate a generator function\nsuch that `yield` is effectively equivalent to `await` or `defer` syntax as\nsupported by languages like Go and C# 5.\n\nGenerator functions are presently on the standards track for ES6.  As of July\n2013, they are only fully supported by bleeding edge V8, which hasn't made it\nout to a released Chromium yet but will probably be in Chromium 29. Even then,\nthey must be enabled from [chrome://flags](chrome://flags) as \"Experimental\nJavaScript features.\" SpiderMonkey (used in Firefox) includes an older style of\ngenerators, but these are not supported by Q.\n\nHere's an example of using generators by themselves, without any Q features:\n\n```js\nfunction* count() {\n    var i = 0;\n    while (true) {\n        yield i++;\n    }\n}\n\nvar counter = count();\ncounter.next().value === 0;\ncounter.next().value === 1;\ncounter.next().value === 2;\n```\n\n`yield` can also return a value, if the `next` method of the generator is\ncalled with a parameter:\n\n```js\nvar buffer = (function* () {\n    var x;\n    while (true) {\n        x = yield x;\n    }\n}());\n\nbuffer.next(1).value === undefined;\nbuffer.next(\"a\").value === 1;\nbuffer.value(2).value === \"a\";\nbuffer.next().value === 2;\nbuffer.next().value === undefined;\nbuffer.next().value === undefined;\n```\n\nInside functions wrapped with `Q.async`, we can use `yield` to wait for a\npromise to settle:\n\n```js\nvar eventualAdd = Q.async(function* (oneP, twoP) {\n    var one = yield oneP;\n    var two = yield twoP;\n    return one + two;\n});\n\neventualAdd(eventualOne, eventualTwo).then(function (three) {\n    three === 3;\n});\n```\nYou can see more examples of how this works, as well as the `Q.spawn` function,\nin the other files in this folder.\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"q\",\n  \"version\": \"1.5.1\",\n  \"description\": \"A library for promises (CommonJS/Promises/A,B,D)\",\n  \"homepage\": \"https://github.com/kriskowal/q\",\n  \"author\": \"Kris Kowal <kris@cixar.com> (https://github.com/kriskowal)\",\n  \"keywords\": [\n    \"q\",\n    \"promise\",\n    \"promises\",\n    \"promises-a\",\n    \"promises-aplus\",\n    \"deferred\",\n    \"future\",\n    \"async\",\n    \"flow control\",\n    \"fluent\",\n    \"browser\",\n    \"node\"\n  ],\n  \"contributors\": [\n    \"Kris Kowal <kris@cixar.com> (https://github.com/kriskowal)\",\n    \"Irakli Gozalishvili <rfobic@gmail.com> (http://jeditoolkit.com)\",\n    \"Domenic Denicola <domenic@domenicdenicola.com> (http://domenicdenicola.com)\"\n  ],\n  \"bugs\": {\n    \"mail\": \"kris@cixar.com\",\n    \"url\": \"http://github.com/kriskowal/q/issues\"\n  },\n  \"license\": \"MIT\",\n  \"main\": \"q.js\",\n  \"files\": [\n    \"LICENSE\",\n    \"q.js\",\n    \"queue.js\"\n  ],\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git://github.com/kriskowal/q.git\"\n  },\n  \"engines\": {\n    \"node\": \">=0.6.0\",\n    \"teleport\": \">=0.2.0\"\n  },\n  \"dependencies\": {},\n  \"devDependencies\": {\n    \"cover\": \"*\",\n    \"grunt\": \"~0.4.1\",\n    \"grunt-cli\": \"~0.1.9\",\n    \"grunt-contrib-uglify\": \"~0.9.1\",\n    \"jasmine-node\": \"1.11.0\",\n    \"jshint\": \"~2.1.9\",\n    \"matcha\": \"~0.2.0\",\n    \"opener\": \"*\",\n    \"promises-aplus-tests\": \"1.x\"\n  },\n  \"scripts\": {\n    \"test\": \"npm ls -s && jasmine-node spec && promises-aplus-tests spec/aplus-adapter && npm run -s lint\",\n    \"test-browser\": \"opener spec/q-spec.html\",\n    \"benchmark\": \"matcha\",\n    \"lint\": \"jshint q.js\",\n    \"cover\": \"cover run jasmine-node spec && cover report html && opener cover_html/index.html\",\n    \"minify\": \"grunt\",\n    \"prepublish\": \"grunt\"\n  },\n  \"overlay\": {\n    \"teleport\": {\n      \"dependencies\": {\n        \"system\": \">=0.0.4\"\n      }\n    }\n  },\n  \"directories\": {\n    \"test\": \"./spec\"\n  }\n}\n"
  },
  {
    "path": "q.js",
    "content": "// vim:ts=4:sts=4:sw=4:\n/*!\n *\n * Copyright 2009-2017 Kris Kowal under the terms of the MIT\n * license found at https://github.com/kriskowal/q/blob/v1/LICENSE\n *\n * With parts by Tyler Close\n * Copyright 2007-2009 Tyler Close under the terms of the MIT X license found\n * at http://www.opensource.org/licenses/mit-license.html\n * Forked at ref_send.js version: 2009-05-11\n *\n * With parts by Mark Miller\n * Copyright (C) 2011 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\n\n(function (definition) {\n    \"use strict\";\n\n    // This file will function properly as a <script> tag, or a module\n    // using CommonJS and NodeJS or RequireJS module formats.  In\n    // Common/Node/RequireJS, the module exports the Q API and when\n    // executed as a simple <script>, it creates a Q global instead.\n\n    // Montage Require\n    if (typeof bootstrap === \"function\") {\n        bootstrap(\"promise\", definition);\n\n    // CommonJS\n    } else if (typeof exports === \"object\" && typeof module === \"object\") {\n        module.exports = definition();\n\n    // RequireJS\n    } else if (typeof define === \"function\" && define.amd) {\n        define(definition);\n\n    // SES (Secure EcmaScript)\n    } else if (typeof ses !== \"undefined\") {\n        if (!ses.ok()) {\n            return;\n        } else {\n            ses.makeQ = definition;\n        }\n\n    // <script>\n    } else if (typeof window !== \"undefined\" || typeof self !== \"undefined\") {\n        // Prefer window over self for add-on scripts. Use self for\n        // non-windowed contexts.\n        var global = typeof window !== \"undefined\" ? window : self;\n\n        // Get the `window` object, save the previous Q global\n        // and initialize Q as a global.\n        var previousQ = global.Q;\n        global.Q = definition();\n\n        // Add a noConflict function so Q can be removed from the\n        // global namespace.\n        global.Q.noConflict = function () {\n            global.Q = previousQ;\n            return this;\n        };\n\n    } else {\n        throw new Error(\"This environment was not anticipated by Q. Please file a bug.\");\n    }\n\n})(function () {\n\"use strict\";\n\nvar hasStacks = false;\ntry {\n    throw new Error();\n} catch (e) {\n    hasStacks = !!e.stack;\n}\n\n// All code after this point will be filtered from stack traces reported\n// by Q.\nvar qStartingLine = captureLine();\nvar qFileName;\n\n// shims\n\n// used for fallback in \"allResolved\"\nvar noop = function () {};\n\n// Use the fastest possible means to execute a task in a future turn\n// of the event loop.\nvar nextTick =(function () {\n    // linked list of tasks (single, with head node)\n    var head = {task: void 0, next: null};\n    var tail = head;\n    var flushing = false;\n    var requestTick = void 0;\n    var isNodeJS = false;\n    // queue for late tasks, used by unhandled rejection tracking\n    var laterQueue = [];\n\n    function flush() {\n        /* jshint loopfunc: true */\n        var task, domain;\n\n        while (head.next) {\n            head = head.next;\n            task = head.task;\n            head.task = void 0;\n            domain = head.domain;\n\n            if (domain) {\n                head.domain = void 0;\n                domain.enter();\n            }\n            runSingle(task, domain);\n\n        }\n        while (laterQueue.length) {\n            task = laterQueue.pop();\n            runSingle(task);\n        }\n        flushing = false;\n    }\n    // runs a single function in the async queue\n    function runSingle(task, domain) {\n        try {\n            task();\n\n        } catch (e) {\n            if (isNodeJS) {\n                // In node, uncaught exceptions are considered fatal errors.\n                // Re-throw them synchronously to interrupt flushing!\n\n                // Ensure continuation if the uncaught exception is suppressed\n                // listening \"uncaughtException\" events (as domains does).\n                // Continue in next event to avoid tick recursion.\n                if (domain) {\n                    domain.exit();\n                }\n                setTimeout(flush, 0);\n                if (domain) {\n                    domain.enter();\n                }\n\n                throw e;\n\n            } else {\n                // In browsers, uncaught exceptions are not fatal.\n                // Re-throw them asynchronously to avoid slow-downs.\n                setTimeout(function () {\n                    throw e;\n                }, 0);\n            }\n        }\n\n        if (domain) {\n            domain.exit();\n        }\n    }\n\n    nextTick = function (task) {\n        tail = tail.next = {\n            task: task,\n            domain: isNodeJS && process.domain,\n            next: null\n        };\n\n        if (!flushing) {\n            flushing = true;\n            requestTick();\n        }\n    };\n\n    if (typeof process === \"object\" &&\n        process.toString() === \"[object process]\" && process.nextTick) {\n        // Ensure Q is in a real Node environment, with a `process.nextTick`.\n        // To see through fake Node environments:\n        // * Mocha test runner - exposes a `process` global without a `nextTick`\n        // * Browserify - exposes a `process.nexTick` function that uses\n        //   `setTimeout`. In this case `setImmediate` is preferred because\n        //    it is faster. Browserify's `process.toString()` yields\n        //   \"[object Object]\", while in a real Node environment\n        //   `process.toString()` yields \"[object process]\".\n        isNodeJS = true;\n\n        requestTick = function () {\n            process.nextTick(flush);\n        };\n\n    } else if (typeof setImmediate === \"function\") {\n        // In IE10, Node.js 0.9+, or https://github.com/NobleJS/setImmediate\n        if (typeof window !== \"undefined\") {\n            requestTick = setImmediate.bind(window, flush);\n        } else {\n            requestTick = function () {\n                setImmediate(flush);\n            };\n        }\n\n    } else if (typeof MessageChannel !== \"undefined\") {\n        // modern browsers\n        // http://www.nonblocking.io/2011/06/windownexttick.html\n        var channel = new MessageChannel();\n        // At least Safari Version 6.0.5 (8536.30.1) intermittently cannot create\n        // working message ports the first time a page loads.\n        channel.port1.onmessage = function () {\n            requestTick = requestPortTick;\n            channel.port1.onmessage = flush;\n            flush();\n        };\n        var requestPortTick = function () {\n            // Opera requires us to provide a message payload, regardless of\n            // whether we use it.\n            channel.port2.postMessage(0);\n        };\n        requestTick = function () {\n            setTimeout(flush, 0);\n            requestPortTick();\n        };\n\n    } else {\n        // old browsers\n        requestTick = function () {\n            setTimeout(flush, 0);\n        };\n    }\n    // runs a task after all other tasks have been run\n    // this is useful for unhandled rejection tracking that needs to happen\n    // after all `then`d tasks have been run.\n    nextTick.runAfter = function (task) {\n        laterQueue.push(task);\n        if (!flushing) {\n            flushing = true;\n            requestTick();\n        }\n    };\n    return nextTick;\n})();\n\n// Attempt to make generics safe in the face of downstream\n// modifications.\n// There is no situation where this is necessary.\n// If you need a security guarantee, these primordials need to be\n// deeply frozen anyway, and if you don’t need a security guarantee,\n// this is just plain paranoid.\n// However, this **might** have the nice side-effect of reducing the size of\n// the minified code by reducing x.call() to merely x()\n// See Mark Miller’s explanation of what this does.\n// http://wiki.ecmascript.org/doku.php?id=conventions:safe_meta_programming\nvar call = Function.call;\nfunction uncurryThis(f) {\n    return function () {\n        return call.apply(f, arguments);\n    };\n}\n// This is equivalent, but slower:\n// uncurryThis = Function_bind.bind(Function_bind.call);\n// http://jsperf.com/uncurrythis\n\nvar array_slice = uncurryThis(Array.prototype.slice);\n\nvar array_reduce = uncurryThis(\n    Array.prototype.reduce || function (callback, basis) {\n        var index = 0,\n            length = this.length;\n        // concerning the initial value, if one is not provided\n        if (arguments.length === 1) {\n            // seek to the first value in the array, accounting\n            // for the possibility that is is a sparse array\n            do {\n                if (index in this) {\n                    basis = this[index++];\n                    break;\n                }\n                if (++index >= length) {\n                    throw new TypeError();\n                }\n            } while (1);\n        }\n        // reduce\n        for (; index < length; index++) {\n            // account for the possibility that the array is sparse\n            if (index in this) {\n                basis = callback(basis, this[index], index);\n            }\n        }\n        return basis;\n    }\n);\n\nvar array_indexOf = uncurryThis(\n    Array.prototype.indexOf || function (value) {\n        // not a very good shim, but good enough for our one use of it\n        for (var i = 0; i < this.length; i++) {\n            if (this[i] === value) {\n                return i;\n            }\n        }\n        return -1;\n    }\n);\n\nvar array_map = uncurryThis(\n    Array.prototype.map || function (callback, thisp) {\n        var self = this;\n        var collect = [];\n        array_reduce(self, function (undefined, value, index) {\n            collect.push(callback.call(thisp, value, index, self));\n        }, void 0);\n        return collect;\n    }\n);\n\nvar object_create = Object.create || function (prototype) {\n    function Type() { }\n    Type.prototype = prototype;\n    return new Type();\n};\n\nvar object_defineProperty = Object.defineProperty || function (obj, prop, descriptor) {\n    obj[prop] = descriptor.value;\n    return obj;\n};\n\nvar object_hasOwnProperty = uncurryThis(Object.prototype.hasOwnProperty);\n\nvar object_keys = Object.keys || function (object) {\n    var keys = [];\n    for (var key in object) {\n        if (object_hasOwnProperty(object, key)) {\n            keys.push(key);\n        }\n    }\n    return keys;\n};\n\nvar object_toString = uncurryThis(Object.prototype.toString);\n\nfunction isObject(value) {\n    return value === Object(value);\n}\n\n// generator related shims\n\n// FIXME: Remove this function once ES6 generators are in SpiderMonkey.\nfunction isStopIteration(exception) {\n    return (\n        object_toString(exception) === \"[object StopIteration]\" ||\n        exception instanceof QReturnValue\n    );\n}\n\n// FIXME: Remove this helper and Q.return once ES6 generators are in\n// SpiderMonkey.\nvar QReturnValue;\nif (typeof ReturnValue !== \"undefined\") {\n    QReturnValue = ReturnValue;\n} else {\n    QReturnValue = function (value) {\n        this.value = value;\n    };\n}\n\n// long stack traces\n\nvar STACK_JUMP_SEPARATOR = \"From previous event:\";\n\nfunction makeStackTraceLong(error, promise) {\n    // If possible, transform the error stack trace by removing Node and Q\n    // cruft, then concatenating with the stack trace of `promise`. See #57.\n    if (hasStacks &&\n        promise.stack &&\n        typeof error === \"object\" &&\n        error !== null &&\n        error.stack\n    ) {\n        var stacks = [];\n        for (var p = promise; !!p; p = p.source) {\n            if (p.stack && (!error.__minimumStackCounter__ || error.__minimumStackCounter__ > p.stackCounter)) {\n                object_defineProperty(error, \"__minimumStackCounter__\", {value: p.stackCounter, configurable: true});\n                stacks.unshift(p.stack);\n            }\n        }\n        stacks.unshift(error.stack);\n\n        var concatedStacks = stacks.join(\"\\n\" + STACK_JUMP_SEPARATOR + \"\\n\");\n        var stack = filterStackString(concatedStacks);\n        object_defineProperty(error, \"stack\", {value: stack, configurable: true});\n    }\n}\n\nfunction filterStackString(stackString) {\n    var lines = stackString.split(\"\\n\");\n    var desiredLines = [];\n    for (var i = 0; i < lines.length; ++i) {\n        var line = lines[i];\n\n        if (!isInternalFrame(line) && !isNodeFrame(line) && line) {\n            desiredLines.push(line);\n        }\n    }\n    return desiredLines.join(\"\\n\");\n}\n\nfunction isNodeFrame(stackLine) {\n    return stackLine.indexOf(\"(module.js:\") !== -1 ||\n           stackLine.indexOf(\"(node.js:\") !== -1;\n}\n\nfunction getFileNameAndLineNumber(stackLine) {\n    // Named functions: \"at functionName (filename:lineNumber:columnNumber)\"\n    // In IE10 function name can have spaces (\"Anonymous function\") O_o\n    var attempt1 = /at .+ \\((.+):(\\d+):(?:\\d+)\\)$/.exec(stackLine);\n    if (attempt1) {\n        return [attempt1[1], Number(attempt1[2])];\n    }\n\n    // Anonymous functions: \"at filename:lineNumber:columnNumber\"\n    var attempt2 = /at ([^ ]+):(\\d+):(?:\\d+)$/.exec(stackLine);\n    if (attempt2) {\n        return [attempt2[1], Number(attempt2[2])];\n    }\n\n    // Firefox style: \"function@filename:lineNumber or @filename:lineNumber\"\n    var attempt3 = /.*@(.+):(\\d+)$/.exec(stackLine);\n    if (attempt3) {\n        return [attempt3[1], Number(attempt3[2])];\n    }\n}\n\nfunction isInternalFrame(stackLine) {\n    var fileNameAndLineNumber = getFileNameAndLineNumber(stackLine);\n\n    if (!fileNameAndLineNumber) {\n        return false;\n    }\n\n    var fileName = fileNameAndLineNumber[0];\n    var lineNumber = fileNameAndLineNumber[1];\n\n    return fileName === qFileName &&\n        lineNumber >= qStartingLine &&\n        lineNumber <= qEndingLine;\n}\n\n// discover own file name and line number range for filtering stack\n// traces\nfunction captureLine() {\n    if (!hasStacks) {\n        return;\n    }\n\n    try {\n        throw new Error();\n    } catch (e) {\n        var lines = e.stack.split(\"\\n\");\n        var firstLine = lines[0].indexOf(\"@\") > 0 ? lines[1] : lines[2];\n        var fileNameAndLineNumber = getFileNameAndLineNumber(firstLine);\n        if (!fileNameAndLineNumber) {\n            return;\n        }\n\n        qFileName = fileNameAndLineNumber[0];\n        return fileNameAndLineNumber[1];\n    }\n}\n\nfunction deprecate(callback, name, alternative) {\n    return function () {\n        if (typeof console !== \"undefined\" &&\n            typeof console.warn === \"function\") {\n            console.warn(name + \" is deprecated, use \" + alternative +\n                         \" instead.\", new Error(\"\").stack);\n        }\n        return callback.apply(callback, arguments);\n    };\n}\n\n// end of shims\n// beginning of real work\n\n/**\n * Constructs a promise for an immediate reference, passes promises through, or\n * coerces promises from different systems.\n * @param value immediate reference or promise\n */\nfunction Q(value) {\n    // If the object is already a Promise, return it directly.  This enables\n    // the resolve function to both be used to created references from objects,\n    // but to tolerably coerce non-promises to promises.\n    if (value instanceof Promise) {\n        return value;\n    }\n\n    // assimilate thenables\n    if (isPromiseAlike(value)) {\n        return coerce(value);\n    } else {\n        return fulfill(value);\n    }\n}\nQ.resolve = Q;\n\n/**\n * Performs a task in a future turn of the event loop.\n * @param {Function} task\n */\nQ.nextTick = nextTick;\n\n/**\n * Controls whether or not long stack traces will be on\n */\nQ.longStackSupport = false;\n\n/**\n * The counter is used to determine the stopping point for building\n * long stack traces. In makeStackTraceLong we walk backwards through\n * the linked list of promises, only stacks which were created before\n * the rejection are concatenated.\n */\nvar longStackCounter = 1;\n\n// enable long stacks if Q_DEBUG is set\nif (typeof process === \"object\" && process && process.env && process.env.Q_DEBUG) {\n    Q.longStackSupport = true;\n}\n\n/**\n * Constructs a {promise, resolve, reject} object.\n *\n * `resolve` is a callback to invoke with a more resolved value for the\n * promise. To fulfill the promise, invoke `resolve` with any value that is\n * not a thenable. To reject the promise, invoke `resolve` with a rejected\n * thenable, or invoke `reject` with the reason directly. To resolve the\n * promise to another thenable, thus putting it in the same state, invoke\n * `resolve` with that other thenable.\n */\nQ.defer = defer;\nfunction defer() {\n    // if \"messages\" is an \"Array\", that indicates that the promise has not yet\n    // been resolved.  If it is \"undefined\", it has been resolved.  Each\n    // element of the messages array is itself an array of complete arguments to\n    // forward to the resolved promise.  We coerce the resolution value to a\n    // promise using the `resolve` function because it handles both fully\n    // non-thenable values and other thenables gracefully.\n    var messages = [], progressListeners = [], resolvedPromise;\n\n    var deferred = object_create(defer.prototype);\n    var promise = object_create(Promise.prototype);\n\n    promise.promiseDispatch = function (resolve, op, operands) {\n        var args = array_slice(arguments);\n        if (messages) {\n            messages.push(args);\n            if (op === \"when\" && operands[1]) { // progress operand\n                progressListeners.push(operands[1]);\n            }\n        } else {\n            Q.nextTick(function () {\n                resolvedPromise.promiseDispatch.apply(resolvedPromise, args);\n            });\n        }\n    };\n\n    // XXX deprecated\n    promise.valueOf = function () {\n        if (messages) {\n            return promise;\n        }\n        var nearerValue = nearer(resolvedPromise);\n        if (isPromise(nearerValue)) {\n            resolvedPromise = nearerValue; // shorten chain\n        }\n        return nearerValue;\n    };\n\n    promise.inspect = function () {\n        if (!resolvedPromise) {\n            return { state: \"pending\" };\n        }\n        return resolvedPromise.inspect();\n    };\n\n    if (Q.longStackSupport && hasStacks) {\n        try {\n            throw new Error();\n        } catch (e) {\n            // NOTE: don't try to use `Error.captureStackTrace` or transfer the\n            // accessor around; that causes memory leaks as per GH-111. Just\n            // reify the stack trace as a string ASAP.\n            //\n            // At the same time, cut off the first line; it's always just\n            // \"[object Promise]\\n\", as per the `toString`.\n            promise.stack = e.stack.substring(e.stack.indexOf(\"\\n\") + 1);\n            promise.stackCounter = longStackCounter++;\n        }\n    }\n\n    // NOTE: we do the checks for `resolvedPromise` in each method, instead of\n    // consolidating them into `become`, since otherwise we'd create new\n    // promises with the lines `become(whatever(value))`. See e.g. GH-252.\n\n    function become(newPromise) {\n        resolvedPromise = newPromise;\n\n        if (Q.longStackSupport && hasStacks) {\n            // Only hold a reference to the new promise if long stacks\n            // are enabled to reduce memory usage\n            promise.source = newPromise;\n        }\n\n        array_reduce(messages, function (undefined, message) {\n            Q.nextTick(function () {\n                newPromise.promiseDispatch.apply(newPromise, message);\n            });\n        }, void 0);\n\n        messages = void 0;\n        progressListeners = void 0;\n    }\n\n    deferred.promise = promise;\n    deferred.resolve = function (value) {\n        if (resolvedPromise) {\n            return;\n        }\n\n        become(Q(value));\n    };\n\n    deferred.fulfill = function (value) {\n        if (resolvedPromise) {\n            return;\n        }\n\n        become(fulfill(value));\n    };\n    deferred.reject = function (reason) {\n        if (resolvedPromise) {\n            return;\n        }\n\n        become(reject(reason));\n    };\n    deferred.notify = function (progress) {\n        if (resolvedPromise) {\n            return;\n        }\n\n        array_reduce(progressListeners, function (undefined, progressListener) {\n            Q.nextTick(function () {\n                progressListener(progress);\n            });\n        }, void 0);\n    };\n\n    return deferred;\n}\n\n/**\n * Creates a Node-style callback that will resolve or reject the deferred\n * promise.\n * @returns a nodeback\n */\ndefer.prototype.makeNodeResolver = function () {\n    var self = this;\n    return function (error, value) {\n        if (error) {\n            self.reject(error);\n        } else if (arguments.length > 2) {\n            self.resolve(array_slice(arguments, 1));\n        } else {\n            self.resolve(value);\n        }\n    };\n};\n\n/**\n * @param resolver {Function} a function that returns nothing and accepts\n * the resolve, reject, and notify functions for a deferred.\n * @returns a promise that may be resolved with the given resolve and reject\n * functions, or rejected by a thrown exception in resolver\n */\nQ.Promise = promise; // ES6\nQ.promise = promise;\nfunction promise(resolver) {\n    if (typeof resolver !== \"function\") {\n        throw new TypeError(\"resolver must be a function.\");\n    }\n    var deferred = defer();\n    try {\n        resolver(deferred.resolve, deferred.reject, deferred.notify);\n    } catch (reason) {\n        deferred.reject(reason);\n    }\n    return deferred.promise;\n}\n\npromise.race = race; // ES6\npromise.all = all; // ES6\npromise.reject = reject; // ES6\npromise.resolve = Q; // ES6\n\n// XXX experimental.  This method is a way to denote that a local value is\n// serializable and should be immediately dispatched to a remote upon request,\n// instead of passing a reference.\nQ.passByCopy = function (object) {\n    //freeze(object);\n    //passByCopies.set(object, true);\n    return object;\n};\n\nPromise.prototype.passByCopy = function () {\n    //freeze(object);\n    //passByCopies.set(object, true);\n    return this;\n};\n\n/**\n * If two promises eventually fulfill to the same value, promises that value,\n * but otherwise rejects.\n * @param x {Any*}\n * @param y {Any*}\n * @returns {Any*} a promise for x and y if they are the same, but a rejection\n * otherwise.\n *\n */\nQ.join = function (x, y) {\n    return Q(x).join(y);\n};\n\nPromise.prototype.join = function (that) {\n    return Q([this, that]).spread(function (x, y) {\n        if (x === y) {\n            // TODO: \"===\" should be Object.is or equiv\n            return x;\n        } else {\n            throw new Error(\"Q can't join: not the same: \" + x + \" \" + y);\n        }\n    });\n};\n\n/**\n * Returns a promise for the first of an array of promises to become settled.\n * @param answers {Array[Any*]} promises to race\n * @returns {Any*} the first promise to be settled\n */\nQ.race = race;\nfunction race(answerPs) {\n    return promise(function (resolve, reject) {\n        // Switch to this once we can assume at least ES5\n        // answerPs.forEach(function (answerP) {\n        //     Q(answerP).then(resolve, reject);\n        // });\n        // Use this in the meantime\n        for (var i = 0, len = answerPs.length; i < len; i++) {\n            Q(answerPs[i]).then(resolve, reject);\n        }\n    });\n}\n\nPromise.prototype.race = function () {\n    return this.then(Q.race);\n};\n\n/**\n * Constructs a Promise with a promise descriptor object and optional fallback\n * function.  The descriptor contains methods like when(rejected), get(name),\n * set(name, value), post(name, args), and delete(name), which all\n * return either a value, a promise for a value, or a rejection.  The fallback\n * accepts the operation name, a resolver, and any further arguments that would\n * have been forwarded to the appropriate method above had a method been\n * provided with the proper name.  The API makes no guarantees about the nature\n * of the returned object, apart from that it is usable wherever promises are\n * bought and sold.\n */\nQ.makePromise = Promise;\nfunction Promise(descriptor, fallback, inspect) {\n    if (fallback === void 0) {\n        fallback = function (op) {\n            return reject(new Error(\n                \"Promise does not support operation: \" + op\n            ));\n        };\n    }\n    if (inspect === void 0) {\n        inspect = function () {\n            return {state: \"unknown\"};\n        };\n    }\n\n    var promise = object_create(Promise.prototype);\n\n    promise.promiseDispatch = function (resolve, op, args) {\n        var result;\n        try {\n            if (descriptor[op]) {\n                result = descriptor[op].apply(promise, args);\n            } else {\n                result = fallback.call(promise, op, args);\n            }\n        } catch (exception) {\n            result = reject(exception);\n        }\n        if (resolve) {\n            resolve(result);\n        }\n    };\n\n    promise.inspect = inspect;\n\n    // XXX deprecated `valueOf` and `exception` support\n    if (inspect) {\n        var inspected = inspect();\n        if (inspected.state === \"rejected\") {\n            promise.exception = inspected.reason;\n        }\n\n        promise.valueOf = function () {\n            var inspected = inspect();\n            if (inspected.state === \"pending\" ||\n                inspected.state === \"rejected\") {\n                return promise;\n            }\n            return inspected.value;\n        };\n    }\n\n    return promise;\n}\n\nPromise.prototype.toString = function () {\n    return \"[object Promise]\";\n};\n\nPromise.prototype.then = function (fulfilled, rejected, progressed) {\n    var self = this;\n    var deferred = defer();\n    var done = false;   // ensure the untrusted promise makes at most a\n                        // single call to one of the callbacks\n\n    function _fulfilled(value) {\n        try {\n            return typeof fulfilled === \"function\" ? fulfilled(value) : value;\n        } catch (exception) {\n            return reject(exception);\n        }\n    }\n\n    function _rejected(exception) {\n        if (typeof rejected === \"function\") {\n            makeStackTraceLong(exception, self);\n            try {\n                return rejected(exception);\n            } catch (newException) {\n                return reject(newException);\n            }\n        }\n        return reject(exception);\n    }\n\n    function _progressed(value) {\n        return typeof progressed === \"function\" ? progressed(value) : value;\n    }\n\n    Q.nextTick(function () {\n        self.promiseDispatch(function (value) {\n            if (done) {\n                return;\n            }\n            done = true;\n\n            deferred.resolve(_fulfilled(value));\n        }, \"when\", [function (exception) {\n            if (done) {\n                return;\n            }\n            done = true;\n\n            deferred.resolve(_rejected(exception));\n        }]);\n    });\n\n    // Progress propagator need to be attached in the current tick.\n    self.promiseDispatch(void 0, \"when\", [void 0, function (value) {\n        var newValue;\n        var threw = false;\n        try {\n            newValue = _progressed(value);\n        } catch (e) {\n            threw = true;\n            if (Q.onerror) {\n                Q.onerror(e);\n            } else {\n                throw e;\n            }\n        }\n\n        if (!threw) {\n            deferred.notify(newValue);\n        }\n    }]);\n\n    return deferred.promise;\n};\n\nQ.tap = function (promise, callback) {\n    return Q(promise).tap(callback);\n};\n\n/**\n * Works almost like \"finally\", but not called for rejections.\n * Original resolution value is passed through callback unaffected.\n * Callback may return a promise that will be awaited for.\n * @param {Function} callback\n * @returns {Q.Promise}\n * @example\n * doSomething()\n *   .then(...)\n *   .tap(console.log)\n *   .then(...);\n */\nPromise.prototype.tap = function (callback) {\n    callback = Q(callback);\n\n    return this.then(function (value) {\n        return callback.fcall(value).thenResolve(value);\n    });\n};\n\n/**\n * Registers an observer on a promise.\n *\n * Guarantees:\n *\n * 1. that fulfilled and rejected will be called only once.\n * 2. that either the fulfilled callback or the rejected callback will be\n *    called, but not both.\n * 3. that fulfilled and rejected will not be called in this turn.\n *\n * @param value      promise or immediate reference to observe\n * @param fulfilled  function to be called with the fulfilled value\n * @param rejected   function to be called with the rejection exception\n * @param progressed function to be called on any progress notifications\n * @return promise for the return value from the invoked callback\n */\nQ.when = when;\nfunction when(value, fulfilled, rejected, progressed) {\n    return Q(value).then(fulfilled, rejected, progressed);\n}\n\nPromise.prototype.thenResolve = function (value) {\n    return this.then(function () { return value; });\n};\n\nQ.thenResolve = function (promise, value) {\n    return Q(promise).thenResolve(value);\n};\n\nPromise.prototype.thenReject = function (reason) {\n    return this.then(function () { throw reason; });\n};\n\nQ.thenReject = function (promise, reason) {\n    return Q(promise).thenReject(reason);\n};\n\n/**\n * If an object is not a promise, it is as \"near\" as possible.\n * If a promise is rejected, it is as \"near\" as possible too.\n * If it’s a fulfilled promise, the fulfillment value is nearer.\n * If it’s a deferred promise and the deferred has been resolved, the\n * resolution is \"nearer\".\n * @param object\n * @returns most resolved (nearest) form of the object\n */\n\n// XXX should we re-do this?\nQ.nearer = nearer;\nfunction nearer(value) {\n    if (isPromise(value)) {\n        var inspected = value.inspect();\n        if (inspected.state === \"fulfilled\") {\n            return inspected.value;\n        }\n    }\n    return value;\n}\n\n/**\n * @returns whether the given object is a promise.\n * Otherwise it is a fulfilled value.\n */\nQ.isPromise = isPromise;\nfunction isPromise(object) {\n    return object instanceof Promise;\n}\n\nQ.isPromiseAlike = isPromiseAlike;\nfunction isPromiseAlike(object) {\n    return isObject(object) && typeof object.then === \"function\";\n}\n\n/**\n * @returns whether the given object is a pending promise, meaning not\n * fulfilled or rejected.\n */\nQ.isPending = isPending;\nfunction isPending(object) {\n    return isPromise(object) && object.inspect().state === \"pending\";\n}\n\nPromise.prototype.isPending = function () {\n    return this.inspect().state === \"pending\";\n};\n\n/**\n * @returns whether the given object is a value or fulfilled\n * promise.\n */\nQ.isFulfilled = isFulfilled;\nfunction isFulfilled(object) {\n    return !isPromise(object) || object.inspect().state === \"fulfilled\";\n}\n\nPromise.prototype.isFulfilled = function () {\n    return this.inspect().state === \"fulfilled\";\n};\n\n/**\n * @returns whether the given object is a rejected promise.\n */\nQ.isRejected = isRejected;\nfunction isRejected(object) {\n    return isPromise(object) && object.inspect().state === \"rejected\";\n}\n\nPromise.prototype.isRejected = function () {\n    return this.inspect().state === \"rejected\";\n};\n\n//// BEGIN UNHANDLED REJECTION TRACKING\n\n// This promise library consumes exceptions thrown in handlers so they can be\n// handled by a subsequent promise.  The exceptions get added to this array when\n// they are created, and removed when they are handled.  Note that in ES6 or\n// shimmed environments, this would naturally be a `Set`.\nvar unhandledReasons = [];\nvar unhandledRejections = [];\nvar reportedUnhandledRejections = [];\nvar trackUnhandledRejections = true;\n\nfunction resetUnhandledRejections() {\n    unhandledReasons.length = 0;\n    unhandledRejections.length = 0;\n\n    if (!trackUnhandledRejections) {\n        trackUnhandledRejections = true;\n    }\n}\n\nfunction trackRejection(promise, reason) {\n    if (!trackUnhandledRejections) {\n        return;\n    }\n    if (typeof process === \"object\" && typeof process.emit === \"function\") {\n        Q.nextTick.runAfter(function () {\n            if (array_indexOf(unhandledRejections, promise) !== -1) {\n                process.emit(\"unhandledRejection\", reason, promise);\n                reportedUnhandledRejections.push(promise);\n            }\n        });\n    }\n\n    unhandledRejections.push(promise);\n    if (reason && typeof reason.stack !== \"undefined\") {\n        unhandledReasons.push(reason.stack);\n    } else {\n        unhandledReasons.push(\"(no stack) \" + reason);\n    }\n}\n\nfunction untrackRejection(promise) {\n    if (!trackUnhandledRejections) {\n        return;\n    }\n\n    var at = array_indexOf(unhandledRejections, promise);\n    if (at !== -1) {\n        if (typeof process === \"object\" && typeof process.emit === \"function\") {\n            Q.nextTick.runAfter(function () {\n                var atReport = array_indexOf(reportedUnhandledRejections, promise);\n                if (atReport !== -1) {\n                    process.emit(\"rejectionHandled\", unhandledReasons[at], promise);\n                    reportedUnhandledRejections.splice(atReport, 1);\n                }\n            });\n        }\n        unhandledRejections.splice(at, 1);\n        unhandledReasons.splice(at, 1);\n    }\n}\n\nQ.resetUnhandledRejections = resetUnhandledRejections;\n\nQ.getUnhandledReasons = function () {\n    // Make a copy so that consumers can't interfere with our internal state.\n    return unhandledReasons.slice();\n};\n\nQ.stopUnhandledRejectionTracking = function () {\n    resetUnhandledRejections();\n    trackUnhandledRejections = false;\n};\n\nresetUnhandledRejections();\n\n//// END UNHANDLED REJECTION TRACKING\n\n/**\n * Constructs a rejected promise.\n * @param reason value describing the failure\n */\nQ.reject = reject;\nfunction reject(reason) {\n    var rejection = Promise({\n        \"when\": function (rejected) {\n            // note that the error has been handled\n            if (rejected) {\n                untrackRejection(this);\n            }\n            return rejected ? rejected(reason) : this;\n        }\n    }, function fallback() {\n        return this;\n    }, function inspect() {\n        return { state: \"rejected\", reason: reason };\n    });\n\n    // Note that the reason has not been handled.\n    trackRejection(rejection, reason);\n\n    return rejection;\n}\n\n/**\n * Constructs a fulfilled promise for an immediate reference.\n * @param value immediate reference\n */\nQ.fulfill = fulfill;\nfunction fulfill(value) {\n    return Promise({\n        \"when\": function () {\n            return value;\n        },\n        \"get\": function (name) {\n            return value[name];\n        },\n        \"set\": function (name, rhs) {\n            value[name] = rhs;\n        },\n        \"delete\": function (name) {\n            delete value[name];\n        },\n        \"post\": function (name, args) {\n            // Mark Miller proposes that post with no name should apply a\n            // promised function.\n            if (name === null || name === void 0) {\n                return value.apply(void 0, args);\n            } else {\n                return value[name].apply(value, args);\n            }\n        },\n        \"apply\": function (thisp, args) {\n            return value.apply(thisp, args);\n        },\n        \"keys\": function () {\n            return object_keys(value);\n        }\n    }, void 0, function inspect() {\n        return { state: \"fulfilled\", value: value };\n    });\n}\n\n/**\n * Converts thenables to Q promises.\n * @param promise thenable promise\n * @returns a Q promise\n */\nfunction coerce(promise) {\n    var deferred = defer();\n    Q.nextTick(function () {\n        try {\n            promise.then(deferred.resolve, deferred.reject, deferred.notify);\n        } catch (exception) {\n            deferred.reject(exception);\n        }\n    });\n    return deferred.promise;\n}\n\n/**\n * Annotates an object such that it will never be\n * transferred away from this process over any promise\n * communication channel.\n * @param object\n * @returns promise a wrapping of that object that\n * additionally responds to the \"isDef\" message\n * without a rejection.\n */\nQ.master = master;\nfunction master(object) {\n    return Promise({\n        \"isDef\": function () {}\n    }, function fallback(op, args) {\n        return dispatch(object, op, args);\n    }, function () {\n        return Q(object).inspect();\n    });\n}\n\n/**\n * Spreads the values of a promised array of arguments into the\n * fulfillment callback.\n * @param fulfilled callback that receives variadic arguments from the\n * promised array\n * @param rejected callback that receives the exception if the promise\n * is rejected.\n * @returns a promise for the return value or thrown exception of\n * either callback.\n */\nQ.spread = spread;\nfunction spread(value, fulfilled, rejected) {\n    return Q(value).spread(fulfilled, rejected);\n}\n\nPromise.prototype.spread = function (fulfilled, rejected) {\n    return this.all().then(function (array) {\n        return fulfilled.apply(void 0, array);\n    }, rejected);\n};\n\n/**\n * The async function is a decorator for generator functions, turning\n * them into asynchronous generators.  Although generators are only part\n * of the newest ECMAScript 6 drafts, this code does not cause syntax\n * errors in older engines.  This code should continue to work and will\n * in fact improve over time as the language improves.\n *\n * ES6 generators are currently part of V8 version 3.19 with the\n * --harmony-generators runtime flag enabled.  SpiderMonkey has had them\n * for longer, but under an older Python-inspired form.  This function\n * works on both kinds of generators.\n *\n * Decorates a generator function such that:\n *  - it may yield promises\n *  - execution will continue when that promise is fulfilled\n *  - the value of the yield expression will be the fulfilled value\n *  - it returns a promise for the return value (when the generator\n *    stops iterating)\n *  - the decorated function returns a promise for the return value\n *    of the generator or the first rejected promise among those\n *    yielded.\n *  - if an error is thrown in the generator, it propagates through\n *    every following yield until it is caught, or until it escapes\n *    the generator function altogether, and is translated into a\n *    rejection for the promise returned by the decorated generator.\n */\nQ.async = async;\nfunction async(makeGenerator) {\n    return function () {\n        // when verb is \"send\", arg is a value\n        // when verb is \"throw\", arg is an exception\n        function continuer(verb, arg) {\n            var result;\n\n            // Until V8 3.19 / Chromium 29 is released, SpiderMonkey is the only\n            // engine that has a deployed base of browsers that support generators.\n            // However, SM's generators use the Python-inspired semantics of\n            // outdated ES6 drafts.  We would like to support ES6, but we'd also\n            // like to make it possible to use generators in deployed browsers, so\n            // we also support Python-style generators.  At some point we can remove\n            // this block.\n\n            if (typeof StopIteration === \"undefined\") {\n                // ES6 Generators\n                try {\n                    result = generator[verb](arg);\n                } catch (exception) {\n                    return reject(exception);\n                }\n                if (result.done) {\n                    return Q(result.value);\n                } else {\n                    return when(result.value, callback, errback);\n                }\n            } else {\n                // SpiderMonkey Generators\n                // FIXME: Remove this case when SM does ES6 generators.\n                try {\n                    result = generator[verb](arg);\n                } catch (exception) {\n                    if (isStopIteration(exception)) {\n                        return Q(exception.value);\n                    } else {\n                        return reject(exception);\n                    }\n                }\n                return when(result, callback, errback);\n            }\n        }\n        var generator = makeGenerator.apply(this, arguments);\n        var callback = continuer.bind(continuer, \"next\");\n        var errback = continuer.bind(continuer, \"throw\");\n        return callback();\n    };\n}\n\n/**\n * The spawn function is a small wrapper around async that immediately\n * calls the generator and also ends the promise chain, so that any\n * unhandled errors are thrown instead of forwarded to the error\n * handler. This is useful because it's extremely common to run\n * generators at the top-level to work with libraries.\n */\nQ.spawn = spawn;\nfunction spawn(makeGenerator) {\n    Q.done(Q.async(makeGenerator)());\n}\n\n// FIXME: Remove this interface once ES6 generators are in SpiderMonkey.\n/**\n * Throws a ReturnValue exception to stop an asynchronous generator.\n *\n * This interface is a stop-gap measure to support generator return\n * values in older Firefox/SpiderMonkey.  In browsers that support ES6\n * generators like Chromium 29, just use \"return\" in your generator\n * functions.\n *\n * @param value the return value for the surrounding generator\n * @throws ReturnValue exception with the value.\n * @example\n * // ES6 style\n * Q.async(function* () {\n *      var foo = yield getFooPromise();\n *      var bar = yield getBarPromise();\n *      return foo + bar;\n * })\n * // Older SpiderMonkey style\n * Q.async(function () {\n *      var foo = yield getFooPromise();\n *      var bar = yield getBarPromise();\n *      Q.return(foo + bar);\n * })\n */\nQ[\"return\"] = _return;\nfunction _return(value) {\n    throw new QReturnValue(value);\n}\n\n/**\n * The promised function decorator ensures that any promise arguments\n * are settled and passed as values (`this` is also settled and passed\n * as a value).  It will also ensure that the result of a function is\n * always a promise.\n *\n * @example\n * var add = Q.promised(function (a, b) {\n *     return a + b;\n * });\n * add(Q(a), Q(B));\n *\n * @param {function} callback The function to decorate\n * @returns {function} a function that has been decorated.\n */\nQ.promised = promised;\nfunction promised(callback) {\n    return function () {\n        return spread([this, all(arguments)], function (self, args) {\n            return callback.apply(self, args);\n        });\n    };\n}\n\n/**\n * sends a message to a value in a future turn\n * @param object* the recipient\n * @param op the name of the message operation, e.g., \"when\",\n * @param args further arguments to be forwarded to the operation\n * @returns result {Promise} a promise for the result of the operation\n */\nQ.dispatch = dispatch;\nfunction dispatch(object, op, args) {\n    return Q(object).dispatch(op, args);\n}\n\nPromise.prototype.dispatch = function (op, args) {\n    var self = this;\n    var deferred = defer();\n    Q.nextTick(function () {\n        self.promiseDispatch(deferred.resolve, op, args);\n    });\n    return deferred.promise;\n};\n\n/**\n * Gets the value of a property in a future turn.\n * @param object    promise or immediate reference for target object\n * @param name      name of property to get\n * @return promise for the property value\n */\nQ.get = function (object, key) {\n    return Q(object).dispatch(\"get\", [key]);\n};\n\nPromise.prototype.get = function (key) {\n    return this.dispatch(\"get\", [key]);\n};\n\n/**\n * Sets the value of a property in a future turn.\n * @param object    promise or immediate reference for object object\n * @param name      name of property to set\n * @param value     new value of property\n * @return promise for the return value\n */\nQ.set = function (object, key, value) {\n    return Q(object).dispatch(\"set\", [key, value]);\n};\n\nPromise.prototype.set = function (key, value) {\n    return this.dispatch(\"set\", [key, value]);\n};\n\n/**\n * Deletes a property in a future turn.\n * @param object    promise or immediate reference for target object\n * @param name      name of property to delete\n * @return promise for the return value\n */\nQ.del = // XXX legacy\nQ[\"delete\"] = function (object, key) {\n    return Q(object).dispatch(\"delete\", [key]);\n};\n\nPromise.prototype.del = // XXX legacy\nPromise.prototype[\"delete\"] = function (key) {\n    return this.dispatch(\"delete\", [key]);\n};\n\n/**\n * Invokes a method in a future turn.\n * @param object    promise or immediate reference for target object\n * @param name      name of method to invoke\n * @param value     a value to post, typically an array of\n *                  invocation arguments for promises that\n *                  are ultimately backed with `resolve` values,\n *                  as opposed to those backed with URLs\n *                  wherein the posted value can be any\n *                  JSON serializable object.\n * @return promise for the return value\n */\n// bound locally because it is used by other methods\nQ.mapply = // XXX As proposed by \"Redsandro\"\nQ.post = function (object, name, args) {\n    return Q(object).dispatch(\"post\", [name, args]);\n};\n\nPromise.prototype.mapply = // XXX As proposed by \"Redsandro\"\nPromise.prototype.post = function (name, args) {\n    return this.dispatch(\"post\", [name, args]);\n};\n\n/**\n * Invokes a method in a future turn.\n * @param object    promise or immediate reference for target object\n * @param name      name of method to invoke\n * @param ...args   array of invocation arguments\n * @return promise for the return value\n */\nQ.send = // XXX Mark Miller's proposed parlance\nQ.mcall = // XXX As proposed by \"Redsandro\"\nQ.invoke = function (object, name /*...args*/) {\n    return Q(object).dispatch(\"post\", [name, array_slice(arguments, 2)]);\n};\n\nPromise.prototype.send = // XXX Mark Miller's proposed parlance\nPromise.prototype.mcall = // XXX As proposed by \"Redsandro\"\nPromise.prototype.invoke = function (name /*...args*/) {\n    return this.dispatch(\"post\", [name, array_slice(arguments, 1)]);\n};\n\n/**\n * Applies the promised function in a future turn.\n * @param object    promise or immediate reference for target function\n * @param args      array of application arguments\n */\nQ.fapply = function (object, args) {\n    return Q(object).dispatch(\"apply\", [void 0, args]);\n};\n\nPromise.prototype.fapply = function (args) {\n    return this.dispatch(\"apply\", [void 0, args]);\n};\n\n/**\n * Calls the promised function in a future turn.\n * @param object    promise or immediate reference for target function\n * @param ...args   array of application arguments\n */\nQ[\"try\"] =\nQ.fcall = function (object /* ...args*/) {\n    return Q(object).dispatch(\"apply\", [void 0, array_slice(arguments, 1)]);\n};\n\nPromise.prototype.fcall = function (/*...args*/) {\n    return this.dispatch(\"apply\", [void 0, array_slice(arguments)]);\n};\n\n/**\n * Binds the promised function, transforming return values into a fulfilled\n * promise and thrown errors into a rejected one.\n * @param object    promise or immediate reference for target function\n * @param ...args   array of application arguments\n */\nQ.fbind = function (object /*...args*/) {\n    var promise = Q(object);\n    var args = array_slice(arguments, 1);\n    return function fbound() {\n        return promise.dispatch(\"apply\", [\n            this,\n            args.concat(array_slice(arguments))\n        ]);\n    };\n};\nPromise.prototype.fbind = function (/*...args*/) {\n    var promise = this;\n    var args = array_slice(arguments);\n    return function fbound() {\n        return promise.dispatch(\"apply\", [\n            this,\n            args.concat(array_slice(arguments))\n        ]);\n    };\n};\n\n/**\n * Requests the names of the owned properties of a promised\n * object in a future turn.\n * @param object    promise or immediate reference for target object\n * @return promise for the keys of the eventually settled object\n */\nQ.keys = function (object) {\n    return Q(object).dispatch(\"keys\", []);\n};\n\nPromise.prototype.keys = function () {\n    return this.dispatch(\"keys\", []);\n};\n\n/**\n * Turns an array of promises into a promise for an array.  If any of\n * the promises gets rejected, the whole array is rejected immediately.\n * @param {Array*} an array (or promise for an array) of values (or\n * promises for values)\n * @returns a promise for an array of the corresponding values\n */\n// By Mark Miller\n// http://wiki.ecmascript.org/doku.php?id=strawman:concurrency&rev=1308776521#allfulfilled\nQ.all = all;\nfunction all(promises) {\n    return when(promises, function (promises) {\n        var pendingCount = 0;\n        var deferred = defer();\n        array_reduce(promises, function (undefined, promise, index) {\n            var snapshot;\n            if (\n                isPromise(promise) &&\n                (snapshot = promise.inspect()).state === \"fulfilled\"\n            ) {\n                promises[index] = snapshot.value;\n            } else {\n                ++pendingCount;\n                when(\n                    promise,\n                    function (value) {\n                        promises[index] = value;\n                        if (--pendingCount === 0) {\n                            deferred.resolve(promises);\n                        }\n                    },\n                    deferred.reject,\n                    function (progress) {\n                        deferred.notify({ index: index, value: progress });\n                    }\n                );\n            }\n        }, void 0);\n        if (pendingCount === 0) {\n            deferred.resolve(promises);\n        }\n        return deferred.promise;\n    });\n}\n\nPromise.prototype.all = function () {\n    return all(this);\n};\n\n/**\n * Returns the first resolved promise of an array. Prior rejected promises are\n * ignored.  Rejects only if all promises are rejected.\n * @param {Array*} an array containing values or promises for values\n * @returns a promise fulfilled with the value of the first resolved promise,\n * or a rejected promise if all promises are rejected.\n */\nQ.any = any;\n\nfunction any(promises) {\n    if (promises.length === 0) {\n        return Q.resolve();\n    }\n\n    var deferred = Q.defer();\n    var pendingCount = 0;\n    array_reduce(promises, function (prev, current, index) {\n        var promise = promises[index];\n\n        pendingCount++;\n\n        when(promise, onFulfilled, onRejected, onProgress);\n        function onFulfilled(result) {\n            deferred.resolve(result);\n        }\n        function onRejected(err) {\n            pendingCount--;\n            if (pendingCount === 0) {\n                var rejection = err || new Error(\"\" + err);\n\n                rejection.message = (\"Q can't get fulfillment value from any promise, all \" +\n                    \"promises were rejected. Last error message: \" + rejection.message);\n\n                deferred.reject(rejection);\n            }\n        }\n        function onProgress(progress) {\n            deferred.notify({\n                index: index,\n                value: progress\n            });\n        }\n    }, undefined);\n\n    return deferred.promise;\n}\n\nPromise.prototype.any = function () {\n    return any(this);\n};\n\n/**\n * Waits for all promises to be settled, either fulfilled or\n * rejected.  This is distinct from `all` since that would stop\n * waiting at the first rejection.  The promise returned by\n * `allResolved` will never be rejected.\n * @param promises a promise for an array (or an array) of promises\n * (or values)\n * @return a promise for an array of promises\n */\nQ.allResolved = deprecate(allResolved, \"allResolved\", \"allSettled\");\nfunction allResolved(promises) {\n    return when(promises, function (promises) {\n        promises = array_map(promises, Q);\n        return when(all(array_map(promises, function (promise) {\n            return when(promise, noop, noop);\n        })), function () {\n            return promises;\n        });\n    });\n}\n\nPromise.prototype.allResolved = function () {\n    return allResolved(this);\n};\n\n/**\n * @see Promise#allSettled\n */\nQ.allSettled = allSettled;\nfunction allSettled(promises) {\n    return Q(promises).allSettled();\n}\n\n/**\n * Turns an array of promises into a promise for an array of their states (as\n * returned by `inspect`) when they have all settled.\n * @param {Array[Any*]} values an array (or promise for an array) of values (or\n * promises for values)\n * @returns {Array[State]} an array of states for the respective values.\n */\nPromise.prototype.allSettled = function () {\n    return this.then(function (promises) {\n        return all(array_map(promises, function (promise) {\n            promise = Q(promise);\n            function regardless() {\n                return promise.inspect();\n            }\n            return promise.then(regardless, regardless);\n        }));\n    });\n};\n\n/**\n * Captures the failure of a promise, giving an oportunity to recover\n * with a callback.  If the given promise is fulfilled, the returned\n * promise is fulfilled.\n * @param {Any*} promise for something\n * @param {Function} callback to fulfill the returned promise if the\n * given promise is rejected\n * @returns a promise for the return value of the callback\n */\nQ.fail = // XXX legacy\nQ[\"catch\"] = function (object, rejected) {\n    return Q(object).then(void 0, rejected);\n};\n\nPromise.prototype.fail = // XXX legacy\nPromise.prototype[\"catch\"] = function (rejected) {\n    return this.then(void 0, rejected);\n};\n\n/**\n * Attaches a listener that can respond to progress notifications from a\n * promise's originating deferred. This listener receives the exact arguments\n * passed to ``deferred.notify``.\n * @param {Any*} promise for something\n * @param {Function} callback to receive any progress notifications\n * @returns the given promise, unchanged\n */\nQ.progress = progress;\nfunction progress(object, progressed) {\n    return Q(object).then(void 0, void 0, progressed);\n}\n\nPromise.prototype.progress = function (progressed) {\n    return this.then(void 0, void 0, progressed);\n};\n\n/**\n * Provides an opportunity to observe the settling of a promise,\n * regardless of whether the promise is fulfilled or rejected.  Forwards\n * the resolution to the returned promise when the callback is done.\n * The callback can return a promise to defer completion.\n * @param {Any*} promise\n * @param {Function} callback to observe the resolution of the given\n * promise, takes no arguments.\n * @returns a promise for the resolution of the given promise when\n * ``fin`` is done.\n */\nQ.fin = // XXX legacy\nQ[\"finally\"] = function (object, callback) {\n    return Q(object)[\"finally\"](callback);\n};\n\nPromise.prototype.fin = // XXX legacy\nPromise.prototype[\"finally\"] = function (callback) {\n    if (!callback || typeof callback.apply !== \"function\") {\n        throw new Error(\"Q can't apply finally callback\");\n    }\n    callback = Q(callback);\n    return this.then(function (value) {\n        return callback.fcall().then(function () {\n            return value;\n        });\n    }, function (reason) {\n        // TODO attempt to recycle the rejection with \"this\".\n        return callback.fcall().then(function () {\n            throw reason;\n        });\n    });\n};\n\n/**\n * Terminates a chain of promises, forcing rejections to be\n * thrown as exceptions.\n * @param {Any*} promise at the end of a chain of promises\n * @returns nothing\n */\nQ.done = function (object, fulfilled, rejected, progress) {\n    return Q(object).done(fulfilled, rejected, progress);\n};\n\nPromise.prototype.done = function (fulfilled, rejected, progress) {\n    var onUnhandledError = function (error) {\n        // forward to a future turn so that ``when``\n        // does not catch it and turn it into a rejection.\n        Q.nextTick(function () {\n            makeStackTraceLong(error, promise);\n            if (Q.onerror) {\n                Q.onerror(error);\n            } else {\n                throw error;\n            }\n        });\n    };\n\n    // Avoid unnecessary `nextTick`ing via an unnecessary `when`.\n    var promise = fulfilled || rejected || progress ?\n        this.then(fulfilled, rejected, progress) :\n        this;\n\n    if (typeof process === \"object\" && process && process.domain) {\n        onUnhandledError = process.domain.bind(onUnhandledError);\n    }\n\n    promise.then(void 0, onUnhandledError);\n};\n\n/**\n * Causes a promise to be rejected if it does not get fulfilled before\n * some milliseconds time out.\n * @param {Any*} promise\n * @param {Number} milliseconds timeout\n * @param {Any*} custom error message or Error object (optional)\n * @returns a promise for the resolution of the given promise if it is\n * fulfilled before the timeout, otherwise rejected.\n */\nQ.timeout = function (object, ms, error) {\n    return Q(object).timeout(ms, error);\n};\n\nPromise.prototype.timeout = function (ms, error) {\n    var deferred = defer();\n    var timeoutId = setTimeout(function () {\n        if (!error || \"string\" === typeof error) {\n            error = new Error(error || \"Timed out after \" + ms + \" ms\");\n            error.code = \"ETIMEDOUT\";\n        }\n        deferred.reject(error);\n    }, ms);\n\n    this.then(function (value) {\n        clearTimeout(timeoutId);\n        deferred.resolve(value);\n    }, function (exception) {\n        clearTimeout(timeoutId);\n        deferred.reject(exception);\n    }, deferred.notify);\n\n    return deferred.promise;\n};\n\n/**\n * Returns a promise for the given value (or promised value), some\n * milliseconds after it resolved. Passes rejections immediately.\n * @param {Any*} promise\n * @param {Number} milliseconds\n * @returns a promise for the resolution of the given promise after milliseconds\n * time has elapsed since the resolution of the given promise.\n * If the given promise rejects, that is passed immediately.\n */\nQ.delay = function (object, timeout) {\n    if (timeout === void 0) {\n        timeout = object;\n        object = void 0;\n    }\n    return Q(object).delay(timeout);\n};\n\nPromise.prototype.delay = function (timeout) {\n    return this.then(function (value) {\n        var deferred = defer();\n        setTimeout(function () {\n            deferred.resolve(value);\n        }, timeout);\n        return deferred.promise;\n    });\n};\n\n/**\n * Passes a continuation to a Node function, which is called with the given\n * arguments provided as an array, and returns a promise.\n *\n *      Q.nfapply(FS.readFile, [__filename])\n *      .then(function (content) {\n *      })\n *\n */\nQ.nfapply = function (callback, args) {\n    return Q(callback).nfapply(args);\n};\n\nPromise.prototype.nfapply = function (args) {\n    var deferred = defer();\n    var nodeArgs = array_slice(args);\n    nodeArgs.push(deferred.makeNodeResolver());\n    this.fapply(nodeArgs).fail(deferred.reject);\n    return deferred.promise;\n};\n\n/**\n * Passes a continuation to a Node function, which is called with the given\n * arguments provided individually, and returns a promise.\n * @example\n * Q.nfcall(FS.readFile, __filename)\n * .then(function (content) {\n * })\n *\n */\nQ.nfcall = function (callback /*...args*/) {\n    var args = array_slice(arguments, 1);\n    return Q(callback).nfapply(args);\n};\n\nPromise.prototype.nfcall = function (/*...args*/) {\n    var nodeArgs = array_slice(arguments);\n    var deferred = defer();\n    nodeArgs.push(deferred.makeNodeResolver());\n    this.fapply(nodeArgs).fail(deferred.reject);\n    return deferred.promise;\n};\n\n/**\n * Wraps a NodeJS continuation passing function and returns an equivalent\n * version that returns a promise.\n * @example\n * Q.nfbind(FS.readFile, __filename)(\"utf-8\")\n * .then(console.log)\n * .done()\n */\nQ.nfbind =\nQ.denodeify = function (callback /*...args*/) {\n    if (callback === undefined) {\n        throw new Error(\"Q can't wrap an undefined function\");\n    }\n    var baseArgs = array_slice(arguments, 1);\n    return function () {\n        var nodeArgs = baseArgs.concat(array_slice(arguments));\n        var deferred = defer();\n        nodeArgs.push(deferred.makeNodeResolver());\n        Q(callback).fapply(nodeArgs).fail(deferred.reject);\n        return deferred.promise;\n    };\n};\n\nPromise.prototype.nfbind =\nPromise.prototype.denodeify = function (/*...args*/) {\n    var args = array_slice(arguments);\n    args.unshift(this);\n    return Q.denodeify.apply(void 0, args);\n};\n\nQ.nbind = function (callback, thisp /*...args*/) {\n    var baseArgs = array_slice(arguments, 2);\n    return function () {\n        var nodeArgs = baseArgs.concat(array_slice(arguments));\n        var deferred = defer();\n        nodeArgs.push(deferred.makeNodeResolver());\n        function bound() {\n            return callback.apply(thisp, arguments);\n        }\n        Q(bound).fapply(nodeArgs).fail(deferred.reject);\n        return deferred.promise;\n    };\n};\n\nPromise.prototype.nbind = function (/*thisp, ...args*/) {\n    var args = array_slice(arguments, 0);\n    args.unshift(this);\n    return Q.nbind.apply(void 0, args);\n};\n\n/**\n * Calls a method of a Node-style object that accepts a Node-style\n * callback with a given array of arguments, plus a provided callback.\n * @param object an object that has the named method\n * @param {String} name name of the method of object\n * @param {Array} args arguments to pass to the method; the callback\n * will be provided by Q and appended to these arguments.\n * @returns a promise for the value or error\n */\nQ.nmapply = // XXX As proposed by \"Redsandro\"\nQ.npost = function (object, name, args) {\n    return Q(object).npost(name, args);\n};\n\nPromise.prototype.nmapply = // XXX As proposed by \"Redsandro\"\nPromise.prototype.npost = function (name, args) {\n    var nodeArgs = array_slice(args || []);\n    var deferred = defer();\n    nodeArgs.push(deferred.makeNodeResolver());\n    this.dispatch(\"post\", [name, nodeArgs]).fail(deferred.reject);\n    return deferred.promise;\n};\n\n/**\n * Calls a method of a Node-style object that accepts a Node-style\n * callback, forwarding the given variadic arguments, plus a provided\n * callback argument.\n * @param object an object that has the named method\n * @param {String} name name of the method of object\n * @param ...args arguments to pass to the method; the callback will\n * be provided by Q and appended to these arguments.\n * @returns a promise for the value or error\n */\nQ.nsend = // XXX Based on Mark Miller's proposed \"send\"\nQ.nmcall = // XXX Based on \"Redsandro's\" proposal\nQ.ninvoke = function (object, name /*...args*/) {\n    var nodeArgs = array_slice(arguments, 2);\n    var deferred = defer();\n    nodeArgs.push(deferred.makeNodeResolver());\n    Q(object).dispatch(\"post\", [name, nodeArgs]).fail(deferred.reject);\n    return deferred.promise;\n};\n\nPromise.prototype.nsend = // XXX Based on Mark Miller's proposed \"send\"\nPromise.prototype.nmcall = // XXX Based on \"Redsandro's\" proposal\nPromise.prototype.ninvoke = function (name /*...args*/) {\n    var nodeArgs = array_slice(arguments, 1);\n    var deferred = defer();\n    nodeArgs.push(deferred.makeNodeResolver());\n    this.dispatch(\"post\", [name, nodeArgs]).fail(deferred.reject);\n    return deferred.promise;\n};\n\n/**\n * If a function would like to support both Node continuation-passing-style and\n * promise-returning-style, it can end its internal promise chain with\n * `nodeify(nodeback)`, forwarding the optional nodeback argument.  If the user\n * elects to use a nodeback, the result will be sent there.  If they do not\n * pass a nodeback, they will receive the result promise.\n * @param object a result (or a promise for a result)\n * @param {Function} nodeback a Node.js-style callback\n * @returns either the promise or nothing\n */\nQ.nodeify = nodeify;\nfunction nodeify(object, nodeback) {\n    return Q(object).nodeify(nodeback);\n}\n\nPromise.prototype.nodeify = function (nodeback) {\n    if (nodeback) {\n        this.then(function (value) {\n            Q.nextTick(function () {\n                nodeback(null, value);\n            });\n        }, function (error) {\n            Q.nextTick(function () {\n                nodeback(error);\n            });\n        });\n    } else {\n        return this;\n    }\n};\n\nQ.noConflict = function() {\n    throw new Error(\"Q.noConflict only works when Q is used as a global\");\n};\n\n// All code before this point will be filtered from stack traces.\nvar qEndingLine = captureLine();\n\nreturn Q;\n\n});\n"
  },
  {
    "path": "queue.js",
    "content": "\nvar Q = require(\"./q\");\n\nmodule.exports = Queue;\nfunction Queue() {\n    var ends = Q.defer();\n    var closed = Q.defer();\n    return {\n        put: function (value) {\n            var next = Q.defer();\n            ends.resolve({\n                head: value,\n                tail: next.promise\n            });\n            ends.resolve = next.resolve;\n        },\n        get: function () {\n            var result = ends.promise.get(\"head\");\n            ends.promise = ends.promise.get(\"tail\");\n            return result.fail(function (error) {\n                closed.resolve(error);\n                throw error;\n            });\n        },\n        closed: closed.promise,\n        close: function (error) {\n            error = error || new Error(\"Can't get value from closed queue\");\n            var end = {head: Q.reject(error)};\n            end.tail = end;\n            ends.resolve(end);\n            return closed.promise;\n        }\n    };\n}\n\n"
  },
  {
    "path": "ref_send.md",
    "content": "\nThis API varies from Tyler Closes ref_send in the\nfollowing ways:\n\n*   Promises can be resolved to function values.\n*   Promises can be resolved to null or undefined.\n*   Promises are distinguishable from arbitrary functions.\n*   The promise API is abstracted with a Promise constructor\n    that accepts a descriptor that receives all of the\n    messages forwarded to that promise and handles the\n    common patterns for message receivers.  The promise\n    constructor also takes optional fallback and valueOf\n    methods which handle the cases for missing handlers on\n    the descriptor (rejection by default) and the valueOf\n    call (which returns the promise itself by default)\n*   near(ref) has been changed to Promise.valueOf() in\n    keeping with JavaScript's existing Object.valueOf().\n*   post(promise, name, args) has been altered to a variadic\n    post(promise, name ...args)\n*   variadic arguments are used internally where\n    applicable. However, I have not altered the Q.post()\n    API to expand variadic arguments since Tyler Close\n    informed the CommonJS list that it would restrict\n    usage patterns for web_send, posting arbitrary JSON\n    objects as the \"arguments\" over HTTP.\n\n"
  },
  {
    "path": "spec/aplus-adapter.js",
    "content": "\"use strict\";\n\nvar Q = require(\"../q\");\n\nexports.fulfilled = Q.resolve;\nexports.rejected = Q.reject;\nexports.pending = function () {\n    var deferred = Q.defer();\n\n    return {\n        promise: deferred.promise,\n        fulfill: deferred.resolve,\n        reject: deferred.reject\n    };\n};\n"
  },
  {
    "path": "spec/lib/jasmine-1.2.0/MIT.LICENSE",
    "content": "Copyright (c) 2008-2011 Pivotal Labs\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "spec/lib/jasmine-1.2.0/jasmine-html.js",
    "content": "jasmine.HtmlReporterHelpers = {};\n\njasmine.HtmlReporterHelpers.createDom = function(type, attrs, childrenVarArgs) {\n  var el = document.createElement(type);\n\n  for (var i = 2; i < arguments.length; i++) {\n    var child = arguments[i];\n\n    if (typeof child === 'string') {\n      el.appendChild(document.createTextNode(child));\n    } else {\n      if (child) {\n        el.appendChild(child);\n      }\n    }\n  }\n\n  for (var attr in attrs) {\n    if (attr == \"className\") {\n      el[attr] = attrs[attr];\n    } else {\n      el.setAttribute(attr, attrs[attr]);\n    }\n  }\n\n  return el;\n};\n\njasmine.HtmlReporterHelpers.getSpecStatus = function(child) {\n  var results = child.results();\n  var status = results.passed() ? 'passed' : 'failed';\n  if (results.skipped) {\n    status = 'skipped';\n  }\n\n  return status;\n};\n\njasmine.HtmlReporterHelpers.appendToSummary = function(child, childElement) {\n  var parentDiv = this.dom.summary;\n  var parentSuite = (typeof child.parentSuite == 'undefined') ? 'suite' : 'parentSuite';\n  var parent = child[parentSuite];\n\n  if (parent) {\n    if (typeof this.views.suites[parent.id] == 'undefined') {\n      this.views.suites[parent.id] = new jasmine.HtmlReporter.SuiteView(parent, this.dom, this.views);\n    }\n    parentDiv = this.views.suites[parent.id].element;\n  }\n\n  parentDiv.appendChild(childElement);\n};\n\n\njasmine.HtmlReporterHelpers.addHelpers = function(ctor) {\n  for(var fn in jasmine.HtmlReporterHelpers) {\n    ctor.prototype[fn] = jasmine.HtmlReporterHelpers[fn];\n  }\n};\n\njasmine.HtmlReporter = function(_doc) {\n  var self = this;\n  var doc = _doc || window.document;\n\n  var reporterView;\n\n  var dom = {};\n\n  // Jasmine Reporter Public Interface\n  self.logRunningSpecs = false;\n\n  self.reportRunnerStarting = function(runner) {\n    var specs = runner.specs() || [];\n\n    if (specs.length == 0) {\n      return;\n    }\n\n    createReporterDom(runner.env.versionString());\n    doc.body.appendChild(dom.reporter);\n\n    reporterView = new jasmine.HtmlReporter.ReporterView(dom);\n    reporterView.addSpecs(specs, self.specFilter);\n  };\n\n  self.reportRunnerResults = function(runner) {\n    reporterView && reporterView.complete();\n  };\n\n  self.reportSuiteResults = function(suite) {\n    reporterView.suiteComplete(suite);\n  };\n\n  self.reportSpecStarting = function(spec) {\n    if (self.logRunningSpecs) {\n      self.log('>> Jasmine Running ' + spec.suite.description + ' ' + spec.description + '...');\n    }\n  };\n\n  self.reportSpecResults = function(spec) {\n    reporterView.specComplete(spec);\n  };\n\n  self.log = function() {\n    var console = jasmine.getGlobal().console;\n    if (console && console.log) {\n      if (console.log.apply) {\n        console.log.apply(console, arguments);\n      } else {\n        console.log(arguments); // ie fix: console.log.apply doesn't exist on ie\n      }\n    }\n  };\n\n  self.specFilter = function(spec) {\n    if (!focusedSpecName()) {\n      return true;\n    }\n\n    return spec.getFullName().indexOf(focusedSpecName()) === 0;\n  };\n\n  return self;\n\n  function focusedSpecName() {\n    var specName;\n\n    (function memoizeFocusedSpec() {\n      if (specName) {\n        return;\n      }\n\n      var paramMap = [];\n      var params = doc.location.search.substring(1).split('&');\n\n      for (var i = 0; i < params.length; i++) {\n        var p = params[i].split('=');\n        paramMap[decodeURIComponent(p[0])] = decodeURIComponent(p[1]);\n      }\n\n      specName = paramMap.spec;\n    })();\n\n    return specName;\n  }\n\n  function createReporterDom(version) {\n    dom.reporter = self.createDom('div', { id: 'HTMLReporter', className: 'jasmine_reporter' },\n      dom.banner = self.createDom('div', { className: 'banner' },\n        self.createDom('span', { className: 'title' }, \"Jasmine \"),\n        self.createDom('span', { className: 'version' }, version)),\n\n      dom.symbolSummary = self.createDom('ul', {className: 'symbolSummary'}),\n      dom.alert = self.createDom('div', {className: 'alert'}),\n      dom.results = self.createDom('div', {className: 'results'},\n        dom.summary = self.createDom('div', { className: 'summary' }),\n        dom.details = self.createDom('div', { id: 'details' }))\n    );\n  }\n};\njasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter);jasmine.HtmlReporter.ReporterView = function(dom) {\n  this.startedAt = new Date();\n  this.runningSpecCount = 0;\n  this.completeSpecCount = 0;\n  this.passedCount = 0;\n  this.failedCount = 0;\n  this.skippedCount = 0;\n\n  this.createResultsMenu = function() {\n    this.resultsMenu = this.createDom('span', {className: 'resultsMenu bar'},\n      this.summaryMenuItem = this.createDom('a', {className: 'summaryMenuItem', href: \"#\"}, '0 specs'),\n      ' | ',\n      this.detailsMenuItem = this.createDom('a', {className: 'detailsMenuItem', href: \"#\"}, '0 failing'));\n\n    this.summaryMenuItem.onclick = function() {\n      dom.reporter.className = dom.reporter.className.replace(/ showDetails/g, '');\n    };\n\n    this.detailsMenuItem.onclick = function() {\n      showDetails();\n    };\n  };\n\n  this.addSpecs = function(specs, specFilter) {\n    this.totalSpecCount = specs.length;\n\n    this.views = {\n      specs: {},\n      suites: {}\n    };\n\n    for (var i = 0; i < specs.length; i++) {\n      var spec = specs[i];\n      this.views.specs[spec.id] = new jasmine.HtmlReporter.SpecView(spec, dom, this.views);\n      if (specFilter(spec)) {\n        this.runningSpecCount++;\n      }\n    }\n  };\n\n  this.specComplete = function(spec) {\n    this.completeSpecCount++;\n\n    if (isUndefined(this.views.specs[spec.id])) {\n      this.views.specs[spec.id] = new jasmine.HtmlReporter.SpecView(spec, dom);\n    }\n\n    var specView = this.views.specs[spec.id];\n\n    switch (specView.status()) {\n      case 'passed':\n        this.passedCount++;\n        break;\n\n      case 'failed':\n        this.failedCount++;\n        break;\n\n      case 'skipped':\n        this.skippedCount++;\n        break;\n    }\n\n    specView.refresh();\n    this.refresh();\n  };\n\n  this.suiteComplete = function(suite) {\n    var suiteView = this.views.suites[suite.id];\n    if (isUndefined(suiteView)) {\n      return;\n    }\n    suiteView.refresh();\n  };\n\n  this.refresh = function() {\n\n    if (isUndefined(this.resultsMenu)) {\n      this.createResultsMenu();\n    }\n\n    // currently running UI\n    if (isUndefined(this.runningAlert)) {\n      this.runningAlert = this.createDom('a', {href: \"?\", className: \"runningAlert bar\"});\n      dom.alert.appendChild(this.runningAlert);\n    }\n    this.runningAlert.innerHTML = \"Running \" + this.completeSpecCount + \" of \" + specPluralizedFor(this.totalSpecCount);\n\n    // skipped specs UI\n    if (isUndefined(this.skippedAlert)) {\n      this.skippedAlert = this.createDom('a', {href: \"?\", className: \"skippedAlert bar\"});\n    }\n\n    this.skippedAlert.innerHTML = \"Skipping \" + this.skippedCount + \" of \" + specPluralizedFor(this.totalSpecCount) + \" - run all\";\n\n    if (this.skippedCount === 1 && isDefined(dom.alert)) {\n      dom.alert.appendChild(this.skippedAlert);\n    }\n\n    // passing specs UI\n    if (isUndefined(this.passedAlert)) {\n      this.passedAlert = this.createDom('span', {href: \"?\", className: \"passingAlert bar\"});\n    }\n    this.passedAlert.innerHTML = \"Passing \" + specPluralizedFor(this.passedCount);\n\n    // failing specs UI\n    if (isUndefined(this.failedAlert)) {\n      this.failedAlert = this.createDom('span', {href: \"?\", className: \"failingAlert bar\"});\n    }\n    this.failedAlert.innerHTML = \"Failing \" + specPluralizedFor(this.failedCount);\n\n    if (this.failedCount === 1 && isDefined(dom.alert)) {\n      dom.alert.appendChild(this.failedAlert);\n      dom.alert.appendChild(this.resultsMenu);\n    }\n\n    // summary info\n    this.summaryMenuItem.innerHTML = \"\" + specPluralizedFor(this.runningSpecCount);\n    this.detailsMenuItem.innerHTML = \"\" + this.failedCount + \" failing\";\n  };\n\n  this.complete = function() {\n    dom.alert.removeChild(this.runningAlert);\n\n    this.skippedAlert.innerHTML = \"Ran \" + this.runningSpecCount + \" of \" + specPluralizedFor(this.totalSpecCount) + \" - run all\";\n\n    if (this.failedCount === 0) {\n      dom.alert.appendChild(this.createDom('span', {className: 'passingAlert bar'}, \"Passing \" + specPluralizedFor(this.passedCount)));\n    } else {\n      showDetails();\n    }\n\n    dom.banner.appendChild(this.createDom('span', {className: 'duration'}, \"finished in \" + ((new Date().getTime() - this.startedAt.getTime()) / 1000) + \"s\"));\n  };\n\n  return this;\n\n  function showDetails() {\n    if (dom.reporter.className.search(/showDetails/) === -1) {\n      dom.reporter.className += \" showDetails\";\n    }\n  }\n\n  function isUndefined(obj) {\n    return typeof obj === 'undefined';\n  }\n\n  function isDefined(obj) {\n    return !isUndefined(obj);\n  }\n\n  function specPluralizedFor(count) {\n    var str = count + \" spec\";\n    if (count > 1) {\n      str += \"s\"\n    }\n    return str;\n  }\n\n};\n\njasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter.ReporterView);\n\n\njasmine.HtmlReporter.SpecView = function(spec, dom, views) {\n  this.spec = spec;\n  this.dom = dom;\n  this.views = views;\n\n  this.symbol = this.createDom('li', { className: 'pending' });\n  this.dom.symbolSummary.appendChild(this.symbol);\n\n  this.summary = this.createDom('div', { className: 'specSummary' },\n      this.createDom('a', {\n        className: 'description',\n        href: '?spec=' + encodeURIComponent(this.spec.getFullName()),\n        title: this.spec.getFullName()\n      }, this.spec.description)\n  );\n\n  this.detail = this.createDom('div', { className: 'specDetail' },\n      this.createDom('a', {\n        className: 'description',\n        href: '?spec=' + encodeURIComponent(this.spec.getFullName()),\n        title: this.spec.getFullName()\n      }, this.spec.getFullName())\n  );\n};\n\njasmine.HtmlReporter.SpecView.prototype.status = function() {\n  return this.getSpecStatus(this.spec);\n};\n\njasmine.HtmlReporter.SpecView.prototype.refresh = function() {\n  this.symbol.className = this.status();\n\n  switch (this.status()) {\n    case 'skipped':\n      break;\n\n    case 'passed':\n      this.appendSummaryToSuiteDiv();\n      break;\n\n    case 'failed':\n      this.appendSummaryToSuiteDiv();\n      this.appendFailureDetail();\n      break;\n  }\n};\n\njasmine.HtmlReporter.SpecView.prototype.appendSummaryToSuiteDiv = function() {\n  this.summary.className += ' ' + this.status();\n  this.appendToSummary(this.spec, this.summary);\n};\n\njasmine.HtmlReporter.SpecView.prototype.appendFailureDetail = function() {\n  this.detail.className += ' ' + this.status();\n\n  var resultItems = this.spec.results().getItems();\n  var messagesDiv = this.createDom('div', { className: 'messages' });\n\n  for (var i = 0; i < resultItems.length; i++) {\n    var result = resultItems[i];\n\n    if (result.type == 'log') {\n      messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage log'}, result.toString()));\n    } else if (result.type == 'expect' && result.passed && !result.passed()) {\n      messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage fail'}, result.message));\n\n      if (result.trace.stack) {\n        messagesDiv.appendChild(this.createDom('div', {className: 'stackTrace'}, result.trace.stack));\n      }\n    }\n  }\n\n  if (messagesDiv.childNodes.length > 0) {\n    this.detail.appendChild(messagesDiv);\n    this.dom.details.appendChild(this.detail);\n  }\n};\n\njasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter.SpecView);jasmine.HtmlReporter.SuiteView = function(suite, dom, views) {\n  this.suite = suite;\n  this.dom = dom;\n  this.views = views;\n\n  this.element = this.createDom('div', { className: 'suite' },\n      this.createDom('a', { className: 'description', href: '?spec=' + encodeURIComponent(this.suite.getFullName()) }, this.suite.description)\n  );\n\n  this.appendToSummary(this.suite, this.element);\n};\n\njasmine.HtmlReporter.SuiteView.prototype.status = function() {\n  return this.getSpecStatus(this.suite);\n};\n\njasmine.HtmlReporter.SuiteView.prototype.refresh = function() {\n  this.element.className += \" \" + this.status();\n};\n\njasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter.SuiteView);\n\n/* @deprecated Use jasmine.HtmlReporter instead\n */\njasmine.TrivialReporter = function(doc) {\n  this.document = doc || document;\n  this.suiteDivs = {};\n  this.logRunningSpecs = false;\n};\n\njasmine.TrivialReporter.prototype.createDom = function(type, attrs, childrenVarArgs) {\n  var el = document.createElement(type);\n\n  for (var i = 2; i < arguments.length; i++) {\n    var child = arguments[i];\n\n    if (typeof child === 'string') {\n      el.appendChild(document.createTextNode(child));\n    } else {\n      if (child) { el.appendChild(child); }\n    }\n  }\n\n  for (var attr in attrs) {\n    if (attr == \"className\") {\n      el[attr] = attrs[attr];\n    } else {\n      el.setAttribute(attr, attrs[attr]);\n    }\n  }\n\n  return el;\n};\n\njasmine.TrivialReporter.prototype.reportRunnerStarting = function(runner) {\n  var showPassed, showSkipped;\n\n  this.outerDiv = this.createDom('div', { id: 'TrivialReporter', className: 'jasmine_reporter' },\n      this.createDom('div', { className: 'banner' },\n        this.createDom('div', { className: 'logo' },\n            this.createDom('span', { className: 'title' }, \"Jasmine\"),\n            this.createDom('span', { className: 'version' }, runner.env.versionString())),\n        this.createDom('div', { className: 'options' },\n            \"Show \",\n            showPassed = this.createDom('input', { id: \"__jasmine_TrivialReporter_showPassed__\", type: 'checkbox' }),\n            this.createDom('label', { \"for\": \"__jasmine_TrivialReporter_showPassed__\" }, \" passed \"),\n            showSkipped = this.createDom('input', { id: \"__jasmine_TrivialReporter_showSkipped__\", type: 'checkbox' }),\n            this.createDom('label', { \"for\": \"__jasmine_TrivialReporter_showSkipped__\" }, \" skipped\")\n            )\n          ),\n\n      this.runnerDiv = this.createDom('div', { className: 'runner running' },\n          this.createDom('a', { className: 'run_spec', href: '?' }, \"run all\"),\n          this.runnerMessageSpan = this.createDom('span', {}, \"Running...\"),\n          this.finishedAtSpan = this.createDom('span', { className: 'finished-at' }, \"\"))\n      );\n\n  this.document.body.appendChild(this.outerDiv);\n\n  var suites = runner.suites();\n  for (var i = 0; i < suites.length; i++) {\n    var suite = suites[i];\n    var suiteDiv = this.createDom('div', { className: 'suite' },\n        this.createDom('a', { className: 'run_spec', href: '?spec=' + encodeURIComponent(suite.getFullName()) }, \"run\"),\n        this.createDom('a', { className: 'description', href: '?spec=' + encodeURIComponent(suite.getFullName()) }, suite.description));\n    this.suiteDivs[suite.id] = suiteDiv;\n    var parentDiv = this.outerDiv;\n    if (suite.parentSuite) {\n      parentDiv = this.suiteDivs[suite.parentSuite.id];\n    }\n    parentDiv.appendChild(suiteDiv);\n  }\n\n  this.startedAt = new Date();\n\n  var self = this;\n  showPassed.onclick = function(evt) {\n    if (showPassed.checked) {\n      self.outerDiv.className += ' show-passed';\n    } else {\n      self.outerDiv.className = self.outerDiv.className.replace(/ show-passed/, '');\n    }\n  };\n\n  showSkipped.onclick = function(evt) {\n    if (showSkipped.checked) {\n      self.outerDiv.className += ' show-skipped';\n    } else {\n      self.outerDiv.className = self.outerDiv.className.replace(/ show-skipped/, '');\n    }\n  };\n};\n\njasmine.TrivialReporter.prototype.reportRunnerResults = function(runner) {\n  var results = runner.results();\n  var className = (results.failedCount > 0) ? \"runner failed\" : \"runner passed\";\n  this.runnerDiv.setAttribute(\"class\", className);\n  //do it twice for IE\n  this.runnerDiv.setAttribute(\"className\", className);\n  var specs = runner.specs();\n  var specCount = 0;\n  for (var i = 0; i < specs.length; i++) {\n    if (this.specFilter(specs[i])) {\n      specCount++;\n    }\n  }\n  var message = \"\" + specCount + \" spec\" + (specCount == 1 ? \"\" : \"s\" ) + \", \" + results.failedCount + \" failure\" + ((results.failedCount == 1) ? \"\" : \"s\");\n  message += \" in \" + ((new Date().getTime() - this.startedAt.getTime()) / 1000) + \"s\";\n  this.runnerMessageSpan.replaceChild(this.createDom('a', { className: 'description', href: '?'}, message), this.runnerMessageSpan.firstChild);\n\n  this.finishedAtSpan.appendChild(document.createTextNode(\"Finished at \" + new Date().toString()));\n};\n\njasmine.TrivialReporter.prototype.reportSuiteResults = function(suite) {\n  var results = suite.results();\n  var status = results.passed() ? 'passed' : 'failed';\n  if (results.totalCount === 0) { // todo: change this to check results.skipped\n    status = 'skipped';\n  }\n  this.suiteDivs[suite.id].className += \" \" + status;\n};\n\njasmine.TrivialReporter.prototype.reportSpecStarting = function(spec) {\n  if (this.logRunningSpecs) {\n    this.log('>> Jasmine Running ' + spec.suite.description + ' ' + spec.description + '...');\n  }\n};\n\njasmine.TrivialReporter.prototype.reportSpecResults = function(spec) {\n  var results = spec.results();\n  var status = results.passed() ? 'passed' : 'failed';\n  if (results.skipped) {\n    status = 'skipped';\n  }\n  var specDiv = this.createDom('div', { className: 'spec '  + status },\n      this.createDom('a', { className: 'run_spec', href: '?spec=' + encodeURIComponent(spec.getFullName()) }, \"run\"),\n      this.createDom('a', {\n        className: 'description',\n        href: '?spec=' + encodeURIComponent(spec.getFullName()),\n        title: spec.getFullName()\n      }, spec.description));\n\n\n  var resultItems = results.getItems();\n  var messagesDiv = this.createDom('div', { className: 'messages' });\n  for (var i = 0; i < resultItems.length; i++) {\n    var result = resultItems[i];\n\n    if (result.type == 'log') {\n      messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage log'}, result.toString()));\n    } else if (result.type == 'expect' && result.passed && !result.passed()) {\n      messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage fail'}, result.message));\n\n      if (result.trace.stack) {\n        messagesDiv.appendChild(this.createDom('div', {className: 'stackTrace'}, result.trace.stack));\n      }\n    }\n  }\n\n  if (messagesDiv.childNodes.length > 0) {\n    specDiv.appendChild(messagesDiv);\n  }\n\n  this.suiteDivs[spec.suite.id].appendChild(specDiv);\n};\n\njasmine.TrivialReporter.prototype.log = function() {\n  var console = jasmine.getGlobal().console;\n  if (console && console.log) {\n    if (console.log.apply) {\n      console.log.apply(console, arguments);\n    } else {\n      console.log(arguments); // ie fix: console.log.apply doesn't exist on ie\n    }\n  }\n};\n\njasmine.TrivialReporter.prototype.getLocation = function() {\n  return this.document.location;\n};\n\njasmine.TrivialReporter.prototype.specFilter = function(spec) {\n  var paramMap = {};\n  var params = this.getLocation().search.substring(1).split('&');\n  for (var i = 0; i < params.length; i++) {\n    var p = params[i].split('=');\n    paramMap[decodeURIComponent(p[0])] = decodeURIComponent(p[1]);\n  }\n\n  if (!paramMap.spec) {\n    return true;\n  }\n  return spec.getFullName().indexOf(paramMap.spec) === 0;\n};\n"
  },
  {
    "path": "spec/lib/jasmine-1.2.0/jasmine.css",
    "content": "body { background-color: #eeeeee; padding: 0; margin: 5px; overflow-y: scroll; }\n\n#HTMLReporter { font-size: 11px; font-family: Monaco, \"Lucida Console\", monospace; line-height: 14px; color: #333333; }\n#HTMLReporter a { text-decoration: none; }\n#HTMLReporter a:hover { text-decoration: underline; }\n#HTMLReporter p, #HTMLReporter h1, #HTMLReporter h2, #HTMLReporter h3, #HTMLReporter h4, #HTMLReporter h5, #HTMLReporter h6 { margin: 0; line-height: 14px; }\n#HTMLReporter .banner, #HTMLReporter .symbolSummary, #HTMLReporter .summary, #HTMLReporter .resultMessage, #HTMLReporter .specDetail .description, #HTMLReporter .alert .bar, #HTMLReporter .stackTrace { padding-left: 9px; padding-right: 9px; }\n#HTMLReporter #jasmine_content { position: fixed; right: 100%; }\n#HTMLReporter .version { color: #aaaaaa; }\n#HTMLReporter .banner { margin-top: 14px; }\n#HTMLReporter .duration { color: #aaaaaa; float: right; }\n#HTMLReporter .symbolSummary { overflow: hidden; *zoom: 1; margin: 14px 0; }\n#HTMLReporter .symbolSummary li { display: block; float: left; height: 7px; width: 14px; margin-bottom: 7px; font-size: 16px; }\n#HTMLReporter .symbolSummary li.passed { font-size: 14px; }\n#HTMLReporter .symbolSummary li.passed:before { color: #5e7d00; content: \"\\02022\"; }\n#HTMLReporter .symbolSummary li.failed { line-height: 9px; }\n#HTMLReporter .symbolSummary li.failed:before { color: #b03911; content: \"x\"; font-weight: bold; margin-left: -1px; }\n#HTMLReporter .symbolSummary li.skipped { font-size: 14px; }\n#HTMLReporter .symbolSummary li.skipped:before { color: #bababa; content: \"\\02022\"; }\n#HTMLReporter .symbolSummary li.pending { line-height: 11px; }\n#HTMLReporter .symbolSummary li.pending:before { color: #aaaaaa; content: \"-\"; }\n#HTMLReporter .bar { line-height: 28px; font-size: 14px; display: block; color: #eee; }\n#HTMLReporter .runningAlert { background-color: #666666; }\n#HTMLReporter .skippedAlert { background-color: #aaaaaa; }\n#HTMLReporter .skippedAlert:first-child { background-color: #333333; }\n#HTMLReporter .skippedAlert:hover { text-decoration: none; color: white; text-decoration: underline; }\n#HTMLReporter .passingAlert { background-color: #a6b779; }\n#HTMLReporter .passingAlert:first-child { background-color: #5e7d00; }\n#HTMLReporter .failingAlert { background-color: #cf867e; }\n#HTMLReporter .failingAlert:first-child { background-color: #b03911; }\n#HTMLReporter .results { margin-top: 14px; }\n#HTMLReporter #details { display: none; }\n#HTMLReporter .resultsMenu, #HTMLReporter .resultsMenu a { background-color: #fff; color: #333333; }\n#HTMLReporter.showDetails .summaryMenuItem { font-weight: normal; text-decoration: inherit; }\n#HTMLReporter.showDetails .summaryMenuItem:hover { text-decoration: underline; }\n#HTMLReporter.showDetails .detailsMenuItem { font-weight: bold; text-decoration: underline; }\n#HTMLReporter.showDetails .summary { display: none; }\n#HTMLReporter.showDetails #details { display: block; }\n#HTMLReporter .summaryMenuItem { font-weight: bold; text-decoration: underline; }\n#HTMLReporter .summary { margin-top: 14px; }\n#HTMLReporter .summary .suite .suite, #HTMLReporter .summary .specSummary { margin-left: 14px; }\n#HTMLReporter .summary .specSummary.passed a { color: #5e7d00; }\n#HTMLReporter .summary .specSummary.failed a { color: #b03911; }\n#HTMLReporter .description + .suite { margin-top: 0; }\n#HTMLReporter .suite { margin-top: 14px; }\n#HTMLReporter .suite a { color: #333333; }\n#HTMLReporter #details .specDetail { margin-bottom: 28px; }\n#HTMLReporter #details .specDetail .description { display: block; color: white; background-color: #b03911; }\n#HTMLReporter .resultMessage { padding-top: 14px; color: #333333; }\n#HTMLReporter .resultMessage span.result { display: block; }\n#HTMLReporter .stackTrace { margin: 5px 0 0 0; max-height: 224px; overflow: auto; line-height: 18px; color: #666666; border: 1px solid #ddd; background: white; white-space: pre; }\n\n#TrivialReporter { padding: 8px 13px; position: absolute; top: 0; bottom: 0; left: 0; right: 0; overflow-y: scroll; background-color: white; font-family: \"Helvetica Neue Light\", \"Lucida Grande\", \"Calibri\", \"Arial\", sans-serif; /*.resultMessage {*/ /*white-space: pre;*/ /*}*/ }\n#TrivialReporter a:visited, #TrivialReporter a { color: #303; }\n#TrivialReporter a:hover, #TrivialReporter a:active { color: blue; }\n#TrivialReporter .run_spec { float: right; padding-right: 5px; font-size: .8em; text-decoration: none; }\n#TrivialReporter .banner { color: #303; background-color: #fef; padding: 5px; }\n#TrivialReporter .logo { float: left; font-size: 1.1em; padding-left: 5px; }\n#TrivialReporter .logo .version { font-size: .6em; padding-left: 1em; }\n#TrivialReporter .runner.running { background-color: yellow; }\n#TrivialReporter .options { text-align: right; font-size: .8em; }\n#TrivialReporter .suite { border: 1px outset gray; margin: 5px 0; padding-left: 1em; }\n#TrivialReporter .suite .suite { margin: 5px; }\n#TrivialReporter .suite.passed { background-color: #dfd; }\n#TrivialReporter .suite.failed { background-color: #fdd; }\n#TrivialReporter .spec { margin: 5px; padding-left: 1em; clear: both; }\n#TrivialReporter .spec.failed, #TrivialReporter .spec.passed, #TrivialReporter .spec.skipped { padding-bottom: 5px; border: 1px solid gray; }\n#TrivialReporter .spec.failed { background-color: #fbb; border-color: red; }\n#TrivialReporter .spec.passed { background-color: #bfb; border-color: green; }\n#TrivialReporter .spec.skipped { background-color: #bbb; }\n#TrivialReporter .messages { border-left: 1px dashed gray; padding-left: 1em; padding-right: 1em; }\n#TrivialReporter .passed { background-color: #cfc; display: none; }\n#TrivialReporter .failed { background-color: #fbb; }\n#TrivialReporter .skipped { color: #777; background-color: #eee; display: none; }\n#TrivialReporter .resultMessage span.result { display: block; line-height: 2em; color: black; }\n#TrivialReporter .resultMessage .mismatch { color: black; }\n#TrivialReporter .stackTrace { white-space: pre; font-size: .8em; margin-left: 10px; max-height: 5em; overflow: auto; border: 1px inset red; padding: 1em; background: #eef; }\n#TrivialReporter .finished-at { padding-left: 1em; font-size: .6em; }\n#TrivialReporter.show-passed .passed, #TrivialReporter.show-skipped .skipped { display: block; }\n#TrivialReporter #jasmine_content { position: fixed; right: 100%; }\n#TrivialReporter .runner { border: 1px solid gray; display: block; margin: 5px 0; padding: 2px 0 2px 10px; }\n"
  },
  {
    "path": "spec/lib/jasmine-1.2.0/jasmine.js",
    "content": "var isCommonJS = typeof window == \"undefined\";\n\n/**\n * Top level namespace for Jasmine, a lightweight JavaScript BDD/spec/testing framework.\n *\n * @namespace\n */\nvar jasmine = {};\nif (isCommonJS) exports.jasmine = jasmine;\n/**\n * @private\n */\njasmine.unimplementedMethod_ = function() {\n  throw new Error(\"unimplemented method\");\n};\n\n/**\n * Use <code>jasmine.undefined</code> instead of <code>undefined</code>, since <code>undefined</code> is just\n * a plain old variable and may be redefined by somebody else.\n *\n * @private\n */\njasmine.undefined = jasmine.___undefined___;\n\n/**\n * Show diagnostic messages in the console if set to true\n *\n */\njasmine.VERBOSE = false;\n\n/**\n * Default interval in milliseconds for event loop yields (e.g. to allow network activity or to refresh the screen with the HTML-based runner). Small values here may result in slow test running. Zero means no updates until all tests have completed.\n *\n */\njasmine.DEFAULT_UPDATE_INTERVAL = 250;\n\n/**\n * Default timeout interval in milliseconds for waitsFor() blocks.\n */\njasmine.DEFAULT_TIMEOUT_INTERVAL = 5000;\n\njasmine.getGlobal = function() {\n  function getGlobal() {\n    return this;\n  }\n\n  return getGlobal();\n};\n\n/**\n * Allows for bound functions to be compared.  Internal use only.\n *\n * @ignore\n * @private\n * @param base {Object} bound 'this' for the function\n * @param name {Function} function to find\n */\njasmine.bindOriginal_ = function(base, name) {\n  var original = base[name];\n  if (original.apply) {\n    return function() {\n      return original.apply(base, arguments);\n    };\n  } else {\n    // IE support\n    return jasmine.getGlobal()[name];\n  }\n};\n\njasmine.setTimeout = jasmine.bindOriginal_(jasmine.getGlobal(), 'setTimeout');\njasmine.clearTimeout = jasmine.bindOriginal_(jasmine.getGlobal(), 'clearTimeout');\njasmine.setInterval = jasmine.bindOriginal_(jasmine.getGlobal(), 'setInterval');\njasmine.clearInterval = jasmine.bindOriginal_(jasmine.getGlobal(), 'clearInterval');\n\njasmine.MessageResult = function(values) {\n  this.type = 'log';\n  this.values = values;\n  this.trace = new Error(); // todo: test better\n};\n\njasmine.MessageResult.prototype.toString = function() {\n  var text = \"\";\n  for (var i = 0; i < this.values.length; i++) {\n    if (i > 0) text += \" \";\n    if (jasmine.isString_(this.values[i])) {\n      text += this.values[i];\n    } else {\n      text += jasmine.pp(this.values[i]);\n    }\n  }\n  return text;\n};\n\njasmine.ExpectationResult = function(params) {\n  this.type = 'expect';\n  this.matcherName = params.matcherName;\n  this.passed_ = params.passed;\n  this.expected = params.expected;\n  this.actual = params.actual;\n  this.message = this.passed_ ? 'Passed.' : params.message;\n\n  var trace = (params.trace || new Error(this.message));\n  this.trace = this.passed_ ? '' : trace;\n};\n\njasmine.ExpectationResult.prototype.toString = function () {\n  return this.message;\n};\n\njasmine.ExpectationResult.prototype.passed = function () {\n  return this.passed_;\n};\n\n/**\n * Getter for the Jasmine environment. Ensures one gets created\n */\njasmine.getEnv = function() {\n  var env = jasmine.currentEnv_ = jasmine.currentEnv_ || new jasmine.Env();\n  return env;\n};\n\n/**\n * @ignore\n * @private\n * @param value\n * @returns {Boolean}\n */\njasmine.isArray_ = function(value) {\n  return jasmine.isA_(\"Array\", value);\n};\n\n/**\n * @ignore\n * @private\n * @param value\n * @returns {Boolean}\n */\njasmine.isString_ = function(value) {\n  return jasmine.isA_(\"String\", value);\n};\n\n/**\n * @ignore\n * @private\n * @param value\n * @returns {Boolean}\n */\njasmine.isNumber_ = function(value) {\n  return jasmine.isA_(\"Number\", value);\n};\n\n/**\n * @ignore\n * @private\n * @param {String} typeName\n * @param value\n * @returns {Boolean}\n */\njasmine.isA_ = function(typeName, value) {\n  return Object.prototype.toString.apply(value) === '[object ' + typeName + ']';\n};\n\n/**\n * Pretty printer for expecations.  Takes any object and turns it into a human-readable string.\n *\n * @param value {Object} an object to be outputted\n * @returns {String}\n */\njasmine.pp = function(value) {\n  var stringPrettyPrinter = new jasmine.StringPrettyPrinter();\n  stringPrettyPrinter.format(value);\n  return stringPrettyPrinter.string;\n};\n\n/**\n * Returns true if the object is a DOM Node.\n *\n * @param {Object} obj object to check\n * @returns {Boolean}\n */\njasmine.isDomNode = function(obj) {\n  return obj.nodeType > 0;\n};\n\n/**\n * Returns a matchable 'generic' object of the class type.  For use in expecations of type when values don't matter.\n *\n * @example\n * // don't care about which function is passed in, as long as it's a function\n * expect(mySpy).toHaveBeenCalledWith(jasmine.any(Function));\n *\n * @param {Class} clazz\n * @returns matchable object of the type clazz\n */\njasmine.any = function(clazz) {\n  return new jasmine.Matchers.Any(clazz);\n};\n\n/**\n * Returns a matchable subset of a JSON object. For use in expectations when you don't care about all of the\n * attributes on the object.\n *\n * @example\n * // don't care about any other attributes than foo.\n * expect(mySpy).toHaveBeenCalledWith(jasmine.objectContaining({foo: \"bar\"});\n *\n * @param sample {Object} sample\n * @returns matchable object for the sample\n */\njasmine.objectContaining = function (sample) {\n    return new jasmine.Matchers.ObjectContaining(sample);\n};\n\n/**\n * Jasmine Spies are test doubles that can act as stubs, spies, fakes or when used in an expecation, mocks.\n *\n * Spies should be created in test setup, before expectations.  They can then be checked, using the standard Jasmine\n * expectation syntax. Spies can be checked if they were called or not and what the calling params were.\n *\n * A Spy has the following fields: wasCalled, callCount, mostRecentCall, and argsForCall (see docs).\n *\n * Spies are torn down at the end of every spec.\n *\n * Note: Do <b>not</b> call new jasmine.Spy() directly - a spy must be created using spyOn, jasmine.createSpy or jasmine.createSpyObj.\n *\n * @example\n * // a stub\n * var myStub = jasmine.createSpy('myStub');  // can be used anywhere\n *\n * // spy example\n * var foo = {\n *   not: function(bool) { return !bool; }\n * }\n *\n * // actual foo.not will not be called, execution stops\n * spyOn(foo, 'not');\n\n // foo.not spied upon, execution will continue to implementation\n * spyOn(foo, 'not').andCallThrough();\n *\n * // fake example\n * var foo = {\n *   not: function(bool) { return !bool; }\n * }\n *\n * // foo.not(val) will return val\n * spyOn(foo, 'not').andCallFake(function(value) {return value;});\n *\n * // mock example\n * foo.not(7 == 7);\n * expect(foo.not).toHaveBeenCalled();\n * expect(foo.not).toHaveBeenCalledWith(true);\n *\n * @constructor\n * @see spyOn, jasmine.createSpy, jasmine.createSpyObj\n * @param {String} name\n */\njasmine.Spy = function(name) {\n  /**\n   * The name of the spy, if provided.\n   */\n  this.identity = name || 'unknown';\n  /**\n   *  Is this Object a spy?\n   */\n  this.isSpy = true;\n  /**\n   * The actual function this spy stubs.\n   */\n  this.plan = function() {\n  };\n  /**\n   * Tracking of the most recent call to the spy.\n   * @example\n   * var mySpy = jasmine.createSpy('foo');\n   * mySpy(1, 2);\n   * mySpy.mostRecentCall.args = [1, 2];\n   */\n  this.mostRecentCall = {};\n\n  /**\n   * Holds arguments for each call to the spy, indexed by call count\n   * @example\n   * var mySpy = jasmine.createSpy('foo');\n   * mySpy(1, 2);\n   * mySpy(7, 8);\n   * mySpy.mostRecentCall.args = [7, 8];\n   * mySpy.argsForCall[0] = [1, 2];\n   * mySpy.argsForCall[1] = [7, 8];\n   */\n  this.argsForCall = [];\n  this.calls = [];\n};\n\n/**\n * Tells a spy to call through to the actual implemenatation.\n *\n * @example\n * var foo = {\n *   bar: function() { // do some stuff }\n * }\n *\n * // defining a spy on an existing property: foo.bar\n * spyOn(foo, 'bar').andCallThrough();\n */\njasmine.Spy.prototype.andCallThrough = function() {\n  this.plan = this.originalValue;\n  return this;\n};\n\n/**\n * For setting the return value of a spy.\n *\n * @example\n * // defining a spy from scratch: foo() returns 'baz'\n * var foo = jasmine.createSpy('spy on foo').andReturn('baz');\n *\n * // defining a spy on an existing property: foo.bar() returns 'baz'\n * spyOn(foo, 'bar').andReturn('baz');\n *\n * @param {Object} value\n */\njasmine.Spy.prototype.andReturn = function(value) {\n  this.plan = function() {\n    return value;\n  };\n  return this;\n};\n\n/**\n * For throwing an exception when a spy is called.\n *\n * @example\n * // defining a spy from scratch: foo() throws an exception w/ message 'ouch'\n * var foo = jasmine.createSpy('spy on foo').andThrow('baz');\n *\n * // defining a spy on an existing property: foo.bar() throws an exception w/ message 'ouch'\n * spyOn(foo, 'bar').andThrow('baz');\n *\n * @param {String} exceptionMsg\n */\njasmine.Spy.prototype.andThrow = function(exceptionMsg) {\n  this.plan = function() {\n    throw exceptionMsg;\n  };\n  return this;\n};\n\n/**\n * Calls an alternate implementation when a spy is called.\n *\n * @example\n * var baz = function() {\n *   // do some stuff, return something\n * }\n * // defining a spy from scratch: foo() calls the function baz\n * var foo = jasmine.createSpy('spy on foo').andCall(baz);\n *\n * // defining a spy on an existing property: foo.bar() calls an anonymnous function\n * spyOn(foo, 'bar').andCall(function() { return 'baz';} );\n *\n * @param {Function} fakeFunc\n */\njasmine.Spy.prototype.andCallFake = function(fakeFunc) {\n  this.plan = fakeFunc;\n  return this;\n};\n\n/**\n * Resets all of a spy's the tracking variables so that it can be used again.\n *\n * @example\n * spyOn(foo, 'bar');\n *\n * foo.bar();\n *\n * expect(foo.bar.callCount).toEqual(1);\n *\n * foo.bar.reset();\n *\n * expect(foo.bar.callCount).toEqual(0);\n */\njasmine.Spy.prototype.reset = function() {\n  this.wasCalled = false;\n  this.callCount = 0;\n  this.argsForCall = [];\n  this.calls = [];\n  this.mostRecentCall = {};\n};\n\njasmine.createSpy = function(name) {\n\n  var spyObj = function() {\n    spyObj.wasCalled = true;\n    spyObj.callCount++;\n    var args = jasmine.util.argsToArray(arguments);\n    spyObj.mostRecentCall.object = this;\n    spyObj.mostRecentCall.args = args;\n    spyObj.argsForCall.push(args);\n    spyObj.calls.push({object: this, args: args});\n    return spyObj.plan.apply(this, arguments);\n  };\n\n  var spy = new jasmine.Spy(name);\n\n  for (var prop in spy) {\n    spyObj[prop] = spy[prop];\n  }\n\n  spyObj.reset();\n\n  return spyObj;\n};\n\n/**\n * Determines whether an object is a spy.\n *\n * @param {jasmine.Spy|Object} putativeSpy\n * @returns {Boolean}\n */\njasmine.isSpy = function(putativeSpy) {\n  return putativeSpy && putativeSpy.isSpy;\n};\n\n/**\n * Creates a more complicated spy: an Object that has every property a function that is a spy.  Used for stubbing something\n * large in one call.\n *\n * @param {String} baseName name of spy class\n * @param {Array} methodNames array of names of methods to make spies\n */\njasmine.createSpyObj = function(baseName, methodNames) {\n  if (!jasmine.isArray_(methodNames) || methodNames.length === 0) {\n    throw new Error('createSpyObj requires a non-empty array of method names to create spies for');\n  }\n  var obj = {};\n  for (var i = 0; i < methodNames.length; i++) {\n    obj[methodNames[i]] = jasmine.createSpy(baseName + '.' + methodNames[i]);\n  }\n  return obj;\n};\n\n/**\n * All parameters are pretty-printed and concatenated together, then written to the current spec's output.\n *\n * Be careful not to leave calls to <code>jasmine.log</code> in production code.\n */\njasmine.log = function() {\n  var spec = jasmine.getEnv().currentSpec;\n  spec.log.apply(spec, arguments);\n};\n\n/**\n * Function that installs a spy on an existing object's method name.  Used within a Spec to create a spy.\n *\n * @example\n * // spy example\n * var foo = {\n *   not: function(bool) { return !bool; }\n * }\n * spyOn(foo, 'not'); // actual foo.not will not be called, execution stops\n *\n * @see jasmine.createSpy\n * @param obj\n * @param methodName\n * @returns a Jasmine spy that can be chained with all spy methods\n */\nvar spyOn = function(obj, methodName) {\n  return jasmine.getEnv().currentSpec.spyOn(obj, methodName);\n};\nif (isCommonJS) exports.spyOn = spyOn;\n\n/**\n * Creates a Jasmine spec that will be added to the current suite.\n *\n * // TODO: pending tests\n *\n * @example\n * it('should be true', function() {\n *   expect(true).toEqual(true);\n * });\n *\n * @param {String} desc description of this specification\n * @param {Function} func defines the preconditions and expectations of the spec\n */\nvar it = function(desc, func) {\n  return jasmine.getEnv().it(desc, func);\n};\nif (isCommonJS) exports.it = it;\n\n/**\n * Creates a <em>disabled</em> Jasmine spec.\n *\n * A convenience method that allows existing specs to be disabled temporarily during development.\n *\n * @param {String} desc description of this specification\n * @param {Function} func defines the preconditions and expectations of the spec\n */\nvar xit = function(desc, func) {\n  return jasmine.getEnv().xit(desc, func);\n};\nif (isCommonJS) exports.xit = xit;\n\n/**\n * Starts a chain for a Jasmine expectation.\n *\n * It is passed an Object that is the actual value and should chain to one of the many\n * jasmine.Matchers functions.\n *\n * @param {Object} actual Actual value to test against and expected value\n */\nvar expect = function(actual) {\n  return jasmine.getEnv().currentSpec.expect(actual);\n};\nif (isCommonJS) exports.expect = expect;\n\n/**\n * Defines part of a jasmine spec.  Used in cominbination with waits or waitsFor in asynchrnous specs.\n *\n * @param {Function} func Function that defines part of a jasmine spec.\n */\nvar runs = function(func) {\n  jasmine.getEnv().currentSpec.runs(func);\n};\nif (isCommonJS) exports.runs = runs;\n\n/**\n * Waits a fixed time period before moving to the next block.\n *\n * @deprecated Use waitsFor() instead\n * @param {Number} timeout milliseconds to wait\n */\nvar waits = function(timeout) {\n  jasmine.getEnv().currentSpec.waits(timeout);\n};\nif (isCommonJS) exports.waits = waits;\n\n/**\n * Waits for the latchFunction to return true before proceeding to the next block.\n *\n * @param {Function} latchFunction\n * @param {String} optional_timeoutMessage\n * @param {Number} optional_timeout\n */\nvar waitsFor = function(latchFunction, optional_timeoutMessage, optional_timeout) {\n  jasmine.getEnv().currentSpec.waitsFor.apply(jasmine.getEnv().currentSpec, arguments);\n};\nif (isCommonJS) exports.waitsFor = waitsFor;\n\n/**\n * A function that is called before each spec in a suite.\n *\n * Used for spec setup, including validating assumptions.\n *\n * @param {Function} beforeEachFunction\n */\nvar beforeEach = function(beforeEachFunction) {\n  jasmine.getEnv().beforeEach(beforeEachFunction);\n};\nif (isCommonJS) exports.beforeEach = beforeEach;\n\n/**\n * A function that is called after each spec in a suite.\n *\n * Used for restoring any state that is hijacked during spec execution.\n *\n * @param {Function} afterEachFunction\n */\nvar afterEach = function(afterEachFunction) {\n  jasmine.getEnv().afterEach(afterEachFunction);\n};\nif (isCommonJS) exports.afterEach = afterEach;\n\n/**\n * Defines a suite of specifications.\n *\n * Stores the description and all defined specs in the Jasmine environment as one suite of specs. Variables declared\n * are accessible by calls to beforeEach, it, and afterEach. Describe blocks can be nested, allowing for specialization\n * of setup in some tests.\n *\n * @example\n * // TODO: a simple suite\n *\n * // TODO: a simple suite with a nested describe block\n *\n * @param {String} description A string, usually the class under test.\n * @param {Function} specDefinitions function that defines several specs.\n */\nvar describe = function(description, specDefinitions) {\n  return jasmine.getEnv().describe(description, specDefinitions);\n};\nif (isCommonJS) exports.describe = describe;\n\n/**\n * Disables a suite of specifications.  Used to disable some suites in a file, or files, temporarily during development.\n *\n * @param {String} description A string, usually the class under test.\n * @param {Function} specDefinitions function that defines several specs.\n */\nvar xdescribe = function(description, specDefinitions) {\n  return jasmine.getEnv().xdescribe(description, specDefinitions);\n};\nif (isCommonJS) exports.xdescribe = xdescribe;\n\n\n// Provide the XMLHttpRequest class for IE 5.x-6.x:\njasmine.XmlHttpRequest = (typeof XMLHttpRequest == \"undefined\") ? function() {\n  function tryIt(f) {\n    try {\n      return f();\n    } catch(e) {\n    }\n    return null;\n  }\n\n  var xhr = tryIt(function() {\n    return new ActiveXObject(\"Msxml2.XMLHTTP.6.0\");\n  }) ||\n    tryIt(function() {\n      return new ActiveXObject(\"Msxml2.XMLHTTP.3.0\");\n    }) ||\n    tryIt(function() {\n      return new ActiveXObject(\"Msxml2.XMLHTTP\");\n    }) ||\n    tryIt(function() {\n      return new ActiveXObject(\"Microsoft.XMLHTTP\");\n    });\n\n  if (!xhr) throw new Error(\"This browser does not support XMLHttpRequest.\");\n\n  return xhr;\n} : XMLHttpRequest;\n/**\n * @namespace\n */\njasmine.util = {};\n\n/**\n * Declare that a child class inherit it's prototype from the parent class.\n *\n * @private\n * @param {Function} childClass\n * @param {Function} parentClass\n */\njasmine.util.inherit = function(childClass, parentClass) {\n  /**\n   * @private\n   */\n  var subclass = function() {\n  };\n  subclass.prototype = parentClass.prototype;\n  childClass.prototype = new subclass();\n};\n\njasmine.util.formatException = function(e) {\n  var lineNumber;\n  if (e.line) {\n    lineNumber = e.line;\n  }\n  else if (e.lineNumber) {\n    lineNumber = e.lineNumber;\n  }\n\n  var file;\n\n  if (e.sourceURL) {\n    file = e.sourceURL;\n  }\n  else if (e.fileName) {\n    file = e.fileName;\n  }\n\n  var message = (e.name && e.message) ? (e.name + ': ' + e.message) : e.toString();\n\n  if (file && lineNumber) {\n    message += ' in ' + file + ' (line ' + lineNumber + ')';\n  }\n\n  return message;\n};\n\njasmine.util.htmlEscape = function(str) {\n  if (!str) return str;\n  return str.replace(/&/g, '&amp;')\n    .replace(/</g, '&lt;')\n    .replace(/>/g, '&gt;');\n};\n\njasmine.util.argsToArray = function(args) {\n  var arrayOfArgs = [];\n  for (var i = 0; i < args.length; i++) arrayOfArgs.push(args[i]);\n  return arrayOfArgs;\n};\n\njasmine.util.extend = function(destination, source) {\n  for (var property in source) destination[property] = source[property];\n  return destination;\n};\n\n/**\n * Environment for Jasmine\n *\n * @constructor\n */\njasmine.Env = function() {\n  this.currentSpec = null;\n  this.currentSuite = null;\n  this.currentRunner_ = new jasmine.Runner(this);\n\n  this.reporter = new jasmine.MultiReporter();\n\n  this.updateInterval = jasmine.DEFAULT_UPDATE_INTERVAL;\n  this.defaultTimeoutInterval = jasmine.DEFAULT_TIMEOUT_INTERVAL;\n  this.lastUpdate = 0;\n  this.specFilter = function() {\n    return true;\n  };\n\n  this.nextSpecId_ = 0;\n  this.nextSuiteId_ = 0;\n  this.equalityTesters_ = [];\n\n  // wrap matchers\n  this.matchersClass = function() {\n    jasmine.Matchers.apply(this, arguments);\n  };\n  jasmine.util.inherit(this.matchersClass, jasmine.Matchers);\n\n  jasmine.Matchers.wrapInto_(jasmine.Matchers.prototype, this.matchersClass);\n};\n\n\njasmine.Env.prototype.setTimeout = jasmine.setTimeout;\njasmine.Env.prototype.clearTimeout = jasmine.clearTimeout;\njasmine.Env.prototype.setInterval = jasmine.setInterval;\njasmine.Env.prototype.clearInterval = jasmine.clearInterval;\n\n/**\n * @returns an object containing jasmine version build info, if set.\n */\njasmine.Env.prototype.version = function () {\n  if (jasmine.version_) {\n    return jasmine.version_;\n  } else {\n    throw new Error('Version not set');\n  }\n};\n\n/**\n * @returns string containing jasmine version build info, if set.\n */\njasmine.Env.prototype.versionString = function() {\n  if (!jasmine.version_) {\n    return \"version unknown\";\n  }\n\n  var version = this.version();\n  var versionString = version.major + \".\" + version.minor + \".\" + version.build;\n  if (version.release_candidate) {\n    versionString += \".rc\" + version.release_candidate;\n  }\n  versionString += \" revision \" + version.revision;\n  return versionString;\n};\n\n/**\n * @returns a sequential integer starting at 0\n */\njasmine.Env.prototype.nextSpecId = function () {\n  return this.nextSpecId_++;\n};\n\n/**\n * @returns a sequential integer starting at 0\n */\njasmine.Env.prototype.nextSuiteId = function () {\n  return this.nextSuiteId_++;\n};\n\n/**\n * Register a reporter to receive status updates from Jasmine.\n * @param {jasmine.Reporter} reporter An object which will receive status updates.\n */\njasmine.Env.prototype.addReporter = function(reporter) {\n  this.reporter.addReporter(reporter);\n};\n\njasmine.Env.prototype.execute = function() {\n  this.currentRunner_.execute();\n};\n\njasmine.Env.prototype.describe = function(description, specDefinitions) {\n  var suite = new jasmine.Suite(this, description, specDefinitions, this.currentSuite);\n\n  var parentSuite = this.currentSuite;\n  if (parentSuite) {\n    parentSuite.add(suite);\n  } else {\n    this.currentRunner_.add(suite);\n  }\n\n  this.currentSuite = suite;\n\n  var declarationError = null;\n  try {\n    specDefinitions.call(suite);\n  } catch(e) {\n    declarationError = e;\n  }\n\n  if (declarationError) {\n    this.it(\"encountered a declaration exception\", function() {\n      throw declarationError;\n    });\n  }\n\n  this.currentSuite = parentSuite;\n\n  return suite;\n};\n\njasmine.Env.prototype.beforeEach = function(beforeEachFunction) {\n  if (this.currentSuite) {\n    this.currentSuite.beforeEach(beforeEachFunction);\n  } else {\n    this.currentRunner_.beforeEach(beforeEachFunction);\n  }\n};\n\njasmine.Env.prototype.currentRunner = function () {\n  return this.currentRunner_;\n};\n\njasmine.Env.prototype.afterEach = function(afterEachFunction) {\n  if (this.currentSuite) {\n    this.currentSuite.afterEach(afterEachFunction);\n  } else {\n    this.currentRunner_.afterEach(afterEachFunction);\n  }\n\n};\n\njasmine.Env.prototype.xdescribe = function(desc, specDefinitions) {\n  return {\n    execute: function() {\n    }\n  };\n};\n\njasmine.Env.prototype.it = function(description, func) {\n  var spec = new jasmine.Spec(this, this.currentSuite, description);\n  this.currentSuite.add(spec);\n  this.currentSpec = spec;\n\n  if (func) {\n    spec.runs(func);\n  }\n\n  return spec;\n};\n\njasmine.Env.prototype.xit = function(desc, func) {\n  return {\n    id: this.nextSpecId(),\n    runs: function() {\n    }\n  };\n};\n\njasmine.Env.prototype.compareObjects_ = function(a, b, mismatchKeys, mismatchValues) {\n  if (a.__Jasmine_been_here_before__ === b && b.__Jasmine_been_here_before__ === a) {\n    return true;\n  }\n\n  a.__Jasmine_been_here_before__ = b;\n  b.__Jasmine_been_here_before__ = a;\n\n  var hasKey = function(obj, keyName) {\n    return obj !== null && obj[keyName] !== jasmine.undefined;\n  };\n\n  for (var property in b) {\n    if (!hasKey(a, property) && hasKey(b, property)) {\n      mismatchKeys.push(\"expected has key '\" + property + \"', but missing from actual.\");\n    }\n  }\n  for (property in a) {\n    if (!hasKey(b, property) && hasKey(a, property)) {\n      mismatchKeys.push(\"expected missing key '\" + property + \"', but present in actual.\");\n    }\n  }\n  for (property in b) {\n    if (property == '__Jasmine_been_here_before__') continue;\n    if (!this.equals_(a[property], b[property], mismatchKeys, mismatchValues)) {\n      mismatchValues.push(\"'\" + property + \"' was '\" + (b[property] ? jasmine.util.htmlEscape(b[property].toString()) : b[property]) + \"' in expected, but was '\" + (a[property] ? jasmine.util.htmlEscape(a[property].toString()) : a[property]) + \"' in actual.\");\n    }\n  }\n\n  if (jasmine.isArray_(a) && jasmine.isArray_(b) && a.length != b.length) {\n    mismatchValues.push(\"arrays were not the same length\");\n  }\n\n  delete a.__Jasmine_been_here_before__;\n  delete b.__Jasmine_been_here_before__;\n  return (mismatchKeys.length === 0 && mismatchValues.length === 0);\n};\n\njasmine.Env.prototype.equals_ = function(a, b, mismatchKeys, mismatchValues) {\n  mismatchKeys = mismatchKeys || [];\n  mismatchValues = mismatchValues || [];\n\n  for (var i = 0; i < this.equalityTesters_.length; i++) {\n    var equalityTester = this.equalityTesters_[i];\n    var result = equalityTester(a, b, this, mismatchKeys, mismatchValues);\n    if (result !== jasmine.undefined) return result;\n  }\n\n  if (a === b) return true;\n\n  if (a === jasmine.undefined || a === null || b === jasmine.undefined || b === null) {\n    return (a == jasmine.undefined && b == jasmine.undefined);\n  }\n\n  if (jasmine.isDomNode(a) && jasmine.isDomNode(b)) {\n    return a === b;\n  }\n\n  if (a instanceof Date && b instanceof Date) {\n    return a.getTime() == b.getTime();\n  }\n\n  if (a.jasmineMatches) {\n    return a.jasmineMatches(b);\n  }\n\n  if (b.jasmineMatches) {\n    return b.jasmineMatches(a);\n  }\n\n  if (a instanceof jasmine.Matchers.ObjectContaining) {\n    return a.matches(b);\n  }\n\n  if (b instanceof jasmine.Matchers.ObjectContaining) {\n    return b.matches(a);\n  }\n\n  if (jasmine.isString_(a) && jasmine.isString_(b)) {\n    return (a == b);\n  }\n\n  if (jasmine.isNumber_(a) && jasmine.isNumber_(b)) {\n    return (a == b);\n  }\n\n  if (typeof a === \"object\" && typeof b === \"object\") {\n    return this.compareObjects_(a, b, mismatchKeys, mismatchValues);\n  }\n\n  //Straight check\n  return (a === b);\n};\n\njasmine.Env.prototype.contains_ = function(haystack, needle) {\n  if (jasmine.isArray_(haystack)) {\n    for (var i = 0; i < haystack.length; i++) {\n      if (this.equals_(haystack[i], needle)) return true;\n    }\n    return false;\n  }\n  return haystack.indexOf(needle) >= 0;\n};\n\njasmine.Env.prototype.addEqualityTester = function(equalityTester) {\n  this.equalityTesters_.push(equalityTester);\n};\n/** No-op base class for Jasmine reporters.\n *\n * @constructor\n */\njasmine.Reporter = function() {\n};\n\n//noinspection JSUnusedLocalSymbols\njasmine.Reporter.prototype.reportRunnerStarting = function(runner) {\n};\n\n//noinspection JSUnusedLocalSymbols\njasmine.Reporter.prototype.reportRunnerResults = function(runner) {\n};\n\n//noinspection JSUnusedLocalSymbols\njasmine.Reporter.prototype.reportSuiteResults = function(suite) {\n};\n\n//noinspection JSUnusedLocalSymbols\njasmine.Reporter.prototype.reportSpecStarting = function(spec) {\n};\n\n//noinspection JSUnusedLocalSymbols\njasmine.Reporter.prototype.reportSpecResults = function(spec) {\n};\n\n//noinspection JSUnusedLocalSymbols\njasmine.Reporter.prototype.log = function(str) {\n};\n\n/**\n * Blocks are functions with executable code that make up a spec.\n *\n * @constructor\n * @param {jasmine.Env} env\n * @param {Function} func\n * @param {jasmine.Spec} spec\n */\njasmine.Block = function(env, func, spec) {\n  this.env = env;\n  this.func = func;\n  this.spec = spec;\n};\n\njasmine.Block.prototype.execute = function(onComplete) {  \n  try {\n    this.func.apply(this.spec);\n  } catch (e) {\n    this.spec.fail(e);\n  }\n  onComplete();\n};\n/** JavaScript API reporter.\n *\n * @constructor\n */\njasmine.JsApiReporter = function() {\n  this.started = false;\n  this.finished = false;\n  this.suites_ = [];\n  this.results_ = {};\n};\n\njasmine.JsApiReporter.prototype.reportRunnerStarting = function(runner) {\n  this.started = true;\n  var suites = runner.topLevelSuites();\n  for (var i = 0; i < suites.length; i++) {\n    var suite = suites[i];\n    this.suites_.push(this.summarize_(suite));\n  }\n};\n\njasmine.JsApiReporter.prototype.suites = function() {\n  return this.suites_;\n};\n\njasmine.JsApiReporter.prototype.summarize_ = function(suiteOrSpec) {\n  var isSuite = suiteOrSpec instanceof jasmine.Suite;\n  var summary = {\n    id: suiteOrSpec.id,\n    name: suiteOrSpec.description,\n    type: isSuite ? 'suite' : 'spec',\n    children: []\n  };\n  \n  if (isSuite) {\n    var children = suiteOrSpec.children();\n    for (var i = 0; i < children.length; i++) {\n      summary.children.push(this.summarize_(children[i]));\n    }\n  }\n  return summary;\n};\n\njasmine.JsApiReporter.prototype.results = function() {\n  return this.results_;\n};\n\njasmine.JsApiReporter.prototype.resultsForSpec = function(specId) {\n  return this.results_[specId];\n};\n\n//noinspection JSUnusedLocalSymbols\njasmine.JsApiReporter.prototype.reportRunnerResults = function(runner) {\n  this.finished = true;\n};\n\n//noinspection JSUnusedLocalSymbols\njasmine.JsApiReporter.prototype.reportSuiteResults = function(suite) {\n};\n\n//noinspection JSUnusedLocalSymbols\njasmine.JsApiReporter.prototype.reportSpecResults = function(spec) {\n  this.results_[spec.id] = {\n    messages: spec.results().getItems(),\n    result: spec.results().failedCount > 0 ? \"failed\" : \"passed\"\n  };\n};\n\n//noinspection JSUnusedLocalSymbols\njasmine.JsApiReporter.prototype.log = function(str) {\n};\n\njasmine.JsApiReporter.prototype.resultsForSpecs = function(specIds){\n  var results = {};\n  for (var i = 0; i < specIds.length; i++) {\n    var specId = specIds[i];\n    results[specId] = this.summarizeResult_(this.results_[specId]);\n  }\n  return results;\n};\n\njasmine.JsApiReporter.prototype.summarizeResult_ = function(result){\n  var summaryMessages = [];\n  var messagesLength = result.messages.length;\n  for (var messageIndex = 0; messageIndex < messagesLength; messageIndex++) {\n    var resultMessage = result.messages[messageIndex];\n    summaryMessages.push({\n      text: resultMessage.type == 'log' ? resultMessage.toString() : jasmine.undefined,\n      passed: resultMessage.passed ? resultMessage.passed() : true,\n      type: resultMessage.type,\n      message: resultMessage.message,\n      trace: {\n        stack: resultMessage.passed && !resultMessage.passed() ? resultMessage.trace.stack : jasmine.undefined\n      }\n    });\n  }\n\n  return {\n    result : result.result,\n    messages : summaryMessages\n  };\n};\n\n/**\n * @constructor\n * @param {jasmine.Env} env\n * @param actual\n * @param {jasmine.Spec} spec\n */\njasmine.Matchers = function(env, actual, spec, opt_isNot) {\n  this.env = env;\n  this.actual = actual;\n  this.spec = spec;\n  this.isNot = opt_isNot || false;\n  this.reportWasCalled_ = false;\n};\n\n// todo: @deprecated as of Jasmine 0.11, remove soon [xw]\njasmine.Matchers.pp = function(str) {\n  throw new Error(\"jasmine.Matchers.pp() is no longer supported, please use jasmine.pp() instead!\");\n};\n\n// todo: @deprecated Deprecated as of Jasmine 0.10. Rewrite your custom matchers to return true or false. [xw]\njasmine.Matchers.prototype.report = function(result, failing_message, details) {\n  throw new Error(\"As of jasmine 0.11, custom matchers must be implemented differently -- please see jasmine docs\");\n};\n\njasmine.Matchers.wrapInto_ = function(prototype, matchersClass) {\n  for (var methodName in prototype) {\n    if (methodName == 'report') continue;\n    var orig = prototype[methodName];\n    matchersClass.prototype[methodName] = jasmine.Matchers.matcherFn_(methodName, orig);\n  }\n};\n\njasmine.Matchers.matcherFn_ = function(matcherName, matcherFunction) {\n  return function() {\n    var matcherArgs = jasmine.util.argsToArray(arguments);\n    var result = matcherFunction.apply(this, arguments);\n\n    if (this.isNot) {\n      result = !result;\n    }\n\n    if (this.reportWasCalled_) return result;\n\n    var message;\n    if (!result) {\n      if (this.message) {\n        message = this.message.apply(this, arguments);\n        if (jasmine.isArray_(message)) {\n          message = message[this.isNot ? 1 : 0];\n        }\n      } else {\n        var englishyPredicate = matcherName.replace(/[A-Z]/g, function(s) { return ' ' + s.toLowerCase(); });\n        message = \"Expected \" + jasmine.pp(this.actual) + (this.isNot ? \" not \" : \" \") + englishyPredicate;\n        if (matcherArgs.length > 0) {\n          for (var i = 0; i < matcherArgs.length; i++) {\n            if (i > 0) message += \",\";\n            message += \" \" + jasmine.pp(matcherArgs[i]);\n          }\n        }\n        message += \".\";\n      }\n    }\n    var expectationResult = new jasmine.ExpectationResult({\n      matcherName: matcherName,\n      passed: result,\n      expected: matcherArgs.length > 1 ? matcherArgs : matcherArgs[0],\n      actual: this.actual,\n      message: message\n    });\n    this.spec.addMatcherResult(expectationResult);\n    return jasmine.undefined;\n  };\n};\n\n\n\n\n/**\n * toBe: compares the actual to the expected using ===\n * @param expected\n */\njasmine.Matchers.prototype.toBe = function(expected) {\n  return this.actual === expected;\n};\n\n/**\n * toNotBe: compares the actual to the expected using !==\n * @param expected\n * @deprecated as of 1.0. Use not.toBe() instead.\n */\njasmine.Matchers.prototype.toNotBe = function(expected) {\n  return this.actual !== expected;\n};\n\n/**\n * toEqual: compares the actual to the expected using common sense equality. Handles Objects, Arrays, etc.\n *\n * @param expected\n */\njasmine.Matchers.prototype.toEqual = function(expected) {\n  return this.env.equals_(this.actual, expected);\n};\n\n/**\n * toNotEqual: compares the actual to the expected using the ! of jasmine.Matchers.toEqual\n * @param expected\n * @deprecated as of 1.0. Use not.toEqual() instead.\n */\njasmine.Matchers.prototype.toNotEqual = function(expected) {\n  return !this.env.equals_(this.actual, expected);\n};\n\n/**\n * Matcher that compares the actual to the expected using a regular expression.  Constructs a RegExp, so takes\n * a pattern or a String.\n *\n * @param expected\n */\njasmine.Matchers.prototype.toMatch = function(expected) {\n  return new RegExp(expected).test(this.actual);\n};\n\n/**\n * Matcher that compares the actual to the expected using the boolean inverse of jasmine.Matchers.toMatch\n * @param expected\n * @deprecated as of 1.0. Use not.toMatch() instead.\n */\njasmine.Matchers.prototype.toNotMatch = function(expected) {\n  return !(new RegExp(expected).test(this.actual));\n};\n\n/**\n * Matcher that compares the actual to jasmine.undefined.\n */\njasmine.Matchers.prototype.toBeDefined = function() {\n  return (this.actual !== jasmine.undefined);\n};\n\n/**\n * Matcher that compares the actual to jasmine.undefined.\n */\njasmine.Matchers.prototype.toBeUndefined = function() {\n  return (this.actual === jasmine.undefined);\n};\n\n/**\n * Matcher that compares the actual to null.\n */\njasmine.Matchers.prototype.toBeNull = function() {\n  return (this.actual === null);\n};\n\n/**\n * Matcher that boolean not-nots the actual.\n */\njasmine.Matchers.prototype.toBeTruthy = function() {\n  return !!this.actual;\n};\n\n\n/**\n * Matcher that boolean nots the actual.\n */\njasmine.Matchers.prototype.toBeFalsy = function() {\n  return !this.actual;\n};\n\n\n/**\n * Matcher that checks to see if the actual, a Jasmine spy, was called.\n */\njasmine.Matchers.prototype.toHaveBeenCalled = function() {\n  if (arguments.length > 0) {\n    throw new Error('toHaveBeenCalled does not take arguments, use toHaveBeenCalledWith');\n  }\n\n  if (!jasmine.isSpy(this.actual)) {\n    throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.');\n  }\n\n  this.message = function() {\n    return [\n      \"Expected spy \" + this.actual.identity + \" to have been called.\",\n      \"Expected spy \" + this.actual.identity + \" not to have been called.\"\n    ];\n  };\n\n  return this.actual.wasCalled;\n};\n\n/** @deprecated Use expect(xxx).toHaveBeenCalled() instead */\njasmine.Matchers.prototype.wasCalled = jasmine.Matchers.prototype.toHaveBeenCalled;\n\n/**\n * Matcher that checks to see if the actual, a Jasmine spy, was not called.\n *\n * @deprecated Use expect(xxx).not.toHaveBeenCalled() instead\n */\njasmine.Matchers.prototype.wasNotCalled = function() {\n  if (arguments.length > 0) {\n    throw new Error('wasNotCalled does not take arguments');\n  }\n\n  if (!jasmine.isSpy(this.actual)) {\n    throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.');\n  }\n\n  this.message = function() {\n    return [\n      \"Expected spy \" + this.actual.identity + \" to not have been called.\",\n      \"Expected spy \" + this.actual.identity + \" to have been called.\"\n    ];\n  };\n\n  return !this.actual.wasCalled;\n};\n\n/**\n * Matcher that checks to see if the actual, a Jasmine spy, was called with a set of parameters.\n *\n * @example\n *\n */\njasmine.Matchers.prototype.toHaveBeenCalledWith = function() {\n  var expectedArgs = jasmine.util.argsToArray(arguments);\n  if (!jasmine.isSpy(this.actual)) {\n    throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.');\n  }\n  this.message = function() {\n    if (this.actual.callCount === 0) {\n      // todo: what should the failure message for .not.toHaveBeenCalledWith() be? is this right? test better. [xw]\n      return [\n        \"Expected spy \" + this.actual.identity + \" to have been called with \" + jasmine.pp(expectedArgs) + \" but it was never called.\",\n        \"Expected spy \" + this.actual.identity + \" not to have been called with \" + jasmine.pp(expectedArgs) + \" but it was.\"\n      ];\n    } else {\n      return [\n        \"Expected spy \" + this.actual.identity + \" to have been called with \" + jasmine.pp(expectedArgs) + \" but was called with \" + jasmine.pp(this.actual.argsForCall),\n        \"Expected spy \" + this.actual.identity + \" not to have been called with \" + jasmine.pp(expectedArgs) + \" but was called with \" + jasmine.pp(this.actual.argsForCall)\n      ];\n    }\n  };\n\n  return this.env.contains_(this.actual.argsForCall, expectedArgs);\n};\n\n/** @deprecated Use expect(xxx).toHaveBeenCalledWith() instead */\njasmine.Matchers.prototype.wasCalledWith = jasmine.Matchers.prototype.toHaveBeenCalledWith;\n\n/** @deprecated Use expect(xxx).not.toHaveBeenCalledWith() instead */\njasmine.Matchers.prototype.wasNotCalledWith = function() {\n  var expectedArgs = jasmine.util.argsToArray(arguments);\n  if (!jasmine.isSpy(this.actual)) {\n    throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.');\n  }\n\n  this.message = function() {\n    return [\n      \"Expected spy not to have been called with \" + jasmine.pp(expectedArgs) + \" but it was\",\n      \"Expected spy to have been called with \" + jasmine.pp(expectedArgs) + \" but it was\"\n    ];\n  };\n\n  return !this.env.contains_(this.actual.argsForCall, expectedArgs);\n};\n\n/**\n * Matcher that checks that the expected item is an element in the actual Array.\n *\n * @param {Object} expected\n */\njasmine.Matchers.prototype.toContain = function(expected) {\n  return this.env.contains_(this.actual, expected);\n};\n\n/**\n * Matcher that checks that the expected item is NOT an element in the actual Array.\n *\n * @param {Object} expected\n * @deprecated as of 1.0. Use not.toContain() instead.\n */\njasmine.Matchers.prototype.toNotContain = function(expected) {\n  return !this.env.contains_(this.actual, expected);\n};\n\njasmine.Matchers.prototype.toBeLessThan = function(expected) {\n  return this.actual < expected;\n};\n\njasmine.Matchers.prototype.toBeGreaterThan = function(expected) {\n  return this.actual > expected;\n};\n\n/**\n * Matcher that checks that the expected item is equal to the actual item\n * up to a given level of decimal precision (default 2).\n *\n * @param {Number} expected\n * @param {Number} precision\n */\njasmine.Matchers.prototype.toBeCloseTo = function(expected, precision) {\n  if (!(precision === 0)) {\n    precision = precision || 2;\n  }\n  var multiplier = Math.pow(10, precision);\n  var actual = Math.round(this.actual * multiplier);\n  expected = Math.round(expected * multiplier);\n  return expected == actual;\n};\n\n/**\n * Matcher that checks that the expected exception was thrown by the actual.\n *\n * @param {String} expected\n */\njasmine.Matchers.prototype.toThrow = function(expected) {\n  var result = false;\n  var exception;\n  if (typeof this.actual != 'function') {\n    throw new Error('Actual is not a function');\n  }\n  try {\n    this.actual();\n  } catch (e) {\n    exception = e;\n  }\n  if (exception) {\n    result = (expected === jasmine.undefined || this.env.equals_(exception.message || exception, expected.message || expected));\n  }\n\n  var not = this.isNot ? \"not \" : \"\";\n\n  this.message = function() {\n    if (exception && (expected === jasmine.undefined || !this.env.equals_(exception.message || exception, expected.message || expected))) {\n      return [\"Expected function \" + not + \"to throw\", expected ? expected.message || expected : \"an exception\", \", but it threw\", exception.message || exception].join(' ');\n    } else {\n      return \"Expected function to throw an exception.\";\n    }\n  };\n\n  return result;\n};\n\njasmine.Matchers.Any = function(expectedClass) {\n  this.expectedClass = expectedClass;\n};\n\njasmine.Matchers.Any.prototype.jasmineMatches = function(other) {\n  if (this.expectedClass == String) {\n    return typeof other == 'string' || other instanceof String;\n  }\n\n  if (this.expectedClass == Number) {\n    return typeof other == 'number' || other instanceof Number;\n  }\n\n  if (this.expectedClass == Function) {\n    return typeof other == 'function' || other instanceof Function;\n  }\n\n  if (this.expectedClass == Object) {\n    return typeof other == 'object';\n  }\n\n  return other instanceof this.expectedClass;\n};\n\njasmine.Matchers.Any.prototype.jasmineToString = function() {\n  return '<jasmine.any(' + this.expectedClass + ')>';\n};\n\njasmine.Matchers.ObjectContaining = function (sample) {\n  this.sample = sample;\n};\n\njasmine.Matchers.ObjectContaining.prototype.jasmineMatches = function(other, mismatchKeys, mismatchValues) {\n  mismatchKeys = mismatchKeys || [];\n  mismatchValues = mismatchValues || [];\n\n  var env = jasmine.getEnv();\n\n  var hasKey = function(obj, keyName) {\n    return obj != null && obj[keyName] !== jasmine.undefined;\n  };\n\n  for (var property in this.sample) {\n    if (!hasKey(other, property) && hasKey(this.sample, property)) {\n      mismatchKeys.push(\"expected has key '\" + property + \"', but missing from actual.\");\n    }\n    else if (!env.equals_(this.sample[property], other[property], mismatchKeys, mismatchValues)) {\n      mismatchValues.push(\"'\" + property + \"' was '\" + (other[property] ? jasmine.util.htmlEscape(other[property].toString()) : other[property]) + \"' in expected, but was '\" + (this.sample[property] ? jasmine.util.htmlEscape(this.sample[property].toString()) : this.sample[property]) + \"' in actual.\");\n    }\n  }\n\n  return (mismatchKeys.length === 0 && mismatchValues.length === 0);\n};\n\njasmine.Matchers.ObjectContaining.prototype.jasmineToString = function () {\n  return \"<jasmine.objectContaining(\" + jasmine.pp(this.sample) + \")>\";\n};\n// Mock setTimeout, clearTimeout\n// Contributed by Pivotal Computer Systems, www.pivotalsf.com\n\njasmine.FakeTimer = function() {\n  this.reset();\n\n  var self = this;\n  self.setTimeout = function(funcToCall, millis) {\n    self.timeoutsMade++;\n    self.scheduleFunction(self.timeoutsMade, funcToCall, millis, false);\n    return self.timeoutsMade;\n  };\n\n  self.setInterval = function(funcToCall, millis) {\n    self.timeoutsMade++;\n    self.scheduleFunction(self.timeoutsMade, funcToCall, millis, true);\n    return self.timeoutsMade;\n  };\n\n  self.clearTimeout = function(timeoutKey) {\n    self.scheduledFunctions[timeoutKey] = jasmine.undefined;\n  };\n\n  self.clearInterval = function(timeoutKey) {\n    self.scheduledFunctions[timeoutKey] = jasmine.undefined;\n  };\n\n};\n\njasmine.FakeTimer.prototype.reset = function() {\n  this.timeoutsMade = 0;\n  this.scheduledFunctions = {};\n  this.nowMillis = 0;\n};\n\njasmine.FakeTimer.prototype.tick = function(millis) {\n  var oldMillis = this.nowMillis;\n  var newMillis = oldMillis + millis;\n  this.runFunctionsWithinRange(oldMillis, newMillis);\n  this.nowMillis = newMillis;\n};\n\njasmine.FakeTimer.prototype.runFunctionsWithinRange = function(oldMillis, nowMillis) {\n  var scheduledFunc;\n  var funcsToRun = [];\n  for (var timeoutKey in this.scheduledFunctions) {\n    scheduledFunc = this.scheduledFunctions[timeoutKey];\n    if (scheduledFunc != jasmine.undefined &&\n        scheduledFunc.runAtMillis >= oldMillis &&\n        scheduledFunc.runAtMillis <= nowMillis) {\n      funcsToRun.push(scheduledFunc);\n      this.scheduledFunctions[timeoutKey] = jasmine.undefined;\n    }\n  }\n\n  if (funcsToRun.length > 0) {\n    funcsToRun.sort(function(a, b) {\n      return a.runAtMillis - b.runAtMillis;\n    });\n    for (var i = 0; i < funcsToRun.length; ++i) {\n      try {\n        var funcToRun = funcsToRun[i];\n        this.nowMillis = funcToRun.runAtMillis;\n        funcToRun.funcToCall();\n        if (funcToRun.recurring) {\n          this.scheduleFunction(funcToRun.timeoutKey,\n              funcToRun.funcToCall,\n              funcToRun.millis,\n              true);\n        }\n      } catch(e) {\n      }\n    }\n    this.runFunctionsWithinRange(oldMillis, nowMillis);\n  }\n};\n\njasmine.FakeTimer.prototype.scheduleFunction = function(timeoutKey, funcToCall, millis, recurring) {\n  this.scheduledFunctions[timeoutKey] = {\n    runAtMillis: this.nowMillis + millis,\n    funcToCall: funcToCall,\n    recurring: recurring,\n    timeoutKey: timeoutKey,\n    millis: millis\n  };\n};\n\n/**\n * @namespace\n */\njasmine.Clock = {\n  defaultFakeTimer: new jasmine.FakeTimer(),\n\n  reset: function() {\n    jasmine.Clock.assertInstalled();\n    jasmine.Clock.defaultFakeTimer.reset();\n  },\n\n  tick: function(millis) {\n    jasmine.Clock.assertInstalled();\n    jasmine.Clock.defaultFakeTimer.tick(millis);\n  },\n\n  runFunctionsWithinRange: function(oldMillis, nowMillis) {\n    jasmine.Clock.defaultFakeTimer.runFunctionsWithinRange(oldMillis, nowMillis);\n  },\n\n  scheduleFunction: function(timeoutKey, funcToCall, millis, recurring) {\n    jasmine.Clock.defaultFakeTimer.scheduleFunction(timeoutKey, funcToCall, millis, recurring);\n  },\n\n  useMock: function() {\n    if (!jasmine.Clock.isInstalled()) {\n      var spec = jasmine.getEnv().currentSpec;\n      spec.after(jasmine.Clock.uninstallMock);\n\n      jasmine.Clock.installMock();\n    }\n  },\n\n  installMock: function() {\n    jasmine.Clock.installed = jasmine.Clock.defaultFakeTimer;\n  },\n\n  uninstallMock: function() {\n    jasmine.Clock.assertInstalled();\n    jasmine.Clock.installed = jasmine.Clock.real;\n  },\n\n  real: {\n    setTimeout: jasmine.getGlobal().setTimeout,\n    clearTimeout: jasmine.getGlobal().clearTimeout,\n    setInterval: jasmine.getGlobal().setInterval,\n    clearInterval: jasmine.getGlobal().clearInterval\n  },\n\n  assertInstalled: function() {\n    if (!jasmine.Clock.isInstalled()) {\n      throw new Error(\"Mock clock is not installed, use jasmine.Clock.useMock()\");\n    }\n  },\n\n  isInstalled: function() {\n    return jasmine.Clock.installed == jasmine.Clock.defaultFakeTimer;\n  },\n\n  installed: null\n};\njasmine.Clock.installed = jasmine.Clock.real;\n\n//else for IE support\njasmine.getGlobal().setTimeout = function(funcToCall, millis) {\n  if (jasmine.Clock.installed.setTimeout.apply) {\n    return jasmine.Clock.installed.setTimeout.apply(this, arguments);\n  } else {\n    return jasmine.Clock.installed.setTimeout(funcToCall, millis);\n  }\n};\n\njasmine.getGlobal().setInterval = function(funcToCall, millis) {\n  if (jasmine.Clock.installed.setInterval.apply) {\n    return jasmine.Clock.installed.setInterval.apply(this, arguments);\n  } else {\n    return jasmine.Clock.installed.setInterval(funcToCall, millis);\n  }\n};\n\njasmine.getGlobal().clearTimeout = function(timeoutKey) {\n  if (jasmine.Clock.installed.clearTimeout.apply) {\n    return jasmine.Clock.installed.clearTimeout.apply(this, arguments);\n  } else {\n    return jasmine.Clock.installed.clearTimeout(timeoutKey);\n  }\n};\n\njasmine.getGlobal().clearInterval = function(timeoutKey) {\n  if (jasmine.Clock.installed.clearTimeout.apply) {\n    return jasmine.Clock.installed.clearInterval.apply(this, arguments);\n  } else {\n    return jasmine.Clock.installed.clearInterval(timeoutKey);\n  }\n};\n\n/**\n * @constructor\n */\njasmine.MultiReporter = function() {\n  this.subReporters_ = [];\n};\njasmine.util.inherit(jasmine.MultiReporter, jasmine.Reporter);\n\njasmine.MultiReporter.prototype.addReporter = function(reporter) {\n  this.subReporters_.push(reporter);\n};\n\n(function() {\n  var functionNames = [\n    \"reportRunnerStarting\",\n    \"reportRunnerResults\",\n    \"reportSuiteResults\",\n    \"reportSpecStarting\",\n    \"reportSpecResults\",\n    \"log\"\n  ];\n  for (var i = 0; i < functionNames.length; i++) {\n    var functionName = functionNames[i];\n    jasmine.MultiReporter.prototype[functionName] = (function(functionName) {\n      return function() {\n        for (var j = 0; j < this.subReporters_.length; j++) {\n          var subReporter = this.subReporters_[j];\n          if (subReporter[functionName]) {\n            subReporter[functionName].apply(subReporter, arguments);\n          }\n        }\n      };\n    })(functionName);\n  }\n})();\n/**\n * Holds results for a set of Jasmine spec. Allows for the results array to hold another jasmine.NestedResults\n *\n * @constructor\n */\njasmine.NestedResults = function() {\n  /**\n   * The total count of results\n   */\n  this.totalCount = 0;\n  /**\n   * Number of passed results\n   */\n  this.passedCount = 0;\n  /**\n   * Number of failed results\n   */\n  this.failedCount = 0;\n  /**\n   * Was this suite/spec skipped?\n   */\n  this.skipped = false;\n  /**\n   * @ignore\n   */\n  this.items_ = [];\n};\n\n/**\n * Roll up the result counts.\n *\n * @param result\n */\njasmine.NestedResults.prototype.rollupCounts = function(result) {\n  this.totalCount += result.totalCount;\n  this.passedCount += result.passedCount;\n  this.failedCount += result.failedCount;\n};\n\n/**\n * Adds a log message.\n * @param values Array of message parts which will be concatenated later.\n */\njasmine.NestedResults.prototype.log = function(values) {\n  this.items_.push(new jasmine.MessageResult(values));\n};\n\n/**\n * Getter for the results: message & results.\n */\njasmine.NestedResults.prototype.getItems = function() {\n  return this.items_;\n};\n\n/**\n * Adds a result, tracking counts (total, passed, & failed)\n * @param {jasmine.ExpectationResult|jasmine.NestedResults} result\n */\njasmine.NestedResults.prototype.addResult = function(result) {\n  if (result.type != 'log') {\n    if (result.items_) {\n      this.rollupCounts(result);\n    } else {\n      this.totalCount++;\n      if (result.passed()) {\n        this.passedCount++;\n      } else {\n        this.failedCount++;\n      }\n    }\n  }\n  this.items_.push(result);\n};\n\n/**\n * @returns {Boolean} True if <b>everything</b> below passed\n */\njasmine.NestedResults.prototype.passed = function() {\n  return this.passedCount === this.totalCount;\n};\n/**\n * Base class for pretty printing for expectation results.\n */\njasmine.PrettyPrinter = function() {\n  this.ppNestLevel_ = 0;\n};\n\n/**\n * Formats a value in a nice, human-readable string.\n *\n * @param value\n */\njasmine.PrettyPrinter.prototype.format = function(value) {\n  if (this.ppNestLevel_ > 40) {\n    throw new Error('jasmine.PrettyPrinter: format() nested too deeply!');\n  }\n\n  this.ppNestLevel_++;\n  try {\n    if (value === jasmine.undefined) {\n      this.emitScalar('undefined');\n    } else if (value === null) {\n      this.emitScalar('null');\n    } else if (value === jasmine.getGlobal()) {\n      this.emitScalar('<global>');\n    } else if (value.jasmineToString) {\n      this.emitScalar(value.jasmineToString());\n    } else if (typeof value === 'string') {\n      this.emitString(value);\n    } else if (jasmine.isSpy(value)) {\n      this.emitScalar(\"spy on \" + value.identity);\n    } else if (value instanceof RegExp) {\n      this.emitScalar(value.toString());\n    } else if (typeof value === 'function') {\n      this.emitScalar('Function');\n    } else if (typeof value.nodeType === 'number') {\n      this.emitScalar('HTMLNode');\n    } else if (value instanceof Date) {\n      this.emitScalar('Date(' + value + ')');\n    } else if (value.__Jasmine_been_here_before__) {\n      this.emitScalar('<circular reference: ' + (jasmine.isArray_(value) ? 'Array' : 'Object') + '>');\n    } else if (jasmine.isArray_(value) || typeof value == 'object') {\n      value.__Jasmine_been_here_before__ = true;\n      if (jasmine.isArray_(value)) {\n        this.emitArray(value);\n      } else {\n        this.emitObject(value);\n      }\n      delete value.__Jasmine_been_here_before__;\n    } else {\n      this.emitScalar(value.toString());\n    }\n  } finally {\n    this.ppNestLevel_--;\n  }\n};\n\njasmine.PrettyPrinter.prototype.iterateObject = function(obj, fn) {\n  for (var property in obj) {\n    if (property == '__Jasmine_been_here_before__') continue;\n    fn(property, obj.__lookupGetter__ ? (obj.__lookupGetter__(property) !== jasmine.undefined && \n                                         obj.__lookupGetter__(property) !== null) : false);\n  }\n};\n\njasmine.PrettyPrinter.prototype.emitArray = jasmine.unimplementedMethod_;\njasmine.PrettyPrinter.prototype.emitObject = jasmine.unimplementedMethod_;\njasmine.PrettyPrinter.prototype.emitScalar = jasmine.unimplementedMethod_;\njasmine.PrettyPrinter.prototype.emitString = jasmine.unimplementedMethod_;\n\njasmine.StringPrettyPrinter = function() {\n  jasmine.PrettyPrinter.call(this);\n\n  this.string = '';\n};\njasmine.util.inherit(jasmine.StringPrettyPrinter, jasmine.PrettyPrinter);\n\njasmine.StringPrettyPrinter.prototype.emitScalar = function(value) {\n  this.append(value);\n};\n\njasmine.StringPrettyPrinter.prototype.emitString = function(value) {\n  this.append(\"'\" + value + \"'\");\n};\n\njasmine.StringPrettyPrinter.prototype.emitArray = function(array) {\n  this.append('[ ');\n  for (var i = 0; i < array.length; i++) {\n    if (i > 0) {\n      this.append(', ');\n    }\n    this.format(array[i]);\n  }\n  this.append(' ]');\n};\n\njasmine.StringPrettyPrinter.prototype.emitObject = function(obj) {\n  var self = this;\n  this.append('{ ');\n  var first = true;\n\n  this.iterateObject(obj, function(property, isGetter) {\n    if (first) {\n      first = false;\n    } else {\n      self.append(', ');\n    }\n\n    self.append(property);\n    self.append(' : ');\n    if (isGetter) {\n      self.append('<getter>');\n    } else {\n      self.format(obj[property]);\n    }\n  });\n\n  this.append(' }');\n};\n\njasmine.StringPrettyPrinter.prototype.append = function(value) {\n  this.string += value;\n};\njasmine.Queue = function(env) {\n  this.env = env;\n  this.blocks = [];\n  this.running = false;\n  this.index = 0;\n  this.offset = 0;\n  this.abort = false;\n};\n\njasmine.Queue.prototype.addBefore = function(block) {\n  this.blocks.unshift(block);\n};\n\njasmine.Queue.prototype.add = function(block) {\n  this.blocks.push(block);\n};\n\njasmine.Queue.prototype.insertNext = function(block) {\n  this.blocks.splice((this.index + this.offset + 1), 0, block);\n  this.offset++;\n};\n\njasmine.Queue.prototype.start = function(onComplete) {\n  this.running = true;\n  this.onComplete = onComplete;\n  this.next_();\n};\n\njasmine.Queue.prototype.isRunning = function() {\n  return this.running;\n};\n\njasmine.Queue.LOOP_DONT_RECURSE = true;\n\njasmine.Queue.prototype.next_ = function() {\n  var self = this;\n  var goAgain = true;\n\n  while (goAgain) {\n    goAgain = false;\n    \n    if (self.index < self.blocks.length && !this.abort) {\n      var calledSynchronously = true;\n      var completedSynchronously = false;\n\n      var onComplete = function () {\n        if (jasmine.Queue.LOOP_DONT_RECURSE && calledSynchronously) {\n          completedSynchronously = true;\n          return;\n        }\n\n        if (self.blocks[self.index].abort) {\n          self.abort = true;\n        }\n\n        self.offset = 0;\n        self.index++;\n\n        var now = new Date().getTime();\n        if (self.env.updateInterval && now - self.env.lastUpdate > self.env.updateInterval) {\n          self.env.lastUpdate = now;\n          self.env.setTimeout(function() {\n            self.next_();\n          }, 0);\n        } else {\n          if (jasmine.Queue.LOOP_DONT_RECURSE && completedSynchronously) {\n            goAgain = true;\n          } else {\n            self.next_();\n          }\n        }\n      };\n      self.blocks[self.index].execute(onComplete);\n\n      calledSynchronously = false;\n      if (completedSynchronously) {\n        onComplete();\n      }\n      \n    } else {\n      self.running = false;\n      if (self.onComplete) {\n        self.onComplete();\n      }\n    }\n  }\n};\n\njasmine.Queue.prototype.results = function() {\n  var results = new jasmine.NestedResults();\n  for (var i = 0; i < this.blocks.length; i++) {\n    if (this.blocks[i].results) {\n      results.addResult(this.blocks[i].results());\n    }\n  }\n  return results;\n};\n\n\n/**\n * Runner\n *\n * @constructor\n * @param {jasmine.Env} env\n */\njasmine.Runner = function(env) {\n  var self = this;\n  self.env = env;\n  self.queue = new jasmine.Queue(env);\n  self.before_ = [];\n  self.after_ = [];\n  self.suites_ = [];\n};\n\njasmine.Runner.prototype.execute = function() {\n  var self = this;\n  if (self.env.reporter.reportRunnerStarting) {\n    self.env.reporter.reportRunnerStarting(this);\n  }\n  self.queue.start(function () {\n    self.finishCallback();\n  });\n};\n\njasmine.Runner.prototype.beforeEach = function(beforeEachFunction) {\n  beforeEachFunction.typeName = 'beforeEach';\n  this.before_.splice(0,0,beforeEachFunction);\n};\n\njasmine.Runner.prototype.afterEach = function(afterEachFunction) {\n  afterEachFunction.typeName = 'afterEach';\n  this.after_.splice(0,0,afterEachFunction);\n};\n\n\njasmine.Runner.prototype.finishCallback = function() {\n  this.env.reporter.reportRunnerResults(this);\n};\n\njasmine.Runner.prototype.addSuite = function(suite) {\n  this.suites_.push(suite);\n};\n\njasmine.Runner.prototype.add = function(block) {\n  if (block instanceof jasmine.Suite) {\n    this.addSuite(block);\n  }\n  this.queue.add(block);\n};\n\njasmine.Runner.prototype.specs = function () {\n  var suites = this.suites();\n  var specs = [];\n  for (var i = 0; i < suites.length; i++) {\n    specs = specs.concat(suites[i].specs());\n  }\n  return specs;\n};\n\njasmine.Runner.prototype.suites = function() {\n  return this.suites_;\n};\n\njasmine.Runner.prototype.topLevelSuites = function() {\n  var topLevelSuites = [];\n  for (var i = 0; i < this.suites_.length; i++) {\n    if (!this.suites_[i].parentSuite) {\n      topLevelSuites.push(this.suites_[i]);\n    }\n  }\n  return topLevelSuites;\n};\n\njasmine.Runner.prototype.results = function() {\n  return this.queue.results();\n};\n/**\n * Internal representation of a Jasmine specification, or test.\n *\n * @constructor\n * @param {jasmine.Env} env\n * @param {jasmine.Suite} suite\n * @param {String} description\n */\njasmine.Spec = function(env, suite, description) {\n  if (!env) {\n    throw new Error('jasmine.Env() required');\n  }\n  if (!suite) {\n    throw new Error('jasmine.Suite() required');\n  }\n  var spec = this;\n  spec.id = env.nextSpecId ? env.nextSpecId() : null;\n  spec.env = env;\n  spec.suite = suite;\n  spec.description = description;\n  spec.queue = new jasmine.Queue(env);\n\n  spec.afterCallbacks = [];\n  spec.spies_ = [];\n\n  spec.results_ = new jasmine.NestedResults();\n  spec.results_.description = description;\n  spec.matchersClass = null;\n};\n\njasmine.Spec.prototype.getFullName = function() {\n  return this.suite.getFullName() + ' ' + this.description + '.';\n};\n\n\njasmine.Spec.prototype.results = function() {\n  return this.results_;\n};\n\n/**\n * All parameters are pretty-printed and concatenated together, then written to the spec's output.\n *\n * Be careful not to leave calls to <code>jasmine.log</code> in production code.\n */\njasmine.Spec.prototype.log = function() {\n  return this.results_.log(arguments);\n};\n\njasmine.Spec.prototype.runs = function (func) {\n  var block = new jasmine.Block(this.env, func, this);\n  this.addToQueue(block);\n  return this;\n};\n\njasmine.Spec.prototype.addToQueue = function (block) {\n  if (this.queue.isRunning()) {\n    this.queue.insertNext(block);\n  } else {\n    this.queue.add(block);\n  }\n};\n\n/**\n * @param {jasmine.ExpectationResult} result\n */\njasmine.Spec.prototype.addMatcherResult = function(result) {\n  this.results_.addResult(result);\n};\n\njasmine.Spec.prototype.expect = function(actual) {\n  var positive = new (this.getMatchersClass_())(this.env, actual, this);\n  positive.not = new (this.getMatchersClass_())(this.env, actual, this, true);\n  return positive;\n};\n\n/**\n * Waits a fixed time period before moving to the next block.\n *\n * @deprecated Use waitsFor() instead\n * @param {Number} timeout milliseconds to wait\n */\njasmine.Spec.prototype.waits = function(timeout) {\n  var waitsFunc = new jasmine.WaitsBlock(this.env, timeout, this);\n  this.addToQueue(waitsFunc);\n  return this;\n};\n\n/**\n * Waits for the latchFunction to return true before proceeding to the next block.\n *\n * @param {Function} latchFunction\n * @param {String} optional_timeoutMessage\n * @param {Number} optional_timeout\n */\njasmine.Spec.prototype.waitsFor = function(latchFunction, optional_timeoutMessage, optional_timeout) {\n  var latchFunction_ = null;\n  var optional_timeoutMessage_ = null;\n  var optional_timeout_ = null;\n\n  for (var i = 0; i < arguments.length; i++) {\n    var arg = arguments[i];\n    switch (typeof arg) {\n      case 'function':\n        latchFunction_ = arg;\n        break;\n      case 'string':\n        optional_timeoutMessage_ = arg;\n        break;\n      case 'number':\n        optional_timeout_ = arg;\n        break;\n    }\n  }\n\n  var waitsForFunc = new jasmine.WaitsForBlock(this.env, optional_timeout_, latchFunction_, optional_timeoutMessage_, this);\n  this.addToQueue(waitsForFunc);\n  return this;\n};\n\njasmine.Spec.prototype.fail = function (e) {\n  var expectationResult = new jasmine.ExpectationResult({\n    passed: false,\n    message: e ? jasmine.util.formatException(e) : 'Exception',\n    trace: { stack: e.stack }\n  });\n  this.results_.addResult(expectationResult);\n};\n\njasmine.Spec.prototype.getMatchersClass_ = function() {\n  return this.matchersClass || this.env.matchersClass;\n};\n\njasmine.Spec.prototype.addMatchers = function(matchersPrototype) {\n  var parent = this.getMatchersClass_();\n  var newMatchersClass = function() {\n    parent.apply(this, arguments);\n  };\n  jasmine.util.inherit(newMatchersClass, parent);\n  jasmine.Matchers.wrapInto_(matchersPrototype, newMatchersClass);\n  this.matchersClass = newMatchersClass;\n};\n\njasmine.Spec.prototype.finishCallback = function() {\n  this.env.reporter.reportSpecResults(this);\n};\n\njasmine.Spec.prototype.finish = function(onComplete) {\n  this.removeAllSpies();\n  this.finishCallback();\n  if (onComplete) {\n    onComplete();\n  }\n};\n\njasmine.Spec.prototype.after = function(doAfter) {\n  if (this.queue.isRunning()) {\n    this.queue.add(new jasmine.Block(this.env, doAfter, this));\n  } else {\n    this.afterCallbacks.unshift(doAfter);\n  }\n};\n\njasmine.Spec.prototype.execute = function(onComplete) {\n  var spec = this;\n  if (!spec.env.specFilter(spec)) {\n    spec.results_.skipped = true;\n    spec.finish(onComplete);\n    return;\n  }\n\n  this.env.reporter.reportSpecStarting(this);\n\n  spec.env.currentSpec = spec;\n\n  spec.addBeforesAndAftersToQueue();\n\n  spec.queue.start(function () {\n    spec.finish(onComplete);\n  });\n};\n\njasmine.Spec.prototype.addBeforesAndAftersToQueue = function() {\n  var runner = this.env.currentRunner();\n  var i;\n\n  for (var suite = this.suite; suite; suite = suite.parentSuite) {\n    for (i = 0; i < suite.before_.length; i++) {\n      this.queue.addBefore(new jasmine.Block(this.env, suite.before_[i], this));\n    }\n  }\n  for (i = 0; i < runner.before_.length; i++) {\n    this.queue.addBefore(new jasmine.Block(this.env, runner.before_[i], this));\n  }\n  for (i = 0; i < this.afterCallbacks.length; i++) {\n    this.queue.add(new jasmine.Block(this.env, this.afterCallbacks[i], this));\n  }\n  for (suite = this.suite; suite; suite = suite.parentSuite) {\n    for (i = 0; i < suite.after_.length; i++) {\n      this.queue.add(new jasmine.Block(this.env, suite.after_[i], this));\n    }\n  }\n  for (i = 0; i < runner.after_.length; i++) {\n    this.queue.add(new jasmine.Block(this.env, runner.after_[i], this));\n  }\n};\n\njasmine.Spec.prototype.explodes = function() {\n  throw 'explodes function should not have been called';\n};\n\njasmine.Spec.prototype.spyOn = function(obj, methodName, ignoreMethodDoesntExist) {\n  if (obj == jasmine.undefined) {\n    throw \"spyOn could not find an object to spy upon for \" + methodName + \"()\";\n  }\n\n  if (!ignoreMethodDoesntExist && obj[methodName] === jasmine.undefined) {\n    throw methodName + '() method does not exist';\n  }\n\n  if (!ignoreMethodDoesntExist && obj[methodName] && obj[methodName].isSpy) {\n    throw new Error(methodName + ' has already been spied upon');\n  }\n\n  var spyObj = jasmine.createSpy(methodName);\n\n  this.spies_.push(spyObj);\n  spyObj.baseObj = obj;\n  spyObj.methodName = methodName;\n  spyObj.originalValue = obj[methodName];\n\n  obj[methodName] = spyObj;\n\n  return spyObj;\n};\n\njasmine.Spec.prototype.removeAllSpies = function() {\n  for (var i = 0; i < this.spies_.length; i++) {\n    var spy = this.spies_[i];\n    spy.baseObj[spy.methodName] = spy.originalValue;\n  }\n  this.spies_ = [];\n};\n\n/**\n * Internal representation of a Jasmine suite.\n *\n * @constructor\n * @param {jasmine.Env} env\n * @param {String} description\n * @param {Function} specDefinitions\n * @param {jasmine.Suite} parentSuite\n */\njasmine.Suite = function(env, description, specDefinitions, parentSuite) {\n  var self = this;\n  self.id = env.nextSuiteId ? env.nextSuiteId() : null;\n  self.description = description;\n  self.queue = new jasmine.Queue(env);\n  self.parentSuite = parentSuite;\n  self.env = env;\n  self.before_ = [];\n  self.after_ = [];\n  self.children_ = [];\n  self.suites_ = [];\n  self.specs_ = [];\n};\n\njasmine.Suite.prototype.getFullName = function() {\n  var fullName = this.description;\n  for (var parentSuite = this.parentSuite; parentSuite; parentSuite = parentSuite.parentSuite) {\n    fullName = parentSuite.description + ' ' + fullName;\n  }\n  return fullName;\n};\n\njasmine.Suite.prototype.finish = function(onComplete) {\n  this.env.reporter.reportSuiteResults(this);\n  this.finished = true;\n  if (typeof(onComplete) == 'function') {\n    onComplete();\n  }\n};\n\njasmine.Suite.prototype.beforeEach = function(beforeEachFunction) {\n  beforeEachFunction.typeName = 'beforeEach';\n  this.before_.unshift(beforeEachFunction);\n};\n\njasmine.Suite.prototype.afterEach = function(afterEachFunction) {\n  afterEachFunction.typeName = 'afterEach';\n  this.after_.unshift(afterEachFunction);\n};\n\njasmine.Suite.prototype.results = function() {\n  return this.queue.results();\n};\n\njasmine.Suite.prototype.add = function(suiteOrSpec) {\n  this.children_.push(suiteOrSpec);\n  if (suiteOrSpec instanceof jasmine.Suite) {\n    this.suites_.push(suiteOrSpec);\n    this.env.currentRunner().addSuite(suiteOrSpec);\n  } else {\n    this.specs_.push(suiteOrSpec);\n  }\n  this.queue.add(suiteOrSpec);\n};\n\njasmine.Suite.prototype.specs = function() {\n  return this.specs_;\n};\n\njasmine.Suite.prototype.suites = function() {\n  return this.suites_;\n};\n\njasmine.Suite.prototype.children = function() {\n  return this.children_;\n};\n\njasmine.Suite.prototype.execute = function(onComplete) {\n  var self = this;\n  this.queue.start(function () {\n    self.finish(onComplete);\n  });\n};\njasmine.WaitsBlock = function(env, timeout, spec) {\n  this.timeout = timeout;\n  jasmine.Block.call(this, env, null, spec);\n};\n\njasmine.util.inherit(jasmine.WaitsBlock, jasmine.Block);\n\njasmine.WaitsBlock.prototype.execute = function (onComplete) {\n  if (jasmine.VERBOSE) {\n    this.env.reporter.log('>> Jasmine waiting for ' + this.timeout + ' ms...');\n  }\n  this.env.setTimeout(function () {\n    onComplete();\n  }, this.timeout);\n};\n/**\n * A block which waits for some condition to become true, with timeout.\n *\n * @constructor\n * @extends jasmine.Block\n * @param {jasmine.Env} env The Jasmine environment.\n * @param {Number} timeout The maximum time in milliseconds to wait for the condition to become true.\n * @param {Function} latchFunction A function which returns true when the desired condition has been met.\n * @param {String} message The message to display if the desired condition hasn't been met within the given time period.\n * @param {jasmine.Spec} spec The Jasmine spec.\n */\njasmine.WaitsForBlock = function(env, timeout, latchFunction, message, spec) {\n  this.timeout = timeout || env.defaultTimeoutInterval;\n  this.latchFunction = latchFunction;\n  this.message = message;\n  this.totalTimeSpentWaitingForLatch = 0;\n  jasmine.Block.call(this, env, null, spec);\n};\njasmine.util.inherit(jasmine.WaitsForBlock, jasmine.Block);\n\njasmine.WaitsForBlock.TIMEOUT_INCREMENT = 10;\n\njasmine.WaitsForBlock.prototype.execute = function(onComplete) {\n  if (jasmine.VERBOSE) {\n    this.env.reporter.log('>> Jasmine waiting for ' + (this.message || 'something to happen'));\n  }\n  var latchFunctionResult;\n  try {\n    latchFunctionResult = this.latchFunction.apply(this.spec);\n  } catch (e) {\n    this.spec.fail(e);\n    onComplete();\n    return;\n  }\n\n  if (latchFunctionResult) {\n    onComplete();\n  } else if (this.totalTimeSpentWaitingForLatch >= this.timeout) {\n    var message = 'timed out after ' + this.timeout + ' msec waiting for ' + (this.message || 'something to happen');\n    this.spec.fail({\n      name: 'timeout',\n      message: message\n    });\n\n    this.abort = true;\n    onComplete();\n  } else {\n    this.totalTimeSpentWaitingForLatch += jasmine.WaitsForBlock.TIMEOUT_INCREMENT;\n    var self = this;\n    this.env.setTimeout(function() {\n      self.execute(onComplete);\n    }, jasmine.WaitsForBlock.TIMEOUT_INCREMENT);\n  }\n};\n\njasmine.version_= {\n  \"major\": 1,\n  \"minor\": 2,\n  \"build\": 0,\n  \"revision\": 1337005947\n};\n"
  },
  {
    "path": "spec/lib/jasmine-promise.js",
    "content": "\"use strict\";\n\n/**\n * Modifies the way that individual specs are run to easily test async\n * code with promises.\n *\n * A spec may return a promise. If it does, then the spec passes if and\n * only if that promise is fulfilled within a very short period of time.\n * If it is rejected, or if it isn't fulfilled quickly, the spec fails.\n *\n * In this way, we can use promise chaining to structure our asynchronous\n * tests. Expectations all down the chain of promises are all checked and\n * guaranteed to be run and resolved or the test fails.\n *\n * This is a big win over the runs() and watches() code that jasmine\n * supports out of the box.\n */\njasmine.Block.prototype.execute = function (onComplete) {\n    var spec = this.spec;\n    try {\n        var result = this.func.call(spec, onComplete);\n\n        // It seems Jasmine likes to return the suite if you pass it anything.\n        // So make sure it's a promise first.\n        if (result && typeof result.then === \"function\") {\n            Q.timeout(result, 500).then(function () {\n                onComplete();\n            }, function (error) {\n                spec.fail(error);\n                onComplete();\n            });\n        } else if (this.func.length === 0) {\n            onComplete();\n        }\n    } catch (error) {\n        spec.fail(error);\n        onComplete();\n    }\n};\n\n/**\n * Tests and documents the behavior of the above extension to jasmine.\n */\ndescribe('jasmine-promise', function() {\n  it('passes if the deferred resolves immediately', function() {\n    var deferred = Q.defer();\n    deferred.resolve();\n    return deferred.promise;\n  });\n  it('passes if the deferred resolves after a short delay', function() {\n    var deferred = Q.defer();\n    setTimeout(function() {deferred.resolve();}, 100);\n    return deferred.promise;\n  });\n  it('lets specs that return nothing pass', function() {\n\n  });\n  it('lets specs that return non-promises pass', function() {\n    return {'some object': 'with values'};\n  });\n  it('works ok with specs that return crappy non-Q promises', function() {\n    return {\n      'then': function(callback) {\n        callback();\n      }\n    }\n  });\n  // These are expected to fail. Remove the x from xdescribe to test that.\n  xdescribe('failure cases (expected to fail)', function() {\n    it('fails if the deferred is rejected', function() {\n      var deferred = Q.defer();\n      deferred.reject();\n      return deferred.promise;\n    });\n    it('fails if the deferred takes too long to resolve', function() {\n      var deferred = Q.defer();\n      setTimeout(function() {deferred.resolve()}, 5 * 1000);\n      return deferred.promise;\n    });\n    it('fails if a returned crappy non-Q promise is rejected', function() {\n      return {\n        'then': function(_, callback) {callback()}\n      }\n    });\n    it('fails if a returned crappy promise is never resolved', function() {\n      return {\n        'then': function() {}\n      }\n    });\n  })\n});\n"
  },
  {
    "path": "spec/q-spec.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n    <title>Jasmine Spec Runner</title>\n    <meta charset=\"utf-8\" />\n\n    <link rel=\"shortcut icon\" type=\"image/png\" href=\"lib/jasmine-1.2.0/jasmine_favicon.png\" />\n    <link rel=\"stylesheet\" href=\"lib/jasmine-1.2.0/jasmine.css\" />\n    <script src=\"lib/jasmine-1.2.0/jasmine.js\"></script>\n    <script src=\"lib/jasmine-1.2.0/jasmine-html.js\"></script>\n    <script src=\"lib/jasmine-promise.js\"></script>\n\n    <!-- include source files here... -->\n    <script src=\"../q.js\"></script>\n\n    <!-- include spec files here... -->\n    <script src=\"q-spec.js\"></script>\n\n    <script>\n        (function() {\n            var jasmineEnv = jasmine.getEnv();\n            jasmineEnv.updateInterval = 1000;\n\n            var htmlReporter = new jasmine.HtmlReporter();\n\n            jasmineEnv.addReporter(htmlReporter);\n\n            jasmineEnv.specFilter = function(spec) {\n                return htmlReporter.specFilter(spec);\n            };\n\n            var currentWindowOnload = window.onload;\n\n            window.onload = function() {\n                if (currentWindowOnload) {\n                    currentWindowOnload();\n                }\n                execJasmine();\n            };\n\n            function execJasmine() {\n                jasmineEnv.execute();\n            }\n\n        })();\n    </script>\n\n</head>\n\n<body>\n</body>\n</html>\n"
  },
  {
    "path": "spec/q-spec.js",
    "content": "\"use strict\";\n/*jshint newcap: false*/\n/*global Q: true, describe: false, it: false, expect: false, beforeEach: false,\n         afterEach: false, require: false, jasmine: false, waitsFor: false,\n         runs: false */\n\nif (typeof Q === \"undefined\" && typeof require !== \"undefined\") {\n    // For Node compatibility.\n    global.Q = require(\"../q\");\n    require(\"./lib/jasmine-promise\");\n}\n\nvar REASON = \"this is not an error, but it might show up in the console\";\n\n// In browsers that support strict mode, it'll be `undefined`; otherwise, the global.\nvar calledAsFunctionThis = (function () { return this; }());\n\nafterEach(function () {\n    Q.onerror = null;\n});\n\ndescribe(\"computing sum of integers using promises\", function() {\n    it(\"should compute correct result without blowing stack\", function () {\n        var array = [];\n        var iters = 1000;\n        for (var i = 1; i <= iters; i++) {\n            array.push(i);\n        }\n\n        var pZero = Q.fulfill(0);\n        var result = array.reduce(function (promise, nextVal) {\n            return promise.then(function (currentVal) {\n                return Q.fulfill(currentVal + nextVal);\n            });\n        }, pZero);\n\n        return result.then(function (value) {\n            expect(value).toEqual(iters * (iters + 1) / 2);\n        });\n    });\n});\n\ndescribe(\"Q function\", function () {\n    it(\"should result in a fulfilled promise when given a value\", function () {\n        expect(Q(5).isFulfilled()).toBe(true);\n    });\n\n    it(\"should be the identity when given promise\", function () {\n        var f = Q.fulfill(5);\n        var r = Q.reject(new Error(\"aaargh\"));\n        var p = Q.promise(function () { });\n\n        expect(Q(f)).toBe(f);\n        expect(Q(r)).toBe(r);\n        expect(Q(p)).toBe(p);\n    });\n});\n\ndescribe(\"defer and when\", function () {\n\n    it(\"resolve before when\", function () {\n        var turn = 0;\n        var deferred = Q.defer();\n        deferred.resolve(10);\n        var promise = Q.when(deferred.promise, function (value) {\n            expect(turn).toEqual(1);\n            expect(value).toEqual(10);\n        });\n        turn++;\n        return promise;\n    });\n\n    it(\"reject before when\", function () {\n        var turn = 0;\n        var deferred = Q.defer();\n        deferred.reject(-1);\n        var promise = Q.when(deferred.promise, function () {\n            expect(true).toBe(false);\n        }, function (value) {\n            expect(turn).toEqual(1);\n            expect(value).toEqual(-1);\n        });\n        turn++;\n        return promise;\n    });\n\n    it(\"when before resolve\", function () {\n        var turn = 0;\n        var deferred = Q.defer();\n        var promise = deferred.promise.then(function (value) {\n            expect(turn).toEqual(2);\n            expect(value).toEqual(10);\n            turn++;\n        });\n        Q.nextTick(function () {\n            expect(turn).toEqual(1);\n            deferred.resolve(10);\n            turn++;\n        });\n        turn++;\n        return promise;\n    });\n\n    it(\"when before reject\", function () {\n        var turn = 0;\n        var deferred = Q.defer();\n        var promise = deferred.promise.then(function () {\n            expect(true).toBe(false);\n        }, function (value) {\n            expect(turn).toEqual(2);\n            expect(value).toEqual(-1);\n            turn++;\n        });\n        Q.nextTick(function () {\n            expect(turn).toEqual(1);\n            deferred.reject(-1);\n            turn++;\n        });\n        turn++;\n        return promise;\n    });\n\n    it(\"resolves multiple observers\", function (done) {\n        var nextTurn = false;\n\n        var resolution = \"Taram pam param!\";\n        var deferred = Q.defer();\n        var count = 10;\n        var i = 0;\n\n        function resolve(value) {\n            i++;\n            expect(value).toBe(resolution);\n            expect(nextTurn).toBe(true);\n            if (i === count) {\n                done();\n            }\n        }\n\n        while (++i <= count) {\n            Q.when(deferred.promise, resolve);\n        }\n\n        deferred.resolve(resolution);\n        i = 0;\n        nextTurn = true;\n    });\n\n    it(\"observers called even after throw\", function () {\n        var threw = false;\n        var deferred = Q.defer();\n        Q.when(deferred.promise, function () {\n            threw = true;\n            throw new Error(REASON);\n        });\n        var promise = Q.when(deferred.promise, function (value) {\n            expect(value).toEqual(10);\n        }, function () {\n            expect(\"not\").toEqual(\"here\");\n        });\n        deferred.resolve(10);\n        return promise;\n    });\n\n    it(\"returns `undefined` from the deferred's methods\", function () {\n        expect(Q.defer().resolve()).toBe(undefined);\n        expect(Q.defer().reject()).toBe(undefined);\n    });\n\n});\n\ndescribe(\"always next tick\", function () {\n\n    it(\"generated by `resolve`\", function () {\n        var turn = 0;\n        var promise = Q.when(Q(), function () {\n            expect(turn).toEqual(1);\n        });\n        turn++;\n        return promise;\n    });\n\n    it(\"generated by `reject`\", function () {\n        var turn = 0;\n        var promise = Q.when(Q.reject(), function () {\n            expect(true).toBe(false);\n        }, function () {\n            expect(turn).toEqual(1);\n        });\n        turn++;\n        return promise;\n    });\n\n\tit(\"allows overriding global nextTick\", function () {\n\t\tvar spy = jasmine.createSpy();\n\t\tspyOn(Q, 'nextTick').andCallFake(function immediateTick(task){\n\t\t\ttask();\n\t\t});\n\n\t\tQ.when(Q(), spy);\n\n\t\texpect(spy).toHaveBeenCalled();\n\t\texpect(Q.nextTick).toHaveBeenCalled();\n\t});\n});\n\ndescribe(\"progress\", function () {\n\n    it(\"calls a single progress listener\", function () {\n        var progressed = false;\n        var deferred = Q.defer();\n\n        var promise = Q.when(\n            deferred.promise,\n            function () {\n                expect(progressed).toBe(true);\n            },\n            function () {\n                expect(true).toBe(false);\n            },\n            function () {\n                progressed = true;\n            }\n        );\n\n        deferred.notify();\n        deferred.resolve();\n\n        return promise;\n    });\n\n    it(\"calls multiple progress listeners\", function () {\n        var progressed1 = false;\n        var progressed2 = false;\n        var deferred = Q.defer();\n        var promise = Q.when(\n            deferred.promise,\n            function () {\n                expect(progressed1).toBe(true);\n                expect(progressed2).toBe(true);\n            },\n            function () {\n                expect(true).toBe(false);\n            },\n            function () {\n                progressed1 = true;\n            }\n        );\n        Q.when(deferred.promise, null, null, function () {\n            progressed2 = true;\n        });\n\n        deferred.notify();\n        deferred.resolve();\n\n        return promise;\n    });\n\n    it(\"calls all progress listeners even if one throws\", function () {\n        var progressed1 = false;\n        var progressed2 = false;\n        var progressed3 = false;\n        var deferred = Q.defer();\n        var promise = Q.when(\n            deferred.promise,\n            function () {\n                expect(progressed1).toBe(true);\n                expect(progressed2).toBe(true);\n                expect(progressed3).toBe(true);\n            },\n            function () {\n                expect(true).toBe(false);\n            },\n            function () {\n                progressed1 = true;\n            }\n        );\n\n        Q.onerror = function () { };\n\n        Q.when(deferred.promise, null, null, function () {\n            progressed2 = true;\n            throw new Error(\"just a test, ok if it shows up in the console\");\n        });\n        Q.when(deferred.promise, null, null, function () {\n            progressed3 = true;\n        });\n\n        deferred.notify();\n        deferred.resolve();\n\n        return promise;\n    });\n\n    it(\"calls the progress listener even if later rejected\", function () {\n        var progressed = false;\n        var deferred = Q.defer();\n        var promise = Q.when(\n            deferred.promise,\n            function () {\n                expect(true).toBe(false);\n            },\n            function () {\n                expect(progressed).toEqual(true);\n            },\n            function () {\n                progressed = true;\n            }\n        );\n\n        deferred.notify();\n        deferred.reject();\n\n        return promise;\n    });\n\n    it(\"calls the progress listener with the notify values\", function () {\n        var progressValues = [];\n        var desiredProgressValues = [{}, {}, \"foo\", 5];\n        var deferred = Q.defer();\n        var promise = Q.when(\n            deferred.promise,\n            function () {\n                for (var i = 0; i < desiredProgressValues.length; ++i) {\n                    var desired = desiredProgressValues[i];\n                    var actual = progressValues[i];\n                    expect(actual).toBe(desired);\n                }\n            },\n            function () {\n                expect(true).toBe(false);\n            },\n            function (value) {\n                progressValues.push(value);\n            }\n        );\n\n        for (var i = 0; i < desiredProgressValues.length; ++i) {\n            deferred.notify(desiredProgressValues[i]);\n        }\n        deferred.resolve();\n\n        return promise;\n    });\n\n    it(\"does not call the progress listener if notify is called after fulfillment\", function () {\n        var deferred = Q.defer();\n        var called = false;\n\n        Q.when(deferred.promise, null, null, function () {\n            called = true;\n        });\n\n        deferred.resolve();\n        deferred.notify();\n\n        return Q.delay(10).then(function () {\n            expect(called).toBe(false);\n        });\n    });\n\n    it(\"does not call the progress listener if notify is called after rejection\", function () {\n        var deferred = Q.defer();\n        var called = false;\n\n        Q.when(deferred.promise, null, null, function () {\n            called = true;\n        });\n\n        deferred.reject();\n        deferred.notify();\n\n        return Q.delay(10).then(function () {\n            expect(called).toBe(false);\n        });\n    });\n\n    it(\"should not save and re-emit progress notifications\", function () {\n        var deferred = Q.defer();\n        var progressValues = [];\n\n        deferred.notify(1);\n\n        var promise = Q.when(\n            deferred.promise,\n            function () {\n                expect(progressValues).toEqual([2]);\n            },\n            function () {\n                expect(true).toBe(false);\n            },\n            function (progressValue) {\n                progressValues.push(progressValue);\n            }\n        );\n\n        deferred.notify(2);\n        deferred.resolve();\n\n        return promise;\n    });\n\n    it(\"should allow attaching progress listeners w/ .progress\", function () {\n        var progressed = false;\n        var deferred = Q.defer();\n\n        deferred.promise.progress(function () {\n            progressed = true;\n        });\n\n        deferred.notify();\n        deferred.resolve();\n\n        return deferred.promise;\n    });\n\n    it(\"should allow attaching progress listeners w/ Q.progress\", function () {\n        var progressed = false;\n        var deferred = Q.defer();\n\n        Q.progress(deferred.promise, function () {\n            progressed = true;\n        });\n\n        deferred.notify();\n        deferred.resolve();\n\n        return deferred.promise;\n    });\n\n    it(\"should call the progress listener with undefined context\", function () {\n        var progressed = false;\n        var progressContext = {};\n        var deferred = Q.defer();\n        var promise = Q.when(\n            deferred.promise,\n            function () {\n                expect(progressed).toBe(true);\n                expect(progressContext).toBe(calledAsFunctionThis);\n            },\n            function () {\n                expect(true).toBe(false);\n            },\n            function () {\n                progressed = true;\n                progressContext = this;\n            }\n        );\n\n        deferred.notify();\n        deferred.resolve();\n\n        return promise;\n    });\n\n    it(\"should forward only the first notify argument to listeners\", function () {\n        var progressValueArrays = [];\n        var deferred = Q.defer();\n\n        var promise = Q.when(\n            deferred.promise,\n            function () {\n                expect(progressValueArrays).toEqual([[1], [2], [4]]);\n            },\n            function () {\n                expect(true).toBe(false);\n            },\n            function () {\n                var args = Array.prototype.slice.call(arguments);\n                progressValueArrays.push(args);\n            }\n        );\n\n        deferred.notify(1);\n        deferred.notify(2, 3);\n        deferred.notify(4, 5, 6);\n        deferred.resolve();\n\n        return promise;\n    });\n\n    it(\"should work with .then as well\", function () {\n        var progressed = false;\n        var deferred = Q.defer();\n\n        var promise = deferred.promise.then(\n            function () {\n                expect(progressed).toBe(true);\n            },\n            function () {\n                expect(true).toBe(false);\n            },\n            function () {\n                progressed = true;\n            }\n        );\n\n        deferred.notify();\n        deferred.resolve();\n\n        return promise;\n    });\n\n    it(\"should re-throw all errors thrown by listeners to Q.onerror\", function () {\n        var theError = new Error(\"boo!\");\n\n        var def = Q.defer();\n        def.promise.progress(function () {\n            throw theError;\n        });\n\n        var deferred = Q.defer();\n        Q.onerror = function (error) {\n            expect(error).toBe(theError);\n            deferred.resolve();\n        };\n        Q.delay(100).then(deferred.reject);\n\n        def.notify();\n\n        return deferred.promise;\n    });\n});\n\ndescribe(\"promises for objects\", function () {\n\n    describe(\"get\", function () {\n\n        it(\"fulfills a promise\", function () {\n            var deferred = Q.defer();\n            deferred.resolve({a: 1});\n            return deferred.promise.get(\"a\")\n            .then(function (a) {\n                expect(a).toBe(1);\n            });\n        });\n\n        it(\"propagates a rejection\", function () {\n            var exception = new Error(\"boo!\");\n            return Q.fcall(function () {\n                throw exception;\n            })\n            .get(\"a\")\n            .then(function () {\n                expect(\"be\").toBe(\"not to be\");\n            }, function (_exception) {\n                expect(_exception).toBe(exception);\n            });\n        });\n\n    });\n\n    describe(\"set\", function () {\n\n        it(\"fulfills a promise\", function () {\n            var object = {};\n            return Q(object)\n            .set(\"a\", 1)\n            .then(function (result) {\n                expect(result).toBe(undefined);\n                expect(object.a).toBe(1);\n            });\n        });\n\n        it(\"propagates a rejection\", function () {\n            var exception = new Error(\"Gah!\");\n            return Q.reject(exception)\n            .set(\"a\", 1)\n            .then(function () {\n                expect(\"frozen over\").toBe(\"quite warm\");\n            }, function (_exception) {\n                expect(_exception).toBe(exception);\n            });\n        });\n\n    });\n\n    describe(\"del\", function () {\n\n        it(\"fulfills a promise\", function () {\n            var object = {a: 10};\n            return Q.fcall(function () {\n                return object;\n            })\n            .del(\"a\")\n            .then(function (result) {\n                expect(\"a\" in object).toBe(false);\n                expect(result).toBe(void 0);\n            }, function () {\n                expect(\"up\").toBe(\"down\");\n            });\n        });\n\n        it(\"propagates a rejection\", function () {\n            var exception = new Error(\"hah-hah\");\n            return Q.fcall(function () {\n                throw exception;\n            })\n            .del(\"a\")\n            .then(function () {\n                expect(true).toBe(false);\n            }, function (_exception) {\n                expect(_exception).toBe(exception);\n            });\n        });\n\n    });\n\n    describe(\"post\", function () {\n\n        it(\"fulfills a promise\", function () {\n            var subject = {\n                a: function a(value) {\n                    this._a = value;\n                    return 1 + value;\n                }\n            };\n            return Q.when(Q.post(subject, \"a\", [1]), function (two) {\n                expect(subject._a).toBe(1);\n                expect(two).toBe(2);\n            });\n        });\n\n        it(\"works as apply when given no name\", function () {\n            return Q(function (a, b, c) {\n                return a + b + c;\n            })\n            .post(undefined, [1, 2, 3])\n            .then(function (sum) {\n                expect(sum).toEqual(6);\n            });\n        });\n\n    });\n\n    describe(\"send\", function () {\n\n        it(\"fulfills a promise\", function () {\n            var foo;\n            var subject = {\n                foo: function (_bar) {\n                    return _bar;\n                },\n                bar: function (_foo, _bar) {\n                    foo = _foo;\n                    return this.foo(_bar);\n                }\n            };\n            return Q.send(subject, \"bar\", 1, 2)\n            .then(function (two) {\n                expect(foo).toEqual(1);\n                expect(two).toEqual(2);\n            });\n        });\n\n        it(\"is rejected for undefined method\", function () {\n            var subject = {};\n            return Q(subject)\n            .send(\"foo\")\n            .then(function () {\n                expect(\"here\").toEqual(\"not here\");\n            }, function () {\n            });\n        });\n\n        it(\"is rejected for undefined object\", function () {\n            return Q()\n            .send(\"foo\")\n            .then(function () {\n                expect(\"here\").toEqual(\"not here\");\n            }, function () {\n            });\n        });\n\n    });\n\n    describe(\"keys\", function () {\n\n        function Klass (a, b) {\n            this.a = a;\n            this.b = b;\n        }\n        Klass.prototype.notOwn = 1;\n\n        it(\"fulfills a promise\", function () {\n            return Q.keys(new Klass(10, 20))\n            .then(function (keys) {\n                expect(keys.sort()).toEqual([\"a\", \"b\"]);\n            });\n        });\n\n    });\n\n});\n\ndescribe(\"promises for functions\", function () {\n\n    describe(\"fapply\", function () {\n        it(\"fulfills a promise using arguments\", function () {\n            return Q(function (a, b, c) {\n                return a + b + c;\n            })\n            .fapply([1, 2, 3])\n            .then(function (sum) {\n                expect(sum).toEqual(6);\n            });\n        });\n    });\n\n    describe(\"fcall\", function () {\n        it(\"fulfills a promise using arguments\", function () {\n            return Q(function (a, b, c) {\n                return a + b + c;\n            })\n            .fcall(1, 2, 3)\n            .then(function (sum) {\n                expect(sum).toEqual(6);\n            });\n        });\n    });\n\n    describe(\"fbind\", function () {\n\n        it(\"accepts a promise for a function\", function () {\n            return Q.fbind(Q(function (high, low) {\n                return high - low;\n            }))\n            (2, 1)\n            .then(function (difference) {\n                expect(difference).toEqual(1);\n            });\n        });\n\n        it(\"chains partial application on a promise for a function\", function () {\n            return Q(function (a, b) {\n                return a * b;\n            })\n            .fbind(2)(3)\n            .then(function (product) {\n                expect(product).toEqual(6);\n            });\n        });\n\n        it(\"returns a fulfilled promise\", function () {\n            var result = {};\n            var bound = Q.fbind(function () {\n                return result;\n            });\n            return bound()\n            .then(function (_result) {\n                expect(_result).toBe(result);\n            });\n        });\n\n        it(\"returns a rejected promise from a thrown error\", function () {\n            var exception = new Error(\"Boo!\");\n            var bound = Q.fbind(function () {\n                throw exception;\n            });\n            return bound()\n            .then(function () {\n                expect(\"flying pigs\").toBe(\"swillin' pigs\");\n            }, function (_exception) {\n                expect(_exception).toBe(exception);\n            });\n        });\n\n        it(\"passes arguments through\", function () {\n            var x = {}, y = {};\n            var bound = Q.fbind(function (a, b) {\n                expect(a).toBe(x);\n                expect(b).toBe(y);\n            });\n            return bound(x, y);\n        });\n\n        it(\"passes and also partially applies arguments\", function () {\n            var x = {}, y = {};\n            var bound = Q.fbind(function (a, b) {\n                expect(a).toBe(x);\n                expect(b).toBe(y);\n            }, x);\n            return bound(y);\n        });\n\n        it(\"doesn't bind `this`\", function () {\n            var theThis = { me: \"this\" };\n            var bound = Q.fbind(function () {\n                expect(this).toBe(theThis);\n            });\n\n            return bound.call(theThis);\n        });\n\n    });\n\n});\n\ndescribe(\"inspect\", function () {\n\n    it(\"for a fulfilled promise\", function () {\n        expect(Q(10).inspect()).toEqual({\n            state: \"fulfilled\",\n            value: 10\n        });\n    });\n\n    it(\"for a rejected promise\", function () {\n        var error = new Error(\"In your face.\");\n        var rejected = Q.reject(error);\n        expect(rejected.inspect()).toEqual({\n            state: \"rejected\",\n            reason: error\n        });\n    });\n\n    it(\"for a pending, unresolved promise\", function () {\n        var pending = Q.defer().promise;\n        expect(pending.inspect()).toEqual({ state: \"pending\" });\n    });\n\n    it(\"for a promise resolved to a rejected promise\", function () {\n        var deferred = Q.defer();\n        var error = new Error(\"Rejected!\");\n        var rejected = Q.reject(error);\n        deferred.resolve(rejected);\n\n        expect(deferred.promise.inspect()).toEqual({\n            state: \"rejected\",\n            reason: error\n        });\n    });\n\n    it(\"for a promise resolved to a fulfilled promise\", function () {\n        var deferred = Q.defer();\n        var fulfilled = Q(10);\n        deferred.resolve(fulfilled);\n\n        expect(deferred.promise.inspect()).toEqual({\n            state: \"fulfilled\",\n            value: 10\n        });\n    });\n\n    it(\"for a promise resolved to a pending promise\", function () {\n        var a = Q.defer();\n        var b = Q.defer();\n        a.resolve(b.promise);\n\n        expect(a.promise.inspect()).toEqual({ state: \"pending\" });\n    });\n\n});\n\ndescribe(\"promise states\", function () {\n\n    it(\"of fulfilled value\", function () {\n        expect(Q.isFulfilled(void 0)).toBe(true);\n        expect(Q.isRejected(false)).toBe(false);\n        expect(Q.isPending(true)).toBe(false);\n    });\n\n    it(\"of fulfillment\", function () {\n        var promise = Q(10);\n        expect(Q.isFulfilled(promise)).toBe(true);\n        expect(promise.isFulfilled()).toBe(true);\n        expect(Q.isRejected(promise)).toBe(false);\n        expect(promise.isRejected()).toBe(false);\n        expect(Q.isPending(promise)).toBe(false);\n        expect(promise.isPending()).toBe(false);\n    });\n\n    it(\"of rejection\", function () {\n        var error = new Error(\"Oh, snap.\");\n        var promise = Q.reject(error);\n        expect(promise.isFulfilled()).toBe(false);\n        expect(promise.isRejected()).toBe(true);\n        expect(promise.isPending()).toBe(false);\n    });\n\n    it(\"of rejection with a falsy value\", function () {\n        var promise = Q.reject(undefined);\n        expect(promise.isFulfilled()).toBe(false);\n        expect(promise.isRejected()).toBe(true);\n        expect(promise.isPending()).toBe(false);\n    });\n\n    it(\"of deferred\", function () {\n        var deferred = Q.defer();\n        var promise = deferred.promise;\n        expect(promise.isFulfilled()).toBe(false);\n        expect(promise.isRejected()).toBe(false);\n        expect(promise.isPending()).toBe(true);\n    });\n\n    it(\"of deferred rejection\", function () {\n        var deferred = Q.defer();\n        var rejection = Q.reject(new Error(\"Rejected!\"));\n        deferred.resolve(rejection);\n        var promise = deferred.promise;\n        expect(promise.isFulfilled()).toBe(false);\n        expect(promise.isRejected()).toBe(true);\n        expect(promise.isPending()).toBe(false);\n    });\n\n    it(\"of deferred fulfillment\", function () {\n        var deferred = Q.defer();\n        deferred.resolve(10);\n        var promise = deferred.promise;\n        expect(promise.isFulfilled()).toBe(true);\n        expect(promise.isRejected()).toBe(false);\n        expect(promise.isPending()).toBe(false);\n    });\n\n    it(\"of deferred deferred\", function () {\n        var a = Q.defer();\n        var b = Q.defer();\n        a.resolve(b.promise);\n        var promise = a.promise;\n        expect(promise.isFulfilled()).toBe(false);\n        expect(promise.isRejected()).toBe(false);\n        expect(promise.isPending()).toBe(true);\n    });\n\n    it(\"of isFulfilled side effects\", function () {\n        var deferred = Q.defer();\n        var finished = false;\n\n        waitsFor(function () {\n            return finished;\n        });\n\n        var parentPromise = deferred.promise;\n\n        var childPromise = parentPromise.then(function () {\n            expect(parentPromise.isFulfilled()).toBe(true);\n            expect(childPromise.isFulfilled()).toBe(false);\n\n            return parentPromise.then(function (value) {\n                finished = true;\n                return value + 1;\n            });\n        });\n\n        deferred.resolve(1);\n\n        runs(function () {\n            expect(childPromise.isPending()).toBe(false);\n            expect(childPromise.isRejected()).toBe(false);\n            expect(childPromise.isFulfilled()).toBe(true);\n            expect(childPromise.inspect().value).toBe(2);\n        });\n    });\n\n});\n\ndescribe(\"propagation\", function () {\n\n    it(\"propagate through then with no callback\", function () {\n        return Q(10)\n        .then()\n        .then(function (ten) {\n            expect(ten).toBe(10);\n        });\n    });\n\n    it(\"propagate through then with modifying callback\", function () {\n        return Q(10)\n        .then(function (ten) {\n            return ten + 10;\n        })\n        .then(function (twen) {\n            expect(twen).toBe(20);\n        });\n    });\n\n    it(\"errback recovers from exception\", function () {\n        var error = new Error(\"Bah!\");\n        return Q.reject(error)\n        .then(null, function (_error) {\n            expect(_error).toBe(error);\n            return 10;\n        })\n        .then(function (value) {\n            expect(value).toBe(10);\n        });\n    });\n\n    it(\"rejection propagates through then with no errback\", function () {\n        var error = new Error(\"Foolish mortals!\");\n        return Q.reject(error)\n        .then()\n        .then(null, function (_error) {\n            expect(_error).toBe(error);\n        });\n    });\n\n    it(\"rejection intercepted and rethrown\", function () {\n        var error = new Error(\"Foolish mortals!\");\n        var nextError = new Error(\"Silly humans!\");\n        return Q.reject(error)\n        .fail(function () {\n            throw nextError;\n        })\n        .then(null, function (_error) {\n            expect(_error).toBe(nextError);\n        });\n    });\n\n    it(\"resolution is forwarded through deferred promise\", function () {\n        var a = Q.defer();\n        var b = Q.defer();\n        a.resolve(b.promise);\n        b.resolve(10);\n        return a.promise.then(function (eh) {\n            expect(eh).toEqual(10);\n        });\n    });\n\n    it(\"should propagate progress by default\", function () {\n        var d = Q.defer();\n\n        var progressValues = [];\n        var promise = d.promise\n        .then()\n        .then(\n            function () {\n                expect(progressValues).toEqual([1]);\n            },\n            function () {\n                expect(true).toBe(false);\n            },\n            function (progressValue) {\n                progressValues.push(progressValue);\n            }\n        );\n\n        d.notify(1);\n        d.resolve();\n\n        return promise;\n    });\n\n    it(\"should allow translation of progress in the progressback\", function () {\n        var d = Q.defer();\n\n        var progressValues = [];\n        var promise = d.promise\n        .progress(function (p) {\n            return p + 5;\n        })\n        .then(\n            function () {\n                expect(progressValues).toEqual([10]);\n            },\n            function () {\n                expect(true).toBe(false);\n            },\n            function (progressValue) {\n                progressValues.push(progressValue);\n            }\n        );\n\n        d.notify(5);\n        d.resolve();\n\n        return promise;\n    });\n\n\n    it(\"should stop progress propagation if an error is thrown\", function () {\n        var def = Q.defer();\n        var p2 = def.promise.progress(function () {\n            throw new Error(\"boo!\");\n        });\n\n        Q.onerror = function () { /* just swallow it for this test */ };\n\n        var progressValues = [];\n        var result = p2.then(\n            function () {\n                expect(progressValues).toEqual([]);\n            },\n            function () {\n                expect(true).toBe(false);\n            },\n            function (progressValue) {\n                progressValues.push(progressValue);\n            }\n        );\n\n        def.notify();\n        def.resolve();\n        return result;\n    });\n});\n\ndescribe(\"all\", function () {\n    it(\"fulfills when passed an empty array\", function () {\n        return Q.all([]);\n    });\n\n    it(\"rejects after any constituent promise is rejected\", function () {\n        var toResolve = Q.defer(); // never resolve\n        var toReject = Q.defer();\n        var promises = [toResolve.promise, toReject.promise];\n        var promise = Q.all(promises);\n\n        toReject.reject(new Error(\"Rejected\"));\n\n        return Q.delay(250)\n        .then(function () {\n            expect(promise.isRejected()).toBe(true);\n        })\n        .timeout(1000);\n    });\n\n    it(\"resolves foreign thenables\", function () {\n        var normal = Q(1);\n        var foreign = { then: function (f) { f(2); } };\n\n        return Q.all([normal, foreign])\n        .then(function (result) {\n            expect(result).toEqual([1, 2]);\n        });\n    });\n\n    it(\"fulfills when passed an sparse array\", function () {\n        var toResolve = Q.defer();\n        var promises = [];\n        promises[0] = Q(0);\n        promises[2] = toResolve.promise;\n        var promise = Q.all(promises);\n\n        toResolve.resolve(2);\n\n        return promise.then(function (result) {\n            expect(result).toEqual([0, void 0, 2]);\n        });\n    });\n\n    it(\"modifies the input array\", function () {\n        var input = [Q(0), Q(1)];\n\n        return Q.all(input).then(function (result) {\n            expect(result).toBe(input);\n            expect(input).toEqual([0, 1]);\n        });\n    });\n\n    it(\"sends { index, value } progress updates\", function () {\n        var deferred1 = Q.defer();\n        var deferred2 = Q.defer();\n\n        var progressValues = [];\n\n        Q.delay(50).then(function () {\n            deferred1.notify(\"a\");\n        });\n        Q.delay(100).then(function () {\n            deferred2.notify(\"b\");\n            deferred2.resolve();\n        });\n        Q.delay(150).then(function () {\n            deferred1.notify(\"c\");\n            deferred1.resolve();\n        });\n\n        return Q.all([deferred1.promise, deferred2.promise]).then(\n            function () {\n                expect(progressValues).toEqual([\n                    { index: 0, value: \"a\" },\n                    { index: 1, value: \"b\" },\n                    { index: 0, value: \"c\" }\n                ]);\n            },\n            undefined,\n            function (progressValue) {\n                progressValues.push(progressValue);\n            }\n        )\n    });\n\n});\n\ndescribe(\"any\", function() {\n    it(\"fulfills when passed an empty array\", function() {\n        return Q.any([]);\n    });\n\n    it(\"rejects after all promises are rejected\", function() {\n        var deferreds = [Q.defer(), Q.defer()];\n        var promises = [deferreds[0].promise, deferreds[1].promise];\n\n        return testReject(promises, deferreds, new Error(\"Rejected\"));\n    });\n\n    it(\"rejects after all promises in a sparse array are rejected\", function() {\n        var deferreds = [Q.defer(), Q.defer()];\n        var promises = [];\n        promises[0] = deferreds[0].promise;\n        promises[3] = deferreds[1].promise;\n\n        return testReject(promises, deferreds, new Error(\"Rejected\"));\n    });\n\n\n    it(\"rejects after all promises are rejected with null\", function() {\n        var deferreds = [Q.defer(), Q.defer()];\n        var promises = [deferreds[0].promise, deferreds[1].promise];\n\n        return testReject(promises, deferreds, null);\n    });\n\n    it(\"rejects after all promises are rejected with undefined\", function() {\n        var deferreds = [Q.defer(), Q.defer()];\n        var promises = [deferreds[0].promise, deferreds[1].promise];\n\n        return testReject(promises, deferreds, undefined);\n    });\n\n    function testReject(promises, deferreds, rejectionValue) {\n        var promise = Q.any(promises);\n        var expectedError;\n\n        if (rejectionValue) {\n          expectedError = new Error(rejectionValue.message);\n        } else {\n          expectedError = new Error(\"\" + rejectionValue);\n        }\n\n        for (var index = 0; index < deferreds.length; index++) {\n            var deferred = deferreds[index];\n            (function() {\n              deferred.reject(rejectionValue);\n            })();\n        }\n\n        return Q.delay(250)\n          .then(function() {\n              expect(promise.isRejected()).toBe(true);\n              expect(promise.inspect().reason).toEqual(expectedError);\n              expect(promise.inspect().reason.message)\n                .toBe(\"Q can't get fulfillment value from any promise, all promises were rejected. Last error message: \" + expectedError.message);\n          })\n          .timeout(1000);\n    }\n\n    it(\"fulfills with the first resolved promise\", function() {\n        var deferreds = [Q.defer(), Q.defer()];\n        var promises = [deferreds[0].promise, deferreds[1].promise];\n\n        testFulfill(promises, deferreds);\n    });\n\n    it(\"fulfills when passed a sparse array\", function() {\n        var deferreds = [Q.defer(), Q.defer()];\n        var promises = [];\n        promises[0] = deferreds[0].promise;\n        promises[2] = deferreds[1].promise;\n\n        testFulfill(promises, deferreds);\n    });\n\n    function testFulfill(promises, deferreds) {\n        var promise = Q.any(promises);\n\n        var j = 1;\n        for (var index = 0; index < deferreds.length; index++) {\n            var toResolve = deferreds[index];\n            if (!toResolve || !Q.isPromiseAlike(toResolve.promise)) {\n                continue;\n            }\n\n            (function(index, toResolve) {\n                var time = index * 50;\n                Q.delay(time).then(function() {\n                    toResolve.resolve('Fulfilled' + index);\n                });\n            })(j, toResolve);\n\n            j++;\n        }\n\n        return Q.delay(400)\n          .then(function() {\n              expect(promise.isFulfilled()).toBe(true);\n              expect(promise.inspect().value).toBe('Fulfilled1');\n          })\n          .timeout(1000);\n    }\n\n    it(\"fulfills with the first value\", function() {\n        var toResolve1 = Q.defer();\n        var toResolve2 = Q.defer();\n        var toResolve3 = Q.defer();\n        var promises = [toResolve1.promise, toResolve2.promise, 4, 5,\n            toResolve3.promise\n        ];\n\n        var promise = Q.any(promises);\n\n        Q.delay(150).then(function() {\n            toResolve1.resolve(1);\n        });\n        Q.delay(50).then(function() {\n            toResolve2.resolve(2);\n        });\n        Q.delay(100).then(function() {\n            toResolve3.resolve(3);\n        });\n\n        return Q.delay(250)\n          .then(function() {\n              expect(promise.isFulfilled()).toBe(true);\n              expect(promise.inspect().value).toBe(4);\n          })\n          .timeout(1000);\n    });\n\n    it(\"fulfills after rejections\", function() {\n        var toReject = [Q.defer(), Q.defer()];\n        var toResolve = Q.defer();\n        var promises = [toReject[0].promise, toReject[1].promise,\n            toResolve\n            .promise\n        ];\n\n        var promise = Q.any(promises);\n\n        testFulfillAfterRejections(promises, toReject, toResolve);\n    });\n\n    it(\"fulfills after rejections in sparse array\", function() {\n        var toReject = [Q.defer(), Q.defer()];\n        var toResolve = Q.defer();\n        var promises = [];\n        promises[2] = toReject[0].promise;\n        promises[5] = toReject[1].promise;\n        promises[9] = toResolve.promise;\n\n        testFulfillAfterRejections(promises, toReject, toResolve);\n    });\n\n    function testFulfillAfterRejections(promises, rejectDeferreds,\n      fulfillDeferred) {\n        var promise = Q.any(promises);\n\n        for (var index = 0; index < rejectDeferreds.length; index++) {\n            var toReject = rejectDeferreds[index];\n            (function(index, toReject) {\n                var time = (index + 1) * 50;\n                Q.delay(time).then(function() {\n                    toReject.reject(new Error('Rejected'));\n                });\n            })(index, toReject);\n\n            index++;\n        }\n        Q.delay(index * 50).then(function() {\n            fulfillDeferred.resolve('Fulfilled');\n        });\n\n        return Q.delay(400)\n          .then(function() {\n              expect(promise.isFulfilled()).toBe(true);\n              expect(promise.inspect().value).toBe('Fulfilled');\n          })\n          .timeout(1000);\n    }\n\n    it(\"resolves foreign thenables\", function() {\n        var normal = Q.delay(150)\n            .then(function() {})\n            .thenResolve(1);\n        var foreign = {\n            then: function(f) {\n                return f(2);\n            }\n        };\n\n        return Q.any([normal, foreign])\n          .then(function(result) {\n              expect(result).toEqual(2);\n          });\n    });\n\n    it(\"sends { index, value } progress updates\", function() {\n        var deferred1 = Q.defer();\n        var deferred2 = Q.defer();\n\n        var progressValues = [];\n\n        Q.delay(50).then(function() {\n            deferred1.notify(\"a\");\n        });\n        Q.delay(100).then(function() {\n            deferred2.notify(\"b\");\n            deferred2.resolve();\n        });\n        Q.delay(150).then(function() {\n            deferred1.notify(\"c\"); // Is lost, deferred2 already resolved.\n            deferred1.resolve();\n        });\n\n        return Q.any([deferred1.promise, deferred2.promise])\n          .delay(250)\n          .then(function() {\n              expect(progressValues).toEqual([{\n                  index: 0,\n                  value: \"a\"\n              }, {\n                  index: 1,\n                  value: \"b\"\n              }]);\n            },\n            undefined,\n            function(progressValue) {\n                progressValues.push(progressValue);\n            }\n          );\n    });\n\n});\n\ndescribe(\"allSettled\", function () {\n    it(\"works on an empty array\", function () {\n        return Q.allSettled([])\n        .then(function (snapshots) {\n            expect(snapshots).toEqual([]);\n        });\n    });\n\n    it(\"deals with a mix of non-promises and promises\", function () {\n        return Q.allSettled([1, Q(2), Q.reject(3)])\n        .then(function (snapshots) {\n            expect(snapshots).toEqual([\n                { state: \"fulfilled\", value: 1 },\n                { state: \"fulfilled\", value: 2 },\n                { state: \"rejected\", reason: 3 }\n            ]);\n        });\n    });\n\n    it(\"is settled after every constituent promise is settled\", function () {\n        var toFulfill = Q.defer();\n        var toReject = Q.defer();\n        var promises = [toFulfill.promise, toReject.promise];\n        var fulfilled;\n        var rejected;\n\n        Q.fcall(function () {\n            toReject.reject();\n            rejected = true;\n        })\n        .delay(15)\n        .then(function () {\n            toFulfill.resolve();\n            fulfilled = true;\n        });\n\n        return Q.allSettled(promises)\n        .then(function () {\n            expect(fulfilled).toBe(true);\n            expect(rejected).toBe(true);\n        });\n    });\n\n    it(\"does not modify the input array\", function () {\n        var input = [1, Q(2), Q.reject(3)];\n\n        return Q.allSettled(input)\n        .then(function (snapshots) {\n            expect(snapshots).not.toBe(input);\n            expect(snapshots).toEqual([\n                { state: \"fulfilled\", value: 1 },\n                { state: \"fulfilled\", value: 2 },\n                { state: \"rejected\", reason: 3 }\n            ]);\n        });\n    });\n\n});\n\ndescribe(\"spread\", function () {\n\n    it(\"spreads values across arguments\", function () {\n        return Q.spread([1, 2, 3], function (a, b) {\n            expect(b).toBe(2);\n        });\n    });\n\n    it(\"spreads promises for arrays across arguments\", function () {\n        return Q([Q(10)])\n        .spread(function (value) {\n            expect(value).toEqual(10);\n        });\n    });\n\n    it(\"spreads arrays of promises across arguments\", function () {\n        var deferredA = Q.defer();\n        var deferredB = Q.defer();\n\n        var promise = Q.spread([deferredA.promise, deferredB.promise],\n                               function (a, b) {\n            expect(a).toEqual(10);\n            expect(b).toEqual(20);\n        });\n\n        Q.delay(5).then(function () {\n            deferredA.resolve(10);\n        });\n        Q.delay(10).then(function () {\n            deferredB.resolve(20);\n        });\n\n        return promise;\n    });\n\n    it(\"calls the errback when given a rejected promise\", function () {\n        var err = new Error();\n        return Q.spread([Q(10), Q.reject(err)],\n            function () {\n                expect(true).toBe(false);\n            },\n            function (actual) {\n                expect(actual).toBe(err);\n            }\n        );\n    });\n\n});\n\ndescribe(\"fin\", function () {\n\n    var exception1 = new Error(\"boo!\");\n    var exception2 = new TypeError(\"evil!\");\n\n    describe(\"when the promise is fulfilled\", function () {\n\n        it(\"should call the callback\", function () {\n            var called = false;\n\n            return Q(\"foo\")\n            .fin(function () {\n                called = true;\n            })\n            .then(function () {\n                expect(called).toBe(true);\n            });\n        });\n\n        it(\"should fulfill with the original value\", function () {\n            return Q(\"foo\")\n            .fin(function () {\n                return \"bar\";\n            })\n            .then(function (result) {\n                expect(result).toBe(\"foo\");\n            });\n        });\n\n        describe(\"when the callback returns a promise\", function () {\n\n            describe(\"that is fulfilled\", function () {\n                it(\"should fulfill with the original reason after that promise resolves\", function () {\n                    var promise = Q.delay(250);\n\n                    return Q(\"foo\")\n                    .fin(function () {\n                        return promise;\n                    })\n                    .then(function (result) {\n                        expect(Q.isPending(promise)).toBe(false);\n                        expect(result).toBe(\"foo\");\n                    });\n                });\n            });\n\n            describe(\"that is rejected\", function () {\n                it(\"should reject with this new rejection reason\", function () {\n                    return Q(\"foo\")\n                    .fin(function () {\n                        return Q.reject(exception1);\n                    })\n                    .then(function () {\n                        expect(false).toBe(true);\n                    },\n                    function (exception) {\n                        expect(exception).toBe(exception1);\n                    });\n                });\n            });\n\n        });\n\n        describe(\"when the callback throws an exception\", function () {\n            it(\"should reject with this new exception\", function () {\n                return Q(\"foo\")\n                .fin(function () {\n                    throw exception1;\n                })\n                .then(function () {\n                    expect(false).toBe(true);\n                },\n                function (exception) {\n                    expect(exception).toBe(exception1);\n                });\n            });\n        });\n\n    });\n\n    describe(\"when the promise is rejected\", function () {\n\n        it(\"should call the callback\", function () {\n            var called = false;\n\n            return Q.reject(exception1)\n            .fin(function () {\n                called = true;\n            })\n            .then(function () {\n                expect(called).toBe(true);\n            }, function () {\n                expect(called).toBe(true);\n            });\n        });\n\n        it(\"should reject with the original reason\", function () {\n            return Q.reject(exception1)\n            .fin(function () {\n                return \"bar\";\n            })\n            .then(function () {\n                expect(false).toBe(true);\n            },\n            function (exception) {\n                expect(exception).toBe(exception1);\n            });\n        });\n\n        describe(\"when the callback returns a promise\", function () {\n\n            describe(\"that is fulfilled\", function () {\n                it(\"should reject with the original reason after that promise resolves\", function () {\n                    var promise = Q.delay(250);\n\n                    return Q.reject(exception1)\n                    .fin(function () {\n                        return promise;\n                    })\n                    .then(function () {\n                        expect(false).toBe(true);\n                    },\n                    function (exception) {\n                        expect(exception).toBe(exception1);\n                        expect(Q.isPending(promise)).toBe(false);\n                    });\n                });\n            });\n\n            describe(\"that is rejected\", function () {\n                it(\"should reject with the new reason\", function () {\n                    return Q.reject(exception1)\n                    .fin(function () {\n                        return Q.reject(exception2);\n                    })\n                    .then(function () {\n                        expect(false).toBe(true);\n                    },\n                    function (exception) {\n                        expect(exception).toBe(exception2);\n                    });\n                });\n            });\n\n        });\n\n        describe(\"when the callback throws an exception\", function () {\n            it(\"should reject with this new exception\", function () {\n                return Q.reject(exception1)\n                .fin(function () {\n                    throw exception2;\n                })\n                .then(function () {\n                    expect(false).toBe(true);\n                },\n                function (exception) {\n                    expect(exception).toBe(exception2);\n                });\n            });\n        });\n\n    });\n\n    describe(\"when the callback is invalid\", function () {\n        describe(\"undefined\", function () {\n            it(\"should have a useful error\", function () {\n                var foo = {},\n                    threw = false;\n\n                try {\n                    Q().fin(foo.bar);\n                } catch (err) {\n                    expect(err.message).toBe(\"Q can't apply finally callback\");\n                    threw = true;\n                }\n\n                expect(threw).toBe(true);\n            });\n        });\n\n        describe(\"not a function\", function () {\n            it(\"should have a useful error\", function () {\n                var threw = false;\n\n                try {\n                    Q().fin(123);\n                } catch (err) {\n                    expect(err.message).toBe(\"Q can't apply finally callback\");\n                    threw = true;\n                }\n\n                expect(threw).toBe(true);\n            });\n        });\n    });\n});\n\n// Almost like \"fin\"\ndescribe(\"tap\", function () {\n    var exception1 = new Error(\"boo!\");\n\n    describe(\"when the promise is fulfilled\", function () {\n        it(\"should call the callback\", function () {\n            var called = false;\n            return Q(\"foo\")\n                .tap(function () {\n                    called = true;\n                })\n                .then(function () {\n                    expect(called).toBe(true);\n                });\n        });\n\n        it(\"should fulfill with the original value\", function () {\n            return Q(\"foo\")\n                .tap(function () {\n                    return \"bar\";\n                })\n                .then(function (result) {\n                    expect(result).toBe(\"foo\");\n                });\n        });\n\n        describe(\"when the callback returns a promise\", function () {\n            describe(\"that is fulfilled\", function () {\n                it(\"should fulfill with the original reason after that promise resolves\", function () {\n                    var promise = Q.delay(250);\n\n                    return Q(\"foo\")\n                        .tap(function () {\n                            return promise;\n                        })\n                        .then(function (result) {\n                            expect(Q.isPending(promise)).toBe(false);\n                            expect(result).toBe(\"foo\");\n                        });\n                });\n            });\n\n            describe(\"that is rejected\", function () {\n                it(\"should reject with this new rejection reason\", function () {\n                    return Q(\"foo\")\n                        .tap(function () {\n                            return Q.reject(exception1);\n                        })\n                        .then(function () {\n                            expect(false).toBe(true);\n                        },\n                        function (exception) {\n                            expect(exception).toBe(exception1);\n                        });\n                });\n            });\n\n        });\n\n        describe(\"when the callback throws an exception\", function () {\n            it(\"should reject with this new exception\", function () {\n                return Q(\"foo\")\n                    .tap(function () {\n                        throw exception1;\n                    })\n                    .then(function () {\n                        expect(false).toBe(true);\n                    },\n                    function (exception) {\n                        expect(exception).toBe(exception1);\n                    });\n            });\n        });\n\n    });\n\n    describe(\"when the promise is rejected\", function () {\n        it(\"should not call the callback\", function () {\n            var called = false;\n\n            return Q.reject(exception1)\n                .tap(function () {\n                    called = true;\n                })\n                .then(function () {\n                    expect(called).toBe(false);\n                }, function () {\n                    expect(called).toBe(false);\n                });\n        });\n    });\n});\n\n\ndescribe(\"done\", function () {\n    describe(\"when the promise is fulfilled\", function () {\n        describe(\"and the callback does not throw\", function () {\n            it(\"should call the callback and return nothing\", function () {\n                var called = false;\n\n                var promise = Q();\n\n                var returnValue = promise.done(function () {\n                    called = true;\n                });\n\n                return promise.fail(function () { }).fin(function () {\n                    expect(called).toBe(true);\n                    expect(returnValue).toBe(undefined);\n                });\n            });\n        });\n\n        describe(\"and the callback throws\", function () {\n            it(\"should rethrow that error in the next turn and return nothing\", function () {\n                var turn = 0;\n                Q.nextTick(function () {\n                    ++turn;\n                });\n\n                var returnValue = Q().done(\n                    function () {\n                        throw \"foo\";\n                    }\n                );\n\n                var deferred = Q.defer();\n                Q.onerror = function (error) {\n                    expect(turn).toBe(1);\n                    expect(error).toBe(\"foo\");\n                    expect(returnValue).toBe(undefined);\n                    deferred.resolve();\n                };\n                Q.delay(100).then(deferred.reject);\n\n                return deferred.promise;\n            });\n        });\n    });\n\n    describe(\"when the promise is rejected\", function () {\n        describe(\"and the errback handles it\", function () {\n            it(\"should call the errback and return nothing\", function () {\n                var called = false;\n\n                var promise = Q.reject(new Error());\n\n                var returnValue = promise.done(\n                    function () { },\n                    function () {\n                        called = true;\n                    }\n                );\n\n                return promise.fail(function () { }).fin(function () {\n                    expect(called).toBe(true);\n                    expect(returnValue).toBe(undefined);\n                });\n            });\n        });\n\n        describe(\"and the errback throws\", function () {\n            it(\"should rethrow that error in the next turn and return nothing\", function () {\n                var turn = 0;\n                Q.nextTick(function () {\n                    ++turn;\n                });\n\n                var returnValue = Q.reject(\"bar\").done(\n                    null,\n                    function () {\n                        throw \"foo\";\n                    }\n                );\n\n                var deferred = Q.defer();\n                Q.onerror = function (error) {\n                    expect(turn).toBe(1);\n                    expect(error).toBe(\"foo\");\n                    expect(returnValue).toBe(undefined);\n                    deferred.resolve();\n                };\n                Q.delay(100).then(deferred.reject);\n\n                return deferred.promise;\n            });\n        });\n\n        describe(\"and there is no errback\", function () {\n            it(\"should throw the original error in the next turn\", function () {\n                var turn = 0;\n                Q.nextTick(function () {\n                    ++turn;\n                });\n\n                var returnValue = Q.reject(\"bar\").done();\n\n                var deferred = Q.defer();\n                Q.onerror = function (error) {\n                    expect(turn).toBe(1);\n                    expect(error).toBe(\"bar\");\n                    expect(returnValue).toBe(undefined);\n                    deferred.resolve();\n                };\n                Q.delay(10).then(deferred.reject);\n\n                return deferred.promise;\n            });\n        });\n    });\n\n    it(\"should attach a progress listener\", function () {\n        var deferred = Q.defer();\n\n        var spy = jasmine.createSpy();\n        deferred.promise.done(null, null, spy);\n\n        deferred.notify(10);\n        deferred.resolve();\n\n        return deferred.promise.then(function () {\n            expect(spy).toHaveBeenCalledWith(10);\n        });\n    });\n});\n\ndescribe(\"timeout\", function () {\n    it(\"should do nothing if the promise fulfills quickly\", function () {\n        return Q.delay(10).timeout(200);\n    });\n\n    it(\"should do nothing if the promise rejects quickly\", function () {\n        var goodError = new Error(\"haha!\");\n        return Q.delay(10)\n        .then(function () {\n            throw goodError;\n        })\n        .timeout(200)\n        .then(undefined, function (error) {\n            expect(error).toBe(goodError);\n        });\n    });\n\n    it(\"should reject with a timeout error if the promise is too slow\", function () {\n        return Q.delay(100)\n        .timeout(10)\n        .then(\n            function () {\n                expect(true).toBe(false);\n            },\n            function (error) {\n                expect(/time/i.test(error.message)).toBe(true);\n            }\n        );\n    });\n\n    it(\"should pass through progress notifications\", function () {\n        var deferred = Q.defer();\n\n        var progressValsSeen = [];\n        var promise = Q.timeout(deferred.promise, 300).then(function () {\n            expect(progressValsSeen).toEqual([1, 2, 3]);\n        }, undefined, function (progressVal) {\n            progressValsSeen.push(progressVal);\n        });\n\n        Q.delay(5).then(function () { deferred.notify(1); });\n        Q.delay(15).then(function () { deferred.notify(2); });\n        Q.delay(25).then(function () { deferred.notify(3); });\n        Q.delay(35).then(function () { deferred.resolve(); });\n\n        return promise;\n    });\n\n    it(\"should reject with a custom timeout error if the promise is too slow and msg was provided\", function () {\n        return Q.delay(100)\n        .timeout(10, \"custom\")\n        .then(\n            function () {\n                expect(true).toBe(false);\n            },\n            function (error) {\n                expect(/custom/i.test(error.message)).toBe(true);\n                expect(error.code).toBe(\"ETIMEDOUT\");\n            }\n        );\n    });\n\n    it(\"should reject with a custom timeout error if the promise is too slow and Error object was provided\", function () {\n        var customError = new Error(\"custom\");\n        customError.isCustom = true;\n        return Q.delay(100)\n        .timeout(10, customError)\n        .then(\n            function () {\n                expect(true).toBe(false);\n            },\n            function (error) {\n                expect(/custom/i.test(error.message)).toBe(true);\n                expect(error.isCustom).toBe(true);\n            }\n        );\n    });\n\n});\n\ndescribe(\"delay\", function () {\n    it(\"should delay fulfillment\", function () {\n        var promise = Q(5).delay(50);\n\n        setTimeout(function () {\n            expect(promise.isPending()).toBe(true);\n        }, 40);\n\n        return promise;\n    });\n\n    it(\"should not delay rejection\", function () {\n        var promise = Q.reject(5).delay(50);\n\n        return Q.delay(20).then(function () {\n            expect(promise.isPending()).toBe(false);\n        });\n    });\n\n    it(\"should treat a single argument as a time\", function () {\n        var promise = Q.delay(50);\n\n        setTimeout(function () {\n            expect(promise.isPending()).toBe(true);\n        }, 40);\n\n        return promise;\n    });\n\n    it(\"should treat two arguments as a value + a time\", function () {\n        var promise = Q.delay(\"what\", 50);\n\n        setTimeout(function () {\n            expect(promise.isPending()).toBe(true);\n        }, 40);\n\n        return promise.then(function (value) {\n            expect(value).toBe(\"what\");\n        });\n    });\n\n    it(\"should delay after resolution\", function () {\n        var promise1 = Q.delay(\"what\", 30);\n        var promise2 = promise1.delay(30);\n\n        setTimeout(function () {\n            expect(promise1.isPending()).toBe(false);\n            expect(promise2.isPending()).toBe(true);\n        }, 40);\n\n        return promise2.then(function (value) {\n            expect(value).toBe(\"what\");\n        });\n    });\n\n\n    it(\"should pass through progress notifications from passed promises\", function () {\n        var deferred = Q.defer();\n\n        var progressValsSeen = [];\n        var promise = Q.delay(deferred.promise, 100).then(function () {\n            expect(progressValsSeen).toEqual([1, 2, 3]);\n        }, undefined, function (progressVal) {\n            progressValsSeen.push(progressVal);\n        });\n\n        Q.delay(5).then(function () { deferred.notify(1); });\n        Q.delay(15).then(function () { deferred.notify(2); });\n        Q.delay(25).then(function () { deferred.notify(3); });\n        Q.delay(35).then(function () { deferred.resolve(); });\n\n        return promise;\n    });\n});\n\ndescribe(\"thenResolve\", function () {\n    describe(\"Resolving with a non-thenable value\", function () {\n        it(\"returns a promise for that object once the promise is resolved\", function () {\n            var waited = false;\n            return Q.delay(20)\n                .then(function () {\n                    waited = true;\n                })\n                .thenResolve(\"foo\")\n                .then(function (val) {\n                    expect(waited).toBe(true);\n                    expect(val).toBe(\"foo\");\n                });\n        });\n\n        describe(\"based off a rejected promise\", function () {\n            it(\"does nothing, letting the rejection flow through\", function () {\n                return Q.reject(\"boo\")\n                    .thenResolve(\"foo\")\n                    .then(\n                        function () {\n                            expect(true).toBe(false);\n                        },\n                        function (reason) {\n                            expect(reason).toBe(\"boo\");\n                        }\n                    );\n            });\n        });\n    });\n\n    describe(\"Resolving with an promise\", function () {\n        it(\"returns a promise for the result of that promise once the promise is resolved\", function () {\n            var waited = false;\n            return Q.delay(20)\n                .then(function () {\n                    waited = true;\n                })\n                .thenResolve(Q(\"foo\"))\n                .then(function (val) {\n                    expect(waited).toBe(true);\n                    expect(val).toBe(\"foo\");\n                });\n        });\n    });\n});\n\ndescribe(\"thenReject\", function () {\n    describe(\"Rejecting with a reason\", function () {\n        it(\"returns a promise rejected with that object once the original promise is resolved\", function () {\n            var waited = false;\n            return Q.delay(20)\n                .then(function () {\n                    waited = true;\n                })\n                .thenReject(\"foo\")\n                .then(\n                    function () {\n                        expect(true).toBe(false);\n                    },\n                    function (reason) {\n                        expect(waited).toBe(true);\n                        expect(reason).toBe(\"foo\");\n                    }\n                );\n        });\n\n        describe(\"based off a rejected promise\", function () {\n            it(\"does nothing, letting the rejection flow through\", function () {\n                return Q.reject(\"boo\")\n                    .thenResolve(\"foo\")\n                    .then(\n                        function () {\n                            expect(true).toBe(false);\n                        },\n                        function (reason) {\n                            expect(reason).toBe(\"boo\");\n                        }\n                    );\n            });\n        });\n    });\n});\n\ndescribe(\"thenables\", function () {\n\n    it(\"assimilates a thenable with fulfillment with resolve\", function () {\n        return Q({\n            then: function (resolved) {\n                resolved(10);\n            }\n        })\n        .then(function (ten) {\n            expect(ten).toEqual(10);\n        })\n        .then(function (undefined) {\n            expect(undefined).toEqual(void 0);\n        });\n    });\n\n    it(\"assimilates a thenable with progress and fulfillment (using resolve)\", function () {\n        var progressValueArrays = [];\n        return Q({\n            then: function (fulfilled, rejected, progressed) {\n                Q.nextTick(function () {\n                    progressed(1, 2);\n                    progressed(3, 4, 5);\n                    fulfilled();\n                });\n            }\n        })\n        .progress(function () {\n            progressValueArrays.push(Array.prototype.slice.call(arguments));\n        })\n        .then(function () {\n            expect(progressValueArrays).toEqual([[1], [3]]);\n        });\n    });\n\n    it(\"assimilates a thenable with progress and fulfillment (using when)\", function () {\n        var progressValueArrays = [];\n        return Q.when({\n            then: function (fulfilled, rejected, progressed) {\n                Q.nextTick(function () {\n                    progressed(1, 2);\n                    progressed(3, 4, 5);\n                    fulfilled();\n                });\n            }\n        })\n        .progress(function () {\n            progressValueArrays.push(Array.prototype.slice.call(arguments));\n        })\n        .then(function () {\n            expect(progressValueArrays).toEqual([[1], [3]]);\n        });\n    });\n\n    it(\"flows fulfillment into a promise pipeline\", function () {\n        return Q({\n            then: function (resolved) {\n                resolved([10]);\n            }\n        })\n        .get(0)\n        .then(function (ten) {\n            expect(ten).toEqual(10);\n        });\n    });\n\n    it(\"assimilates an immediately-fulfilled thenable in allSettled\", function () {\n        return Q.allSettled([\n            {then: function (win) {\n                win(10);\n            }}\n        ])\n        .then(function (snapshots) {\n            expect(snapshots).toEqual([{ state: \"fulfilled\", value: 10 }]);\n        });\n    });\n\n    it(\"assimilates an eventually-fulfilled thenable in allSettled\", function () {\n        return Q.allSettled([\n            {then: function (win) {\n                setTimeout(function () {\n                    win(10);\n                }, 100);\n            }}\n        ])\n        .then(function (snapshots) {\n            expect(snapshots).toEqual([{ state: \"fulfilled\", value: 10 }]);\n        });\n    });\n\n});\n\ndescribe(\"node support\", function () {\n\n    var exception = new Error(\"That is not your favorite color.\");\n\n    var obj = {\n        method: function (a, b, c, callback) {\n            callback(null, a + b + c);\n        },\n        thispChecker: function (callback) {\n            callback(null, this === obj);\n        },\n        errorCallbacker: function (a, b, c, callback) {\n            callback(exception);\n        },\n        errorThrower: function () {\n            throw exception;\n        }\n    };\n\n    describe(\"nfapply\", function () {\n\n        it(\"fulfills with callback result\", function () {\n            return Q.nfapply(function (a, b, c, callback) {\n                callback(null, a + b + c);\n            }, [1, 2, 3])\n            .then(function (sum) {\n                expect(sum).toEqual(6);\n            });\n        });\n\n        it(\"rejects with callback error\", function () {\n            var exception = new Error(\"That is not your favorite color.\");\n            return Q.nfapply(function (a, b, c, callback) {\n                callback(exception);\n            }, [1, 2, 3])\n            .then(function () {\n                expect(true).toBe(false);\n            }, function (_exception) {\n                expect(_exception).toBe(exception);\n            });\n        });\n\n    });\n\n    describe(\"nfcall\", function () {\n        it(\"fulfills with callback result\", function () {\n            return Q.nfcall(function (a, b, c, callback) {\n                callback(null, a + b + c);\n            }, 1, 2, 3)\n            .then(function (sum) {\n                expect(sum).toEqual(6);\n            });\n        });\n\n        it(\"rejects with callback error\", function () {\n            var exception = new Error(\"That is not your favorite color.\");\n            return Q.nfcall(function (a, b, c, callback) {\n                callback(exception);\n            }, 1, 2, 3)\n            .then(function () {\n                expect(true).toBe(false);\n            }, function (_exception) {\n                expect(_exception).toBe(exception);\n            });\n        });\n\n    });\n\n    describe(\"nfbind\", function () {\n\n        it(\"mixes partial application with complete application\", function () {\n            return Q.nfbind(function (a, b, c, d, callback) {\n                callback(null, a + b + c + d);\n            }, 1, 2).call({}, 3, 4)\n            .then(function (ten) {\n                expect(ten).toBe(10);\n            });\n        });\n\n    });\n\n    describe(\"nbind\", function () {\n\n        it(\"binds this, and mixes partial application with complete application\", function () {\n            return Q.nbind(function (a, b, c, callback) {\n                callback(null, this + a + b + c);\n            }, 1, 2).call(3 /* effectively ignored as fn bound to 1 */, 4, 5)\n            .then(function (twelve) {\n                expect(twelve).toBe(12);\n            });\n        });\n\n        it(\"second arg binds this\", function() {\n            var expectedThis = { test: null };\n\n            return Q.nbind(function(callback) {\n                callback(null, this);\n            }, expectedThis).call()\n            .then(function(actualThis) {\n                expect(actualThis).toEqual(expectedThis);\n            });\n        });\n\n    });\n\n\tdescribe(\"npost\", function () {\n\n        it(\"fulfills with callback result\", function () {\n            return Q.npost(obj, \"method\", [1, 2, 3])\n            .then(function (sum) {\n                expect(sum).toEqual(6);\n            });\n        });\n\n        it(\"gets the correct thisp\", function () {\n            return Q.npost(obj, \"thispChecker\", [])\n            .then(function (result) {\n                expect(result).toBe(true);\n            });\n        });\n\n        it(\"rejects with callback error\", function () {\n            return Q.npost(obj, \"errorCallbacker\", [1, 2, 3])\n            .then(function () {\n                expect(\"blue\").toBe(\"no, yellow!\");\n            }, function (_exception) {\n                expect(_exception).toBe(exception);\n            });\n        });\n\n        it(\"rejects with thrown error\", function () {\n            return Q.npost(obj, \"errorThrower\", [1, 2, 3])\n            .then(function () {\n                expect(true).toBe(false);\n            }, function (_exception) {\n                expect(_exception).toBe(exception);\n            });\n        });\n\n        it(\"works on promises for objects with Node methods\", function () {\n            return Q(obj)\n            .npost(\"method\", [1, 2, 3])\n            .then(function (sum) {\n                expect(sum).toEqual(6);\n            });\n        });\n\n    });\n\n    describe(\"nsend\", function () {\n\n        it(\"fulfills with callback result\", function () {\n            return Q.nsend(obj, \"method\", 1, 2, 3)\n            .then(function (sum) {\n                expect(sum).toEqual(6);\n            });\n        });\n\n        it(\"gets the correct thisp\", function () {\n            return Q.nsend(obj, \"thispChecker\")\n            .then(function (result) {\n                expect(result).toBe(true);\n            });\n        });\n\n        it(\"rejects with callback error\", function () {\n            return Q.nsend(obj, \"errorCallbacker\", 1, 2, 3)\n            .then(function () {\n                expect(\"blue\").toBe(\"no, yellow!\");\n            }, function (_exception) {\n                expect(_exception).toBe(exception);\n            });\n        });\n\n        it(\"rejects with thrown error\", function () {\n            return Q.nsend(obj, \"errorThrower\", 1, 2, 3)\n            .then(function () {\n                expect(true).toBe(false);\n            }, function (_exception) {\n                expect(_exception).toBe(exception);\n            });\n        });\n\n        it(\"works on promises for objects with Node methods\", function () {\n            return Q(obj)\n            .nsend(\"method\", 1, 2, 3)\n            .then(function (sum) {\n                expect(sum).toEqual(6);\n            });\n        });\n\n    });\n\n    describe(\"deferred.makeNodeResolver\", function () {\n\n        it(\"fulfills a promise with a single callback argument\", function () {\n            var deferred = Q.defer();\n            var callback = deferred.makeNodeResolver();\n            callback(null, 10);\n            return deferred.promise.then(function (value) {\n                expect(value).toBe(10);\n            });\n        });\n\n        it(\"fulfills a promise with multiple callback arguments\", function () {\n            var deferred = Q.defer();\n            var callback = deferred.makeNodeResolver();\n            callback(null, 10, 20);\n            return deferred.promise.then(function (value) {\n                expect(value).toEqual([10, 20]);\n            });\n        });\n\n        it(\"rejects a promise\", function () {\n            var deferred = Q.defer();\n            var callback = deferred.makeNodeResolver();\n            var exception = new Error(\"Holy Exception of Anitoch\");\n            callback(exception);\n            return deferred.promise.then(function () {\n                expect(5).toBe(3);\n            }, function (_exception) {\n                expect(_exception).toBe(exception);\n            });\n        });\n\n    });\n\n    describe(\"nodeify\", function () {\n\n        it(\"calls back with a resolution\", function () {\n            var spy = jasmine.createSpy();\n            Q(10).nodeify(spy);\n            waitsFor(function () {\n                return spy.argsForCall.length;\n            });\n            runs(function () {\n                expect(spy.argsForCall).toEqual([[null, 10]]);\n            });\n        });\n\n        it(\"calls back with an error\", function () {\n            var spy = jasmine.createSpy();\n            Q.reject(10).nodeify(spy);\n            waitsFor(function () {\n                return spy.argsForCall.length;\n            });\n            runs(function () {\n                expect(spy.argsForCall).toEqual([[10]]);\n            });\n        });\n\n        it(\"forwards a promise\", function () {\n            return Q(10).nodeify().then(function (ten) {\n                expect(ten).toBe(10);\n            });\n        });\n\n    });\n\n});\n\ndescribe(\"browser support\", function () {\n    var _Q;\n\n    beforeEach(function() {\n        _Q = Q;\n    });\n\n    afterEach(function() {\n        Q = _Q;\n    });\n\n    it(\"sets the global Q object to its original value\", function() {\n        if (typeof window !== 'undefined') {\n            // If window is not undefined, the tests are running in the browser\n            // assert that Q.noConflict returns window.Q to it's initial value\n            // In this context the original value of Q is undefined\n            Q.noConflict();\n            expect(Q).toEqual(undefined);\n        }\n    });\n\n    it(\"throws an error if Q.noConflict is called in node\", function () {\n        if (typeof window === 'undefined') {\n            // If window is undefined the tests are being run in node, and\n            // Q.noConflict should throw an error\n            expect(Q.noConflict).toThrow();\n        }\n    });\n});\n\ndescribe(\"isPromise\", function () {\n    it(\"returns true if passed a promise\", function () {\n        expect(Q.isPromise(Q(10))).toBe(true);\n    });\n\n    it(\"returns false if not passed a promise\", function () {\n        expect(Q.isPromise(undefined)).toBe(false);\n        expect(Q.isPromise(null)).toBe(false);\n        expect(Q.isPromise(10)).toBe(false);\n        expect(Q.isPromise(\"str\")).toBe(false);\n        expect(Q.isPromise(\"\")).toBe(false);\n        expect(Q.isPromise(true)).toBe(false);\n        expect(Q.isPromise(false)).toBe(false);\n        expect(Q.isPromise({})).toBe(false);\n        expect(Q.isPromise({\n            then: function () {}\n        })).toBe(false);\n        expect(Q.isPromise(function () {})).toBe(false);\n    });\n});\n\ndescribe(\"isPromiseAlike\", function () {\n    it(\"returns true if passed a promise like object\", function () {\n        expect(Q.isPromiseAlike(Q(10))).toBe(true);\n        expect(Q.isPromiseAlike({\n            then: function () {}\n        })).toBe(true);\n    });\n\n    it(\"returns false if not passed a promise like object\", function () {\n        expect(Q.isPromiseAlike(undefined)).toBe(false);\n        expect(Q.isPromiseAlike(null)).toBe(false);\n        expect(Q.isPromiseAlike(10)).toBe(false);\n        expect(Q.isPromiseAlike(\"str\")).toBe(false);\n        expect(Q.isPromiseAlike(\"\")).toBe(false);\n        expect(Q.isPromiseAlike(true)).toBe(false);\n        expect(Q.isPromiseAlike(false)).toBe(false);\n        expect(Q.isPromiseAlike({})).toBe(false);\n        expect(Q.isPromiseAlike(function () {})).toBe(false);\n    });\n});\n\nif (typeof require === \"function\") {\n    var domain;\n    try {\n        domain = require(\"domain\");\n    } catch (e) { }\n\n    if (domain) {\n        var EventEmitter = require(\"events\").EventEmitter;\n\n        describe(\"node domain support\", function () {\n            var d;\n\n            beforeEach(function () {\n                d = domain.create();\n            });\n\n            it(\"should work for non-promise async inside a promise handler\",\n               function (done) {\n                var error = new Error(\"should be caught by the domain\");\n\n                d.run(function () {\n                    Q().then(function () {\n                        setTimeout(function () {\n                            throw error;\n                        }, 10);\n                    });\n                });\n\n                var errorTimeout = setTimeout(function () {\n                    done(new Error(\"Wasn't caught\"));\n                }, 100);\n\n                d.on(\"error\", function (theError) {\n                    expect(theError).toBe(error);\n                    clearTimeout(errorTimeout);\n                    done();\n                });\n            });\n\n            it(\"should transfer errors from `done` into the domain\",\n               function (done) {\n                var error = new Error(\"should be caught by the domain\");\n\n                d.run(function () {\n                    Q.reject(error).done();\n                });\n\n                var errorTimeout = setTimeout(function () {\n                    done(new Error(\"Wasn't caught\"));\n                }, 100);\n\n                d.on(\"error\", function (theError) {\n                    expect(theError).toBe(error);\n                    clearTimeout(errorTimeout);\n                    done();\n                });\n            });\n\n            it(\"should take care of re-used event emitters\", function (done) {\n                // See discussion in https://github.com/kriskowal/q/issues/120\n                var error = new Error(\"should be caught by the domain\");\n\n                var e = new EventEmitter();\n\n                d.run(function () {\n                    callAsync().done();\n                });\n                setTimeout(function () {\n                    e.emit(\"beep\");\n                }, 100);\n\n                var errorTimeout = setTimeout(function () {\n                    done(new Error(\"Wasn't caught\"));\n                }, 500);\n\n                d.on(\"error\", function (theError) {\n                    expect(theError).toBe(error);\n                    clearTimeout(errorTimeout);\n                    done();\n                });\n\n                function callAsync() {\n                    var def = Q.defer();\n                    e.once(\"beep\", function () {\n                        def.reject(error);\n                    });\n                    return def.promise;\n                }\n            });\n        });\n    }\n}\n\ndescribe(\"decorator functions\", function () {\n    describe(\"promised\", function () {\n        var exception = new Error(\"That is not the meaning of life.\");\n        it(\"resolves promised arguments\", function () {\n            var sum = Q.promised(function add(a, b) {\n                return a + b;\n            });\n            return sum(Q(4), Q(5)).then(function (sum) {\n                expect(sum).toEqual(9);\n            });\n        });\n        it(\"resolves promised `this`\", function () {\n            var inc = Q.promised(function inc(a) {\n                return this + a;\n            });\n            return inc.call(Q(4), Q(5)).then(function (sum) {\n                expect(sum).toEqual(9);\n            });\n        });\n        it(\"is rejected if an argument is rejected\", function () {\n            var sum = Q.promised(function add(a, b) {\n                return a + b;\n            });\n            return sum(Q.reject(exception), Q(4)).then(function () {\n                expect(4).toEqual(42);\n            }, function (_exception) {\n                expect(_exception).toBe(exception);\n            });\n        });\n        it(\"is rejected if `this` is rejected\", function () {\n            var inc = Q.promised(function inc(a) {\n                return this + a;\n            });\n            return inc.call(Q.reject(exception), Q(4)).then(function () {\n                expect(4).toEqual(42);\n            }, function (_exception) {\n                expect(_exception).toBe(exception);\n            });\n        });\n    });\n});\n\ndescribe(\"stack trace formatting\", function () {\n    it(\"doesn't mangle a stack trace that gets handled twice\", function () {\n        var d1 = Q.defer();\n        var d2 = Q.defer();\n        var captured = [];\n        d1.promise.done();\n        d2.promise.done();\n\n        Q.onerror = function (err) {\n            captured.push(err.stack);\n        };\n\n        var error = new Error(\"boom!\");\n        d1.reject(error);\n        d2.reject(error);\n\n        return Q.all([d1.promise.fail(function () {}), d2.promise.fail(function () { })])\n        .then(function () {\n            expect(captured[0]).toEqual(captured[1]);\n        });\n    });\n});\n\ndescribe(\"long stack traces\", function () {\n    beforeEach(function () {\n        Q.longStackSupport = true;\n    });\n\n    afterEach(function () {\n        Q.longStackSupport = false;\n    });\n\n    it(\"include all the calling functions\", function () {\n        function func1() {\n            return Q().then(function () { return func2(); });\n        }\n        function func2() {\n            return new Q.Promise(function (resolve, reject) {\n                func3().then(resolve, reject);\n            });\n        }\n        function func3() {\n            return new Q.Promise(function (resolve, reject) {\n                setTimeout(function () {\n                    reject(new Error(REASON));\n                }, 0);\n            });\n        }\n\n        return func1()\n        .catch(function (err) {\n            expect(err.stack).toMatch(/func3(.|\\n)*func2(.|\\n)*func1/);\n        });\n    });\n\n    it(\"does not duplicate lines when rethrowing an error\", function () {\n        function func1() {\n            return func2()\n                .catch(function rethrow (err) {throw err;})\n                .catch(function rethrow (err) {throw err;});\n        }\n        function func2() {\n            return Q().then(function () {\n                return func3();\n            });\n        }\n        function func3() {\n            return Q.reject(new Error(REASON));\n        }\n\n        return func1()\n        .catch(function (err) {\n            expect(err.stack).toMatch(/func3(.|\\n)*func2(.|\\n)*func1/);\n            expect(err.stack.match(/func1/g).length).toBe(1);\n        });\n    });\n\n    it(\"does not add visible properties to thrown errors\", function () {\n        return Q().then(function () { throw new Error(REASON); })\n        .catch(function (err) {\n            var keys = [];\n            for (var key in err) {\n                keys.push(key);\n            }\n            expect(keys.length).toBe(0);\n        });\n    });\n});\n\ndescribe(\"possible regressions\", function () {\n\n    describe(\"gh-9\", function () {\n        it(\"treats falsy values as resolved values without error\", function () {\n            expect(Q.isPending(null)).toEqual(false);\n            expect(Q.isPending(void 0)).toEqual(false);\n            expect(Q.isPending(false)).toEqual(false);\n            expect(Q.isPending()).toEqual(false);\n        });\n    });\n\n    describe(\"gh-22\", function () {\n        it(\"ensures that the array prototype is intact\", function () {\n            var keys = [];\n            for (var key in []) {\n                keys.push(key);\n            }\n            expect(keys.length).toBe(0);\n        });\n    });\n\n    describe(\"gh-73\", function () {\n        it(\"does not choke on non-error rejection reasons\", function () {\n            Q.reject(REASON).done();\n\n            var deferred = Q.defer();\n\n            Q.onerror = function (error) {\n                expect(error).toBe(REASON);\n                deferred.resolve();\n            };\n            Q.delay(10).then(deferred.reject);\n\n            return deferred.promise;\n        });\n    });\n\n    describe(\"gh-90\", function () {\n        it(\"does not choke on rejection reasons with an undefined `stack`\", function () {\n            var error = new RangeError(REASON);\n            error.stack = undefined;\n            Q.reject(error).done();\n\n            var deferred = Q.defer();\n\n            Q.onerror = function (theError) {\n                expect(theError).toBe(error);\n                deferred.resolve();\n            };\n            Q.delay(10).then(deferred.reject);\n\n            return deferred.promise;\n        });\n    });\n\n    describe(\"gh-75\", function () {\n        it(\"does not double-resolve misbehaved promises\", function () {\n            var badPromise = Q.makePromise({\n                post: function () { return \"hello\"; }\n            });\n\n            var resolutions = 0;\n            function onResolution() {\n                ++resolutions;\n            }\n\n            return Q.when(badPromise, onResolution, onResolution).then(function () {\n                expect(resolutions).toBe(1);\n            });\n        });\n    });\n\n});\n\ndescribe(\"unhandled rejection reporting\", function () {\n    beforeEach(function () {\n        Q.resetUnhandledRejections();\n    });\n\n    it(\"doesn't report a resolve, then reject (gh-252)\", function () {\n        var deferred = Q.defer();\n        deferred.resolve();\n        deferred.reject();\n\n        expect(Q.getUnhandledReasons().length).toEqual(0);\n    });\n\n    it(\"doesn't report when you chain off a rejection\", function () {\n        return Q.reject(\"this will be handled\").get(\"property\").fail(function () {\n            // now it should be handled.\n        }).fin(function() {\n            expect(Q.getUnhandledReasons().length).toEqual(0);\n        });\n    });\n\n    it(\"reports the most basic case\", function () {\n        Q.reject(\"a reason\");\n\n        expect(Q.getUnhandledReasons()).toEqual([\"(no stack) a reason\"]);\n    });\n\n    it(\"reports a stack trace\", function () {\n        var error = new Error(\"a reason\");\n        Q.reject(error);\n\n        expect(Q.getUnhandledReasons()).toEqual([error.stack]);\n    });\n\n    it(\"doesn't let you mutate the internal array\", function () {\n        Q.reject(\"a reason\");\n\n        Q.getUnhandledReasons().length = 0;\n        expect(Q.getUnhandledReasons()).toEqual([\"(no stack) a reason\"]);\n    });\n\n    it(\"resets after calling `Q.resetUnhandledRejections`\", function () {\n        Q.reject(\"a reason\");\n\n        Q.resetUnhandledRejections();\n        expect(Q.getUnhandledReasons()).toEqual([]);\n    });\n\n    it(\"stops tracking after calling `Q.stopUnhandledRejectionTracking`\", function () {\n        Q.reject(\"a reason\");\n\n        Q.stopUnhandledRejectionTracking();\n\n        Q.reject(\"another reason\");\n\n        expect(Q.getUnhandledReasons()).toEqual([]);\n    });\n});\n"
  },
  {
    "path": "spec/queue-spec.js",
    "content": "\nvar Q = require(\"../q\");\nvar Queue = require(\"../queue\");\n\nglobal.Q = Q;\nrequire(\"./lib/jasmine-promise\");\n\ndescribe(\"queue\", function () {\n\n    it(\"should enqueue then dequeue\", function () {\n        var queue = Queue();\n        queue.put(1);\n        return queue.get().then(function (value) {\n            expect(value).toBe(1);\n        });\n    });\n\n    it(\"should dequeue then enqueue\", function () {\n        var queue = Queue();\n        var promise = queue.get().then(function (value) {\n            expect(value).toBe(1);\n        });\n        queue.put(1);\n        return promise;\n    });\n\n    it(\"should stream\", function () {\n        var queue = Queue();\n\n        Q.try(function () {\n            return Q.delay(20).then(function () {\n                queue.put(1);\n            })\n        })\n        .then(function () {\n            return Q.delay(20).then(function () {\n                queue.put(2);\n            })\n        })\n        .then(function () {\n            return Q.delay(20).then(function () {\n                queue.put(3);\n            })\n        })\n        .done();\n\n        return Q.try(function () {\n            return queue.get()\n            .then(function (value) {\n                expect(value).toBe(1);\n            });\n        })\n        .then(function () {\n            return queue.get()\n            .then(function (value) {\n                expect(value).toBe(2);\n            });\n        })\n        .then(function () {\n            return queue.get()\n            .then(function (value) {\n                expect(value).toBe(3);\n            });\n        })\n\n    });\n\n    it(\"should be order agnostic\", function () {\n        var queue = Queue();\n\n        Q.try(function () {\n            return Q.delay(20).then(function () {\n                queue.put(1);\n            })\n        })\n        .then(function () {\n            return Q.delay(20).then(function () {\n                queue.put(2);\n            })\n        })\n        .then(function () {\n            return Q.delay(20).then(function () {\n                queue.put(3);\n            })\n        })\n        .done();\n\n        return Q.all([\n            queue.get()\n            .then(function (value) {\n                expect(value).toBe(1);\n            }),\n            queue.get()\n            .then(function (value) {\n                expect(value).toBe(2);\n            }),\n            queue.get()\n            .then(function (value) {\n                expect(value).toBe(3);\n            })\n        ]);\n    });\n\n    it(\"should close\", function () {\n\n        var queue = Queue();\n\n        Q.try(function () {\n            return Q.delay(20).then(function () {\n                queue.put(1);\n            })\n        })\n        .then(function () {\n            return Q.delay(20).then(function () {\n                queue.put(2);\n            })\n        })\n        .then(function () {\n            queue.close();\n        })\n        .done();\n\n        return Q.try(function () {\n            return queue.get()\n            .then(function (value) {\n                expect(value).toBe(1);\n            });\n        })\n        .then(function () {\n            return queue.get()\n            .then(function (value) {\n                expect(value).toBe(2);\n            });\n        })\n        .then(function () {\n            return queue.get()\n            .then(function (value) {\n                expect(false).toBe(true); // should not get here\n            });\n        })\n        .catch(function (error) {\n            expect(error.message).toBe(\"Can't get value from closed queue\");\n            return queue.get();\n        })\n        .catch(function (error) {\n            expect(error.message).toBe(\"Can't get value from closed queue\");\n        })\n        .then(function () {\n            return queue.closed;\n        })\n        .then(function (error) {\n            expect(error.message).toBe(\"Can't get value from closed queue\");\n        })\n    });\n\n    it(\"should close with alternate error\", function () {\n\n        var queue = Queue();\n        queue.close(new Error(\"Alternate reason\"));\n\n        return Q.try(function () {\n            return queue.get();\n        })\n        .catch(function (error) {\n            expect(error.message).toBe(\"Alternate reason\");\n            return queue.get();\n        })\n        .catch(function (error) {\n            expect(error.message).toBe(\"Alternate reason\");\n        })\n        .then(function () {\n            return queue.closed;\n        })\n        .then(function (error) {\n            expect(error.message).toBe(\"Alternate reason\");\n        })\n    });\n\n});\n\n"
  }
]