| "use strict"; | 
| module.exports = function(Promise, INTERNAL, debug) { | 
| var util = require("./util"); | 
| var TimeoutError = Promise.TimeoutError; | 
|   | 
| function HandleWrapper(handle)  { | 
|     this.handle = handle; | 
| } | 
|   | 
| HandleWrapper.prototype._resultCancelled = function() { | 
|     clearTimeout(this.handle); | 
| }; | 
|   | 
| var afterValue = function(value) { return delay(+this).thenReturn(value); }; | 
| var delay = Promise.delay = function (ms, value) { | 
|     var ret; | 
|     var handle; | 
|     if (value !== undefined) { | 
|         ret = Promise.resolve(value) | 
|                 ._then(afterValue, null, null, ms, undefined); | 
|         if (debug.cancellation() && value instanceof Promise) { | 
|             ret._setOnCancel(value); | 
|         } | 
|     } else { | 
|         ret = new Promise(INTERNAL); | 
|         handle = setTimeout(function() { ret._fulfill(); }, +ms); | 
|         if (debug.cancellation()) { | 
|             ret._setOnCancel(new HandleWrapper(handle)); | 
|         } | 
|         ret._captureStackTrace(); | 
|     } | 
|     ret._setAsyncGuaranteed(); | 
|     return ret; | 
| }; | 
|   | 
| Promise.prototype.delay = function (ms) { | 
|     return delay(ms, this); | 
| }; | 
|   | 
| var afterTimeout = function (promise, message, parent) { | 
|     var err; | 
|     if (typeof message !== "string") { | 
|         if (message instanceof Error) { | 
|             err = message; | 
|         } else { | 
|             err = new TimeoutError("operation timed out"); | 
|         } | 
|     } else { | 
|         err = new TimeoutError(message); | 
|     } | 
|     util.markAsOriginatingFromRejection(err); | 
|     promise._attachExtraTrace(err); | 
|     promise._reject(err); | 
|   | 
|     if (parent != null) { | 
|         parent.cancel(); | 
|     } | 
| }; | 
|   | 
| function successClear(value) { | 
|     clearTimeout(this.handle); | 
|     return value; | 
| } | 
|   | 
| function failureClear(reason) { | 
|     clearTimeout(this.handle); | 
|     throw reason; | 
| } | 
|   | 
| Promise.prototype.timeout = function (ms, message) { | 
|     ms = +ms; | 
|     var ret, parent; | 
|   | 
|     var handleWrapper = new HandleWrapper(setTimeout(function timeoutTimeout() { | 
|         if (ret.isPending()) { | 
|             afterTimeout(ret, message, parent); | 
|         } | 
|     }, ms)); | 
|   | 
|     if (debug.cancellation()) { | 
|         parent = this.then(); | 
|         ret = parent._then(successClear, failureClear, | 
|                             undefined, handleWrapper, undefined); | 
|         ret._setOnCancel(handleWrapper); | 
|     } else { | 
|         ret = this._then(successClear, failureClear, | 
|                             undefined, handleWrapper, undefined); | 
|     } | 
|   | 
|     return ret; | 
| }; | 
|   | 
| }; |