text: /**
  * @license
  * Copyright Google Inc. All Rights Reserved.
  *
  * Use of this source code is governed by an MIT-style license that can be
  * found in the LICENSE file at https://angular.io/license
  */
  (function (global, factory) {
  	typeof exports === 'object' && typeof module !== 'undefined' ? factory() :
  	typeof define === 'function' && define.amd ? define(factory) :
  	(factory());
  }(this, (function () { 'use strict';
  
  /**
   * @license
   * Copyright Google Inc. All Rights Reserved.
   *
   * Use of this source code is governed by an MIT-style license that can be
   * found in the LICENSE file at https://angular.io/license
   */
  var Zone$1 = (function (global) {
      if (global['Zone']) {
          throw new Error('Zone already loaded.');
      }
      var NO_ZONE = { name: 'NO ZONE' };
      var notScheduled = 'notScheduled', scheduling = 'scheduling', scheduled = 'scheduled', running = 'running', canceling = 'canceling', unknown = 'unknown';
      var microTask = 'microTask', macroTask = 'macroTask', eventTask = 'eventTask';
      var Zone = (function () {
          function Zone(parent, zoneSpec) {
              this._properties = null;
              this._parent = parent;
              this._name = zoneSpec ? zoneSpec.name || 'unnamed' : '<root>';
              this._properties = zoneSpec && zoneSpec.properties || {};
              this._zoneDelegate =
                  new ZoneDelegate(this, this._parent && this._parent._zoneDelegate, zoneSpec);
          }
          Zone.assertZonePatched = function () {
              if (global.Promise !== ZoneAwarePromise) {
                  throw new Error('Zone.js has detected that ZoneAwarePromise `(window|global).Promise` ' +
                      'has been overwritten.\n' +
                      'Most likely cause is that a Promise polyfill has been loaded ' +
                      'after Zone.js (Polyfilling Promise api is not necessary when zone.js is loaded. ' +
                      'If you must load one, do so before loading zone.js.)');
              }
          };
          Object.defineProperty(Zone, "root", {
              get: function () {
                  var zone = Zone.current;
                  while (zone.parent) {
                      zone = zone.parent;
                  }
                  return zone;
              },
              enumerable: true,
              configurable: true
          });
          Object.defineProperty(Zone, "current", {
              get: function () {
                  return _currentZoneFrame.zone;
              },
              enumerable: true,
              configurable: true
          });
          
          Object.defineProperty(Zone, "currentTask", {
              get: function () {
                  return _currentTask;
              },
              enumerable: true,
              configurable: true
          });
          
          Object.defineProperty(Zone.prototype, "parent", {
              get: function () {
                  return this._parent;
              },
              enumerable: true,
              configurable: true
          });
          
          Object.defineProperty(Zone.prototype, "name", {
              get: function () {
                  return this._name;
              },
              enumerable: true,
              configurable: true
          });
          
          Zone.prototype.get = function (key) {
              var zone = this.getZoneWith(key);
              if (zone)
                  return zone._properties[key];
          };
          Zone.prototype.getZoneWith = function (key) {
              var current = this;
              while (current) {
                  if (current._properties.hasOwnProperty(key)) {
                      return current;
                  }
                  current = current._parent;
              }
              return null;
          };
          Zone.prototype.fork = function (zoneSpec) {
              if (!zoneSpec)
                  throw new Error('ZoneSpec required!');
              return this._zoneDelegate.fork(this, zoneSpec);
          };
          Zone.prototype.wrap = function (callback, source) {
              if (typeof callback !== 'function') {
                  throw new Error('Expecting function got: ' + callback);
              }
              var _callback = this._zoneDelegate.intercept(this, callback, source);
              var zone = this;
              return function () {
                  return zone.runGuarded(_callback, this, arguments, source);
              };
          };
          Zone.prototype.run = function (callback, applyThis, applyArgs, source) {
              if (applyThis === void 0) { applyThis = undefined; }
              if (applyArgs === void 0) { applyArgs = null; }
              if (source === void 0) { source = null; }
              _currentZoneFrame = new ZoneFrame(_currentZoneFrame, this);
              try {
                  return this._zoneDelegate.invoke(this, callback, applyThis, applyArgs, source);
              }
              finally {
                  _currentZoneFrame = _currentZoneFrame.parent;
              }
          };
          Zone.prototype.runGuarded = function (callback, applyThis, applyArgs, source) {
              if (applyThis === void 0) { applyThis = null; }
              if (applyArgs === void 0) { applyArgs = null; }
              if (source === void 0) { source = null; }
              _currentZoneFrame = new ZoneFrame(_currentZoneFrame, this);
              try {
                  try {
                      return this._zoneDelegate.invoke(this, callback, applyThis, applyArgs, source);
                  }
                  catch (error) {
                      if (this._zoneDelegate.handleError(this, error)) {
                          throw error;
                      }
                  }
              }
              finally {
                  _currentZoneFrame = _currentZoneFrame.parent;
              }
          };
          Zone.prototype.runTask = function (task, applyThis, applyArgs) {
              if (task.zone != this)
                  throw new Error('A task can only be run in the zone of creation! (Creation: ' +
                      (task.zone || NO_ZONE).name + '; Execution: ' + this.name + ')');
              var reEntryGuard = task.state != running;
              reEntryGuard && task._transitionTo(running, scheduled);
              task.runCount++;
              var previousTask = _currentTask;
              _currentTask = task;
              _currentZoneFrame = new ZoneFrame(_currentZoneFrame, this);
              try {
                  if (task.type == macroTask && task.data && !task.data.isPeriodic) {
                      task.cancelFn = null;
                  }
                  try {
                      return this._zoneDelegate.invokeTask(this, task, applyThis, applyArgs);
                  }
                  catch (error) {
                      if (this._zoneDelegate.handleError(this, error)) {
                          throw error;
                      }
                  }
              }
              finally {
                  // if the task's state is notScheduled or unknown, then it has already been cancelled
                  // we should not reset the state to scheduled
                  if (task.state !== notScheduled && task.state !== unknown) {
                      if (task.type == eventTask || (task.data && task.data.isPeriodic)) {
                          reEntryGuard && task._transitionTo(scheduled, running);
                      }
                      else {
                          task.runCount = 0;
                          this._updateTaskCount(task, -1);
                          reEntryGuard &&
                              task._transitionTo(notScheduled, running, notScheduled);
                      }
                  }
                  _currentZoneFrame = _currentZoneFrame.parent;
                  _currentTask = previousTask;
              }
          };
          Zone.prototype.scheduleTask = function (task) {
              if (task.zone && task.zone !== this) {
                  // check if the task was rescheduled, the newZone
                  // should not be the children of the original zone
                  var newZone = this;
                  while (newZone) {
                      if (newZone === task.zone) {
                          throw Error("can not reschedule task to " + this
                              .name + " which is descendants of the original zone " + task.zone.name);
                      }
                      newZone = newZone.parent;
                  }
              }
              task._transitionTo(scheduling, notScheduled);
              var zoneDelegates = [];
              task._zoneDelegates = zoneDelegates;
              task._zone = this;
              try {
                  task = this._zoneDelegate.scheduleTask(this, task);
              }
              catch (err) {
                  // should set task's state to unknown when scheduleTask throw error
                  // because the err may from reschedule, so the fromState maybe notScheduled
                  task._transitionTo(unknown, scheduling, notScheduled);
                  // TODO: @JiaLiPassion, should we check the result from handleError?
                  this._zoneDelegate.handleError(this, err);
                  throw err;
              }
              if (task._zoneDelegates === zoneDelegates) {
                  // we have to check because internally the delegate can reschedule the task.
                  this._updateTaskCount(task, 1);
              }
              if (task.state == scheduling) {
                  task._transitionTo(scheduled, scheduling);
              }
              return task;
          };
          Zone.prototype.scheduleMicroTask = function (source, callback, data, customSchedule) {
              return this.scheduleTask(new ZoneTask(microTask, source, callback, data, customSchedule, null));
          };
          Zone.prototype.scheduleMacroTask = function (source, callback, data, customSchedule, customCancel) {
              return this.scheduleTask(new ZoneTask(macroTask, source, callback, data, customSchedule, customCancel));
          };
          Zone.prototype.scheduleEventTask = function (source, callback, data, customSchedule, customCancel) {
              return this.scheduleTask(new ZoneTask(eventTask, source, callback, data, customSchedule, customCancel));
          };
          Zone.prototype.cancelTask = function (task) {
              if (task.zone != this)
                  throw new Error('A task can only be cancelled in the zone of creation! (Creation: ' +
                      (task.zone || NO_ZONE).name + '; Execution: ' + this.name + ')');
              task._transitionTo(canceling, scheduled, running);
              try {
                  this._zoneDelegate.cancelTask(this, task);
              }
              catch (err) {
                  // if error occurs when cancelTask, transit the state to unknown
                  task._transitionTo(unknown, canceling);
                  this._zoneDelegate.handleError(this, err);
                  throw err;
              }
              this._updateTaskCount(task, -1);
              task._transitionTo(notScheduled, canceling);
              task.runCount = 0;
              return task;
          };
          Zone.prototype._updateTaskCount = function (task, count) {
              var zoneDelegates = task._zoneDelegates;
              if (count == -1) {
                  task._zoneDelegates = null;
              }
              for (var i = 0; i < zoneDelegates.length; i++) {
                  zoneDelegates[i]._updateTaskCount(task.type, count);
              }
          };
          return Zone;
      }());
      Zone.__symbol__ = __symbol__;
      var DELEGATE_ZS = {
          name: '',
          onHasTask: function (delegate, _, target, hasTaskState) {
              return delegate.hasTask(target, hasTaskState);
          },
          onScheduleTask: function (delegate, _, target, task) {
              return delegate.scheduleTask(target, task);
          },
          onInvokeTask: function (delegate, _, target, task, applyThis, applyArgs) { return delegate.invokeTask(target, task, applyThis, applyArgs); },
          onCancelTask: function (delegate, _, target, task) {
              return delegate.cancelTask(target, task);
          }
      };
      var ZoneDelegate = (function () {
          function ZoneDelegate(zone, parentDelegate, zoneSpec) {
              this._taskCounts = { 'microTask': 0, 'macroTask': 0, 'eventTask': 0 };
              this.zone = zone;
              this._parentDelegate = parentDelegate;
              this._forkZS = zoneSpec && (zoneSpec && zoneSpec.onFork ? zoneSpec : parentDelegate._forkZS);
              this._forkDlgt = zoneSpec && (zoneSpec.onFork ? parentDelegate : parentDelegate._forkDlgt);
              this._forkCurrZone = zoneSpec && (zoneSpec.onFork ? this.zone : parentDelegate.zone);
              this._interceptZS =
                  zoneSpec && (zoneSpec.onIntercept ? zoneSpec : parentDelegate._interceptZS);
              this._interceptDlgt =
                  zoneSpec && (zoneSpec.onIntercept ? parentDelegate : parentDelegate._interceptDlgt);
              this._interceptCurrZone =
                  zoneSpec && (zoneSpec.onIntercept ? this.zone : parentDelegate.zone);
              this._invokeZS = zoneSpec && (zoneSpec.onInvoke ? zoneSpec : parentDelegate._invokeZS);
              this._invokeDlgt =
                  zoneSpec && (zoneSpec.onInvoke ? parentDelegate : parentDelegate._invokeDlgt);
              this._invokeCurrZone = zoneSpec && (zoneSpec.onInvoke ? this.zone : parentDelegate.zone);
              this._handleErrorZS =
                  zoneSpec && (zoneSpec.onHandleError ? zoneSpec : parentDelegate._handleErrorZS);
              this._handleErrorDlgt =
                  zoneSpec && (zoneSpec.onHandleError ? parentDelegate : parentDelegate._handleErrorDlgt);
              this._handleErrorCurrZone =
                  zoneSpec && (zoneSpec.onHandleError ? this.zone : parentDelegate.zone);
              this._scheduleTaskZS =
                  zoneSpec && (zoneSpec.onScheduleTask ? zoneSpec : parentDelegate._scheduleTaskZS);
              this._scheduleTaskDlgt =
                  zoneSpec && (zoneSpec.onScheduleTask ? parentDelegate : parentDelegate._scheduleTaskDlgt);
              this._scheduleTaskCurrZone =
                  zoneSpec && (zoneSpec.onScheduleTask ? this.zone : parentDelegate.zone);
              this._invokeTaskZS =
                  zoneSpec && (zoneSpec.onInvokeTask ? zoneSpec : parentDelegate._invokeTaskZS);
              this._invokeTaskDlgt =
                  zoneSpec && (zoneSpec.onInvokeTask ? parentDelegate : parentDelegate._invokeTaskDlgt);
              this._invokeTaskCurrZone =
                  zoneSpec && (zoneSpec.onInvokeTask ? this.zone : parentDelegate.zone);
              this._cancelTaskZS =
                  zoneSpec && (zoneSpec.onCancelTask ? zoneSpec : parentDelegate._cancelTaskZS);
              this._cancelTaskDlgt =
                  zoneSpec && (zoneSpec.onCancelTask ? parentDelegate : parentDelegate._cancelTaskDlgt);
              this._cancelTaskCurrZone =
                  zoneSpec && (zoneSpec.onCancelTask ? this.zone : parentDelegate.zone);
              this._hasTaskZS = null;
              this._hasTaskDlgt = null;
              this._hasTaskDlgtOwner = null;
              this._hasTaskCurrZone = null;
              var zoneSpecHasTask = zoneSpec && zoneSpec.onHasTask;
              var parentHasTask = parentDelegate && parentDelegate._hasTaskZS;
              if (zoneSpecHasTask || parentHasTask) {
                  // If we need to report hasTask, than this ZS needs to do ref counting on tasks. In such
                  // a case all task related interceptors must go through this ZD. We can't short circuit it.
                  this._hasTaskZS = zoneSpecHasTask ? zoneSpec : DELEGATE_ZS;
                  this._hasTaskDlgt = parentDelegate;
                  this._hasTaskDlgtOwner = this;
                  this._hasTaskCurrZone = zone;
                  if (!zoneSpec.onScheduleTask) {
                      this._scheduleTaskZS = DELEGATE_ZS;
                      this._scheduleTaskDlgt = parentDelegate;
                      this._scheduleTaskCurrZone = this.zone;
                  }
                  if (!zoneSpec.onInvokeTask) {
                      this._invokeTaskZS = DELEGATE_ZS;
                      this._invokeTaskDlgt = parentDelegate;
                      this._invokeTaskCurrZone = this.zone;
                  }
                  if (!zoneSpec.onCancelTask) {
                      this._cancelTaskZS = DELEGATE_ZS;
                      this._cancelTaskDlgt = parentDelegate;
                      this._cancelTaskCurrZone = this.zone;
                  }
              }
          }
          ZoneDelegate.prototype.fork = function (targetZone, zoneSpec) {
              return this._forkZS ? this._forkZS.onFork(this._forkDlgt, this.zone, targetZone, zoneSpec) :
                  new Zone(targetZone, zoneSpec);
          };
          ZoneDelegate.prototype.intercept = function (targetZone, callback, source) {
              return this._interceptZS ?
                  this._interceptZS.onIntercept(this._interceptDlgt, this._interceptCurrZone, targetZone, callback, source) :
                  callback;
          };
          ZoneDelegate.prototype.invoke = function (targetZone, callback, applyThis, applyArgs, source) {
              return this._invokeZS ?
                  this._invokeZS.onInvoke(this._invokeDlgt, this._invokeCurrZone, targetZone, callback, applyThis, applyArgs, source) :
                  callback.apply(applyThis, applyArgs);
          };
          ZoneDelegate.prototype.handleError = function (targetZone, error) {
              return this._handleErrorZS ?
                  this._handleErrorZS.onHandleError(this._handleErrorDlgt, this._handleErrorCurrZone, targetZone, error) :
                  true;
          };
          ZoneDelegate.prototype.scheduleTask = function (targetZone, task) {
              var returnTask = task;
              if (this._scheduleTaskZS) {
                  if (this._hasTaskZS) {
                      returnTask._zoneDelegates.push(this._hasTaskDlgtOwner);
                  }
                  returnTask = this._scheduleTaskZS.onScheduleTask(this._scheduleTaskDlgt, this._scheduleTaskCurrZone, targetZone, task);
                  if (!returnTask)
                      returnTask = task;
              }
              else {
                  if (task.scheduleFn) {
                      task.scheduleFn(task);
                  }
                  else if (task.type == microTask) {
                      scheduleMicroTask(task);
                  }
                  else {
                      throw new Error('Task is missing scheduleFn.');
                  }
              }
              return returnTask;
          };
          ZoneDelegate.prototype.invokeTask = function (targetZone, task, applyThis, applyArgs) {
              return this._invokeTaskZS ?
                  this._invokeTaskZS.onInvokeTask(this._invokeTaskDlgt, this._invokeTaskCurrZone, targetZone, task, applyThis, applyArgs) :
                  task.callback.apply(applyThis, applyArgs);
          };
          ZoneDelegate.prototype.cancelTask = function (targetZone, task) {
              var value;
              if (this._cancelTaskZS) {
                  value = this._cancelTaskZS.onCancelTask(this._cancelTaskDlgt, this._cancelTaskCurrZone, targetZone, task);
              }
              else {
                  if (!task.cancelFn) {
                      throw Error('Task is not cancelable');
                  }
                  value = task.cancelFn(task);
              }
              return value;
          };
          ZoneDelegate.prototype.hasTask = function (targetZone, isEmpty) {
              // hasTask should not throw error so other ZoneDelegate
              // can still trigger hasTask callback
              try {
                  return this._hasTaskZS &&
                      this._hasTaskZS.onHasTask(this._hasTaskDlgt, this._hasTaskCurrZone, targetZone, isEmpty);
              }
              catch (err) {
              }
          };
          ZoneDelegate.prototype._updateTaskCount = function (type, count) {
              var counts = this._taskCounts;
              var prev = counts[type];
              var next = counts[type] = prev + count;
              if (next < 0) {
                  throw new Error('More tasks executed then were scheduled.');
              }
              if (prev == 0 || next == 0) {
                  var isEmpty = {
                      microTask: counts.microTask > 0,
                      macroTask: counts.macroTask > 0,
                      eventTask: counts.eventTask > 0,
                      change: type
                  };
                  // TODO(misko): what should happen if it throws?
                  this.hasTask(this.zone, isEmpty);
              }
          };
          return ZoneDelegate;
      }());
      var ZoneTask = (function () {
          function ZoneTask(type, source, callback, options, scheduleFn, cancelFn) {
              this._zone = null;
              this.runCount = 0;
              this._zoneDelegates = null;
              this._state = 'notScheduled';
              this.type = type;
              this.source = source;
              this.data = options;
              this.scheduleFn = scheduleFn;
              this.cancelFn = cancelFn;
              this.callback = callback;
              var self = this;
              this.invoke = function () {
                  _numberOfNestedTaskFrames++;
                  try {
                      self.runCount++;
                      return self.zone.runTask(self, this, arguments);
                  }
                  finally {
                      if (_numberOfNestedTaskFrames == 1) {
                          drainMicroTaskQueue();
                      }
                      _numberOfNestedTaskFrames--;
                  }
              };
          }
          Object.defineProperty(ZoneTask.prototype, "zone", {
              get: function () {
                  return this._zone;
              },
              enumerable: true,
              configurable: true
          });
          Object.defineProperty(ZoneTask.prototype, "state", {
              get: function () {
                  return this._state;
              },
              enumerable: true,
              configurable: true
          });
          ZoneTask.prototype.cancelScheduleRequest = function () {
              this._transitionTo(notScheduled, scheduling);
          };
          ZoneTask.prototype._transitionTo = function (toState, fromState1, fromState2) {
              if (this._state === fromState1 || this._state === fromState2) {
                  this._state = toState;
                  if (toState == notScheduled) {
                      this._zoneDelegates = null;
                  }
              }
              else {
                  throw new Error(this.type + " '" + this.source + "': can not transition to '" + toState + "', expecting state '" + fromState1 + "'" + (fromState2 ?
                      ' or \'' + fromState2 + '\'' :
                      '') + ", was '" + this._state + "'.");
              }
          };
          ZoneTask.prototype.toString = function () {
              if (this.data && typeof this.data.handleId !== 'undefined') {
                  return this.data.handleId;
              }
              else {
                  return Object.prototype.toString.call(this);
              }
          };
          // add toJSON method to prevent cyclic error when
          // call JSON.stringify(zoneTask)
          ZoneTask.prototype.toJSON = function () {
              return {
                  type: this.type,
                  state: this.state,
                  source: this.source,
                  data: this.data,
                  zone: this.zone.name,
                  invoke: this.invoke,
                  scheduleFn: this.scheduleFn,
                  cancelFn: this.cancelFn,
                  runCount: this.runCount,
                  callback: this.callback
              };
          };
          return ZoneTask;
      }());
      var ZoneFrame = (function () {
          function ZoneFrame(parent, zone) {
              this.parent = parent;
              this.zone = zone;
          }
          return ZoneFrame;
      }());
      function __symbol__(name) {
          return '__zone_symbol__' + name;
      }
      
      var symbolSetTimeout = __symbol__('setTimeout');
      var symbolPromise = __symbol__('Promise');
      var symbolThen = __symbol__('then');
      var _currentZoneFrame = new ZoneFrame(null, new Zone(null, null));
      var _currentTask = null;
      var _microTaskQueue = [];
      var _isDrainingMicrotaskQueue = false;
      var _uncaughtPromiseErrors = [];
      var _numberOfNestedTaskFrames = 0;
      function scheduleQueueDrain() {
          // if we are not running in any task, and there has not been anything scheduled
          // we must bootstrap the initial task creation by manually scheduling the drain
          if (_numberOfNestedTaskFrames === 0 && _microTaskQueue.length === 0) {
              // We are not running in Task, so we need to kickstart the microtask queue.
              if (global[symbolPromise]) {
                  global[symbolPromise].resolve(0)[symbolThen](drainMicroTaskQueue);
              }
              else {
                  global[symbolSetTimeout](drainMicroTaskQueue, 0);
              }
          }
      }
      function scheduleMicroTask(task) {
          scheduleQueueDrain();
          _microTaskQueue.push(task);
      }
      function consoleError(e) {
          if (Zone[__symbol__('ignoreConsoleErrorUncaughtError')]) {
              return;
          }
          var rejection = e && e.rejection;
          if (rejection) {
              console.error('Unhandled Promise rejection:', rejection instanceof Error ? rejection.message : rejection, '; Zone:', e.zone.name, '; Task:', e.task && e.task.source, '; Value:', rejection, rejection instanceof Error ? rejection.stack : undefined);
          }
          console.error(e);
      }
      function handleUnhandledRejection(e) {
          consoleError(e);
          try {
              var handler = Zone[__symbol__('unhandledPromiseRejectionHandler')];
              if (handler && typeof handler === 'function') {
                  handler.apply(this, [e]);
              }
          }
          catch (err) {
          }
      }
      function drainMicroTaskQueue() {
          if (!_isDrainingMicrotaskQueue) {
              _isDrainingMicrotaskQueue = true;
              while (_microTaskQueue.length) {
                  var queue = _microTaskQueue;
                  _microTaskQueue = [];
                  for (var i = 0; i < queue.length; i++) {
                      var task = queue[i];
                      try {
                          task.zone.runTask(task, null, null);
                      }
                      catch (error) {
                          consoleError(error);
                      }
                  }
              }
              while (_uncaughtPromiseErrors.length) {
                  var _loop_1 = function () {
                      var uncaughtPromiseError = _uncaughtPromiseErrors.shift();
                      try {
                          uncaughtPromiseError.zone.runGuarded(function () {
                              throw uncaughtPromiseError;
                          });
                      }
                      catch (error) {
                          handleUnhandledRejection(error);
                      }
                  };
                  while (_uncaughtPromiseErrors.length) {
                      _loop_1();
                  }
              }
              _isDrainingMicrotaskQueue = false;
          }
      }
      function isThenable(value) {
          return value && value.then;
      }
      function forwardResolution(value) {
          return value;
      }
      function forwardRejection(rejection) {
          return ZoneAwarePromise.reject(rejection);
      }
      var symbolState = __symbol__('state');
      var symbolValue = __symbol__('value');
      var source = 'Promise.then';
      var UNRESOLVED = null;
      var RESOLVED = true;
      var REJECTED = false;
      var REJECTED_NO_CATCH = 0;
      function makeResolver(promise, state) {
          return function (v) {
              try {
                  resolvePromise(promise, state, v);
              }
              catch (err) {
                  resolvePromise(promise, false, err);
              }
              // Do not return value or you will break the Promise spec.
          };
      }
      var once = function () {
          var wasCalled = false;
          return function wrapper(wrappedFunction) {
              return function () {
                  if (wasCalled) {
                      return;
                  }
                  wasCalled = true;
                  wrappedFunction.apply(null, arguments);
              };
          };
      };
      // Promise Resolution
      function resolvePromise(promise, state, value) {
          var onceWrapper = once();
          if (promise === value) {
              throw new TypeError('Promise resolved with itself');
          }
          if (promise[symbolState] === UNRESOLVED) {
              // should only get value.then once based on promise spec.
              var then = null;
              try {
                  if (typeof value === 'object' || typeof value === 'function') {
                      then = value && value.then;
                  }
              }
              catch (err) {
                  onceWrapper(function () {
                      resolvePromise(promise, false, err);
                  })();
                  return promise;
              }
              // if (value instanceof ZoneAwarePromise) {
              if (state !== REJECTED && value instanceof ZoneAwarePromise &&
                  value.hasOwnProperty(symbolState) && value.hasOwnProperty(symbolValue) &&
                  value[symbolState] !== UNRESOLVED) {
                  clearRejectedNoCatch(value);
                  resolvePromise(promise, value[symbolState], value[symbolValue]);
              }
              else if (state !== REJECTED && typeof then === 'function') {
                  try {
                      then.apply(value, [
                          onceWrapper(makeResolver(promise, state)), onceWrapper(makeResolver(promise, false))
                      ]);
                  }
                  catch (err) {
                      onceWrapper(function () {
                          resolvePromise(promise, false, err);
                      })();
                  }
              }
              else {
                  promise[symbolState] = state;
                  var queue = promise[symbolValue];
                  promise[symbolValue] = value;
                  // record task information in value when error occurs, so we can
                  // do some additional work such as render longStackTrace
                  if (state === REJECTED && value instanceof Error) {
                      value[__symbol__('currentTask')] = Zone.currentTask;
                  }
                  for (var i = 0; i < queue.length;) {
                      scheduleResolveOrReject(promise, queue[i++], queue[i++], queue[i++], queue[i++]);
                  }
                  if (queue.length == 0 && state == REJECTED) {
                      promise[symbolState] = REJECTED_NO_CATCH;
                      try {
                          throw new Error('Uncaught (in promise): ' + value +
                              (value && value.stack ? '\n' + value.stack : ''));
                      }
                      catch (err) {
                          var error_1 = err;
                          error_1.rejection = value;
                          error_1.promise = promise;
                          error_1.zone = Zone.current;
                          error_1.task = Zone.currentTask;
                          _uncaughtPromiseErrors.push(error_1);
                          scheduleQueueDrain();
                      }
                  }
              }
          }
          // Resolving an already resolved promise is a noop.
          return promise;
      }
      function clearRejectedNoCatch(promise) {
          if (promise[symbolState] === REJECTED_NO_CATCH) {
              // if the promise is rejected no catch status
              // and queue.length > 0, means there is a error handler
              // here to handle the rejected promise, we should trigger
              // windows.rejectionhandled eventHandler or nodejs rejectionHandled
              // eventHandler
              try {
                  var handler = Zone[__symbol__('rejectionHandledHandler')];
                  if (handler && typeof handler === 'function') {
                      handler.apply(this, [{ rejection: promise[symbolValue], promise: promise }]);
                  }
              }
              catch (err) {
              }
              promise[symbolState] = REJECTED;
              for (var i = 0; i < _uncaughtPromiseErrors.length; i++) {
                  if (promise === _uncaughtPromiseErrors[i].promise) {
                      _uncaughtPromiseErrors.splice(i, 1);
                  }
              }
          }
      }
      function scheduleResolveOrReject(promise, zone, chainPromise, onFulfilled, onRejected) {
          clearRejectedNoCatch(promise);
          var delegate = promise[symbolState] ?
              (typeof onFulfilled === 'function') ? onFulfilled : forwardResolution :
              (typeof onRejected === 'function') ? onRejected : forwardRejection;
          zone.scheduleMicroTask(source, function () {
              try {
                  resolvePromise(chainPromise, true, zone.run(delegate, undefined, [promise[symbolValue]]));
              }
              catch (error) {
                  resolvePromise(chainPromise, false, error);
              }
          });
      }
      var ZoneAwarePromise = (function () {
          function ZoneAwarePromise(executor) {
              var promise = this;
              if (!(promise instanceof ZoneAwarePromise)) {
                  throw new Error('Must be an instanceof Promise.');
              }
              promise[symbolState] = UNRESOLVED;
              promise[symbolValue] = []; // queue;
              try {
                  executor && executor(makeResolver(promise, RESOLVED), makeResolver(promise, REJECTED));
              }
              catch (error) {
                  resolvePromise(promise, false, error);
              }
          }
          ZoneAwarePromise.toString = function () {
              return 'function ZoneAwarePromise() { [native code] }';
          };
          ZoneAwarePromise.resolve = function (value) {
              return resolvePromise(new this(null), RESOLVED, value);
          };
          ZoneAwarePromise.reject = function (error) {
              return resolvePromise(new this(null), REJECTED, error);
          };
          ZoneAwarePromise.race = function (values) {
              var resolve;
              var reject;
              var promise = new this(function (res, rej) {
                  _a = [res, rej], resolve = _a[0], reject = _a[1];
                  var _a;
              });
              function onResolve(value) {
                  promise && (promise = null || resolve(value));
              }
              function onReject(error) {
                  promise && (promise = null || reject(error));
              }
              for (var _i = 0, values_1 = values; _i < values_1.length; _i++) {
                  var value = values_1[_i];
                  if (!isThenable(value)) {
                      value = this.resolve(value);
                  }
                  value.then(onResolve, onReject);
              }
              return promise;
          };
          ZoneAwarePromise.all = function (values) {
              var resolve;
              var reject;
              var promise = new this(function (res, rej) {
                  resolve = res;
                  reject = rej;
              });
              var count = 0;
              var resolvedValues = [];
              for (var _i = 0, values_2 = values; _i < values_2.length; _i++) {
                  var value = values_2[_i];
                  if (!isThenable(value)) {
                      value = this.resolve(value);
                  }
                  value.then((function (index) { return function (value) {
                      resolvedValues[index] = value;
                      count--;
                      if (!count) {
                          resolve(resolvedValues);
                      }
                  }; })(count), reject);
                  count++;
              }
              if (!count)
                  resolve(resolvedValues);
              return promise;
          };
          ZoneAwarePromise.prototype.then = function (onFulfilled, onRejected) {
              var chainPromise = new this.constructor(null);
              var zone = Zone.current;
              if (this[symbolState] == UNRESOLVED) {
                  this[symbolValue].push(zone, chainPromise, onFulfilled, onRejected);
              }
              else {
                  scheduleResolveOrReject(this, zone, chainPromise, onFulfilled, onRejected);
              }
              return chainPromise;
          };
          ZoneAwarePromise.prototype.catch = function (onRejected) {
              return this.then(null, onRejected);
          };
          return ZoneAwarePromise;
      }());
      // Protect against aggressive optimizers dropping seemingly unused properties.
      // E.g. Closure Compiler in advanced mode.
      ZoneAwarePromise['resolve'] = ZoneAwarePromise.resolve;
      ZoneAwarePromise['reject'] = ZoneAwarePromise.reject;
      ZoneAwarePromise['race'] = ZoneAwarePromise.race;
      ZoneAwarePromise['all'] = ZoneAwarePromise.all;
      var NativePromise = global[symbolPromise] = global['Promise'];
      global['Promise'] = ZoneAwarePromise;
      var symbolThenPatched = __symbol__('thenPatched');
      function patchThen(Ctor) {
          var proto = Ctor.prototype;
          var originalThen = proto.then;
          // Keep a reference to the original method.
          proto[symbolThen] = originalThen;
          Ctor.prototype.then = function (onResolve, onReject) {
              var _this = this;
              var wrapped = new ZoneAwarePromise(function (resolve, reject) {
                  originalThen.call(_this, resolve, reject);
              });
              return wrapped.then(onResolve, onReject);
          };
          Ctor[symbolThenPatched] = true;
      }
      function zoneify(fn) {
          return function () {
              var resultPromise = fn.apply(this, arguments);
              if (resultPromise instanceof ZoneAwarePromise) {
                  return resultPromise;
              }
              var Ctor = resultPromise.constructor;
              if (!Ctor[symbolThenPatched]) {
                  patchThen(Ctor);
              }
              return resultPromise;
          };
      }
      if (NativePromise) {
          patchThen(NativePromise);
          var fetch_1 = global['fetch'];
          if (typeof fetch_1 == 'function') {
              global['fetch'] = zoneify(fetch_1);
          }
      }
      // This is not part of public API, but it is usefull for tests, so we expose it.
      Promise[Zone.__symbol__('uncaughtPromiseErrors')] = _uncaughtPromiseErrors;
      /*
       * This code patches Error so that:
       *   - It ignores un-needed stack frames.
       *   - It Shows the associated Zone for reach frame.
       */
      var FrameType;
      (function (FrameType) {
          /// Skip this frame when printing out stack
          FrameType[FrameType["blackList"] = 0] = "blackList";
          /// This frame marks zone transition
          FrameType[FrameType["transition"] = 1] = "transition";
      })(FrameType || (FrameType = {}));
      var NativeError = global[__symbol__('Error')] = global.Error;
      // Store the frames which should be removed from the stack frames
      var blackListedStackFrames = {};
      // We must find the frame where Error was created, otherwise we assume we don't understand stack
      // the frame will be an array, because Error with new or without new will
      // have different stack frames.
      var zoneAwareErrorStartFrames = [];
      global.Error = ZoneAwareError;
      var stackRewrite = 'stackRewrite';
      // some functions are not easily to be detected here,
      // for example Timeout.ZoneTask.invoke, if we want to detect those functions
      // by detect zone, we have to run all patched APIs, it is too risky
      // so for those functions, just check whether the stack contains the string or not.
      var otherZoneAwareFunctionNames = [
          'ZoneTask.invoke', 'ZoneAware', 'getStacktraceWithUncaughtError', 'new LongStackTrace',
          'long-stack-trace'
      ];
      function attachZoneAndRemoveInternalZoneFrames(error) {
          // Save original stack trace
          error.originalStack = error.stack;
          // Process the stack trace and rewrite the frames.
          if (ZoneAwareError[stackRewrite] && error.originalStack) {
              var frames_1 = error.originalStack.split('\n');
              var zoneFrame = _currentZoneFrame;
              var i_1 = 0;
              // Find the first frame
              while (i_1 < frames_1.length &&
                  zoneAwareErrorStartFrames.filter(function (zf) { return zf.trim() === frames_1[i_1].trim(); }).length === 0) {
                  i_1++;
              }
              var _loop_2 = function () {
                  // trim here because blackListedStackFrames store the trimmed frames
                  var frame = frames_1[i_1].trim();
                  if (frame) {
                      var frameType = blackListedStackFrames.hasOwnProperty(frame) && blackListedStackFrames[frame];
                      if (frameType === FrameType.blackList) {
                          frames_1.splice(i_1, 1);
                          i_1--;
                      }
                      else if (otherZoneAwareFunctionNames
                          .filter(function (f) { return frame.toLowerCase().indexOf(f.toLowerCase()) !== -1; })
                          .length > 0) {
                          frames_1.splice(i_1, 1);
                          i_1--;
                      }
                      else if (frameType === FrameType.transition) {
                          if (zoneFrame.parent) {
                              // This is the special frame where zone changed. Print and process it accordingly
                              zoneFrame = zoneFrame.parent;
                          }
                          else {
                              zoneFrame = null;
                          }
                          frames_1.splice(i_1, 1);
                          i_1--;
                      }
                      else {
                          frames_1[i_1] += " [" + zoneFrame.zone.name + "]";
                      }
                  }
              };
              for (; i_1 < frames_1.length && zoneFrame; i_1++) {
                  _loop_2();
              }
              var finalStack = frames_1.join('\n');
              try {
                  error.stack = error.zoneAwareStack = finalStack;
              }
              catch (nonWritableErr) {
                  // in some browser, the error.stack is readonly such as PhantomJS
                  // so we need to store the stack frames to zoneAwareError directly
              }
          }
      }
      /**
       * This is ZoneAwareError which processes the stack frame and cleans up extra frames as well as
       * adds zone information to it.
       */
      function ZoneAwareError() {
          // We always have to return native error otherwise the browser console will not work.
          var error = NativeError.apply(this, arguments);
          if (!error.stack) {
              // in IE, the error.stack will be undefined
              // when error was constructed, it will only
              // be available when throw
              try {
                  throw error;
              }
              catch (err) {
                  error = err;
              }
          }
          // 1. attach zone information to stack frame
          // 2. remove zone internal stack frames
          attachZoneAndRemoveInternalZoneFrames(error);
          return error;
      }
      // Copy the prototype so that instanceof operator works as expected
      ZoneAwareError.prototype = NativeError.prototype;
      ZoneAwareError[Zone.__symbol__('blacklistedStackFrames')] = blackListedStackFrames;
      ZoneAwareError[stackRewrite] = false;
      // those properties need special handling
      var specialPropertyNames = ['stackTraceLimit', 'captureStackTrace', 'prepareStackTrace'];
      // those properties of NativeError should be set to ZoneAwareError
      var nativeErrorProperties = Object.keys(NativeError);
      if (nativeErrorProperties) {
          nativeErrorProperties.forEach(function (prop) {
              if (specialPropertyNames.filter(function (sp) { return sp === prop; }).length === 0) {
                  Object.defineProperty(ZoneAwareError, prop, {
                      get: function () {
                          return NativeError[prop];
                      },
                      set: function (value) {
                          NativeError[prop] = value;
                      }
                  });
              }
          });
      }
      if (NativeError.hasOwnProperty('stackTraceLimit')) {
          // Extend default stack limit as we will be removing few frames.
          NativeError.stackTraceLimit = Math.max(NativeError.stackTraceLimit, 15);
          // make sure that ZoneAwareError has the same property which forwards to NativeError.
          Object.defineProperty(ZoneAwareError, 'stackTraceLimit', {
              get: function () {
                  return NativeError.stackTraceLimit;
              },
              set: function (value) {
                  return NativeError.stackTraceLimit = value;
              }
          });
      }
      if (NativeError.hasOwnProperty('captureStackTrace')) {
          Object.defineProperty(ZoneAwareError, 'captureStackTrace', {
              // add named function here because we need to remove this
              // stack frame when prepareStackTrace below
              value: function zoneCaptureStackTrace(targetObject, constructorOpt) {
                  NativeError.captureStackTrace(targetObject, constructorOpt);
              }
          });
      }
      Object.defineProperty(ZoneAwareError, 'prepareStackTrace', {
          get: function () {
              return NativeError.prepareStackTrace;
          },
          set: function (value) {
              if (!value || typeof value !== 'function') {
                  return NativeError.prepareStackTrace = value;
              }
              return NativeError.prepareStackTrace = function (error, structuredStackTrace) {
                  // remove additional stack information from ZoneAwareError.captureStackTrace
                  if (structuredStackTrace) {
                      for (var i = 0; i < structuredStackTrace.length; i++) {
                          var st = structuredStackTrace[i];
                          // remove the first function which name is zoneCaptureStackTrace
                          if (st.getFunctionName() === 'zoneCaptureStackTrace') {
                              structuredStackTrace.splice(i, 1);
                              break;
                          }
                      }
                  }
                  return value.apply(this, [error, structuredStackTrace]);
              };
          }
      });
      // Now we need to populate the `blacklistedStackFrames` as well as find the
      // run/runGuraded/runTask frames. This is done by creating a detect zone and then threading
      // the execution through all of the above methods so that we can look at the stack trace and
      // find the frames of interest.
      var detectZone = Zone.current.fork({
          name: 'detect',
          onInvoke: function (parentZoneDelegate, currentZone, targetZone, delegate, applyThis, applyArgs, source) {
              // Here only so that it will show up in the stack frame so that it can be black listed.
              return parentZoneDelegate.invoke(targetZone, delegate, applyThis, applyArgs, source);
          },
          onHandleError: function (parentZD, current, target, error) {
              if (error.originalStack && Error === ZoneAwareError) {
                  var frames_2 = error.originalStack.split(/\n/);
                  var runFrame = false, runGuardedFrame = false, runTaskFrame = false;
                  while (frames_2.length) {
                      var frame = frames_2.shift();
                      // On safari it is possible to have stack frame with no line number.
                      // This check makes sure that we don't filter frames on name only (must have
                      // linenumber)
                      if (/:\d+:\d+/.test(frame)) {
                          // Get rid of the path so that we don't accidentally find function name in path.
                          // In chrome the separator is `(` and `@` in FF and safari
                          // Chrome: at Zone.run (zone.js:100)
                          // Chrome: at Zone.run (http://localhost:9876/base/build/lib/zone.js:100:24)
                          // FireFox: Zone.prototype.run@http://localhost:9876/base/build/lib/zone.js:101:24
                          // Safari: run@http://localhost:9876/base/build/lib/zone.js:101:24
                          var fnName = frame.split('(')[0].split('@')[0];
                          var frameType = FrameType.transition;
                          if (fnName.indexOf('ZoneAwareError') !== -1) {
                              // we found the ZoneAwareError start frame
                              // the frame will be different when call Error(...)
                              // and new Error(...), so we store them both
                              zoneAwareErrorStartFrames.push(frame);
                          }
                          if (fnName.indexOf('runGuarded') !== -1) {
                              runGuardedFrame = true;
                          }
                          else if (fnName.indexOf('runTask') !== -1) {
                              runTaskFrame = true;
                          }
                          else if (fnName.indexOf('run') !== -1) {
                              runFrame = true;
                          }
                          else {
                              frameType = FrameType.blackList;
                          }
                          blackListedStackFrames[frame.trim()] = frameType;
                          // Once we find all of the frames we can stop looking.
                          if (runFrame && runGuardedFrame && runTaskFrame) {
                              ZoneAwareError[stackRewrite] = true;
                              break;
                          }
                      }
                  }
              }
              return false;
          }
      });
      // carefully constructor a stack frame which contains all of the frames of interest which
      // need to be detected and blacklisted.
      // use this method to handle
      // 1. IE issue, the error.stack can only be not undefined after throw
      // 2. handle Error(...) without new options
      var throwError = function (message, withNew) {
          try {
              if (withNew) {
                  throw new Error(message);
              }
              else {
                  throw Error(message);
              }
          }
          catch (err) {
              return err;
          }
      };
      var nativeStackTraceLimit = NativeError.stackTraceLimit;
      // in some system/browser, some additional stack frames
      // will be generated (such as inline function)
      // so the the stack frame to check ZoneAwareError Start
      // maybe ignored because the frame's number will exceed
      // stackTraceLimit, so we just set stackTraceLimit to 100
      // and reset after all detect work is done.
      NativeError.stackTraceLimit = 100;
      var detectRunFn = function () {
          detectZone.run(function () {
              detectZone.runGuarded(function () {
                  throw throwError('blacklistStackFrames', true);
              });
          });
      };
      var detectRunWithoutNewFn = function () {
          detectZone.run(function () {
              detectZone.runGuarded(function () {
                  throw throwError('blacklistStackFrames');
              });
          });
      };
      // Cause the error to extract the stack frames.
      detectZone.runTask(detectZone.scheduleMacroTask('detect', detectRunFn, null, function () { return null; }, null));
      detectZone.runTask(detectZone.scheduleMacroTask('detect', detectRunWithoutNewFn, null, function () { return null; }, null));
      function handleDetectError(error) {
          var frames = error.stack ? error.stack.split(/\n/) : [];
          while (frames.length) {
              var frame = frames.shift();
              // On safari it is possible to have stack frame with no line number.
              // This check makes sure that we don't filter frames on name only (must have
              // linenumber)
              var trimmedFrame = frame.trim().split('[')[0].trim();
              if (/:\d+:\d+/.test(trimmedFrame) && !blackListedStackFrames.hasOwnProperty(trimmedFrame)) {
                  blackListedStackFrames[trimmedFrame] = FrameType.blackList;
              }
              // when we found runGuarded or runTask, we should stop
              // otherwise we will store some stack frames like
              // module.load, require and something like that
              var fnName = frame.split('(')[0].split('@')[0];
              if (fnName.indexOf('runGuarded') !== -1) {
                  break;
              }
              else if (fnName.indexOf('runTask') !== -1) {
                  break;
              }
          }
      }
      var detectEmptyZone = Zone.root.fork({
          name: 'detectEmptyZone',
          onHandleError: function (parentDelegate, currentZone, targetZone, error) {
              parentDelegate.handleError(targetZone, error);
              handleDetectError(error);
              return false;
          }
      });
      var detectZoneWithCallbacks = Zone.root.fork({
          name: 'detectCallbackZone',
          onFork: function (parentDelegate, currentZone, targetZone, zoneSpec) {
              // we need to generate Error with or without new
              handleDetectError(throwError('onFork'));
              handleDetectError(throwError('onFork', false));
              return parentDelegate.fork(targetZone, zoneSpec);
          },
          onIntercept: function (parentDelegate, currentZone, targetZone, delegate, source) {
              handleDetectError(throwError('onIntercept'));
              handleDetectError(throwError('onIntercept', false));
              return parentDelegate.intercept(targetZone, delegate, source);
          },
          onInvoke: function (parentZoneDelegate, currentZone, targetZone, delegate, applyThis, applyArgs, source) {
              handleDetectError(throwError('onInvoke'));
              handleDetectError(throwError('onInvoke', false));
              return parentZoneDelegate.invoke(targetZone, delegate, applyThis, applyArgs, source);
          },
          onScheduleTask: function (parentZoneDelegate, currentZone, targetZone, task) {
              handleDetectError(throwError('onScheduleTask'));
              handleDetectError(throwError('onScheduleTask', false));
              return parentZoneDelegate.scheduleTask(targetZone, task);
          },
          onInvokeTask: function (parentZoneDelegate, currentZone, targetZone, task, applyThis, applyArgs) {
              handleDetectError(throwError('onInvokeTask'));
              handleDetectError(throwError('onInvokeTask', false));
              return parentZoneDelegate.invokeTask(targetZone, task, applyThis, applyArgs);
          },
          onCancelTask: function (parentZoneDelegate, currentZone, targetZone, task) {
              handleDetectError(throwError('onCancelTask'));
              handleDetectError(throwError('onCancelTask', false));
              return parentZoneDelegate.cancelTask(targetZone, task);
          },
          onHasTask: function (delegate, current, target, hasTaskState) {
              handleDetectError(throwError('onHasTask'));
              handleDetectError(throwError('onHasTask', false));
              return delegate.hasTask(target, hasTaskState);
          },
          onHandleError: function (parentDelegate, currentZone, targetZone, error) {
              parentDelegate.handleError(targetZone, error);
              handleDetectError(error);
              return false;
          }
      });
      var detectFn = function () {
          throw throwError('zoneAwareFrames');
      };
      var detectWithoutNewFn = function () {
          throw throwError('zoneAwareFrames', false);
      };
      var detectPromiseFn = function () {
          new Promise(function (resolve, reject) {
              reject(throwError('zoneAwareFrames'));
          });
      };
      var detectPromiseWithoutNewFn = function () {
          new Promise(function (resolve, reject) {
              reject(throwError('zoneAwareFrames', false));
          });
      };
      var detectPromiseCaughtFn = function () {
          var p = new Promise(function (resolve, reject) {
              reject(throwError('zoneAwareFrames'));
          });
          p.catch(function (err) {
              throw err;
          });
      };
      var detectPromiseCaughtWithoutNewFn = function () {
          var p = new Promise(function (resolve, reject) {
              reject(throwError('zoneAwareFrames', false));
          });
          p.catch(function (err) {
              throw err;
          });
      };
      // Cause the error to extract the stack frames.
      detectEmptyZone.runTask(detectEmptyZone.scheduleEventTask('detect', detectFn, null, function () { return null; }, null));
      detectZoneWithCallbacks.runTask(detectZoneWithCallbacks.scheduleEventTask('detect', detectFn, null, function () { return null; }, null));
      detectEmptyZone.runTask(detectEmptyZone.scheduleMacroTask('detect', detectFn, null, function () { return null; }, null));
      detectZoneWithCallbacks.runTask(detectZoneWithCallbacks.scheduleMacroTask('detect', detectFn, null, function () { return null; }, null));
      detectEmptyZone.runTask(detectEmptyZone.scheduleMicroTask('detect', detectFn, null, function () { return null; }));
      detectZoneWithCallbacks.runTask(detectZoneWithCallbacks.scheduleMicroTask('detect', detectFn, null, function () { return null; }));
      detectEmptyZone.runGuarded(function () {
          detectEmptyZone.run(detectFn);
      });
      detectZoneWithCallbacks.runGuarded(function () {
          detectEmptyZone.run(detectFn);
      });
      detectEmptyZone.runTask(detectEmptyZone.scheduleEventTask('detect', detectWithoutNewFn, null, function () { return null; }, null));
      detectZoneWithCallbacks.runTask(detectZoneWithCallbacks.scheduleEventTask('detect', detectWithoutNewFn, null, function () { return null; }, null));
      detectEmptyZone.runTask(detectEmptyZone.scheduleMacroTask('detect', detectWithoutNewFn, null, function () { return null; }, null));
      detectZoneWithCallbacks.runTask(detectZoneWithCallbacks.scheduleMacroTask('detect', detectWithoutNewFn, null, function () { return null; }, null));
      detectEmptyZone.runTask(detectEmptyZone.scheduleMicroTask('detect', detectWithoutNewFn, null, function () { return null; }));
      detectZoneWithCallbacks.runTask(detectZoneWithCallbacks.scheduleMicroTask('detect', detectWithoutNewFn, null, function () { return null; }));
      detectEmptyZone.runGuarded(function () {
          detectEmptyZone.run(detectWithoutNewFn);
      });
      detectZoneWithCallbacks.runGuarded(function () {
          detectEmptyZone.run(detectWithoutNewFn);
      });
      detectEmptyZone.runGuarded(detectPromiseFn);
      detectZoneWithCallbacks.runGuarded(detectPromiseFn);
      detectEmptyZone.runGuarded(detectPromiseWithoutNewFn);
      detectZoneWithCallbacks.runGuarded(detectPromiseWithoutNewFn);
      detectEmptyZone.runGuarded(detectPromiseCaughtFn);
      detectZoneWithCallbacks.runGuarded(detectPromiseCaughtFn);
      detectEmptyZone.runGuarded(detectPromiseCaughtWithoutNewFn);
      detectZoneWithCallbacks.runGuarded(detectPromiseCaughtWithoutNewFn);
      NativeError.stackTraceLimit = nativeStackTraceLimit;
      return global['Zone'] = Zone;
  })(typeof window !== 'undefined' && window || typeof self !== 'undefined' && self || global);
  
  /**
   * @license
   * Copyright Google Inc. All Rights Reserved.
   *
   * Use of this source code is governed by an MIT-style license that can be
   * found in the LICENSE file at https://angular.io/license
   */
  /**
   * Suppress closure compiler errors about unknown 'Zone' variable
   * @fileoverview
   * @suppress {undefinedVars,globalThis}
   */
  var zoneSymbol = function (n) { return "__zone_symbol__" + n; };
  var _global = typeof window === 'object' && window || typeof self === 'object' && self || global;
  
  
  var isWebWorker = (typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope);
  var isNode = (!('nw' in _global) && typeof process !== 'undefined' &&
      {}.toString.call(process) === '[object process]');
  
  // we are in electron of nw, so we are both browser and nodejs
  var isMix = typeof process !== 'undefined' &&
      {}.toString.call(process) === '[object process]' && !isWebWorker &&
      !!(typeof window !== 'undefined' && window['HTMLElement']);
  function patchProperty(obj, prop) {
      var desc = Object.getOwnPropertyDescriptor(obj, prop) || { enumerable: true, configurable: true };
      var originalDesc = Object.getOwnPropertyDescriptor(obj, 'original' + prop);
      if (!originalDesc && desc.get) {
          Object.defineProperty(obj, 'original' + prop, { enumerable: false, configurable: true, get: desc.get });
      }
      // A property descriptor cannot have getter/setter and be writable
      // deleting the writable and value properties avoids this error:
      //
      // TypeError: property descriptors must not specify a value or be writable when a
      // getter or setter has been specified
      delete desc.writable;
      delete desc.value;
      // substr(2) cuz 'onclick' -> 'click', etc
      var eventName = prop.substr(2);
      var _prop = zoneSymbol('_' + prop);
      desc.set = function (fn) {
          if (this[_prop]) {
              this.removeEventListener(eventName, this[_prop]);
          }
          if (typeof fn === 'function') {
              var wrapFn = function (event) {
                  var result;
                  result = fn.apply(this, arguments);
                  if (result != undefined && !result)
                      event.preventDefault();
              };
              this[_prop] = wrapFn;
              this.addEventListener(eventName, wrapFn, false);
          }
          else {
              this[_prop] = null;
          }
      };
      // The getter would return undefined for unassigned properties but the default value of an
      // unassigned property is null
      desc.get = function () {
          var r = this[_prop] || null;
          // result will be null when use inline event attribute,
          // such as <button onclick="func();">OK</button>
          // because the onclick function is internal raw uncompiled handler
          // the onclick will be evaluated when first time event was triggered or
          // the property is accessed, https://github.com/angular/zone.js/issues/525
          // so we should use original native get to retrieve the handler
          if (r === null) {
              if (originalDesc && originalDesc.get) {
                  r = originalDesc.get.apply(this, arguments);
                  if (r) {
                      desc.set.apply(this, [r]);
                      if (typeof this['removeAttribute'] === 'function') {
                          this.removeAttribute(prop);
                      }
                  }
              }
          }
          return this[_prop] || null;
      };
      Object.defineProperty(obj, prop, desc);
  }
  
  function patchOnProperties(obj, properties) {
      var onProperties = [];
      for (var prop in obj) {
          if (prop.substr(0, 2) == 'on') {
              onProperties.push(prop);
          }
      }
      for (var j = 0; j < onProperties.length; j++) {
          patchProperty(obj, onProperties[j]);
      }
      if (properties) {
          for (var i = 0; i < properties.length; i++) {
              patchProperty(obj, 'on' + properties[i]);
          }
      }
  }
  
  var EVENT_TASKS = zoneSymbol('eventTasks');
  // For EventTarget
  var ADD_EVENT_LISTENER = 'addEventListener';
  var REMOVE_EVENT_LISTENER = 'removeEventListener';
  function findExistingRegisteredTask(target, handler, name, capture, remove) {
      var eventTasks = target[EVENT_TASKS];
      if (eventTasks) {
          for (var i = 0; i < eventTasks.length; i++) {
              var eventTask = eventTasks[i];
              var data = eventTask.data;
              var listener = data.handler;
              if ((data.handler === handler || listener.listener === handler) &&
                  data.useCapturing === capture && data.eventName === name) {
                  if (remove) {
                      eventTasks.splice(i, 1);
                  }
                  return eventTask;
              }
          }
      }
      return null;
  }
  function attachRegisteredEvent(target, eventTask, isPrepend) {
      var eventTasks = target[EVENT_TASKS];
      if (!eventTasks) {
          eventTasks = target[EVENT_TASKS] = [];
      }
      if (isPrepend) {
          eventTasks.unshift(eventTask);
      }
      else {
          eventTasks.push(eventTask);
      }
  }
  var defaultListenerMetaCreator = function (self, args) {
      return {
          useCapturing: args[2],
          eventName: args[0],
          handler: args[1],
          target: self || _global,
          name: args[0],
          invokeAddFunc: function (addFnSymbol, delegate) {
              if (delegate && delegate.invoke) {
                  return this.target[addFnSymbol](this.eventName, delegate.invoke, this.useCapturing);
              }
              else {
                  return this.target[addFnSymbol](this.eventName, delegate, this.useCapturing);
              }
          },
          invokeRemoveFunc: function (removeFnSymbol, delegate) {
              if (delegate && delegate.invoke) {
                  return this.target[removeFnSymbol](this.eventName, delegate.invoke, this.useCapturing);
              }
              else {
                  return this.target[removeFnSymbol](this.eventName, delegate, this.useCapturing);
              }
          }
      };
  };
  function makeZoneAwareAddListener(addFnName, removeFnName, useCapturingParam, allowDuplicates, isPrepend, metaCreator) {
      if (useCapturingParam === void 0) { useCapturingParam = true; }
      if (allowDuplicates === void 0) { allowDuplicates = false; }
      if (isPrepend === void 0) { isPrepend = false; }
      if (metaCreator === void 0) { metaCreator = defaultListenerMetaCreator; }
      var addFnSymbol = zoneSymbol(addFnName);
      var removeFnSymbol = zoneSymbol(removeFnName);
      var defaultUseCapturing = useCapturingParam ? false : undefined;
      function scheduleEventListener(eventTask) {
          var meta = eventTask.data;
          attachRegisteredEvent(meta.target, eventTask, isPrepend);
          return meta.invokeAddFunc(addFnSymbol, eventTask);
      }
      function cancelEventListener(eventTask) {
          var meta = eventTask.data;
          findExistingRegisteredTask(meta.target, eventTask.invoke, meta.eventName, meta.useCapturing, true);
          return meta.invokeRemoveFunc(removeFnSymbol, eventTask);
      }
      return function zoneAwareAddListener(self, args) {
          var data = metaCreator(self, args);
          data.useCapturing = data.useCapturing || defaultUseCapturing;
          // - Inside a Web Worker, `this` is undefined, the context is `global`
          // - When `addEventListener` is called on the global context in strict mode, `this` is undefined
          // see https://github.com/angular/zone.js/issues/190
          var delegate = null;
          if (typeof data.handler == 'function') {
              delegate = data.handler;
          }
          else if (data.handler && data.handler.handleEvent) {
              delegate = function (event) { return data.handler.handleEvent(event); };
          }
          var validZoneHandler = false;
          try {
              // In cross site contexts (such as WebDriver frameworks like Selenium),
              // accessing the handler object here will cause an exception to be thrown which
              // will fail tests prematurely.
              validZoneHandler = data.handler && data.handler.toString() === '[object FunctionWrapper]';
          }
          catch (error) {
              // Returning nothing here is fine, because objects in a cross-site context are unusable
              return;
          }
          // Ignore special listeners of IE11 & Edge dev tools, see
          // https://github.com/angular/zone.js/issues/150
          if (!delegate || validZoneHandler) {
              return data.invokeAddFunc(addFnSymbol, data.handler);
          }
          if (!allowDuplicates) {
              var eventTask = findExistingRegisteredTask(data.target, data.handler, data.eventName, data.useCapturing, false);
              if (eventTask) {
                  // we already registered, so this will have noop.
                  return data.invokeAddFunc(addFnSymbol, eventTask);
              }
          }
          var zone = Zone.current;
          var source = data.target.constructor['name'] + '.' + addFnName + ':' + data.eventName;
          zone.scheduleEventTask(source, delegate, data, scheduleEventListener, cancelEventListener);
      };
  }
  function makeZoneAwareRemoveListener(fnName, useCapturingParam, metaCreator) {
      if (useCapturingParam === void 0) { useCapturingParam = true; }
      if (metaCreator === void 0) { metaCreator = defaultListenerMetaCreator; }
      var symbol = zoneSymbol(fnName);
      var defaultUseCapturing = useCapturingParam ? false : undefined;
      return function zoneAwareRemoveListener(self, args) {
          var data = metaCreator(self, args);
          data.useCapturing = data.useCapturing || defaultUseCapturing;
          // - Inside a Web Worker, `this` is undefined, the context is `global`
          // - When `addEventListener` is called on the global context in strict mode, `this` is undefined
          // see https://github.com/angular/zone.js/issues/190
          var eventTask = findExistingRegisteredTask(data.target, data.handler, data.eventName, data.useCapturing, true);
          if (eventTask) {
              eventTask.zone.cancelTask(eventTask);
          }
          else {
              data.invokeRemoveFunc(symbol, data.handler);
          }
      };
  }
  
  
  var zoneAwareAddEventListener = makeZoneAwareAddListener(ADD_EVENT_LISTENER, REMOVE_EVENT_LISTENER);
  var zoneAwareRemoveEventListener = makeZoneAwareRemoveListener(REMOVE_EVENT_LISTENER);
  function patchEventTargetMethods(obj, addFnName, removeFnName, metaCreator) {
      if (addFnName === void 0) { addFnName = ADD_EVENT_LISTENER; }
      if (removeFnName === void 0) { removeFnName = REMOVE_EVENT_LISTENER; }
      if (metaCreator === void 0) { metaCreator = defaultListenerMetaCreator; }
      if (obj && obj[addFnName]) {
          patchMethod(obj, addFnName, function () { return makeZoneAwareAddListener(addFnName, removeFnName, true, false, false, metaCreator); });
          patchMethod(obj, removeFnName, function () { return makeZoneAwareRemoveListener(removeFnName, true, metaCreator); });
          return true;
      }
      else {
          return false;
      }
  }
  // wrap some native API on `window`
  
  
  function createNamedFn(name, delegate) {
      try {
          return (Function('f', "return function " + name + "(){return f(this, arguments)}"))(delegate);
      }
      catch (error) {
          // if we fail, we must be CSP, just return delegate.
          return function () {
              return delegate(this, arguments);
          };
      }
  }
  function patchMethod(target, name, patchFn) {
      var proto = target;
      while (proto && Object.getOwnPropertyNames(proto).indexOf(name) === -1) {
          proto = Object.getPrototypeOf(proto);
      }
      if (!proto && target[name]) {
          // somehow we did not find it, but we can see it. This happens on IE for Window properties.
          proto = target;
      }
      var delegateName = zoneSymbol(name);
      var delegate;
      if (proto && !(delegate = proto[delegateName])) {
          delegate = proto[delegateName] = proto[name];
          proto[name] = createNamedFn(name, patchFn(delegate, delegateName, name));
      }
      return delegate;
  }
  // TODO: @JiaLiPassion, support cancel task later if necessary
  
  
  
  Zone[zoneSymbol('patchEventTargetMethods')] = patchEventTargetMethods;
  Zone[zoneSymbol('patchOnProperties')] = patchOnProperties;
  
  /**
   * @license
   * Copyright Google Inc. All Rights Reserved.
   *
   * Use of this source code is governed by an MIT-style license that can be
   * found in the LICENSE file at https://angular.io/license
   */
  function patchTimer(window, setName, cancelName, nameSuffix) {
      var setNative = null;
      var clearNative = null;
      setName += nameSuffix;
      cancelName += nameSuffix;
      var tasksByHandleId = {};
      function scheduleTask(task) {
          var data = task.data;
          function timer() {
              try {
                  task.invoke.apply(this, arguments);
              }
              finally {
                  delete tasksByHandleId[data.handleId];
              }
          }
          
          data.args[0] = timer;
          data.handleId = setNative.apply(window, data.args);
          tasksByHandleId[data.handleId] = task;
          return task;
      }
      function clearTask(task) {
          delete tasksByHandleId[task.data.handleId];
          return clearNative(task.data.handleId);
      }
      setNative =
          patchMethod(window, setName, function (delegate) { return function (self, args) {
              if (typeof args[0] === 'function') {
                  var zone = Zone.current;
                  var options = {
                      handleId: null,
                      isPeriodic: nameSuffix === 'Interval',
                      delay: (nameSuffix === 'Timeout' || nameSuffix === 'Interval') ? args[1] || 0 : null,
                      args: args
                  };
                  var task = zone.scheduleMacroTask(setName, args[0], options, scheduleTask, clearTask);
                  if (!task) {
                      return task;
                  }
                  // Node.js must additionally support the ref and unref functions.
                  var handle = task.data.handleId;
                  // check whether handle is null, because some polyfill or browser
                  // may return undefined from setTimeout/setInterval/setImmediate/requestAnimationFrame
                  if (handle && handle.ref && handle.unref && typeof handle.ref === 'function' &&
                      typeof handle.unref === 'function') {
                      task.ref = handle.ref.bind(handle);
                      task.unref = handle.unref.bind(handle);
                  }
                  return task;
              }
              else {
                  // cause an error by calling it directly.
                  return delegate.apply(window, args);
              }
          }; });
      clearNative =
          patchMethod(window, cancelName, function (delegate) { return function (self, args) {
              var task = typeof args[0] === 'number' ? tasksByHandleId[args[0]] : args[0];
              if (task && typeof task.type === 'string') {
                  if (task.state !== 'notScheduled' &&
                      (task.cancelFn && task.data.isPeriodic || task.runCount === 0)) {
                      // Do not cancel already canceled functions
                      task.zone.cancelTask(task);
                  }
              }
              else {
                  // cause an error by calling it directly.
                  delegate.apply(window, args);
              }
          }; });
  }
  
  /**
   * @license
   * Copyright Google Inc. All Rights Reserved.
   *
   * Use of this source code is governed by an MIT-style license that can be
   * found in the LICENSE file at https://angular.io/license
   */
  var set = 'set';
  var clear = 'clear';
  // Timers
  patchTimer(global, set, clear, 'Timeout');
  patchTimer(global, set, clear, 'Interval');
  patchTimer(global, set, clear, 'Immediate');
  
  })));
  