whole_func_string: function qFactory(nextTick, exceptionHandler, errorOnUnhandledRejections) {
    var $qMinErr = minErr('$q', TypeError);
    var queueSize = 0;
    var checkQueue = [];
  
    /**
     * @ngdoc method
     * @name ng.$q#defer
     * @kind function
     *
     * @description
     * Creates a `Deferred` object which represents a task which will finish in the future.
     *
     * @returns {Deferred} Returns a new instance of deferred.
     */
    function defer() {
      return new Deferred();
    }
  
    function Deferred() {
      var promise = this.promise = new Promise();
      //Non prototype methods necessary to support unbound execution :/
      this.resolve = function(val) { resolvePromise(promise, val); };
      this.reject = function(reason) { rejectPromise(promise, reason); };
      this.notify = function(progress) { notifyPromise(promise, progress); };
    }
  
  
    function Promise() {
      this.$$state = { status: 0 };
    }
  
    extend(Promise.prototype, {
      then: function(onFulfilled, onRejected, progressBack) {
        if (isUndefined(onFulfilled) && isUndefined(onRejected) && isUndefined(progressBack)) {
          return this;
        }
        var result = new Promise();
  
        this.$$state.pending = this.$$state.pending || [];
        this.$$state.pending.push([result, onFulfilled, onRejected, progressBack]);
        if (this.$$state.status > 0) scheduleProcessQueue(this.$$state);
  
        return result;
      },
  
      'catch': function(callback) {
        return this.then(null, callback);
      },
  
      'finally': function(callback, progressBack) {
        return this.then(function(value) {
          return handleCallback(value, resolve, callback);
        }, function(error) {
          return handleCallback(error, reject, callback);
        }, progressBack);
      }
    });
  
    function processQueue(state) {
      var fn, promise, pending;
  
      pending = state.pending;
      state.processScheduled = false;
      state.pending = undefined;
      try {
        for (var i = 0, ii = pending.length; i < ii; ++i) {
          markQStateExceptionHandled(state);
          promise = pending[i][0];
          fn = pending[i][state.status];
          try {
            if (isFunction(fn)) {
              resolvePromise(promise, fn(state.value));
            } else if (state.status === 1) {
              resolvePromise(promise, state.value);
            } else {
              rejectPromise(promise, state.value);
            }
          } catch (e) {
            rejectPromise(promise, e);
            // This error is explicitly marked for being passed to the $exceptionHandler
            if (e && e.$$passToExceptionHandler === true) {
              exceptionHandler(e);
            }
          }
        }
      } finally {
        --queueSize;
        if (errorOnUnhandledRejections && queueSize === 0) {
          nextTick(processChecks);
        }
      }
    }
  
    function processChecks() {
      // eslint-disable-next-line no-unmodified-loop-condition
      while (!queueSize && checkQueue.length) {
        var toCheck = checkQueue.shift();
        if (!isStateExceptionHandled(toCheck)) {
          markQStateExceptionHandled(toCheck);
          var errorMessage = 'Possibly unhandled rejection: ' + toDebugString(toCheck.value);
          if (isError(toCheck.value)) {
            exceptionHandler(toCheck.value, errorMessage);
          } else {
            exceptionHandler(errorMessage);
          }
        }
      }
    }
  
    function scheduleProcessQueue(state) {
      if (errorOnUnhandledRejections && !state.pending && state.status === 2 && !isStateExceptionHandled(state)) {
        if (queueSize === 0 && checkQueue.length === 0) {
          nextTick(processChecks);
        }
        checkQueue.push(state);
      }
      if (state.processScheduled || !state.pending) return;
      state.processScheduled = true;
      ++queueSize;
      nextTick(function() { processQueue(state); });
    }
  
    function resolvePromise(promise, val) {
      if (promise.$$state.status) return;
      if (val === promise) {
        $$reject(promise, $qMinErr(
          'qcycle',
          'Expected promise to be resolved with value other than itself \'{0}\'',
          val));
      } else {
        $$resolve(promise, val);
      }
  
    }
  
    function $$resolve(promise, val) {
      var then;
      var done = false;
      try {
        if (isObject(val) || isFunction(val)) then = val.then;
        if (isFunction(then)) {
          promise.$$state.status = -1;
          then.call(val, doResolve, doReject, doNotify);
        } else {
          promise.$$state.value = val;
          promise.$$state.status = 1;
          scheduleProcessQueue(promise.$$state);
        }
      } catch (e) {
        doReject(e);
      }
  
      function doResolve(val) {
        if (done) return;
        done = true;
        $$resolve(promise, val);
      }
      function doReject(val) {
        if (done) return;
        done = true;
        $$reject(promise, val);
      }
      function doNotify(progress) {
        notifyPromise(promise, progress);
      }
    }
  
    function rejectPromise(promise, reason) {
      if (promise.$$state.status) return;
      $$reject(promise, reason);
    }
  
    function $$reject(promise, reason) {
      promise.$$state.value = reason;
      promise.$$state.status = 2;
      scheduleProcessQueue(promise.$$state);
    }
  
    function notifyPromise(promise, progress) {
      var callbacks = promise.$$state.pending;
  
      if ((promise.$$state.status <= 0) && callbacks && callbacks.length) {
        nextTick(function() {
          var callback, result;
          for (var i = 0, ii = callbacks.length; i < ii; i++) {
            result = callbacks[i][0];
            callback = callbacks[i][3];
            try {
              notifyPromise(result, isFunction(callback) ? callback(progress) : progress);
            } catch (e) {
              exceptionHandler(e);
            }
          }
        });
      }
    }
  
    /**
     * @ngdoc method
     * @name $q#reject
     * @kind function
     *
     * @description
     * Creates a promise that is resolved as rejected with the specified `reason`. This api should be
     * used to forward rejection in a chain of promises. If you are dealing with the last promise in
     * a promise chain, you don't need to worry about it.
     *
     * When comparing deferreds/promises to the familiar behavior of try/catch/throw, think of
     * `reject` as the `throw` keyword in JavaScript. This also means that if you "catch" an error via
     * a promise error callback and you want to forward the error to the promise derived from the
     * current promise, you have to "rethrow" the error by returning a rejection constructed via
     * `reject`.
     *
     * ```js
     *   promiseB = promiseA.then(function(result) {
     *     // success: do something and resolve promiseB
     *     //          with the old or a new result
     *     return result;
     *   }, function(reason) {
     *     // error: handle the error if possible and
     *     //        resolve promiseB with newPromiseOrValue,
     *     //        otherwise forward the rejection to promiseB
     *     if (canHandle(reason)) {
     *      // handle the error and recover
     *      return newPromiseOrValue;
     *     }
     *     return $q.reject(reason);
     *   });
     * ```
     *
     * @param {*} reason Constant, message, exception or an object representing the rejection reason.
     * @returns {Promise} Returns a promise that was already resolved as rejected with the `reason`.
     */
    function reject(reason) {
      var result = new Promise();
      rejectPromise(result, reason);
      return result;
    }
  
    function handleCallback(value, resolver, callback) {
      var callbackOutput = null;
      try {
        if (isFunction(callback)) callbackOutput = callback();
      } catch (e) {
        return reject(e);
      }
      if (isPromiseLike(callbackOutput)) {
        return callbackOutput.then(function() {
          return resolver(value);
        }, reject);
      } else {
        return resolver(value);
      }
    }
  
    /**
     * @ngdoc method
     * @name $q#when
     * @kind function
     *
     * @description
     * Wraps an object that might be a value or a (3rd party) then-able promise into a $q promise.
     * This is useful when you are dealing with an object that might or might not be a promise, or if
     * the promise comes from a source that can't be trusted.
     *
     * @param {*} value Value or a promise
     * @param {Function=} successCallback
     * @param {Function=} errorCallback
     * @param {Function=} progressCallback
     * @returns {Promise} Returns a promise of the passed value or promise
     */
  
  
    function when(value, callback, errback, progressBack) {
      var result = new Promise();
      resolvePromise(result, value);
      return result.then(callback, errback, progressBack);
    }
  
    /**
     * @ngdoc method
     * @name $q#resolve
     * @kind function
     *
     * @description
     * Alias of {@link ng.$q#when when} to maintain naming consistency with ES6.
     *
     * @param {*} value Value or a promise
     * @param {Function=} successCallback
     * @param {Function=} errorCallback
     * @param {Function=} progressCallback
     * @returns {Promise} Returns a promise of the passed value or promise
     */
    var resolve = when;
  
    /**
     * @ngdoc method
     * @name $q#all
     * @kind function
     *
     * @description
     * Combines multiple promises into a single promise that is resolved when all of the input
     * promises are resolved.
     *
     * @param {Array.<Promise>|Object.<Promise>} promises An array or hash of promises.
     * @returns {Promise} Returns a single promise that will be resolved with an array/hash of values,
     *   each value corresponding to the promise at the same index/key in the `promises` array/hash.
     *   If any of the promises is resolved with a rejection, this resulting promise will be rejected
     *   with the same rejection value.
     */
  
    function all(promises) {
      var result = new Promise(),
          counter = 0,
          results = isArray(promises) ? [] : {};
  
      forEach(promises, function(promise, key) {
        counter++;
        when(promise).then(function(value) {
          results[key] = value;
          if (!(--counter)) resolvePromise(result, results);
        }, function(reason) {
          rejectPromise(result, reason);
        });
      });
  
      if (counter === 0) {
        resolvePromise(result, results);
      }
  
      return result;
    }
  
    /**
     * @ngdoc method
     * @name $q#race
     * @kind function
     *
     * @description
     * Returns a promise that resolves or rejects as soon as one of those promises
     * resolves or rejects, with the value or reason from that promise.
     *
     * @param {Array.<Promise>|Object.<Promise>} promises An array or hash of promises.
     * @returns {Promise} a promise that resolves or rejects as soon as one of the `promises`
     * resolves or rejects, with the value or reason from that promise.
     */
  
    function race(promises) {
      var deferred = defer();
  
      forEach(promises, function(promise) {
        when(promise).then(deferred.resolve, deferred.reject);
      });
  
      return deferred.promise;
    }
  
    function $Q(resolver) {
      if (!isFunction(resolver)) {
        throw $qMinErr('norslvr', 'Expected resolverFn, got \'{0}\'', resolver);
      }
  
      var promise = new Promise();
  
      function resolveFn(value) {
        resolvePromise(promise, value);
      }
  
      function rejectFn(reason) {
        rejectPromise(promise, reason);
      }
  
      resolver(resolveFn, rejectFn);
  
      return promise;
    }
  
    // Let's make the instanceof operator work for promises, so that
    // `new $q(fn) instanceof $q` would evaluate to true.
    $Q.prototype = Promise.prototype;
  
    $Q.defer = defer;
    $Q.reject = reject;
    $Q.when = when;
    $Q.resolve = resolve;
    $Q.all = all;
    $Q.race = race;
  
    return $Q;
  }
func_code_string: function qFactory(nextTick, exceptionHandler, errorOnUnhandledRejections) {
    var $qMinErr = minErr('$q', TypeError);
    var queueSize = 0;
    var checkQueue = [];
  
    /**
     * @ngdoc method
     * @name ng.$q#defer
     * @kind function
     *
     * @description
     * Creates a `Deferred` object which represents a task which will finish in the future.
     *
     * @returns {Deferred} Returns a new instance of deferred.
     */
    function defer() {
      return new Deferred();
    }
  
    function Deferred() {
      var promise = this.promise = new Promise();
      //Non prototype methods necessary to support unbound execution :/
      this.resolve = function(val) { resolvePromise(promise, val); };
      this.reject = function(reason) { rejectPromise(promise, reason); };
      this.notify = function(progress) { notifyPromise(promise, progress); };
    }
  
  
    function Promise() {
      this.$$state = { status: 0 };
    }
  
    extend(Promise.prototype, {
      then: function(onFulfilled, onRejected, progressBack) {
        if (isUndefined(onFulfilled) && isUndefined(onRejected) && isUndefined(progressBack)) {
          return this;
        }
        var result = new Promise();
  
        this.$$state.pending = this.$$state.pending || [];
        this.$$state.pending.push([result, onFulfilled, onRejected, progressBack]);
        if (this.$$state.status > 0) scheduleProcessQueue(this.$$state);
  
        return result;
      },
  
      'catch': function(callback) {
        return this.then(null, callback);
      },
  
      'finally': function(callback, progressBack) {
        return this.then(function(value) {
          return handleCallback(value, resolve, callback);
        }, function(error) {
          return handleCallback(error, reject, callback);
        }, progressBack);
      }
    });
  
    function processQueue(state) {
      var fn, promise, pending;
  
      pending = state.pending;
      state.processScheduled = false;
      state.pending = undefined;
      try {
        for (var i = 0, ii = pending.length; i < ii; ++i) {
          markQStateExceptionHandled(state);
          promise = pending[i][0];
          fn = pending[i][state.status];
          try {
            if (isFunction(fn)) {
              resolvePromise(promise, fn(state.value));
            } else if (state.status === 1) {
              resolvePromise(promise, state.value);
            } else {
              rejectPromise(promise, state.value);
            }
          } catch (e) {
            rejectPromise(promise, e);
            // This error is explicitly marked for being passed to the $exceptionHandler
            if (e && e.$$passToExceptionHandler === true) {
              exceptionHandler(e);
            }
          }
        }
      } finally {
        --queueSize;
        if (errorOnUnhandledRejections && queueSize === 0) {
          nextTick(processChecks);
        }
      }
    }
  
    function processChecks() {
      // eslint-disable-next-line no-unmodified-loop-condition
      while (!queueSize && checkQueue.length) {
        var toCheck = checkQueue.shift();
        if (!isStateExceptionHandled(toCheck)) {
          markQStateExceptionHandled(toCheck);
          var errorMessage = 'Possibly unhandled rejection: ' + toDebugString(toCheck.value);
          if (isError(toCheck.value)) {
            exceptionHandler(toCheck.value, errorMessage);
          } else {
            exceptionHandler(errorMessage);
          }
        }
      }
    }
  
    function scheduleProcessQueue(state) {
      if (errorOnUnhandledRejections && !state.pending && state.status === 2 && !isStateExceptionHandled(state)) {
        if (queueSize === 0 && checkQueue.length === 0) {
          nextTick(processChecks);
        }
        checkQueue.push(state);
      }
      if (state.processScheduled || !state.pending) return;
      state.processScheduled = true;
      ++queueSize;
      nextTick(function() { processQueue(state); });
    }
  
    function resolvePromise(promise, val) {
      if (promise.$$state.status) return;
      if (val === promise) {
        $$reject(promise, $qMinErr(
          'qcycle',
          'Expected promise to be resolved with value other than itself \'{0}\'',
          val));
      } else {
        $$resolve(promise, val);
      }
  
    }
  
    function $$resolve(promise, val) {
      var then;
      var done = false;
      try {
        if (isObject(val) || isFunction(val)) then = val.then;
        if (isFunction(then)) {
          promise.$$state.status = -1;
          then.call(val, doResolve, doReject, doNotify);
        } else {
          promise.$$state.value = val;
          promise.$$state.status = 1;
          scheduleProcessQueue(promise.$$state);
        }
      } catch (e) {
        doReject(e);
      }
  
      function doResolve(val) {
        if (done) return;
        done = true;
        $$resolve(promise, val);
      }
      function doReject(val) {
        if (done) return;
        done = true;
        $$reject(promise, val);
      }
      function doNotify(progress) {
        notifyPromise(promise, progress);
      }
    }
  
    function rejectPromise(promise, reason) {
      if (promise.$$state.status) return;
      $$reject(promise, reason);
    }
  
    function $$reject(promise, reason) {
      promise.$$state.value = reason;
      promise.$$state.status = 2;
      scheduleProcessQueue(promise.$$state);
    }
  
    function notifyPromise(promise, progress) {
      var callbacks = promise.$$state.pending;
  
      if ((promise.$$state.status <= 0) && callbacks && callbacks.length) {
        nextTick(function() {
          var callback, result;
          for (var i = 0, ii = callbacks.length; i < ii; i++) {
            result = callbacks[i][0];
            callback = callbacks[i][3];
            try {
              notifyPromise(result, isFunction(callback) ? callback(progress) : progress);
            } catch (e) {
              exceptionHandler(e);
            }
          }
        });
      }
    }
  
    /**
     * @ngdoc method
     * @name $q#reject
     * @kind function
     *
     * @description
     * Creates a promise that is resolved as rejected with the specified `reason`. This api should be
     * used to forward rejection in a chain of promises. If you are dealing with the last promise in
     * a promise chain, you don't need to worry about it.
     *
     * When comparing deferreds/promises to the familiar behavior of try/catch/throw, think of
     * `reject` as the `throw` keyword in JavaScript. This also means that if you "catch" an error via
     * a promise error callback and you want to forward the error to the promise derived from the
     * current promise, you have to "rethrow" the error by returning a rejection constructed via
     * `reject`.
     *
     * ```js
     *   promiseB = promiseA.then(function(result) {
     *     // success: do something and resolve promiseB
     *     //          with the old or a new result
     *     return result;
     *   }, function(reason) {
     *     // error: handle the error if possible and
     *     //        resolve promiseB with newPromiseOrValue,
     *     //        otherwise forward the rejection to promiseB
     *     if (canHandle(reason)) {
     *      // handle the error and recover
     *      return newPromiseOrValue;
     *     }
     *     return $q.reject(reason);
     *   });
     * ```
     *
     * @param {*} reason Constant, message, exception or an object representing the rejection reason.
     * @returns {Promise} Returns a promise that was already resolved as rejected with the `reason`.
     */
    function reject(reason) {
      var result = new Promise();
      rejectPromise(result, reason);
      return result;
    }
  
    function handleCallback(value, resolver, callback) {
      var callbackOutput = null;
      try {
        if (isFunction(callback)) callbackOutput = callback();
      } catch (e) {
        return reject(e);
      }
      if (isPromiseLike(callbackOutput)) {
        return callbackOutput.then(function() {
          return resolver(value);
        }, reject);
      } else {
        return resolver(value);
      }
    }
  
    /**
     * @ngdoc method
     * @name $q#when
     * @kind function
     *
     * @description
     * Wraps an object that might be a value or a (3rd party) then-able promise into a $q promise.
     * This is useful when you are dealing with an object that might or might not be a promise, or if
     * the promise comes from a source that can't be trusted.
     *
     * @param {*} value Value or a promise
     * @param {Function=} successCallback
     * @param {Function=} errorCallback
     * @param {Function=} progressCallback
     * @returns {Promise} Returns a promise of the passed value or promise
     */
  
  
    function when(value, callback, errback, progressBack) {
      var result = new Promise();
      resolvePromise(result, value);
      return result.then(callback, errback, progressBack);
    }
  
    /**
     * @ngdoc method
     * @name $q#resolve
     * @kind function
     *
     * @description
     * Alias of {@link ng.$q#when when} to maintain naming consistency with ES6.
     *
     * @param {*} value Value or a promise
     * @param {Function=} successCallback
     * @param {Function=} errorCallback
     * @param {Function=} progressCallback
     * @returns {Promise} Returns a promise of the passed value or promise
     */
    var resolve = when;
  
    /**
     * @ngdoc method
     * @name $q#all
     * @kind function
     *
     * @description
     * Combines multiple promises into a single promise that is resolved when all of the input
     * promises are resolved.
     *
     * @param {Array.<Promise>|Object.<Promise>} promises An array or hash of promises.
     * @returns {Promise} Returns a single promise that will be resolved with an array/hash of values,
     *   each value corresponding to the promise at the same index/key in the `promises` array/hash.
     *   If any of the promises is resolved with a rejection, this resulting promise will be rejected
     *   with the same rejection value.
     */
  
    function all(promises) {
      var result = new Promise(),
          counter = 0,
          results = isArray(promises) ? [] : {};
  
      forEach(promises, function(promise, key) {
        counter++;
        when(promise).then(function(value) {
          results[key] = value;
          if (!(--counter)) resolvePromise(result, results);
        }, function(reason) {
          rejectPromise(result, reason);
        });
      });
  
      if (counter === 0) {
        resolvePromise(result, results);
      }
  
      return result;
    }
  
    /**
     * @ngdoc method
     * @name $q#race
     * @kind function
     *
     * @description
     * Returns a promise that resolves or rejects as soon as one of those promises
     * resolves or rejects, with the value or reason from that promise.
     *
     * @param {Array.<Promise>|Object.<Promise>} promises An array or hash of promises.
     * @returns {Promise} a promise that resolves or rejects as soon as one of the `promises`
     * resolves or rejects, with the value or reason from that promise.
     */
  
    function race(promises) {
      var deferred = defer();
  
      forEach(promises, function(promise) {
        when(promise).then(deferred.resolve, deferred.reject);
      });
  
      return deferred.promise;
    }
  
    function $Q(resolver) {
      if (!isFunction(resolver)) {
        throw $qMinErr('norslvr', 'Expected resolverFn, got \'{0}\'', resolver);
      }
  
      var promise = new Promise();
  
      function resolveFn(value) {
        resolvePromise(promise, value);
      }
  
      function rejectFn(reason) {
        rejectPromise(promise, reason);
      }
  
      resolver(resolveFn, rejectFn);
  
      return promise;
    }
  
    // Let's make the instanceof operator work for promises, so that
    // `new $q(fn) instanceof $q` would evaluate to true.
    $Q.prototype = Promise.prototype;
  
    $Q.defer = defer;
    $Q.reject = reject;
    $Q.when = when;
    $Q.resolve = resolve;
    $Q.all = all;
    $Q.race = race;
  
    return $Q;
  }
func_documentation_string: Constructs a promise manager.
  
  @param {function(function)} nextTick Function for executing functions in the next turn.
  @param {function(...*)} exceptionHandler Function into which unexpected exceptions are passed for
  debugging purposes.
  @param {boolean=} errorOnUnhandledRejections Whether an error should be generated on unhandled
  promises rejections.
  @returns {object} Promise manager.