text: /**
   * @license Angular v5.2.7
   * (c) 2010-2018 Google, Inc. https://angular.io/
   * License: MIT
   */
  (function (global, factory) {
  	typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('rxjs/Observable'), require('rxjs/observable/merge'), require('rxjs/operator/share'), require('rxjs/Subject'), require('rxjs/Subscription')) :
  	typeof define === 'function' && define.amd ? define('@angular/core', ['exports', 'rxjs/Observable', 'rxjs/observable/merge', 'rxjs/operator/share', 'rxjs/Subject', 'rxjs/Subscription'], factory) :
  	(factory((global.ng = global.ng || {}, global.ng.core = {}),global.Rx,global.Rx.Observable,global.Rx.Observable.prototype,global.Rx,global.Rx));
  }(this, (function (exports,rxjs_Observable,rxjs_observable_merge,rxjs_operator_share,rxjs_Subject,rxjs_Subscription) { 'use strict';
  
  /*! *****************************************************************************
  Copyright (c) Microsoft Corporation. All rights reserved.
  Licensed under the Apache License, Version 2.0 (the "License"); you may not use
  this file except in compliance with the License. You may obtain a copy of the
  License at http://www.apache.org/licenses/LICENSE-2.0
  
  THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
  WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
  MERCHANTABLITY OR NON-INFRINGEMENT.
  
  See the Apache Version 2.0 License for specific language governing permissions
  and limitations under the License.
  ***************************************************************************** */
  /* global Reflect, Promise */
  
  var extendStatics = Object.setPrototypeOf ||
      ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
      function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  
  function __extends(d, b) {
      extendStatics(d, b);
      function __() { this.constructor = d; }
      d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  }
  
  var __assign = Object.assign || function __assign(t) {
      for (var s, i = 1, n = arguments.length; i < n; i++) {
          s = arguments[i];
          for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
      }
      return t;
  };
  
  /**
   * @license Angular v5.2.7
   * (c) 2010-2018 Google, Inc. https://angular.io/
   * License: MIT
   */
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  /**
   * Creates a token that can be used in a DI Provider.
   *
   * Use an `InjectionToken` whenever the type you are injecting is not reified (does not have a
   * runtime representation) such as when injecting an interface, callable type, array or
   * parametrized type.
   *
   * `InjectionToken` is parameterized on `T` which is the type of object which will be returned by
   * the `Injector`. This provides additional level of type safety.
   *
   * ```
   * interface MyInterface {...}
   * var myInterface = injector.get(new InjectionToken<MyInterface>('SomeToken'));
   * // myInterface is inferred to be MyInterface.
   * ```
   *
   * ### Example
   *
   * {\@example core/di/ts/injector_spec.ts region='InjectionToken'}
   *
   * \@stable
   */
  var InjectionToken = /** @class */ (function () {
      function InjectionToken(_desc) {
          this._desc = _desc;
          /**
           * \@internal
           */
          this.ngMetadataName = 'InjectionToken';
      }
      /**
       * @return {?}
       */
      InjectionToken.prototype.toString = /**
       * @return {?}
       */
      function () { return "InjectionToken " + this._desc; };
      return InjectionToken;
  }());
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  /**
   * An interface implemented by all Angular type decorators, which allows them to be used as ES7
   * decorators as well as
   * Angular DSL syntax.
   *
   * ES7 syntax:
   *
   * ```
   * \@ng.Component({...})
   * class MyClass {...}
   * ```
   * \@stable
   * @record
   */
  
  var ANNOTATIONS = '__annotations__';
  var PARAMETERS = '__paramaters__';
  var PROP_METADATA = '__prop__metadata__';
  /**
   * @suppress {globalThis}
   * @param {?} name
   * @param {?=} props
   * @param {?=} parentClass
   * @param {?=} chainFn
   * @return {?}
   */
  function makeDecorator(name, props, parentClass, chainFn) {
      var /** @type {?} */ metaCtor = makeMetadataCtor(props);
      /**
       * @param {?} objOrType
       * @return {?}
       */
      function DecoratorFactory(objOrType) {
          if (this instanceof DecoratorFactory) {
              metaCtor.call(this, objOrType);
              return this;
          }
          var /** @type {?} */ annotationInstance = new (/** @type {?} */ (DecoratorFactory))(objOrType);
          var /** @type {?} */ TypeDecorator = /** @type {?} */ (function TypeDecorator(cls) {
              // Use of Object.defineProperty is important since it creates non-enumerable property which
              // prevents the property is copied during subclassing.
              var /** @type {?} */ annotations = cls.hasOwnProperty(ANNOTATIONS) ?
                  (/** @type {?} */ (cls))[ANNOTATIONS] :
                  Object.defineProperty(cls, ANNOTATIONS, { value: [] })[ANNOTATIONS];
              annotations.push(annotationInstance);
              return cls;
          });
          if (chainFn)
              chainFn(TypeDecorator);
          return TypeDecorator;
      }
      if (parentClass) {
          DecoratorFactory.prototype = Object.create(parentClass.prototype);
      }
      DecoratorFactory.prototype.ngMetadataName = name;
      (/** @type {?} */ (DecoratorFactory)).annotationCls = DecoratorFactory;
      return /** @type {?} */ (DecoratorFactory);
  }
  /**
   * @param {?=} props
   * @return {?}
   */
  function makeMetadataCtor(props) {
      return function ctor() {
          var args = [];
          for (var _i = 0; _i < arguments.length; _i++) {
              args[_i] = arguments[_i];
          }
          if (props) {
              var /** @type {?} */ values = props.apply(void 0, args);
              for (var /** @type {?} */ propName in values) {
                  this[propName] = values[propName];
              }
          }
      };
  }
  /**
   * @param {?} name
   * @param {?=} props
   * @param {?=} parentClass
   * @return {?}
   */
  function makeParamDecorator(name, props, parentClass) {
      var /** @type {?} */ metaCtor = makeMetadataCtor(props);
      /**
       * @param {...?} args
       * @return {?}
       */
      function ParamDecoratorFactory() {
          var args = [];
          for (var _i = 0; _i < arguments.length; _i++) {
              args[_i] = arguments[_i];
          }
          if (this instanceof ParamDecoratorFactory) {
              metaCtor.apply(this, args);
              return this;
          }
          var /** @type {?} */ annotationInstance = new ((_a = (/** @type {?} */ (ParamDecoratorFactory))).bind.apply(_a, [void 0].concat(args)))();
          (/** @type {?} */ (ParamDecorator)).annotation = annotationInstance;
          return ParamDecorator;
          /**
           * @param {?} cls
           * @param {?} unusedKey
           * @param {?} index
           * @return {?}
           */
          function ParamDecorator(cls, unusedKey, index) {
              // Use of Object.defineProperty is important since it creates non-enumerable property which
              // prevents the property is copied during subclassing.
              var /** @type {?} */ parameters = cls.hasOwnProperty(PARAMETERS) ?
                  (/** @type {?} */ (cls))[PARAMETERS] :
                  Object.defineProperty(cls, PARAMETERS, { value: [] })[PARAMETERS];
              // there might be gaps if some in between parameters do not have annotations.
              // we pad with nulls.
              while (parameters.length <= index) {
                  parameters.push(null);
              }
              (parameters[index] = parameters[index] || []).push(annotationInstance);
              return cls;
          }
          var _a;
      }
      if (parentClass) {
          ParamDecoratorFactory.prototype = Object.create(parentClass.prototype);
      }
      ParamDecoratorFactory.prototype.ngMetadataName = name;
      (/** @type {?} */ (ParamDecoratorFactory)).annotationCls = ParamDecoratorFactory;
      return ParamDecoratorFactory;
  }
  /**
   * @param {?} name
   * @param {?=} props
   * @param {?=} parentClass
   * @return {?}
   */
  function makePropDecorator(name, props, parentClass) {
      var /** @type {?} */ metaCtor = makeMetadataCtor(props);
      /**
       * @param {...?} args
       * @return {?}
       */
      function PropDecoratorFactory() {
          var args = [];
          for (var _i = 0; _i < arguments.length; _i++) {
              args[_i] = arguments[_i];
          }
          if (this instanceof PropDecoratorFactory) {
              metaCtor.apply(this, args);
              return this;
          }
          var /** @type {?} */ decoratorInstance = new ((_a = (/** @type {?} */ (PropDecoratorFactory))).bind.apply(_a, [void 0].concat(args)))();
          return function PropDecorator(target, name) {
              var /** @type {?} */ constructor = target.constructor;
              // Use of Object.defineProperty is important since it creates non-enumerable property which
              // prevents the property is copied during subclassing.
              var /** @type {?} */ meta = constructor.hasOwnProperty(PROP_METADATA) ?
                  (/** @type {?} */ (constructor))[PROP_METADATA] :
                  Object.defineProperty(constructor, PROP_METADATA, { value: {} })[PROP_METADATA];
              meta[name] = meta.hasOwnProperty(name) && meta[name] || [];
              meta[name].unshift(decoratorInstance);
          };
          var _a;
      }
      if (parentClass) {
          PropDecoratorFactory.prototype = Object.create(parentClass.prototype);
      }
      PropDecoratorFactory.prototype.ngMetadataName = name;
      (/** @type {?} */ (PropDecoratorFactory)).annotationCls = PropDecoratorFactory;
      return PropDecoratorFactory;
  }
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  /**
   * This token can be used to create a virtual provider that will populate the
   * `entryComponents` fields of components and ng modules based on its `useValue`.
   * All components that are referenced in the `useValue` value (either directly
   * or in a nested array or map) will be added to the `entryComponents` property.
   *
   * ### Example
   * The following example shows how the router can populate the `entryComponents`
   * field of an NgModule based on the router configuration which refers
   * to components.
   *
   * ```typescript
   * // helper function inside the router
   * function provideRoutes(routes) {
   *   return [
   *     {provide: ROUTES, useValue: routes},
   *     {provide: ANALYZE_FOR_ENTRY_COMPONENTS, useValue: routes, multi: true}
   *   ];
   * }
   *
   * // user code
   * let routes = [
   *   {path: '/root', component: RootComp},
   *   {path: '/teams', component: TeamsComp}
   * ];
   *
   * \@NgModule({
   *   providers: [provideRoutes(routes)]
   * })
   * class ModuleWithRoutes {}
   * ```
   *
   * \@experimental
   */
  var ANALYZE_FOR_ENTRY_COMPONENTS = new InjectionToken('AnalyzeForEntryComponents');
  /**
   * Type of the Attribute decorator / constructor function.
   *
   * \@stable
   * @record
   */
  
  /**
   * Attribute decorator and metadata.
   *
   * \@stable
   * \@Annotation
   */
  var Attribute = makeParamDecorator('Attribute', function (attributeName) { return ({ attributeName: attributeName }); });
  /**
   * Base class for query metadata.
   *
   * See {\@link ContentChildren}, {\@link ContentChild}, {\@link ViewChildren}, {\@link ViewChild} for
   * more information.
   *
   * \@stable
   * @abstract
   */
  var Query = /** @class */ (function () {
      function Query() {
      }
      return Query;
  }());
  /**
   * Type of the ContentChildren decorator / constructor function.
   *
   * See {\@link ContentChildren}.
   *
   * \@stable
   * @record
   */
  
  /**
   * ContentChildren decorator and metadata.
   *
   *  \@stable
   *  \@Annotation
   */
  var ContentChildren = makePropDecorator('ContentChildren', function (selector, data) {
      if (data === void 0) { data = {}; }
      return (__assign({ selector: selector, first: false, isViewQuery: false, descendants: false }, data));
  }, Query);
  /**
   * Type of the ContentChild decorator / constructor function.
   *
   *
   * \@stable
   * @record
   */
  
  /**
   * ContentChild decorator and metadata.
   *
   * \@stable
   * \@Annotation
   */
  var ContentChild = makePropDecorator('ContentChild', function (selector, data) {
      if (data === void 0) { data = {}; }
      return (__assign({ selector: selector, first: true, isViewQuery: false, descendants: true }, data));
  }, Query);
  /**
   * Type of the ViewChildren decorator / constructor function.
   *
   * See {\@link ViewChildren}.
   *
   * \@stable
   * @record
   */
  
  /**
   * ViewChildren decorator and metadata.
   *
   * \@stable
   * \@Annotation
   */
  var ViewChildren = makePropDecorator('ViewChildren', function (selector, data) {
      if (data === void 0) { data = {}; }
      return (__assign({ selector: selector, first: false, isViewQuery: true, descendants: true }, data));
  }, Query);
  /**
   * Type of the ViewChild decorator / constructor function.
   *
   * See {\@link ViewChild}
   *
   * \@stable
   * @record
   */
  
  /**
   * ViewChild decorator and metadata.
   *
   * \@stable
   * \@Annotation
   */
  var ViewChild = makePropDecorator('ViewChild', function (selector, data) {
      return (__assign({ selector: selector, first: true, isViewQuery: true, descendants: true }, data));
  }, Query);
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  /** @enum {number} */
  var ChangeDetectionStrategy = {
      /**
         * `OnPush` means that the change detector's mode will be initially set to `CheckOnce`.
         */
      OnPush: 0,
      /**
         * `Default` means that the change detector's mode will be initially set to `CheckAlways`.
         */
      Default: 1,
  };
  ChangeDetectionStrategy[ChangeDetectionStrategy.OnPush] = "OnPush";
  ChangeDetectionStrategy[ChangeDetectionStrategy.Default] = "Default";
  /** @enum {number} */
  var ChangeDetectorStatus = {
      /**
         * `CheckOnce` means that after calling detectChanges the mode of the change detector
         * will become `Checked`.
         */
      CheckOnce: 0,
      /**
         * `Checked` means that the change detector should be skipped until its mode changes to
         * `CheckOnce`.
         */
      Checked: 1,
      /**
         * `CheckAlways` means that after calling detectChanges the mode of the change detector
         * will remain `CheckAlways`.
         */
      CheckAlways: 2,
      /**
         * `Detached` means that the change detector sub tree is not a part of the main tree and
         * should be skipped.
         */
      Detached: 3,
      /**
         * `Errored` means that the change detector encountered an error checking a binding
         * or calling a directive lifecycle method and is now in an inconsistent state. Change
         * detectors in this state will no longer detect changes.
         */
      Errored: 4,
      /**
         * `Destroyed` means that the change detector is destroyed.
         */
      Destroyed: 5,
  };
  ChangeDetectorStatus[ChangeDetectorStatus.CheckOnce] = "CheckOnce";
  ChangeDetectorStatus[ChangeDetectorStatus.Checked] = "Checked";
  ChangeDetectorStatus[ChangeDetectorStatus.CheckAlways] = "CheckAlways";
  ChangeDetectorStatus[ChangeDetectorStatus.Detached] = "Detached";
  ChangeDetectorStatus[ChangeDetectorStatus.Errored] = "Errored";
  ChangeDetectorStatus[ChangeDetectorStatus.Destroyed] = "Destroyed";
  /**
   * @param {?} changeDetectionStrategy
   * @return {?}
   */
  function isDefaultChangeDetectionStrategy(changeDetectionStrategy) {
      return changeDetectionStrategy == null ||
          changeDetectionStrategy === ChangeDetectionStrategy.Default;
  }
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  /**
   * Type of the Directive decorator / constructor function.
   *
   * \@stable
   * @record
   */
  
  /**
   * Directive decorator and metadata.
   *
   * \@stable
   * \@Annotation
   */
  var Directive = makeDecorator('Directive', function (dir) {
      if (dir === void 0) { dir = {}; }
      return dir;
  });
  /**
   * Type of the Component decorator / constructor function.
   *
   * \@stable
   * @record
   */
  
  /**
   * Component decorator and metadata.
   *
   * \@stable
   * \@Annotation
   */
  var Component = makeDecorator('Component', function (c) {
      if (c === void 0) { c = {}; }
      return (__assign({ changeDetection: ChangeDetectionStrategy.Default }, c));
  }, Directive);
  /**
   * Type of the Pipe decorator / constructor function.
   *
   * \@stable
   * @record
   */
  
  /**
   * Pipe decorator and metadata.
   *
   * \@stable
   * \@Annotation
   */
  var Pipe = makeDecorator('Pipe', function (p) { return (__assign({ pure: true }, p)); });
  /**
   * Type of the Input decorator / constructor function.
   *
   * \@stable
   * @record
   */
  
  /**
   * Input decorator and metadata.
   *
   * \@stable
   * \@Annotation
   */
  var Input = makePropDecorator('Input', function (bindingPropertyName) { return ({ bindingPropertyName: bindingPropertyName }); });
  /**
   * Type of the Output decorator / constructor function.
   *
   * \@stable
   * @record
   */
  
  /**
   * Output decorator and metadata.
   *
   * \@stable
   * \@Annotation
   */
  var Output = makePropDecorator('Output', function (bindingPropertyName) { return ({ bindingPropertyName: bindingPropertyName }); });
  /**
   * Type of the HostBinding decorator / constructor function.
   *
   * \@stable
   * @record
   */
  
  /**
   * HostBinding decorator and metadata.
   *
   * \@stable
   * \@Annotation
   */
  var HostBinding = makePropDecorator('HostBinding', function (hostPropertyName) { return ({ hostPropertyName: hostPropertyName }); });
  /**
   * Type of the HostListener decorator / constructor function.
   *
   * \@stable
   * @record
   */
  
  /**
   * HostListener decorator and metadata.
   *
   * \@stable
   * \@Annotation
   */
  var HostListener = makePropDecorator('HostListener', function (eventName, args) { return ({ eventName: eventName, args: args }); });
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  /**
   * A wrapper around a module that also includes the providers.
   *
   * \@stable
   * @record
   */
  
  /**
   * Interface for schema definitions in \@NgModules.
   *
   * \@experimental
   * @record
   */
  
  /**
   * Defines a schema that will allow:
   * - any non-Angular elements with a `-` in their name,
   * - any properties on elements with a `-` in their name which is the common rule for custom
   * elements.
   *
   * \@stable
   */
  var CUSTOM_ELEMENTS_SCHEMA = {
      name: 'custom-elements'
  };
  /**
   * Defines a schema that will allow any property on any element.
   *
   * \@experimental
   */
  var NO_ERRORS_SCHEMA = {
      name: 'no-errors-schema'
  };
  /**
   * Type of the NgModule decorator / constructor function.
   *
   * \@stable
   * @record
   */
  
  /**
   * NgModule decorator and metadata.
   *
   * \@stable
   * \@Annotation
   */
  var NgModule = makeDecorator('NgModule', function (ngModule) { return ngModule; });
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  /** @enum {number} */
  var ViewEncapsulation = {
      /**
         * Emulate `Native` scoping of styles by adding an attribute containing surrogate id to the Host
         * Element and pre-processing the style rules provided via {@link Component#styles styles} or
         * {@link Component#styleUrls styleUrls}, and adding the new Host Element attribute to all
         * selectors.
         *
         * This is the default option.
         */
      Emulated: 0,
      /**
         * Use the native encapsulation mechanism of the renderer.
         *
         * For the DOM this means using [Shadow DOM](https://w3c.github.io/webcomponents/spec/shadow/) and
         * creating a ShadowRoot for Component's Host Element.
         */
      Native: 1,
      /**
         * Don't provide any template or style encapsulation.
         */
      None: 2,
  };
  ViewEncapsulation[ViewEncapsulation.Emulated] = "Emulated";
  ViewEncapsulation[ViewEncapsulation.Native] = "Native";
  ViewEncapsulation[ViewEncapsulation.None] = "None";
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  /**
   * \@whatItDoes Represents the version of Angular
   *
   * \@stable
   */
  var Version = /** @class */ (function () {
      function Version(full) {
          this.full = full;
          this.major = full.split('.')[0];
          this.minor = full.split('.')[1];
          this.patch = full.split('.').slice(2).join('.');
      }
      return Version;
  }());
  /**
   * \@stable
   */
  var VERSION = new Version('5.2.7');
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  /**
   * Type of the Inject decorator / constructor function.
   *
   * \@stable
   * @record
   */
  
  /**
   * Inject decorator and metadata.
   *
   * \@stable
   * \@Annotation
   */
  var Inject = makeParamDecorator('Inject', function (token) { return ({ token: token }); });
  /**
   * Type of the Optional decorator / constructor function.
   *
   * \@stable
   * @record
   */
  
  /**
   * Optional decorator and metadata.
   *
   * \@stable
   * \@Annotation
   */
  var Optional = makeParamDecorator('Optional');
  /**
   * Type of the Injectable decorator / constructor function.
   *
   * \@stable
   * @record
   */
  
  /**
   * Injectable decorator and metadata.
   *
   * \@stable
   * \@Annotation
   */
  var Injectable = makeDecorator('Injectable');
  /**
   * Type of the Self decorator / constructor function.
   *
   * \@stable
   * @record
   */
  
  /**
   * Self decorator and metadata.
   *
   * \@stable
   * \@Annotation
   */
  var Self = makeParamDecorator('Self');
  /**
   * Type of the SkipSelf decorator / constructor function.
   *
   * \@stable
   * @record
   */
  
  /**
   * SkipSelf decorator and metadata.
   *
   * \@stable
   * \@Annotation
   */
  var SkipSelf = makeParamDecorator('SkipSelf');
  /**
   * Type of the Host decorator / constructor function.
   *
   * \@stable
   * @record
   */
  
  /**
   * Host decorator and metadata.
   *
   * \@stable
   * \@Annotation
   */
  var Host = makeParamDecorator('Host');
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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 __window = typeof window !== 'undefined' && window;
  var __self = typeof self !== 'undefined' && typeof WorkerGlobalScope !== 'undefined' &&
      self instanceof WorkerGlobalScope && self;
  var __global = typeof global !== 'undefined' && global;
  var _global = __window || __global || __self;
  var promise = Promise.resolve(0);
  var _symbolIterator = null;
  /**
   * @return {?}
   */
  function getSymbolIterator() {
      if (!_symbolIterator) {
          var /** @type {?} */ Symbol_1 = _global['Symbol'];
          if (Symbol_1 && Symbol_1.iterator) {
              _symbolIterator = Symbol_1.iterator;
          }
          else {
              // es6-shim specific logic
              var /** @type {?} */ keys = Object.getOwnPropertyNames(Map.prototype);
              for (var /** @type {?} */ i = 0; i < keys.length; ++i) {
                  var /** @type {?} */ key = keys[i];
                  if (key !== 'entries' && key !== 'size' &&
                      (/** @type {?} */ (Map)).prototype[key] === Map.prototype['entries']) {
                      _symbolIterator = key;
                  }
              }
          }
      }
      return _symbolIterator;
  }
  /**
   * @param {?} fn
   * @return {?}
   */
  function scheduleMicroTask(fn) {
      if (typeof Zone === 'undefined') {
          // use promise to schedule microTask instead of use Zone
          promise.then(function () { fn && fn.apply(null, null); });
      }
      else {
          Zone.current.scheduleMicroTask('scheduleMicrotask', fn);
      }
  }
  /**
   * @param {?} a
   * @param {?} b
   * @return {?}
   */
  function looseIdentical(a, b) {
      return a === b || typeof a === 'number' && typeof b === 'number' && isNaN(a) && isNaN(b);
  }
  /**
   * @param {?} token
   * @return {?}
   */
  function stringify(token) {
      if (typeof token === 'string') {
          return token;
      }
      if (token instanceof Array) {
          return '[' + token.map(stringify).join(', ') + ']';
      }
      if (token == null) {
          return '' + token;
      }
      if (token.overriddenName) {
          return "" + token.overriddenName;
      }
      if (token.name) {
          return "" + token.name;
      }
      var /** @type {?} */ res = token.toString();
      if (res == null) {
          return '' + res;
      }
      var /** @type {?} */ newLineIndex = res.indexOf('\n');
      return newLineIndex === -1 ? res : res.substring(0, newLineIndex);
  }
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  /**
   * An interface that a function passed into {\@link forwardRef} has to implement.
   *
   * ### Example
   *
   * {\@example core/di/ts/forward_ref/forward_ref_spec.ts region='forward_ref_fn'}
   * \@experimental
   * @record
   */
  
  /**
   * Allows to refer to references which are not yet defined.
   *
   * For instance, `forwardRef` is used when the `token` which we need to refer to for the purposes of
   * DI is declared,
   * but not yet defined. It is also used when the `token` which we use when creating a query is not
   * yet defined.
   *
   * ### Example
   * {\@example core/di/ts/forward_ref/forward_ref_spec.ts region='forward_ref'}
   * \@experimental
   * @param {?} forwardRefFn
   * @return {?}
   */
  function forwardRef(forwardRefFn) {
      (/** @type {?} */ (forwardRefFn)).__forward_ref__ = forwardRef;
      (/** @type {?} */ (forwardRefFn)).toString = function () { return stringify(this()); };
      return (/** @type {?} */ (/** @type {?} */ (forwardRefFn)));
  }
  /**
   * Lazily retrieves the reference value from a forwardRef.
   *
   * Acts as the identity function when given a non-forward-ref value.
   *
   * ### Example ([live demo](http://plnkr.co/edit/GU72mJrk1fiodChcmiDR?p=preview))
   *
   * {\@example core/di/ts/forward_ref/forward_ref_spec.ts region='resolve_forward_ref'}
   *
   * See: {\@link forwardRef}
   * \@experimental
   * @param {?} type
   * @return {?}
   */
  function resolveForwardRef(type) {
      if (typeof type === 'function' && type.hasOwnProperty('__forward_ref__') &&
          type.__forward_ref__ === forwardRef) {
          return (/** @type {?} */ (type))();
      }
      else {
          return type;
      }
  }
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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 SOURCE = '__source';
  var _THROW_IF_NOT_FOUND = new Object();
  var THROW_IF_NOT_FOUND = _THROW_IF_NOT_FOUND;
  var _NullInjector = /** @class */ (function () {
      function _NullInjector() {
      }
      /**
       * @param {?} token
       * @param {?=} notFoundValue
       * @return {?}
       */
      _NullInjector.prototype.get = /**
       * @param {?} token
       * @param {?=} notFoundValue
       * @return {?}
       */
      function (token, notFoundValue) {
          if (notFoundValue === void 0) { notFoundValue = _THROW_IF_NOT_FOUND; }
          if (notFoundValue === _THROW_IF_NOT_FOUND) {
              throw new Error("NullInjectorError: No provider for " + stringify(token) + "!");
          }
          return notFoundValue;
      };
      return _NullInjector;
  }());
  /**
   * \@whatItDoes Injector interface
   * \@howToUse
   * ```
   * const injector: Injector = ...;
   * injector.get(...);
   * ```
   *
   * \@description
   * For more details, see the {\@linkDocs guide/dependency-injection "Dependency Injection Guide"}.
   *
   * ### Example
   *
   * {\@example core/di/ts/injector_spec.ts region='Injector'}
   *
   * `Injector` returns itself when given `Injector` as a token:
   * {\@example core/di/ts/injector_spec.ts region='injectInjector'}
   *
   * \@stable
   * @abstract
   */
  var Injector = /** @class */ (function () {
      function Injector() {
      }
      /**
       * Create a new Injector which is configure using `StaticProvider`s.
       *
       * ### Example
       *
       * {@example core/di/ts/provider_spec.ts region='ConstructorProvider'}
       */
      /**
       * Create a new Injector which is configure using `StaticProvider`s.
       *
       * ### Example
       *
       * {\@example core/di/ts/provider_spec.ts region='ConstructorProvider'}
       * @param {?} options
       * @param {?=} parent
       * @return {?}
       */
      Injector.create = /**
       * Create a new Injector which is configure using `StaticProvider`s.
       *
       * ### Example
       *
       * {\@example core/di/ts/provider_spec.ts region='ConstructorProvider'}
       * @param {?} options
       * @param {?=} parent
       * @return {?}
       */
      function (options, parent) {
          if (Array.isArray(options)) {
              return new StaticInjector(options, parent);
          }
          else {
              return new StaticInjector(options.providers, options.parent, options.name || null);
          }
      };
      Injector.THROW_IF_NOT_FOUND = _THROW_IF_NOT_FOUND;
      Injector.NULL = new _NullInjector();
      return Injector;
  }());
  var IDENT = function (value) {
      return value;
  };
  var EMPTY = /** @type {?} */ ([]);
  var CIRCULAR = IDENT;
  var MULTI_PROVIDER_FN = function () {
      return Array.prototype.slice.call(arguments);
  };
  var GET_PROPERTY_NAME = /** @type {?} */ ({});
  var ɵ2 = GET_PROPERTY_NAME;
  var USE_VALUE = getClosureSafeProperty({ provide: String, useValue: ɵ2 });
  var NG_TOKEN_PATH = 'ngTokenPath';
  var NG_TEMP_TOKEN_PATH = 'ngTempTokenPath';
  var NULL_INJECTOR = Injector.NULL;
  var NEW_LINE = /\n/gm;
  var NO_NEW_LINE = 'ɵ';
  var StaticInjector = /** @class */ (function () {
      function StaticInjector(providers, parent, source) {
          if (parent === void 0) { parent = NULL_INJECTOR; }
          if (source === void 0) { source = null; }
          this.parent = parent;
          this.source = source;
          var /** @type {?} */ records = this._records = new Map();
          records.set(Injector, /** @type {?} */ ({ token: Injector, fn: IDENT, deps: EMPTY, value: this, useNew: false }));
          recursivelyProcessProviders(records, providers);
      }
      /**
       * @param {?} token
       * @param {?=} notFoundValue
       * @return {?}
       */
      StaticInjector.prototype.get = /**
       * @param {?} token
       * @param {?=} notFoundValue
       * @return {?}
       */
      function (token, notFoundValue) {
          var /** @type {?} */ record = this._records.get(token);
          try {
              return tryResolveToken(token, record, this._records, this.parent, notFoundValue);
          }
          catch (/** @type {?} */ e) {
              var /** @type {?} */ tokenPath = e[NG_TEMP_TOKEN_PATH];
              if (token[SOURCE]) {
                  tokenPath.unshift(token[SOURCE]);
              }
              e.message = formatError('\n' + e.message, tokenPath, this.source);
              e[NG_TOKEN_PATH] = tokenPath;
              e[NG_TEMP_TOKEN_PATH] = null;
              throw e;
          }
      };
      /**
       * @return {?}
       */
      StaticInjector.prototype.toString = /**
       * @return {?}
       */
      function () {
          var /** @type {?} */ tokens = /** @type {?} */ ([]), /** @type {?} */ records = this._records;
          records.forEach(function (v, token) { return tokens.push(stringify(token)); });
          return "StaticInjector[" + tokens.join(', ') + "]";
      };
      return StaticInjector;
  }());
  /**
   * @param {?} provider
   * @return {?}
   */
  function resolveProvider(provider) {
      var /** @type {?} */ deps = computeDeps(provider);
      var /** @type {?} */ fn = IDENT;
      var /** @type {?} */ value = EMPTY;
      var /** @type {?} */ useNew = false;
      var /** @type {?} */ provide = resolveForwardRef(provider.provide);
      if (USE_VALUE in provider) {
          // We need to use USE_VALUE in provider since provider.useValue could be defined as undefined.
          value = (/** @type {?} */ (provider)).useValue;
      }
      else if ((/** @type {?} */ (provider)).useFactory) {
          fn = (/** @type {?} */ (provider)).useFactory;
      }
      else if ((/** @type {?} */ (provider)).useExisting) {
          // Just use IDENT
      }
      else if ((/** @type {?} */ (provider)).useClass) {
          useNew = true;
          fn = resolveForwardRef((/** @type {?} */ (provider)).useClass);
      }
      else if (typeof provide == 'function') {
          useNew = true;
          fn = provide;
      }
      else {
          throw staticError('StaticProvider does not have [useValue|useFactory|useExisting|useClass] or [provide] is not newable', provider);
      }
      return { deps: deps, fn: fn, useNew: useNew, value: value };
  }
  /**
   * @param {?} token
   * @return {?}
   */
  function multiProviderMixError(token) {
      return staticError('Cannot mix multi providers and regular providers', token);
  }
  /**
   * @param {?} records
   * @param {?} provider
   * @return {?}
   */
  function recursivelyProcessProviders(records, provider) {
      if (provider) {
          provider = resolveForwardRef(provider);
          if (provider instanceof Array) {
              // if we have an array recurse into the array
              for (var /** @type {?} */ i = 0; i < provider.length; i++) {
                  recursivelyProcessProviders(records, provider[i]);
              }
          }
          else if (typeof provider === 'function') {
              // Functions were supported in ReflectiveInjector, but are not here. For safety give useful
              // error messages
              throw staticError('Function/Class not supported', provider);
          }
          else if (provider && typeof provider === 'object' && provider.provide) {
              // At this point we have what looks like a provider: {provide: ?, ....}
              var /** @type {?} */ token = resolveForwardRef(provider.provide);
              var /** @type {?} */ resolvedProvider = resolveProvider(provider);
              if (provider.multi === true) {
                  // This is a multi provider.
                  var /** @type {?} */ multiProvider = records.get(token);
                  if (multiProvider) {
                      if (multiProvider.fn !== MULTI_PROVIDER_FN) {
                          throw multiProviderMixError(token);
                      }
                  }
                  else {
                      // Create a placeholder factory which will look up the constituents of the multi provider.
                      records.set(token, multiProvider = /** @type {?} */ ({
                          token: provider.provide,
                          deps: [],
                          useNew: false,
                          fn: MULTI_PROVIDER_FN,
                          value: EMPTY
                      }));
                  }
                  // Treat the provider as the token.
                  token = provider;
                  multiProvider.deps.push({ token: token, options: 6 /* Default */ });
              }
              var /** @type {?} */ record = records.get(token);
              if (record && record.fn == MULTI_PROVIDER_FN) {
                  throw multiProviderMixError(token);
              }
              records.set(token, resolvedProvider);
          }
          else {
              throw staticError('Unexpected provider', provider);
          }
      }
  }
  /**
   * @param {?} token
   * @param {?} record
   * @param {?} records
   * @param {?} parent
   * @param {?} notFoundValue
   * @return {?}
   */
  function tryResolveToken(token, record, records, parent, notFoundValue) {
      try {
          return resolveToken(token, record, records, parent, notFoundValue);
      }
      catch (/** @type {?} */ e) {
          // ensure that 'e' is of type Error.
          if (!(e instanceof Error)) {
              e = new Error(e);
          }
          var /** @type {?} */ path = e[NG_TEMP_TOKEN_PATH] = e[NG_TEMP_TOKEN_PATH] || [];
          path.unshift(token);
          if (record && record.value == CIRCULAR) {
              // Reset the Circular flag.
              record.value = EMPTY;
          }
          throw e;
      }
  }
  /**
   * @param {?} token
   * @param {?} record
   * @param {?} records
   * @param {?} parent
   * @param {?} notFoundValue
   * @return {?}
   */
  function resolveToken(token, record, records, parent, notFoundValue) {
      var /** @type {?} */ value;
      if (record) {
          // If we don't have a record, this implies that we don't own the provider hence don't know how
          // to resolve it.
          value = record.value;
          if (value == CIRCULAR) {
              throw Error(NO_NEW_LINE + 'Circular dependency');
          }
          else if (value === EMPTY) {
              record.value = CIRCULAR;
              var /** @type {?} */ obj = undefined;
              var /** @type {?} */ useNew = record.useNew;
              var /** @type {?} */ fn = record.fn;
              var /** @type {?} */ depRecords = record.deps;
              var /** @type {?} */ deps = EMPTY;
              if (depRecords.length) {
                  deps = [];
                  for (var /** @type {?} */ i = 0; i < depRecords.length; i++) {
                      var /** @type {?} */ depRecord = depRecords[i];
                      var /** @type {?} */ options = depRecord.options;
                      var /** @type {?} */ childRecord = options & 2 /* CheckSelf */ ? records.get(depRecord.token) : undefined;
                      deps.push(tryResolveToken(
                      // Current Token to resolve
                      depRecord.token, childRecord, records, 
                      // If we don't know how to resolve dependency and we should not check parent for it,
                      // than pass in Null injector.
                      !childRecord && !(options & 4 /* CheckParent */) ? NULL_INJECTOR : parent, options & 1 /* Optional */ ? null : Injector.THROW_IF_NOT_FOUND));
                  }
              }
              record.value = value = useNew ? new ((_a = (/** @type {?} */ (fn))).bind.apply(_a, [void 0].concat(deps)))() : fn.apply(obj, deps);
          }
      }
      else {
          value = parent.get(token, notFoundValue);
      }
      return value;
      var _a;
  }
  /**
   * @param {?} provider
   * @return {?}
   */
  function computeDeps(provider) {
      var /** @type {?} */ deps = EMPTY;
      var /** @type {?} */ providerDeps = (/** @type {?} */ (provider)).deps;
      if (providerDeps && providerDeps.length) {
          deps = [];
          for (var /** @type {?} */ i = 0; i < providerDeps.length; i++) {
              var /** @type {?} */ options = 6;
              var /** @type {?} */ token = resolveForwardRef(providerDeps[i]);
              if (token instanceof Array) {
                  for (var /** @type {?} */ j = 0, /** @type {?} */ annotations = token; j < annotations.length; j++) {
                      var /** @type {?} */ annotation = annotations[j];
                      if (annotation instanceof Optional || annotation == Optional) {
                          options = options | 1 /* Optional */;
                      }
                      else if (annotation instanceof SkipSelf || annotation == SkipSelf) {
                          options = options & ~2 /* CheckSelf */;
                      }
                      else if (annotation instanceof Self || annotation == Self) {
                          options = options & ~4 /* CheckParent */;
                      }
                      else if (annotation instanceof Inject) {
                          token = (/** @type {?} */ (annotation)).token;
                      }
                      else {
                          token = resolveForwardRef(annotation);
                      }
                  }
              }
              deps.push({ token: token, options: options });
          }
      }
      else if ((/** @type {?} */ (provider)).useExisting) {
          var /** @type {?} */ token = resolveForwardRef((/** @type {?} */ (provider)).useExisting);
          deps = [{ token: token, options: 6 /* Default */ }];
      }
      else if (!providerDeps && !(USE_VALUE in provider)) {
          // useValue & useExisting are the only ones which are exempt from deps all others need it.
          throw staticError('\'deps\' required', provider);
      }
      return deps;
  }
  /**
   * @param {?} text
   * @param {?} obj
   * @param {?=} source
   * @return {?}
   */
  function formatError(text, obj, source) {
      if (source === void 0) { source = null; }
      text = text && text.charAt(0) === '\n' && text.charAt(1) == NO_NEW_LINE ? text.substr(2) : text;
      var /** @type {?} */ context = stringify(obj);
      if (obj instanceof Array) {
          context = obj.map(stringify).join(' -> ');
      }
      else if (typeof obj === 'object') {
          var /** @type {?} */ parts = /** @type {?} */ ([]);
          for (var /** @type {?} */ key in obj) {
              if (obj.hasOwnProperty(key)) {
                  var /** @type {?} */ value = obj[key];
                  parts.push(key + ':' + (typeof value === 'string' ? JSON.stringify(value) : stringify(value)));
              }
          }
          context = "{" + parts.join(', ') + "}";
      }
      return "StaticInjectorError" + (source ? '(' + source + ')' : '') + "[" + context + "]: " + text.replace(NEW_LINE, '\n  ');
  }
  /**
   * @param {?} text
   * @param {?} obj
   * @return {?}
   */
  function staticError(text, obj) {
      return new Error(formatError(text, obj));
  }
  /**
   * @template T
   * @param {?} objWithPropertyToExtract
   * @return {?}
   */
  function getClosureSafeProperty(objWithPropertyToExtract) {
      for (var /** @type {?} */ key in objWithPropertyToExtract) {
          if (objWithPropertyToExtract[key] === GET_PROPERTY_NAME) {
              return key;
          }
      }
      throw Error('!prop');
  }
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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 ERROR_DEBUG_CONTEXT = 'ngDebugContext';
  var ERROR_ORIGINAL_ERROR = 'ngOriginalError';
  var ERROR_LOGGER = 'ngErrorLogger';
  /**
   * @param {?} error
   * @return {?}
   */
  
  /**
   * @param {?} error
   * @return {?}
   */
  function getDebugContext(error) {
      return (/** @type {?} */ (error))[ERROR_DEBUG_CONTEXT];
  }
  /**
   * @param {?} error
   * @return {?}
   */
  function getOriginalError(error) {
      return (/** @type {?} */ (error))[ERROR_ORIGINAL_ERROR];
  }
  /**
   * @param {?} error
   * @return {?}
   */
  function getErrorLogger(error) {
      return (/** @type {?} */ (error))[ERROR_LOGGER] || defaultErrorLogger;
  }
  /**
   * @param {?} console
   * @param {...?} values
   * @return {?}
   */
  function defaultErrorLogger(console) {
      var values = [];
      for (var _i = 1; _i < arguments.length; _i++) {
          values[_i - 1] = arguments[_i];
      }
      console.error.apply(console, values);
  }
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  /**
   * \@whatItDoes Provides a hook for centralized exception handling.
   *
   * \@description
   *
   * The default implementation of `ErrorHandler` prints error messages to the `console`. To
   * intercept error handling, write a custom exception handler that replaces this default as
   * appropriate for your app.
   *
   * ### Example
   *
   * ```
   * class MyErrorHandler implements ErrorHandler {
   *   handleError(error) {
   *     // do something with the exception
   *   }
   * }
   *
   * \@NgModule({
   *   providers: [{provide: ErrorHandler, useClass: MyErrorHandler}]
   * })
   * class MyModule {}
   * ```
   *
   * \@stable
   */
  var ErrorHandler = /** @class */ (function () {
      function ErrorHandler() {
          /**
           * \@internal
           */
          this._console = console;
      }
      /**
       * @param {?} error
       * @return {?}
       */
      ErrorHandler.prototype.handleError = /**
       * @param {?} error
       * @return {?}
       */
      function (error) {
          var /** @type {?} */ originalError = this._findOriginalError(error);
          var /** @type {?} */ context = this._findContext(error);
          // Note: Browser consoles show the place from where console.error was called.
          // We can use this to give users additional information about the error.
          var /** @type {?} */ errorLogger = getErrorLogger(error);
          errorLogger(this._console, "ERROR", error);
          if (originalError) {
              errorLogger(this._console, "ORIGINAL ERROR", originalError);
          }
          if (context) {
              errorLogger(this._console, 'ERROR CONTEXT', context);
          }
      };
      /** @internal */
      /**
       * \@internal
       * @param {?} error
       * @return {?}
       */
      ErrorHandler.prototype._findContext = /**
       * \@internal
       * @param {?} error
       * @return {?}
       */
      function (error) {
          if (error) {
              return getDebugContext(error) ? getDebugContext(error) :
                  this._findContext(getOriginalError(error));
          }
          return null;
      };
      /** @internal */
      /**
       * \@internal
       * @param {?} error
       * @return {?}
       */
      ErrorHandler.prototype._findOriginalError = /**
       * \@internal
       * @param {?} error
       * @return {?}
       */
      function (error) {
          var /** @type {?} */ e = getOriginalError(error);
          while (e && getOriginalError(e)) {
              e = getOriginalError(e);
          }
          return e;
      };
      return ErrorHandler;
  }());
  /**
   * @param {?} message
   * @param {?} originalError
   * @return {?}
   */
  function wrappedError(message, originalError) {
      var /** @type {?} */ msg = message + " caused by: " + (originalError instanceof Error ? originalError.message : originalError);
      var /** @type {?} */ error = Error(msg);
      (/** @type {?} */ (error))[ERROR_ORIGINAL_ERROR] = originalError;
      return error;
  }
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  /**
   * @param {?} keys
   * @return {?}
   */
  function findFirstClosedCycle(keys) {
      var /** @type {?} */ res = [];
      for (var /** @type {?} */ i = 0; i < keys.length; ++i) {
          if (res.indexOf(keys[i]) > -1) {
              res.push(keys[i]);
              return res;
          }
          res.push(keys[i]);
      }
      return res;
  }
  /**
   * @param {?} keys
   * @return {?}
   */
  function constructResolvingPath(keys) {
      if (keys.length > 1) {
          var /** @type {?} */ reversed = findFirstClosedCycle(keys.slice().reverse());
          var /** @type {?} */ tokenStrs = reversed.map(function (k) { return stringify(k.token); });
          return ' (' + tokenStrs.join(' -> ') + ')';
      }
      return '';
  }
  /**
   * @record
   */
  
  /**
   * @param {?} injector
   * @param {?} key
   * @param {?} constructResolvingMessage
   * @param {?=} originalError
   * @return {?}
   */
  function injectionError(injector, key, constructResolvingMessage, originalError) {
      var /** @type {?} */ keys = [key];
      var /** @type {?} */ errMsg = constructResolvingMessage(keys);
      var /** @type {?} */ error = /** @type {?} */ ((originalError ? wrappedError(errMsg, originalError) : Error(errMsg)));
      error.addKey = addKey;
      error.keys = keys;
      error.injectors = [injector];
      error.constructResolvingMessage = constructResolvingMessage;
      (/** @type {?} */ (error))[ERROR_ORIGINAL_ERROR] = originalError;
      return error;
  }
  /**
   * @this {?}
   * @param {?} injector
   * @param {?} key
   * @return {?}
   */
  function addKey(injector, key) {
      this.injectors.push(injector);
      this.keys.push(key);
      // Note: This updated message won't be reflected in the `.stack` property
      this.message = this.constructResolvingMessage(this.keys);
  }
  /**
   * Thrown when trying to retrieve a dependency by key from {\@link Injector}, but the
   * {\@link Injector} does not have a {\@link Provider} for the given key.
   *
   * ### Example ([live demo](http://plnkr.co/edit/vq8D3FRB9aGbnWJqtEPE?p=preview))
   *
   * ```typescript
   * class A {
   *   constructor(b:B) {}
   * }
   *
   * expect(() => Injector.resolveAndCreate([A])).toThrowError();
   * ```
   * @param {?} injector
   * @param {?} key
   * @return {?}
   */
  function noProviderError(injector, key) {
      return injectionError(injector, key, function (keys) {
          var /** @type {?} */ first = stringify(keys[0].token);
          return "No provider for " + first + "!" + constructResolvingPath(keys);
      });
  }
  /**
   * Thrown when dependencies form a cycle.
   *
   * ### Example ([live demo](http://plnkr.co/edit/wYQdNos0Tzql3ei1EV9j?p=info))
   *
   * ```typescript
   * var injector = Injector.resolveAndCreate([
   *   {provide: "one", useFactory: (two) => "two", deps: [[new Inject("two")]]},
   *   {provide: "two", useFactory: (one) => "one", deps: [[new Inject("one")]]}
   * ]);
   *
   * expect(() => injector.get("one")).toThrowError();
   * ```
   *
   * Retrieving `A` or `B` throws a `CyclicDependencyError` as the graph above cannot be constructed.
   * @param {?} injector
   * @param {?} key
   * @return {?}
   */
  function cyclicDependencyError(injector, key) {
      return injectionError(injector, key, function (keys) {
          return "Cannot instantiate cyclic dependency!" + constructResolvingPath(keys);
      });
  }
  /**
   * Thrown when a constructing type returns with an Error.
   *
   * The `InstantiationError` class contains the original error plus the dependency graph which caused
   * this object to be instantiated.
   *
   * ### Example ([live demo](http://plnkr.co/edit/7aWYdcqTQsP0eNqEdUAf?p=preview))
   *
   * ```typescript
   * class A {
   *   constructor() {
   *     throw new Error('message');
   *   }
   * }
   *
   * var injector = Injector.resolveAndCreate([A]);
   * try {
   *   injector.get(A);
   * } catch (e) {
   *   expect(e instanceof InstantiationError).toBe(true);
   *   expect(e.originalException.message).toEqual("message");
   *   expect(e.originalStack).toBeDefined();
   * }
   * ```
   * @param {?} injector
   * @param {?} originalException
   * @param {?} originalStack
   * @param {?} key
   * @return {?}
   */
  function instantiationError(injector, originalException, originalStack, key) {
      return injectionError(injector, key, function (keys) {
          var /** @type {?} */ first = stringify(keys[0].token);
          return originalException.message + ": Error during instantiation of " + first + "!" + constructResolvingPath(keys) + ".";
      }, originalException);
  }
  /**
   * Thrown when an object other then {\@link Provider} (or `Type`) is passed to {\@link Injector}
   * creation.
   *
   * ### Example ([live demo](http://plnkr.co/edit/YatCFbPAMCL0JSSQ4mvH?p=preview))
   *
   * ```typescript
   * expect(() => Injector.resolveAndCreate(["not a type"])).toThrowError();
   * ```
   * @param {?} provider
   * @return {?}
   */
  function invalidProviderError(provider) {
      return Error("Invalid provider - only instances of Provider and Type are allowed, got: " + provider);
  }
  /**
   * Thrown when the class has no annotation information.
   *
   * Lack of annotation information prevents the {\@link Injector} from determining which dependencies
   * need to be injected into the constructor.
   *
   * ### Example ([live demo](http://plnkr.co/edit/rHnZtlNS7vJOPQ6pcVkm?p=preview))
   *
   * ```typescript
   * class A {
   *   constructor(b) {}
   * }
   *
   * expect(() => Injector.resolveAndCreate([A])).toThrowError();
   * ```
   *
   * This error is also thrown when the class not marked with {\@link Injectable} has parameter types.
   *
   * ```typescript
   * class B {}
   *
   * class A {
   *   constructor(b:B) {} // no information about the parameter types of A is available at runtime.
   * }
   *
   * expect(() => Injector.resolveAndCreate([A,B])).toThrowError();
   * ```
   * \@stable
   * @param {?} typeOrFunc
   * @param {?} params
   * @return {?}
   */
  function noAnnotationError(typeOrFunc, params) {
      var /** @type {?} */ signature = [];
      for (var /** @type {?} */ i = 0, /** @type {?} */ ii = params.length; i < ii; i++) {
          var /** @type {?} */ parameter = params[i];
          if (!parameter || parameter.length == 0) {
              signature.push('?');
          }
          else {
              signature.push(parameter.map(stringify).join(' '));
          }
      }
      return Error('Cannot resolve all parameters for \'' + stringify(typeOrFunc) + '\'(' +
          signature.join(', ') + '). ' +
          'Make sure that all the parameters are decorated with Inject or have valid type annotations and that \'' +
          stringify(typeOrFunc) + '\' is decorated with Injectable.');
  }
  /**
   * Thrown when getting an object by index.
   *
   * ### Example ([live demo](http://plnkr.co/edit/bRs0SX2OTQiJzqvjgl8P?p=preview))
   *
   * ```typescript
   * class A {}
   *
   * var injector = Injector.resolveAndCreate([A]);
   *
   * expect(() => injector.getAt(100)).toThrowError();
   * ```
   * \@stable
   * @param {?} index
   * @return {?}
   */
  function outOfBoundsError(index) {
      return Error("Index " + index + " is out-of-bounds.");
  }
  /**
   * Thrown when a multi provider and a regular provider are bound to the same token.
   *
   * ### Example
   *
   * ```typescript
   * expect(() => Injector.resolveAndCreate([
   *   { provide: "Strings", useValue: "string1", multi: true},
   *   { provide: "Strings", useValue: "string2", multi: false}
   * ])).toThrowError();
   * ```
   * @param {?} provider1
   * @param {?} provider2
   * @return {?}
   */
  function mixingMultiProvidersWithRegularProvidersError(provider1, provider2) {
      return Error("Cannot mix multi providers and regular providers, got: " + provider1 + " " + provider2);
  }
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  /**
   * A unique object used for retrieving items from the {\@link ReflectiveInjector}.
   *
   * Keys have:
   * - a system-wide unique `id`.
   * - a `token`.
   *
   * `Key` is used internally by {\@link ReflectiveInjector} because its system-wide unique `id` allows
   * the
   * injector to store created objects in a more efficient way.
   *
   * `Key` should not be created directly. {\@link ReflectiveInjector} creates keys automatically when
   * resolving
   * providers.
   * @deprecated No replacement
   */
  var ReflectiveKey = /** @class */ (function () {
      /**
       * Private
       */
      function ReflectiveKey(token, id) {
          this.token = token;
          this.id = id;
          if (!token) {
              throw new Error('Token must be defined!');
          }
          this.displayName = stringify(this.token);
      }
      /**
       * Retrieves a `Key` for a token.
       */
      /**
       * Retrieves a `Key` for a token.
       * @param {?} token
       * @return {?}
       */
      ReflectiveKey.get = /**
       * Retrieves a `Key` for a token.
       * @param {?} token
       * @return {?}
       */
      function (token) {
          return _globalKeyRegistry.get(resolveForwardRef(token));
      };
      Object.defineProperty(ReflectiveKey, "numberOfKeys", {
          /**
           * @returns the number of keys registered in the system.
           */
          get: /**
           * @return {?} the number of keys registered in the system.
           */
          function () { return _globalKeyRegistry.numberOfKeys; },
          enumerable: true,
          configurable: true
      });
      return ReflectiveKey;
  }());
  var KeyRegistry = /** @class */ (function () {
      function KeyRegistry() {
          this._allKeys = new Map();
      }
      /**
       * @param {?} token
       * @return {?}
       */
      KeyRegistry.prototype.get = /**
       * @param {?} token
       * @return {?}
       */
      function (token) {
          if (token instanceof ReflectiveKey)
              return token;
          if (this._allKeys.has(token)) {
              return /** @type {?} */ ((this._allKeys.get(token)));
          }
          var /** @type {?} */ newKey = new ReflectiveKey(token, ReflectiveKey.numberOfKeys);
          this._allKeys.set(token, newKey);
          return newKey;
      };
      Object.defineProperty(KeyRegistry.prototype, "numberOfKeys", {
          get: /**
           * @return {?}
           */
          function () { return this._allKeys.size; },
          enumerable: true,
          configurable: true
      });
      return KeyRegistry;
  }());
  var _globalKeyRegistry = new KeyRegistry();
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  /**
   * \@whatItDoes Represents a type that a Component or other object is instances of.
   *
   * \@description
   *
   * An example of a `Type` is `MyCustomComponent` class, which in JavaScript is be represented by
   * the `MyCustomComponent` constructor function.
   *
   * \@stable
   */
  var Type = Function;
  /**
   * @param {?} v
   * @return {?}
   */
  function isType(v) {
      return typeof v === 'function';
  }
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  /**
   * Attention: These regex has to hold even if the code is minified!
   */
  var DELEGATE_CTOR = /^function\s+\S+\(\)\s*{[\s\S]+\.apply\(this,\s*arguments\)/;
  var INHERITED_CLASS = /^class\s+[A-Za-z\d$_]*\s*extends\s+[A-Za-z\d$_]+\s*{/;
  var INHERITED_CLASS_WITH_CTOR = /^class\s+[A-Za-z\d$_]*\s*extends\s+[A-Za-z\d$_]+\s*{[\s\S]*constructor\s*\(/;
  var ReflectionCapabilities = /** @class */ (function () {
      function ReflectionCapabilities(reflect) {
          this._reflect = reflect || _global['Reflect'];
      }
      /**
       * @return {?}
       */
      ReflectionCapabilities.prototype.isReflectionEnabled = /**
       * @return {?}
       */
      function () { return true; };
      /**
       * @template T
       * @param {?} t
       * @return {?}
       */
      ReflectionCapabilities.prototype.factory = /**
       * @template T
       * @param {?} t
       * @return {?}
       */
      function (t) { return function () {
          var args = [];
          for (var _i = 0; _i < arguments.length; _i++) {
              args[_i] = arguments[_i];
          }
          return new (t.bind.apply(t, [void 0].concat(args)))();
      }; };
      /** @internal */
      /**
       * \@internal
       * @param {?} paramTypes
       * @param {?} paramAnnotations
       * @return {?}
       */
      ReflectionCapabilities.prototype._zipTypesAndAnnotations = /**
       * \@internal
       * @param {?} paramTypes
       * @param {?} paramAnnotations
       * @return {?}
       */
      function (paramTypes, paramAnnotations) {
          var /** @type {?} */ result;
          if (typeof paramTypes === 'undefined') {
              result = new Array(paramAnnotations.length);
          }
          else {
              result = new Array(paramTypes.length);
          }
          for (var /** @type {?} */ i = 0; i < result.length; i++) {
              // TS outputs Object for parameters without types, while Traceur omits
              // the annotations. For now we preserve the Traceur behavior to aid
              // migration, but this can be revisited.
              if (typeof paramTypes === 'undefined') {
                  result[i] = [];
              }
              else if (paramTypes[i] != Object) {
                  result[i] = [paramTypes[i]];
              }
              else {
                  result[i] = [];
              }
              if (paramAnnotations && paramAnnotations[i] != null) {
                  result[i] = result[i].concat(paramAnnotations[i]);
              }
          }
          return result;
      };
      /**
       * @param {?} type
       * @param {?} parentCtor
       * @return {?}
       */
      ReflectionCapabilities.prototype._ownParameters = /**
       * @param {?} type
       * @param {?} parentCtor
       * @return {?}
       */
      function (type, parentCtor) {
          var /** @type {?} */ typeStr = type.toString();
          // If we have no decorators, we only have function.length as metadata.
          // In that case, to detect whether a child class declared an own constructor or not,
          // we need to look inside of that constructor to check whether it is
          // just calling the parent.
          // This also helps to work around for https://github.com/Microsoft/TypeScript/issues/12439
          // that sets 'design:paramtypes' to []
          // if a class inherits from another class but has no ctor declared itself.
          if (DELEGATE_CTOR.exec(typeStr) ||
              (INHERITED_CLASS.exec(typeStr) && !INHERITED_CLASS_WITH_CTOR.exec(typeStr))) {
              return null;
          }
          // Prefer the direct API.
          if ((/** @type {?} */ (type)).parameters && (/** @type {?} */ (type)).parameters !== parentCtor.parameters) {
              return (/** @type {?} */ (type)).parameters;
          }
          // API of tsickle for lowering decorators to properties on the class.
          var /** @type {?} */ tsickleCtorParams = (/** @type {?} */ (type)).ctorParameters;
          if (tsickleCtorParams && tsickleCtorParams !== parentCtor.ctorParameters) {
              // Newer tsickle uses a function closure
              // Retain the non-function case for compatibility with older tsickle
              var /** @type {?} */ ctorParameters = typeof tsickleCtorParams === 'function' ? tsickleCtorParams() : tsickleCtorParams;
              var /** @type {?} */ paramTypes_1 = ctorParameters.map(function (ctorParam) { return ctorParam && ctorParam.type; });
              var /** @type {?} */ paramAnnotations_1 = ctorParameters.map(function (ctorParam) {
                  return ctorParam && convertTsickleDecoratorIntoMetadata(ctorParam.decorators);
              });
              return this._zipTypesAndAnnotations(paramTypes_1, paramAnnotations_1);
          }
          // API for metadata created by invoking the decorators.
          var /** @type {?} */ paramAnnotations = type.hasOwnProperty(PARAMETERS) && (/** @type {?} */ (type))[PARAMETERS];
          var /** @type {?} */ paramTypes = this._reflect && this._reflect.getOwnMetadata &&
              this._reflect.getOwnMetadata('design:paramtypes', type);
          if (paramTypes || paramAnnotations) {
              return this._zipTypesAndAnnotations(paramTypes, paramAnnotations);
          }
          // If a class has no decorators, at least create metadata
          // based on function.length.
          // Note: We know that this is a real constructor as we checked
          // the content of the constructor above.
          return new Array((/** @type {?} */ (type.length))).fill(undefined);
      };
      /**
       * @param {?} type
       * @return {?}
       */
      ReflectionCapabilities.prototype.parameters = /**
       * @param {?} type
       * @return {?}
       */
      function (type) {
          // Note: only report metadata if we have at least one class decorator
          // to stay in sync with the static reflector.
          if (!isType(type)) {
              return [];
          }
          var /** @type {?} */ parentCtor = getParentCtor(type);
          var /** @type {?} */ parameters = this._ownParameters(type, parentCtor);
          if (!parameters && parentCtor !== Object) {
              parameters = this.parameters(parentCtor);
          }
          return parameters || [];
      };
      /**
       * @param {?} typeOrFunc
       * @param {?} parentCtor
       * @return {?}
       */
      ReflectionCapabilities.prototype._ownAnnotations = /**
       * @param {?} typeOrFunc
       * @param {?} parentCtor
       * @return {?}
       */
      function (typeOrFunc, parentCtor) {
          // Prefer the direct API.
          if ((/** @type {?} */ (typeOrFunc)).annotations && (/** @type {?} */ (typeOrFunc)).annotations !== parentCtor.annotations) {
              var /** @type {?} */ annotations = (/** @type {?} */ (typeOrFunc)).annotations;
              if (typeof annotations === 'function' && annotations.annotations) {
                  annotations = annotations.annotations;
              }
              return annotations;
          }
          // API of tsickle for lowering decorators to properties on the class.
          if ((/** @type {?} */ (typeOrFunc)).decorators && (/** @type {?} */ (typeOrFunc)).decorators !== parentCtor.decorators) {
              return convertTsickleDecoratorIntoMetadata((/** @type {?} */ (typeOrFunc)).decorators);
          }
          // API for metadata created by invoking the decorators.
          if (typeOrFunc.hasOwnProperty(ANNOTATIONS)) {
              return (/** @type {?} */ (typeOrFunc))[ANNOTATIONS];
          }
          return null;
      };
      /**
       * @param {?} typeOrFunc
       * @return {?}
       */
      ReflectionCapabilities.prototype.annotations = /**
       * @param {?} typeOrFunc
       * @return {?}
       */
      function (typeOrFunc) {
          if (!isType(typeOrFunc)) {
              return [];
          }
          var /** @type {?} */ parentCtor = getParentCtor(typeOrFunc);
          var /** @type {?} */ ownAnnotations = this._ownAnnotations(typeOrFunc, parentCtor) || [];
          var /** @type {?} */ parentAnnotations = parentCtor !== Object ? this.annotations(parentCtor) : [];
          return parentAnnotations.concat(ownAnnotations);
      };
      /**
       * @param {?} typeOrFunc
       * @param {?} parentCtor
       * @return {?}
       */
      ReflectionCapabilities.prototype._ownPropMetadata = /**
       * @param {?} typeOrFunc
       * @param {?} parentCtor
       * @return {?}
       */
      function (typeOrFunc, parentCtor) {
          // Prefer the direct API.
          if ((/** @type {?} */ (typeOrFunc)).propMetadata &&
              (/** @type {?} */ (typeOrFunc)).propMetadata !== parentCtor.propMetadata) {
              var /** @type {?} */ propMetadata = (/** @type {?} */ (typeOrFunc)).propMetadata;
              if (typeof propMetadata === 'function' && propMetadata.propMetadata) {
                  propMetadata = propMetadata.propMetadata;
              }
              return propMetadata;
          }
          // API of tsickle for lowering decorators to properties on the class.
          if ((/** @type {?} */ (typeOrFunc)).propDecorators &&
              (/** @type {?} */ (typeOrFunc)).propDecorators !== parentCtor.propDecorators) {
              var /** @type {?} */ propDecorators_1 = (/** @type {?} */ (typeOrFunc)).propDecorators;
              var /** @type {?} */ propMetadata_1 = /** @type {?} */ ({});
              Object.keys(propDecorators_1).forEach(function (prop) {
                  propMetadata_1[prop] = convertTsickleDecoratorIntoMetadata(propDecorators_1[prop]);
              });
              return propMetadata_1;
          }
          // API for metadata created by invoking the decorators.
          if (typeOrFunc.hasOwnProperty(PROP_METADATA)) {
              return (/** @type {?} */ (typeOrFunc))[PROP_METADATA];
          }
          return null;
      };
      /**
       * @param {?} typeOrFunc
       * @return {?}
       */
      ReflectionCapabilities.prototype.propMetadata = /**
       * @param {?} typeOrFunc
       * @return {?}
       */
      function (typeOrFunc) {
          if (!isType(typeOrFunc)) {
              return {};
          }
          var /** @type {?} */ parentCtor = getParentCtor(typeOrFunc);
          var /** @type {?} */ propMetadata = {};
          if (parentCtor !== Object) {
              var /** @type {?} */ parentPropMetadata_1 = this.propMetadata(parentCtor);
              Object.keys(parentPropMetadata_1).forEach(function (propName) {
                  propMetadata[propName] = parentPropMetadata_1[propName];
              });
          }
          var /** @type {?} */ ownPropMetadata = this._ownPropMetadata(typeOrFunc, parentCtor);
          if (ownPropMetadata) {
              Object.keys(ownPropMetadata).forEach(function (propName) {
                  var /** @type {?} */ decorators = [];
                  if (propMetadata.hasOwnProperty(propName)) {
                      decorators.push.apply(decorators, propMetadata[propName]);
                  }
                  decorators.push.apply(decorators, ownPropMetadata[propName]);
                  propMetadata[propName] = decorators;
              });
          }
          return propMetadata;
      };
      /**
       * @param {?} type
       * @param {?} lcProperty
       * @return {?}
       */
      ReflectionCapabilities.prototype.hasLifecycleHook = /**
       * @param {?} type
       * @param {?} lcProperty
       * @return {?}
       */
      function (type, lcProperty) {
          return type instanceof Type && lcProperty in type.prototype;
      };
      /**
       * @param {?} type
       * @return {?}
       */
      ReflectionCapabilities.prototype.guards = /**
       * @param {?} type
       * @return {?}
       */
      function (type) { return {}; };
      /**
       * @param {?} name
       * @return {?}
       */
      ReflectionCapabilities.prototype.getter = /**
       * @param {?} name
       * @return {?}
       */
      function (name) { return /** @type {?} */ (new Function('o', 'return o.' + name + ';')); };
      /**
       * @param {?} name
       * @return {?}
       */
      ReflectionCapabilities.prototype.setter = /**
       * @param {?} name
       * @return {?}
       */
      function (name) {
          return /** @type {?} */ (new Function('o', 'v', 'return o.' + name + ' = v;'));
      };
      /**
       * @param {?} name
       * @return {?}
       */
      ReflectionCapabilities.prototype.method = /**
       * @param {?} name
       * @return {?}
       */
      function (name) {
          var /** @type {?} */ functionBody = "if (!o." + name + ") throw new Error('\"" + name + "\" is undefined');\n        return o." + name + ".apply(o, args);";
          return /** @type {?} */ (new Function('o', 'args', functionBody));
      };
      // There is not a concept of import uri in Js, but this is useful in developing Dart applications.
      /**
       * @param {?} type
       * @return {?}
       */
      ReflectionCapabilities.prototype.importUri = /**
       * @param {?} type
       * @return {?}
       */
      function (type) {
          // StaticSymbol
          if (typeof type === 'object' && type['filePath']) {
              return type['filePath'];
          }
          // Runtime type
          return "./" + stringify(type);
      };
      /**
       * @param {?} type
       * @return {?}
       */
      ReflectionCapabilities.prototype.resourceUri = /**
       * @param {?} type
       * @return {?}
       */
      function (type) { return "./" + stringify(type); };
      /**
       * @param {?} name
       * @param {?} moduleUrl
       * @param {?} members
       * @param {?} runtime
       * @return {?}
       */
      ReflectionCapabilities.prototype.resolveIdentifier = /**
       * @param {?} name
       * @param {?} moduleUrl
       * @param {?} members
       * @param {?} runtime
       * @return {?}
       */
      function (name, moduleUrl, members, runtime) {
          return runtime;
      };
      /**
       * @param {?} enumIdentifier
       * @param {?} name
       * @return {?}
       */
      ReflectionCapabilities.prototype.resolveEnum = /**
       * @param {?} enumIdentifier
       * @param {?} name
       * @return {?}
       */
      function (enumIdentifier, name) { return enumIdentifier[name]; };
      return ReflectionCapabilities;
  }());
  /**
   * @param {?} decoratorInvocations
   * @return {?}
   */
  function convertTsickleDecoratorIntoMetadata(decoratorInvocations) {
      if (!decoratorInvocations) {
          return [];
      }
      return decoratorInvocations.map(function (decoratorInvocation) {
          var /** @type {?} */ decoratorType = decoratorInvocation.type;
          var /** @type {?} */ annotationCls = decoratorType.annotationCls;
          var /** @type {?} */ annotationArgs = decoratorInvocation.args ? decoratorInvocation.args : [];
          return new (annotationCls.bind.apply(annotationCls, [void 0].concat(annotationArgs)))();
      });
  }
  /**
   * @param {?} ctor
   * @return {?}
   */
  function getParentCtor(ctor) {
      var /** @type {?} */ parentProto = ctor.prototype ? Object.getPrototypeOf(ctor.prototype) : null;
      var /** @type {?} */ parentCtor = parentProto ? parentProto.constructor : null;
      // Note: We always use `Object` as the null value
      // to simplify checking later on.
      return parentCtor || Object;
  }
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  /**
   * Provides access to reflection data about symbols. Used internally by Angular
   * to power dependency injection and compilation.
   */
  var Reflector = /** @class */ (function () {
      function Reflector(reflectionCapabilities) {
          this.reflectionCapabilities = reflectionCapabilities;
      }
      /**
       * @param {?} caps
       * @return {?}
       */
      Reflector.prototype.updateCapabilities = /**
       * @param {?} caps
       * @return {?}
       */
      function (caps) { this.reflectionCapabilities = caps; };
      /**
       * @param {?} type
       * @return {?}
       */
      Reflector.prototype.factory = /**
       * @param {?} type
       * @return {?}
       */
      function (type) { return this.reflectionCapabilities.factory(type); };
      /**
       * @param {?} typeOrFunc
       * @return {?}
       */
      Reflector.prototype.parameters = /**
       * @param {?} typeOrFunc
       * @return {?}
       */
      function (typeOrFunc) {
          return this.reflectionCapabilities.parameters(typeOrFunc);
      };
      /**
       * @param {?} typeOrFunc
       * @return {?}
       */
      Reflector.prototype.annotations = /**
       * @param {?} typeOrFunc
       * @return {?}
       */
      function (typeOrFunc) {
          return this.reflectionCapabilities.annotations(typeOrFunc);
      };
      /**
       * @param {?} typeOrFunc
       * @return {?}
       */
      Reflector.prototype.propMetadata = /**
       * @param {?} typeOrFunc
       * @return {?}
       */
      function (typeOrFunc) {
          return this.reflectionCapabilities.propMetadata(typeOrFunc);
      };
      /**
       * @param {?} type
       * @param {?} lcProperty
       * @return {?}
       */
      Reflector.prototype.hasLifecycleHook = /**
       * @param {?} type
       * @param {?} lcProperty
       * @return {?}
       */
      function (type, lcProperty) {
          return this.reflectionCapabilities.hasLifecycleHook(type, lcProperty);
      };
      /**
       * @param {?} name
       * @return {?}
       */
      Reflector.prototype.getter = /**
       * @param {?} name
       * @return {?}
       */
      function (name) { return this.reflectionCapabilities.getter(name); };
      /**
       * @param {?} name
       * @return {?}
       */
      Reflector.prototype.setter = /**
       * @param {?} name
       * @return {?}
       */
      function (name) { return this.reflectionCapabilities.setter(name); };
      /**
       * @param {?} name
       * @return {?}
       */
      Reflector.prototype.method = /**
       * @param {?} name
       * @return {?}
       */
      function (name) { return this.reflectionCapabilities.method(name); };
      /**
       * @param {?} type
       * @return {?}
       */
      Reflector.prototype.importUri = /**
       * @param {?} type
       * @return {?}
       */
      function (type) { return this.reflectionCapabilities.importUri(type); };
      /**
       * @param {?} type
       * @return {?}
       */
      Reflector.prototype.resourceUri = /**
       * @param {?} type
       * @return {?}
       */
      function (type) { return this.reflectionCapabilities.resourceUri(type); };
      /**
       * @param {?} name
       * @param {?} moduleUrl
       * @param {?} members
       * @param {?} runtime
       * @return {?}
       */
      Reflector.prototype.resolveIdentifier = /**
       * @param {?} name
       * @param {?} moduleUrl
       * @param {?} members
       * @param {?} runtime
       * @return {?}
       */
      function (name, moduleUrl, members, runtime) {
          return this.reflectionCapabilities.resolveIdentifier(name, moduleUrl, members, runtime);
      };
      /**
       * @param {?} identifier
       * @param {?} name
       * @return {?}
       */
      Reflector.prototype.resolveEnum = /**
       * @param {?} identifier
       * @param {?} name
       * @return {?}
       */
      function (identifier, name) {
          return this.reflectionCapabilities.resolveEnum(identifier, name);
      };
      return Reflector;
  }());
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  /**
   * The {\@link Reflector} used internally in Angular to access metadata
   * about symbols.
   */
  var reflector = new Reflector(new ReflectionCapabilities());
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  /**
   * `Dependency` is used by the framework to extend DI.
   * This is internal to Angular and should not be used directly.
   */
  var ReflectiveDependency = /** @class */ (function () {
      function ReflectiveDependency(key, optional, visibility) {
          this.key = key;
          this.optional = optional;
          this.visibility = visibility;
      }
      /**
       * @param {?} key
       * @return {?}
       */
      ReflectiveDependency.fromKey = /**
       * @param {?} key
       * @return {?}
       */
      function (key) {
          return new ReflectiveDependency(key, false, null);
      };
      return ReflectiveDependency;
  }());
  var _EMPTY_LIST = [];
  /**
   * An internal resolved representation of a {\@link Provider} used by the {\@link Injector}.
   *
   * It is usually created automatically by `Injector.resolveAndCreate`.
   *
   * It can be created manually, as follows:
   *
   * ### Example ([live demo](http://plnkr.co/edit/RfEnhh8kUEI0G3qsnIeT?p%3Dpreview&p=preview))
   *
   * ```typescript
   * var resolvedProviders = Injector.resolve([{ provide: 'message', useValue: 'Hello' }]);
   * var injector = Injector.fromResolvedProviders(resolvedProviders);
   *
   * expect(injector.get('message')).toEqual('Hello');
   * ```
   *
   * \@experimental
   * @record
   */
  
  var ResolvedReflectiveProvider_ = /** @class */ (function () {
      function ResolvedReflectiveProvider_(key, resolvedFactories, multiProvider) {
          this.key = key;
          this.resolvedFactories = resolvedFactories;
          this.multiProvider = multiProvider;
          this.resolvedFactory = this.resolvedFactories[0];
      }
      return ResolvedReflectiveProvider_;
  }());
  /**
   * An internal resolved representation of a factory function created by resolving {\@link
   * Provider}.
   * \@experimental
   */
  var ResolvedReflectiveFactory = /** @class */ (function () {
      function ResolvedReflectiveFactory(factory, dependencies) {
          this.factory = factory;
          this.dependencies = dependencies;
      }
      return ResolvedReflectiveFactory;
  }());
  /**
   * Resolve a single provider.
   * @param {?} provider
   * @return {?}
   */
  function resolveReflectiveFactory(provider) {
      var /** @type {?} */ factoryFn;
      var /** @type {?} */ resolvedDeps;
      if (provider.useClass) {
          var /** @type {?} */ useClass = resolveForwardRef(provider.useClass);
          factoryFn = reflector.factory(useClass);
          resolvedDeps = _dependenciesFor(useClass);
      }
      else if (provider.useExisting) {
          factoryFn = function (aliasInstance) { return aliasInstance; };
          resolvedDeps = [ReflectiveDependency.fromKey(ReflectiveKey.get(provider.useExisting))];
      }
      else if (provider.useFactory) {
          factoryFn = provider.useFactory;
          resolvedDeps = constructDependencies(provider.useFactory, provider.deps);
      }
      else {
          factoryFn = function () { return provider.useValue; };
          resolvedDeps = _EMPTY_LIST;
      }
      return new ResolvedReflectiveFactory(factoryFn, resolvedDeps);
  }
  /**
   * Converts the {\@link Provider} into {\@link ResolvedProvider}.
   *
   * {\@link Injector} internally only uses {\@link ResolvedProvider}, {\@link Provider} contains
   * convenience provider syntax.
   * @param {?} provider
   * @return {?}
   */
  function resolveReflectiveProvider(provider) {
      return new ResolvedReflectiveProvider_(ReflectiveKey.get(provider.provide), [resolveReflectiveFactory(provider)], provider.multi || false);
  }
  /**
   * Resolve a list of Providers.
   * @param {?} providers
   * @return {?}
   */
  function resolveReflectiveProviders(providers) {
      var /** @type {?} */ normalized = _normalizeProviders(providers, []);
      var /** @type {?} */ resolved = normalized.map(resolveReflectiveProvider);
      var /** @type {?} */ resolvedProviderMap = mergeResolvedReflectiveProviders(resolved, new Map());
      return Array.from(resolvedProviderMap.values());
  }
  /**
   * Merges a list of ResolvedProviders into a list where
   * each key is contained exactly once and multi providers
   * have been merged.
   * @param {?} providers
   * @param {?} normalizedProvidersMap
   * @return {?}
   */
  function mergeResolvedReflectiveProviders(providers, normalizedProvidersMap) {
      for (var /** @type {?} */ i = 0; i < providers.length; i++) {
          var /** @type {?} */ provider = providers[i];
          var /** @type {?} */ existing = normalizedProvidersMap.get(provider.key.id);
          if (existing) {
              if (provider.multiProvider !== existing.multiProvider) {
                  throw mixingMultiProvidersWithRegularProvidersError(existing, provider);
              }
              if (provider.multiProvider) {
                  for (var /** @type {?} */ j = 0; j < provider.resolvedFactories.length; j++) {
                      existing.resolvedFactories.push(provider.resolvedFactories[j]);
                  }
              }
              else {
                  normalizedProvidersMap.set(provider.key.id, provider);
              }
          }
          else {
              var /** @type {?} */ resolvedProvider = void 0;
              if (provider.multiProvider) {
                  resolvedProvider = new ResolvedReflectiveProvider_(provider.key, provider.resolvedFactories.slice(), provider.multiProvider);
              }
              else {
                  resolvedProvider = provider;
              }
              normalizedProvidersMap.set(provider.key.id, resolvedProvider);
          }
      }
      return normalizedProvidersMap;
  }
  /**
   * @param {?} providers
   * @param {?} res
   * @return {?}
   */
  function _normalizeProviders(providers, res) {
      providers.forEach(function (b) {
          if (b instanceof Type) {
              res.push({ provide: b, useClass: b });
          }
          else if (b && typeof b == 'object' && (/** @type {?} */ (b)).provide !== undefined) {
              res.push(/** @type {?} */ (b));
          }
          else if (b instanceof Array) {
              _normalizeProviders(b, res);
          }
          else {
              throw invalidProviderError(b);
          }
      });
      return res;
  }
  /**
   * @param {?} typeOrFunc
   * @param {?=} dependencies
   * @return {?}
   */
  function constructDependencies(typeOrFunc, dependencies) {
      if (!dependencies) {
          return _dependenciesFor(typeOrFunc);
      }
      else {
          var /** @type {?} */ params_1 = dependencies.map(function (t) { return [t]; });
          return dependencies.map(function (t) { return _extractToken(typeOrFunc, t, params_1); });
      }
  }
  /**
   * @param {?} typeOrFunc
   * @return {?}
   */
  function _dependenciesFor(typeOrFunc) {
      var /** @type {?} */ params = reflector.parameters(typeOrFunc);
      if (!params)
          return [];
      if (params.some(function (p) { return p == null; })) {
          throw noAnnotationError(typeOrFunc, params);
      }
      return params.map(function (p) { return _extractToken(typeOrFunc, p, params); });
  }
  /**
   * @param {?} typeOrFunc
   * @param {?} metadata
   * @param {?} params
   * @return {?}
   */
  function _extractToken(typeOrFunc, metadata, params) {
      var /** @type {?} */ token = null;
      var /** @type {?} */ optional = false;
      if (!Array.isArray(metadata)) {
          if (metadata instanceof Inject) {
              return _createDependency(metadata.token, optional, null);
          }
          else {
              return _createDependency(metadata, optional, null);
          }
      }
      var /** @type {?} */ visibility = null;
      for (var /** @type {?} */ i = 0; i < metadata.length; ++i) {
          var /** @type {?} */ paramMetadata = metadata[i];
          if (paramMetadata instanceof Type) {
              token = paramMetadata;
          }
          else if (paramMetadata instanceof Inject) {
              token = paramMetadata.token;
          }
          else if (paramMetadata instanceof Optional) {
              optional = true;
          }
          else if (paramMetadata instanceof Self || paramMetadata instanceof SkipSelf) {
              visibility = paramMetadata;
          }
          else if (paramMetadata instanceof InjectionToken) {
              token = paramMetadata;
          }
      }
      token = resolveForwardRef(token);
      if (token != null) {
          return _createDependency(token, optional, visibility);
      }
      else {
          throw noAnnotationError(typeOrFunc, params);
      }
  }
  /**
   * @param {?} token
   * @param {?} optional
   * @param {?} visibility
   * @return {?}
   */
  function _createDependency(token, optional, visibility) {
      return new ReflectiveDependency(ReflectiveKey.get(token), optional, visibility);
  }
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  // Threshold for the dynamic version
  var UNDEFINED = new Object();
  /**
   * A ReflectiveDependency injection container used for instantiating objects and resolving
   * dependencies.
   *
   * An `Injector` is a replacement for a `new` operator, which can automatically resolve the
   * constructor dependencies.
   *
   * In typical use, application code asks for the dependencies in the constructor and they are
   * resolved by the `Injector`.
   *
   * ### Example ([live demo](http://plnkr.co/edit/jzjec0?p=preview))
   *
   * The following example creates an `Injector` configured to create `Engine` and `Car`.
   *
   * ```typescript
   * \@Injectable()
   * class Engine {
   * }
   *
   * \@Injectable()
   * class Car {
   *   constructor(public engine:Engine) {}
   * }
   *
   * var injector = ReflectiveInjector.resolveAndCreate([Car, Engine]);
   * var car = injector.get(Car);
   * expect(car instanceof Car).toBe(true);
   * expect(car.engine instanceof Engine).toBe(true);
   * ```
   *
   * Notice, we don't use the `new` operator because we explicitly want to have the `Injector`
   * resolve all of the object's dependencies automatically.
   *
   * @deprecated from v5 - slow and brings in a lot of code, Use `Injector.create` instead.
   * @abstract
   */
  var ReflectiveInjector = /** @class */ (function () {
      function ReflectiveInjector() {
      }
      /**
       * Turns an array of provider definitions into an array of resolved providers.
       *
       * A resolution is a process of flattening multiple nested arrays and converting individual
       * providers into an array of {@link ResolvedReflectiveProvider}s.
       *
       * ### Example ([live demo](http://plnkr.co/edit/AiXTHi?p=preview))
       *
       * ```typescript
       * @Injectable()
       * class Engine {
       * }
       *
       * @Injectable()
       * class Car {
       *   constructor(public engine:Engine) {}
       * }
       *
       * var providers = ReflectiveInjector.resolve([Car, [[Engine]]]);
       *
       * expect(providers.length).toEqual(2);
       *
       * expect(providers[0] instanceof ResolvedReflectiveProvider).toBe(true);
       * expect(providers[0].key.displayName).toBe("Car");
       * expect(providers[0].dependencies.length).toEqual(1);
       * expect(providers[0].factory).toBeDefined();
       *
       * expect(providers[1].key.displayName).toBe("Engine");
       * });
       * ```
       *
       * See {@link ReflectiveInjector#fromResolvedProviders fromResolvedProviders} for more info.
       */
      /**
       * Turns an array of provider definitions into an array of resolved providers.
       *
       * A resolution is a process of flattening multiple nested arrays and converting individual
       * providers into an array of {\@link ResolvedReflectiveProvider}s.
       *
       * ### Example ([live demo](http://plnkr.co/edit/AiXTHi?p=preview))
       *
       * ```typescript
       * \@Injectable()
       * class Engine {
       * }
       *
       * \@Injectable()
       * class Car {
       *   constructor(public engine:Engine) {}
       * }
       *
       * var providers = ReflectiveInjector.resolve([Car, [[Engine]]]);
       *
       * expect(providers.length).toEqual(2);
       *
       * expect(providers[0] instanceof ResolvedReflectiveProvider).toBe(true);
       * expect(providers[0].key.displayName).toBe("Car");
       * expect(providers[0].dependencies.length).toEqual(1);
       * expect(providers[0].factory).toBeDefined();
       *
       * expect(providers[1].key.displayName).toBe("Engine");
       * });
       * ```
       *
       * See {\@link ReflectiveInjector#fromResolvedProviders fromResolvedProviders} for more info.
       * @param {?} providers
       * @return {?}
       */
      ReflectiveInjector.resolve = /**
       * Turns an array of provider definitions into an array of resolved providers.
       *
       * A resolution is a process of flattening multiple nested arrays and converting individual
       * providers into an array of {\@link ResolvedReflectiveProvider}s.
       *
       * ### Example ([live demo](http://plnkr.co/edit/AiXTHi?p=preview))
       *
       * ```typescript
       * \@Injectable()
       * class Engine {
       * }
       *
       * \@Injectable()
       * class Car {
       *   constructor(public engine:Engine) {}
       * }
       *
       * var providers = ReflectiveInjector.resolve([Car, [[Engine]]]);
       *
       * expect(providers.length).toEqual(2);
       *
       * expect(providers[0] instanceof ResolvedReflectiveProvider).toBe(true);
       * expect(providers[0].key.displayName).toBe("Car");
       * expect(providers[0].dependencies.length).toEqual(1);
       * expect(providers[0].factory).toBeDefined();
       *
       * expect(providers[1].key.displayName).toBe("Engine");
       * });
       * ```
       *
       * See {\@link ReflectiveInjector#fromResolvedProviders fromResolvedProviders} for more info.
       * @param {?} providers
       * @return {?}
       */
      function (providers) {
          return resolveReflectiveProviders(providers);
      };
      /**
       * Resolves an array of providers and creates an injector from those providers.
       *
       * The passed-in providers can be an array of `Type`, {@link Provider},
       * or a recursive array of more providers.
       *
       * ### Example ([live demo](http://plnkr.co/edit/ePOccA?p=preview))
       *
       * ```typescript
       * @Injectable()
       * class Engine {
       * }
       *
       * @Injectable()
       * class Car {
       *   constructor(public engine:Engine) {}
       * }
       *
       * var injector = ReflectiveInjector.resolveAndCreate([Car, Engine]);
       * expect(injector.get(Car) instanceof Car).toBe(true);
       * ```
       *
       * This function is slower than the corresponding `fromResolvedProviders`
       * because it needs to resolve the passed-in providers first.
       * See {@link ReflectiveInjector#resolve resolve} and
       * {@link ReflectiveInjector#fromResolvedProviders fromResolvedProviders}.
       */
      /**
       * Resolves an array of providers and creates an injector from those providers.
       *
       * The passed-in providers can be an array of `Type`, {\@link Provider},
       * or a recursive array of more providers.
       *
       * ### Example ([live demo](http://plnkr.co/edit/ePOccA?p=preview))
       *
       * ```typescript
       * \@Injectable()
       * class Engine {
       * }
       *
       * \@Injectable()
       * class Car {
       *   constructor(public engine:Engine) {}
       * }
       *
       * var injector = ReflectiveInjector.resolveAndCreate([Car, Engine]);
       * expect(injector.get(Car) instanceof Car).toBe(true);
       * ```
       *
       * This function is slower than the corresponding `fromResolvedProviders`
       * because it needs to resolve the passed-in providers first.
       * See {\@link ReflectiveInjector#resolve resolve} and
       * {\@link ReflectiveInjector#fromResolvedProviders fromResolvedProviders}.
       * @param {?} providers
       * @param {?=} parent
       * @return {?}
       */
      ReflectiveInjector.resolveAndCreate = /**
       * Resolves an array of providers and creates an injector from those providers.
       *
       * The passed-in providers can be an array of `Type`, {\@link Provider},
       * or a recursive array of more providers.
       *
       * ### Example ([live demo](http://plnkr.co/edit/ePOccA?p=preview))
       *
       * ```typescript
       * \@Injectable()
       * class Engine {
       * }
       *
       * \@Injectable()
       * class Car {
       *   constructor(public engine:Engine) {}
       * }
       *
       * var injector = ReflectiveInjector.resolveAndCreate([Car, Engine]);
       * expect(injector.get(Car) instanceof Car).toBe(true);
       * ```
       *
       * This function is slower than the corresponding `fromResolvedProviders`
       * because it needs to resolve the passed-in providers first.
       * See {\@link ReflectiveInjector#resolve resolve} and
       * {\@link ReflectiveInjector#fromResolvedProviders fromResolvedProviders}.
       * @param {?} providers
       * @param {?=} parent
       * @return {?}
       */
      function (providers, parent) {
          var /** @type {?} */ ResolvedReflectiveProviders = ReflectiveInjector.resolve(providers);
          return ReflectiveInjector.fromResolvedProviders(ResolvedReflectiveProviders, parent);
      };
      /**
       * Creates an injector from previously resolved providers.
       *
       * This API is the recommended way to construct injectors in performance-sensitive parts.
       *
       * ### Example ([live demo](http://plnkr.co/edit/KrSMci?p=preview))
       *
       * ```typescript
       * @Injectable()
       * class Engine {
       * }
       *
       * @Injectable()
       * class Car {
       *   constructor(public engine:Engine) {}
       * }
       *
       * var providers = ReflectiveInjector.resolve([Car, Engine]);
       * var injector = ReflectiveInjector.fromResolvedProviders(providers);
       * expect(injector.get(Car) instanceof Car).toBe(true);
       * ```
       * @experimental
       */
      /**
       * Creates an injector from previously resolved providers.
       *
       * This API is the recommended way to construct injectors in performance-sensitive parts.
       *
       * ### Example ([live demo](http://plnkr.co/edit/KrSMci?p=preview))
       *
       * ```typescript
       * \@Injectable()
       * class Engine {
       * }
       *
       * \@Injectable()
       * class Car {
       *   constructor(public engine:Engine) {}
       * }
       *
       * var providers = ReflectiveInjector.resolve([Car, Engine]);
       * var injector = ReflectiveInjector.fromResolvedProviders(providers);
       * expect(injector.get(Car) instanceof Car).toBe(true);
       * ```
       * \@experimental
       * @param {?} providers
       * @param {?=} parent
       * @return {?}
       */
      ReflectiveInjector.fromResolvedProviders = /**
       * Creates an injector from previously resolved providers.
       *
       * This API is the recommended way to construct injectors in performance-sensitive parts.
       *
       * ### Example ([live demo](http://plnkr.co/edit/KrSMci?p=preview))
       *
       * ```typescript
       * \@Injectable()
       * class Engine {
       * }
       *
       * \@Injectable()
       * class Car {
       *   constructor(public engine:Engine) {}
       * }
       *
       * var providers = ReflectiveInjector.resolve([Car, Engine]);
       * var injector = ReflectiveInjector.fromResolvedProviders(providers);
       * expect(injector.get(Car) instanceof Car).toBe(true);
       * ```
       * \@experimental
       * @param {?} providers
       * @param {?=} parent
       * @return {?}
       */
      function (providers, parent) {
          return new ReflectiveInjector_(providers, parent);
      };
      return ReflectiveInjector;
  }());
  var ReflectiveInjector_ = /** @class */ (function () {
      /**
       * Private
       */
      function ReflectiveInjector_(_providers, _parent) {
          /**
           * \@internal
           */
          this._constructionCounter = 0;
          this._providers = _providers;
          this.parent = _parent || null;
          var /** @type {?} */ len = _providers.length;
          this.keyIds = new Array(len);
          this.objs = new Array(len);
          for (var /** @type {?} */ i = 0; i < len; i++) {
              this.keyIds[i] = _providers[i].key.id;
              this.objs[i] = UNDEFINED;
          }
      }
      /**
       * @param {?} token
       * @param {?=} notFoundValue
       * @return {?}
       */
      ReflectiveInjector_.prototype.get = /**
       * @param {?} token
       * @param {?=} notFoundValue
       * @return {?}
       */
      function (token, notFoundValue) {
          if (notFoundValue === void 0) { notFoundValue = THROW_IF_NOT_FOUND; }
          return this._getByKey(ReflectiveKey.get(token), null, notFoundValue);
      };
      /**
       * @param {?} providers
       * @return {?}
       */
      ReflectiveInjector_.prototype.resolveAndCreateChild = /**
       * @param {?} providers
       * @return {?}
       */
      function (providers) {
          var /** @type {?} */ ResolvedReflectiveProviders = ReflectiveInjector.resolve(providers);
          return this.createChildFromResolved(ResolvedReflectiveProviders);
      };
      /**
       * @param {?} providers
       * @return {?}
       */
      ReflectiveInjector_.prototype.createChildFromResolved = /**
       * @param {?} providers
       * @return {?}
       */
      function (providers) {
          var /** @type {?} */ inj = new ReflectiveInjector_(providers);
          (/** @type {?} */ (inj)).parent = this;
          return inj;
      };
      /**
       * @param {?} provider
       * @return {?}
       */
      ReflectiveInjector_.prototype.resolveAndInstantiate = /**
       * @param {?} provider
       * @return {?}
       */
      function (provider) {
          return this.instantiateResolved(ReflectiveInjector.resolve([provider])[0]);
      };
      /**
       * @param {?} provider
       * @return {?}
       */
      ReflectiveInjector_.prototype.instantiateResolved = /**
       * @param {?} provider
       * @return {?}
       */
      function (provider) {
          return this._instantiateProvider(provider);
      };
      /**
       * @param {?} index
       * @return {?}
       */
      ReflectiveInjector_.prototype.getProviderAtIndex = /**
       * @param {?} index
       * @return {?}
       */
      function (index) {
          if (index < 0 || index >= this._providers.length) {
              throw outOfBoundsError(index);
          }
          return this._providers[index];
      };
      /** @internal */
      /**
       * \@internal
       * @param {?} provider
       * @return {?}
       */
      ReflectiveInjector_.prototype._new = /**
       * \@internal
       * @param {?} provider
       * @return {?}
       */
      function (provider) {
          if (this._constructionCounter++ > this._getMaxNumberOfObjects()) {
              throw cyclicDependencyError(this, provider.key);
          }
          return this._instantiateProvider(provider);
      };
      /**
       * @return {?}
       */
      ReflectiveInjector_.prototype._getMaxNumberOfObjects = /**
       * @return {?}
       */
      function () { return this.objs.length; };
      /**
       * @param {?} provider
       * @return {?}
       */
      ReflectiveInjector_.prototype._instantiateProvider = /**
       * @param {?} provider
       * @return {?}
       */
      function (provider) {
          if (provider.multiProvider) {
              var /** @type {?} */ res = new Array(provider.resolvedFactories.length);
              for (var /** @type {?} */ i = 0; i < provider.resolvedFactories.length; ++i) {
                  res[i] = this._instantiate(provider, provider.resolvedFactories[i]);
              }
              return res;
          }
          else {
              return this._instantiate(provider, provider.resolvedFactories[0]);
          }
      };
      /**
       * @param {?} provider
       * @param {?} ResolvedReflectiveFactory
       * @return {?}
       */
      ReflectiveInjector_.prototype._instantiate = /**
       * @param {?} provider
       * @param {?} ResolvedReflectiveFactory
       * @return {?}
       */
      function (provider, ResolvedReflectiveFactory$$1) {
          var _this = this;
          var /** @type {?} */ factory = ResolvedReflectiveFactory$$1.factory;
          var /** @type {?} */ deps;
          try {
              deps =
                  ResolvedReflectiveFactory$$1.dependencies.map(function (dep) { return _this._getByReflectiveDependency(dep); });
          }
          catch (/** @type {?} */ e) {
              if (e.addKey) {
                  e.addKey(this, provider.key);
              }
              throw e;
          }
          var /** @type {?} */ obj;
          try {
              obj = factory.apply(void 0, deps);
          }
          catch (/** @type {?} */ e) {
              throw instantiationError(this, e, e.stack, provider.key);
          }
          return obj;
      };
      /**
       * @param {?} dep
       * @return {?}
       */
      ReflectiveInjector_.prototype._getByReflectiveDependency = /**
       * @param {?} dep
       * @return {?}
       */
      function (dep) {
          return this._getByKey(dep.key, dep.visibility, dep.optional ? null : THROW_IF_NOT_FOUND);
      };
      /**
       * @param {?} key
       * @param {?} visibility
       * @param {?} notFoundValue
       * @return {?}
       */
      ReflectiveInjector_.prototype._getByKey = /**
       * @param {?} key
       * @param {?} visibility
       * @param {?} notFoundValue
       * @return {?}
       */
      function (key, visibility, notFoundValue) {
          if (key === ReflectiveInjector_.INJECTOR_KEY) {
              return this;
          }
          if (visibility instanceof Self) {
              return this._getByKeySelf(key, notFoundValue);
          }
          else {
              return this._getByKeyDefault(key, notFoundValue, visibility);
          }
      };
      /**
       * @param {?} keyId
       * @return {?}
       */
      ReflectiveInjector_.prototype._getObjByKeyId = /**
       * @param {?} keyId
       * @return {?}
       */
      function (keyId) {
          for (var /** @type {?} */ i = 0; i < this.keyIds.length; i++) {
              if (this.keyIds[i] === keyId) {
                  if (this.objs[i] === UNDEFINED) {
                      this.objs[i] = this._new(this._providers[i]);
                  }
                  return this.objs[i];
              }
          }
          return UNDEFINED;
      };
      /** @internal */
      /**
       * \@internal
       * @param {?} key
       * @param {?} notFoundValue
       * @return {?}
       */
      ReflectiveInjector_.prototype._throwOrNull = /**
       * \@internal
       * @param {?} key
       * @param {?} notFoundValue
       * @return {?}
       */
      function (key, notFoundValue) {
          if (notFoundValue !== THROW_IF_NOT_FOUND) {
              return notFoundValue;
          }
          else {
              throw noProviderError(this, key);
          }
      };
      /** @internal */
      /**
       * \@internal
       * @param {?} key
       * @param {?} notFoundValue
       * @return {?}
       */
      ReflectiveInjector_.prototype._getByKeySelf = /**
       * \@internal
       * @param {?} key
       * @param {?} notFoundValue
       * @return {?}
       */
      function (key, notFoundValue) {
          var /** @type {?} */ obj = this._getObjByKeyId(key.id);
          return (obj !== UNDEFINED) ? obj : this._throwOrNull(key, notFoundValue);
      };
      /** @internal */
      /**
       * \@internal
       * @param {?} key
       * @param {?} notFoundValue
       * @param {?} visibility
       * @return {?}
       */
      ReflectiveInjector_.prototype._getByKeyDefault = /**
       * \@internal
       * @param {?} key
       * @param {?} notFoundValue
       * @param {?} visibility
       * @return {?}
       */
      function (key, notFoundValue, visibility) {
          var /** @type {?} */ inj;
          if (visibility instanceof SkipSelf) {
              inj = this.parent;
          }
          else {
              inj = this;
          }
          while (inj instanceof ReflectiveInjector_) {
              var /** @type {?} */ inj_ = /** @type {?} */ (inj);
              var /** @type {?} */ obj = inj_._getObjByKeyId(key.id);
              if (obj !== UNDEFINED)
                  return obj;
              inj = inj_.parent;
          }
          if (inj !== null) {
              return inj.get(key.token, notFoundValue);
          }
          else {
              return this._throwOrNull(key, notFoundValue);
          }
      };
      Object.defineProperty(ReflectiveInjector_.prototype, "displayName", {
          get: /**
           * @return {?}
           */
          function () {
              var /** @type {?} */ providers = _mapProviders(this, function (b) { return ' "' + b.key.displayName + '" '; })
                  .join(', ');
              return "ReflectiveInjector(providers: [" + providers + "])";
          },
          enumerable: true,
          configurable: true
      });
      /**
       * @return {?}
       */
      ReflectiveInjector_.prototype.toString = /**
       * @return {?}
       */
      function () { return this.displayName; };
      ReflectiveInjector_.INJECTOR_KEY = ReflectiveKey.get(Injector);
      return ReflectiveInjector_;
  }());
  /**
   * @param {?} injector
   * @param {?} fn
   * @return {?}
   */
  function _mapProviders(injector, fn) {
      var /** @type {?} */ res = new Array(injector._providers.length);
      for (var /** @type {?} */ i = 0; i < injector._providers.length; ++i) {
          res[i] = fn(injector.getProviderAtIndex(i));
      }
      return res;
  }
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  /**
   * @module
   * @description
   * The `di` module provides dependency injection container services.
   */
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  /**
   * Determine if the argument is shaped like a Promise
   * @param {?} obj
   * @return {?}
   */
  function isPromise(obj) {
      // allow any Promise/A+ compliant thenable.
      // It's up to the caller to ensure that obj.then conforms to the spec
      return !!obj && typeof obj.then === 'function';
  }
  /**
   * Determine if the argument is an Observable
   * @param {?} obj
   * @return {?}
   */
  function isObservable(obj) {
      // TODO use Symbol.observable when https://github.com/ReactiveX/rxjs/issues/2415 will be resolved
      return !!obj && typeof obj.subscribe === 'function';
  }
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  /**
   * A function that will be executed when an application is initialized.
   * \@experimental
   */
  var APP_INITIALIZER = new InjectionToken('Application Initializer');
  /**
   * A class that reflects the state of running {\@link APP_INITIALIZER}s.
   *
   * \@experimental
   */
  var ApplicationInitStatus = /** @class */ (function () {
      function ApplicationInitStatus(appInits) {
          var _this = this;
          this.appInits = appInits;
          this.initialized = false;
          this.done = false;
          this.donePromise = new Promise(function (res, rej) {
              _this.resolve = res;
              _this.reject = rej;
          });
      }
      /** @internal */
      /**
       * \@internal
       * @return {?}
       */
      ApplicationInitStatus.prototype.runInitializers = /**
       * \@internal
       * @return {?}
       */
      function () {
          var _this = this;
          if (this.initialized) {
              return;
          }
          var /** @type {?} */ asyncInitPromises = [];
          var /** @type {?} */ complete = function () {
              (/** @type {?} */ (_this)).done = true;
              _this.resolve();
          };
          if (this.appInits) {
              for (var /** @type {?} */ i = 0; i < this.appInits.length; i++) {
                  var /** @type {?} */ initResult = this.appInits[i]();
                  if (isPromise(initResult)) {
                      asyncInitPromises.push(initResult);
                  }
              }
          }
          Promise.all(asyncInitPromises).then(function () { complete(); }).catch(function (e) { _this.reject(e); });
          if (asyncInitPromises.length === 0) {
              complete();
          }
          this.initialized = true;
      };
      ApplicationInitStatus.decorators = [
          { type: Injectable },
      ];
      /** @nocollapse */
      ApplicationInitStatus.ctorParameters = function () { return [
          { type: Array, decorators: [{ type: Inject, args: [APP_INITIALIZER,] }, { type: Optional },] },
      ]; };
      return ApplicationInitStatus;
  }());
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  /**
   * A DI Token representing a unique string id assigned to the application by Angular and used
   * primarily for prefixing application attributes and CSS styles when
   * {\@link ViewEncapsulation#Emulated ViewEncapsulation.Emulated} is being used.
   *
   * If you need to avoid randomly generated value to be used as an application id, you can provide
   * a custom value via a DI provider <!-- TODO: provider --> configuring the root {\@link Injector}
   * using this token.
   * \@experimental
   */
  var APP_ID = new InjectionToken('AppId');
  /**
   * @return {?}
   */
  function _appIdRandomProviderFactory() {
      return "" + _randomChar() + _randomChar() + _randomChar();
  }
  /**
   * Providers that will generate a random APP_ID_TOKEN.
   * \@experimental
   */
  var APP_ID_RANDOM_PROVIDER = {
      provide: APP_ID,
      useFactory: _appIdRandomProviderFactory,
      deps: /** @type {?} */ ([]),
  };
  /**
   * @return {?}
   */
  function _randomChar() {
      return String.fromCharCode(97 + Math.floor(Math.random() * 25));
  }
  /**
   * A function that will be executed when a platform is initialized.
   * \@experimental
   */
  var PLATFORM_INITIALIZER = new InjectionToken('Platform Initializer');
  /**
   * A token that indicates an opaque platform id.
   * \@experimental
   */
  var PLATFORM_ID = new InjectionToken('Platform ID');
  /**
   * All callbacks provided via this token will be called for every component that is bootstrapped.
   * Signature of the callback:
   *
   * `(componentRef: ComponentRef) => void`.
   *
   * \@experimental
   */
  var APP_BOOTSTRAP_LISTENER = new InjectionToken('appBootstrapListener');
  /**
   * A token which indicates the root directory of the application
   * \@experimental
   */
  var PACKAGE_ROOT_URL = new InjectionToken('Application Packages Root URL');
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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 Console = /** @class */ (function () {
      function Console() {
      }
      /**
       * @param {?} message
       * @return {?}
       */
      Console.prototype.log = /**
       * @param {?} message
       * @return {?}
       */
      function (message) {
          // tslint:disable-next-line:no-console
          console.log(message);
      };
      // Note: for reporting errors use `DOM.logError()` as it is platform specific
      /**
       * @param {?} message
       * @return {?}
       */
      Console.prototype.warn = /**
       * @param {?} message
       * @return {?}
       */
      function (message) {
          // tslint:disable-next-line:no-console
          console.warn(message);
      };
      Console.decorators = [
          { type: Injectable },
      ];
      /** @nocollapse */
      Console.ctorParameters = function () { return []; };
      return Console;
  }());
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  /**
   * Combination of NgModuleFactory and ComponentFactorys.
   *
   * \@experimental
   */
  var ModuleWithComponentFactories = /** @class */ (function () {
      function ModuleWithComponentFactories(ngModuleFactory, componentFactories) {
          this.ngModuleFactory = ngModuleFactory;
          this.componentFactories = componentFactories;
      }
      return ModuleWithComponentFactories;
  }());
  /**
   * @return {?}
   */
  function _throwError() {
      throw new Error("Runtime compiler is not loaded");
  }
  /**
   * Low-level service for running the angular compiler during runtime
   * to create {\@link ComponentFactory}s, which
   * can later be used to create and render a Component instance.
   *
   * Each `\@NgModule` provides an own `Compiler` to its injector,
   * that will use the directives/pipes of the ng module for compilation
   * of components.
   * \@stable
   */
  var Compiler = /** @class */ (function () {
      function Compiler() {
      }
      /**
       * Compiles the given NgModule and all of its components. All templates of the components listed
       * in `entryComponents` have to be inlined.
       */
      /**
       * Compiles the given NgModule and all of its components. All templates of the components listed
       * in `entryComponents` have to be inlined.
       * @template T
       * @param {?} moduleType
       * @return {?}
       */
      Compiler.prototype.compileModuleSync = /**
       * Compiles the given NgModule and all of its components. All templates of the components listed
       * in `entryComponents` have to be inlined.
       * @template T
       * @param {?} moduleType
       * @return {?}
       */
      function (moduleType) { throw _throwError(); };
      /**
       * Compiles the given NgModule and all of its components
       */
      /**
       * Compiles the given NgModule and all of its components
       * @template T
       * @param {?} moduleType
       * @return {?}
       */
      Compiler.prototype.compileModuleAsync = /**
       * Compiles the given NgModule and all of its components
       * @template T
       * @param {?} moduleType
       * @return {?}
       */
      function (moduleType) { throw _throwError(); };
      /**
       * Same as {@link #compileModuleSync} but also creates ComponentFactories for all components.
       */
      /**
       * Same as {\@link #compileModuleSync} but also creates ComponentFactories for all components.
       * @template T
       * @param {?} moduleType
       * @return {?}
       */
      Compiler.prototype.compileModuleAndAllComponentsSync = /**
       * Same as {\@link #compileModuleSync} but also creates ComponentFactories for all components.
       * @template T
       * @param {?} moduleType
       * @return {?}
       */
      function (moduleType) {
          throw _throwError();
      };
      /**
       * Same as {@link #compileModuleAsync} but also creates ComponentFactories for all components.
       */
      /**
       * Same as {\@link #compileModuleAsync} but also creates ComponentFactories for all components.
       * @template T
       * @param {?} moduleType
       * @return {?}
       */
      Compiler.prototype.compileModuleAndAllComponentsAsync = /**
       * Same as {\@link #compileModuleAsync} but also creates ComponentFactories for all components.
       * @template T
       * @param {?} moduleType
       * @return {?}
       */
      function (moduleType) {
          throw _throwError();
      };
      /**
       * Clears all caches.
       */
      /**
       * Clears all caches.
       * @return {?}
       */
      Compiler.prototype.clearCache = /**
       * Clears all caches.
       * @return {?}
       */
      function () { };
      /**
       * Clears the cache for the given component/ngModule.
       */
      /**
       * Clears the cache for the given component/ngModule.
       * @param {?} type
       * @return {?}
       */
      Compiler.prototype.clearCacheFor = /**
       * Clears the cache for the given component/ngModule.
       * @param {?} type
       * @return {?}
       */
      function (type) { };
      Compiler.decorators = [
          { type: Injectable },
      ];
      /** @nocollapse */
      Compiler.ctorParameters = function () { return []; };
      return Compiler;
  }());
  /**
   * Token to provide CompilerOptions in the platform injector.
   *
   * \@experimental
   */
  var COMPILER_OPTIONS = new InjectionToken('compilerOptions');
  /**
   * A factory for creating a Compiler
   *
   * \@experimental
   * @abstract
   */
  var CompilerFactory = /** @class */ (function () {
      function CompilerFactory() {
      }
      return CompilerFactory;
  }());
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  /**
   * Represents an instance of a Component created via a {\@link ComponentFactory}.
   *
   * `ComponentRef` provides access to the Component Instance as well other objects related to this
   * Component Instance and allows you to destroy the Component Instance via the {\@link #destroy}
   * method.
   * \@stable
   * @abstract
   */
  var ComponentRef = /** @class */ (function () {
      function ComponentRef() {
      }
      return ComponentRef;
  }());
  /**
   * \@stable
   * @abstract
   */
  var ComponentFactory = /** @class */ (function () {
      function ComponentFactory() {
      }
      return ComponentFactory;
  }());
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  /**
   * @param {?} component
   * @return {?}
   */
  function noComponentFactoryError(component) {
      var /** @type {?} */ error = Error("No component factory found for " + stringify(component) + ". Did you add it to @NgModule.entryComponents?");
      (/** @type {?} */ (error))[ERROR_COMPONENT] = component;
      return error;
  }
  var ERROR_COMPONENT = 'ngComponent';
  /**
   * @param {?} error
   * @return {?}
   */
  
  var _NullComponentFactoryResolver = /** @class */ (function () {
      function _NullComponentFactoryResolver() {
      }
      /**
       * @template T
       * @param {?} component
       * @return {?}
       */
      _NullComponentFactoryResolver.prototype.resolveComponentFactory = /**
       * @template T
       * @param {?} component
       * @return {?}
       */
      function (component) {
          throw noComponentFactoryError(component);
      };
      return _NullComponentFactoryResolver;
  }());
  /**
   * \@stable
   * @abstract
   */
  var ComponentFactoryResolver = /** @class */ (function () {
      function ComponentFactoryResolver() {
      }
      ComponentFactoryResolver.NULL = new _NullComponentFactoryResolver();
      return ComponentFactoryResolver;
  }());
  var CodegenComponentFactoryResolver = /** @class */ (function () {
      function CodegenComponentFactoryResolver(factories, _parent, _ngModule) {
          this._parent = _parent;
          this._ngModule = _ngModule;
          this._factories = new Map();
          for (var /** @type {?} */ i = 0; i < factories.length; i++) {
              var /** @type {?} */ factory = factories[i];
              this._factories.set(factory.componentType, factory);
          }
      }
      /**
       * @template T
       * @param {?} component
       * @return {?}
       */
      CodegenComponentFactoryResolver.prototype.resolveComponentFactory = /**
       * @template T
       * @param {?} component
       * @return {?}
       */
      function (component) {
          var /** @type {?} */ factory = this._factories.get(component);
          if (!factory && this._parent) {
              factory = this._parent.resolveComponentFactory(component);
          }
          if (!factory) {
              throw noComponentFactoryError(component);
          }
          return new ComponentFactoryBoundToModule(factory, this._ngModule);
      };
      return CodegenComponentFactoryResolver;
  }());
  var ComponentFactoryBoundToModule = /** @class */ (function (_super) {
      __extends(ComponentFactoryBoundToModule, _super);
      function ComponentFactoryBoundToModule(factory, ngModule) {
          var _this = _super.call(this) || this;
          _this.factory = factory;
          _this.ngModule = ngModule;
          _this.selector = factory.selector;
          _this.componentType = factory.componentType;
          _this.ngContentSelectors = factory.ngContentSelectors;
          _this.inputs = factory.inputs;
          _this.outputs = factory.outputs;
          return _this;
      }
      /**
       * @param {?} injector
       * @param {?=} projectableNodes
       * @param {?=} rootSelectorOrNode
       * @param {?=} ngModule
       * @return {?}
       */
      ComponentFactoryBoundToModule.prototype.create = /**
       * @param {?} injector
       * @param {?=} projectableNodes
       * @param {?=} rootSelectorOrNode
       * @param {?=} ngModule
       * @return {?}
       */
      function (injector, projectableNodes, rootSelectorOrNode, ngModule) {
          return this.factory.create(injector, projectableNodes, rootSelectorOrNode, ngModule || this.ngModule);
      };
      return ComponentFactoryBoundToModule;
  }(ComponentFactory));
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  /**
   * Represents an instance of an NgModule created via a {\@link NgModuleFactory}.
   *
   * `NgModuleRef` provides access to the NgModule Instance as well other objects related to this
   * NgModule Instance.
   *
   * \@stable
   * @abstract
   */
  var NgModuleRef = /** @class */ (function () {
      function NgModuleRef() {
      }
      return NgModuleRef;
  }());
  /**
   * @record
   */
  
  /**
   * \@experimental
   * @abstract
   */
  var NgModuleFactory = /** @class */ (function () {
      function NgModuleFactory() {
      }
      return NgModuleFactory;
  }());
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  /**
   * A scope function for the Web Tracing Framework (WTF).
   *
   * \@experimental
   * @record
   */
  
  /**
   * @record
   */
  
  /**
   * @record
   */
  
  var trace;
  var events;
  /**
   * @return {?}
   */
  function detectWTF() {
      var /** @type {?} */ wtf = (/** @type {?} */ (_global /** TODO #9100 */) /** TODO #9100 */)['wtf'];
      if (wtf) {
          trace = wtf['trace'];
          if (trace) {
              events = trace['events'];
              return true;
          }
      }
      return false;
  }
  /**
   * @param {?} signature
   * @param {?=} flags
   * @return {?}
   */
  function createScope(signature, flags) {
      if (flags === void 0) { flags = null; }
      return events.createScope(signature, flags);
  }
  /**
   * @template T
   * @param {?} scope
   * @param {?=} returnValue
   * @return {?}
   */
  function leave(scope, returnValue) {
      trace.leaveScope(scope, returnValue);
      return returnValue;
  }
  /**
   * @param {?} rangeType
   * @param {?} action
   * @return {?}
   */
  function startTimeRange(rangeType, action) {
      return trace.beginTimeRange(rangeType, action);
  }
  /**
   * @param {?} range
   * @return {?}
   */
  function endTimeRange(range) {
      trace.endTimeRange(range);
  }
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  /**
   * True if WTF is enabled.
   */
  var wtfEnabled = detectWTF();
  /**
   * @param {?=} arg0
   * @param {?=} arg1
   * @return {?}
   */
  function noopScope(arg0, arg1) {
      return null;
  }
  /**
   * Create trace scope.
   *
   * Scopes must be strictly nested and are analogous to stack frames, but
   * do not have to follow the stack frames. Instead it is recommended that they follow logical
   * nesting. You may want to use
   * [Event
   * Signatures](http://google.github.io/tracing-framework/instrumenting-code.html#custom-events)
   * as they are defined in WTF.
   *
   * Used to mark scope entry. The return value is used to leave the scope.
   *
   *     var myScope = wtfCreateScope('MyClass#myMethod(ascii someVal)');
   *
   *     someMethod() {
   *        var s = myScope('Foo'); // 'Foo' gets stored in tracing UI
   *        // DO SOME WORK HERE
   *        return wtfLeave(s, 123); // Return value 123
   *     }
   *
   * Note, adding try-finally block around the work to ensure that `wtfLeave` gets called can
   * negatively impact the performance of your application. For this reason we recommend that
   * you don't add them to ensure that `wtfLeave` gets called. In production `wtfLeave` is a noop and
   * so try-finally block has no value. When debugging perf issues, skipping `wtfLeave`, do to
   * exception, will produce incorrect trace, but presence of exception signifies logic error which
   * needs to be fixed before the app should be profiled. Add try-finally only when you expect that
   * an exception is expected during normal execution while profiling.
   *
   * \@experimental
   */
  var wtfCreateScope = wtfEnabled ? createScope : function (signature, flags) { return noopScope; };
  /**
   * Used to mark end of Scope.
   *
   * - `scope` to end.
   * - `returnValue` (optional) to be passed to the WTF.
   *
   * Returns the `returnValue for easy chaining.
   * \@experimental
   */
  var wtfLeave = wtfEnabled ? leave : function (s, r) { return r; };
  /**
   * Used to mark Async start. Async are similar to scope but they don't have to be strictly nested.
   * The return value is used in the call to [endAsync]. Async ranges only work if WTF has been
   * enabled.
   *
   *     someMethod() {
   *        var s = wtfStartTimeRange('HTTP:GET', 'some.url');
   *        var future = new Future.delay(5).then((_) {
   *          wtfEndTimeRange(s);
   *        });
   *     }
   * \@experimental
   */
  var wtfStartTimeRange = wtfEnabled ? startTimeRange : function (rangeType, action) { return null; };
  /**
   * Ends a async time range operation.
   * [range] is the return value from [wtfStartTimeRange] Async ranges only work if WTF has been
   * enabled.
   * \@experimental
   */
  var wtfEndTimeRange = wtfEnabled ? endTimeRange : function (r) { return null; };
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  /**
   * Use by directives and components to emit custom Events.
   *
   * ### Examples
   *
   * In the following example, `Zippy` alternatively emits `open` and `close` events when its
   * title gets clicked:
   *
   * ```
   * \@Component({
   *   selector: 'zippy',
   *   template: `
   *   <div class="zippy">
   *     <div (click)="toggle()">Toggle</div>
   *     <div [hidden]="!visible">
   *       <ng-content></ng-content>
   *     </div>
   *  </div>`})
   * export class Zippy {
   *   visible: boolean = true;
   *   \@Output() open: EventEmitter<any> = new EventEmitter();
   *   \@Output() close: EventEmitter<any> = new EventEmitter();
   *
   *   toggle() {
   *     this.visible = !this.visible;
   *     if (this.visible) {
   *       this.open.emit(null);
   *     } else {
   *       this.close.emit(null);
   *     }
   *   }
   * }
   * ```
   *
   * The events payload can be accessed by the parameter `$event` on the components output event
   * handler:
   *
   * ```
   * <zippy (open)="onOpen($event)" (close)="onClose($event)"></zippy>
   * ```
   *
   * Uses Rx.Observable but provides an adapter to make it work as specified here:
   * https://github.com/jhusain/observable-spec
   *
   * Once a reference implementation of the spec is available, switch to it.
   * \@stable
   */
  var EventEmitter = /** @class */ (function (_super) {
      __extends(EventEmitter, _super);
      /**
       * Creates an instance of {@link EventEmitter}, which depending on `isAsync`,
       * delivers events synchronously or asynchronously.
       *
       * @param isAsync By default, events are delivered synchronously (default value: `false`).
       * Set to `true` for asynchronous event delivery.
       */
      function EventEmitter(isAsync) {
          if (isAsync === void 0) { isAsync = false; }
          var _this = _super.call(this) || this;
          _this.__isAsync = isAsync;
          return _this;
      }
      /**
       * @param {?=} value
       * @return {?}
       */
      EventEmitter.prototype.emit = /**
       * @param {?=} value
       * @return {?}
       */
      function (value) { _super.prototype.next.call(this, value); };
      /**
       * @param {?=} generatorOrNext
       * @param {?=} error
       * @param {?=} complete
       * @return {?}
       */
      EventEmitter.prototype.subscribe = /**
       * @param {?=} generatorOrNext
       * @param {?=} error
       * @param {?=} complete
       * @return {?}
       */
      function (generatorOrNext, error, complete) {
          var /** @type {?} */ schedulerFn;
          var /** @type {?} */ errorFn = function (err) { return null; };
          var /** @type {?} */ completeFn = function () { return null; };
          if (generatorOrNext && typeof generatorOrNext === 'object') {
              schedulerFn = this.__isAsync ? function (value) {
                  setTimeout(function () { return generatorOrNext.next(value); });
              } : function (value) { generatorOrNext.next(value); };
              if (generatorOrNext.error) {
                  errorFn = this.__isAsync ? function (err) { setTimeout(function () { return generatorOrNext.error(err); }); } :
                      function (err) { generatorOrNext.error(err); };
              }
              if (generatorOrNext.complete) {
                  completeFn = this.__isAsync ? function () { setTimeout(function () { return generatorOrNext.complete(); }); } :
                      function () { generatorOrNext.complete(); };
              }
          }
          else {
              schedulerFn = this.__isAsync ? function (value) { setTimeout(function () { return generatorOrNext(value); }); } :
                  function (value) { generatorOrNext(value); };
              if (error) {
                  errorFn =
                      this.__isAsync ? function (err) { setTimeout(function () { return error(err); }); } : function (err) { error(err); };
              }
              if (complete) {
                  completeFn =
                      this.__isAsync ? function () { setTimeout(function () { return complete(); }); } : function () { complete(); };
              }
          }
          var /** @type {?} */ sink = _super.prototype.subscribe.call(this, schedulerFn, errorFn, completeFn);
          if (generatorOrNext instanceof rxjs_Subscription.Subscription) {
              generatorOrNext.add(sink);
          }
          return sink;
      };
      return EventEmitter;
  }(rxjs_Subject.Subject));
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  /**
   * An injectable service for executing work inside or outside of the Angular zone.
   *
   * The most common use of this service is to optimize performance when starting a work consisting of
   * one or more asynchronous tasks that don't require UI updates or error handling to be handled by
   * Angular. Such tasks can be kicked off via {\@link #runOutsideAngular} and if needed, these tasks
   * can reenter the Angular zone via {\@link #run}.
   *
   * <!-- TODO: add/fix links to:
   *   - docs explaining zones and the use of zones in Angular and change-detection
   *   - link to runOutsideAngular/run (throughout this file!)
   *   -->
   *
   * ### Example
   *
   * ```
   * import {Component, NgZone} from '\@angular/core';
   * import {NgIf} from '\@angular/common';
   *
   * \@Component({
   *   selector: 'ng-zone-demo',
   *   template: `
   *     <h2>Demo: NgZone</h2>
   *
   *     <p>Progress: {{progress}}%</p>
   *     <p *ngIf="progress >= 100">Done processing {{label}} of Angular zone!</p>
   *
   *     <button (click)="processWithinAngularZone()">Process within Angular zone</button>
   *     <button (click)="processOutsideOfAngularZone()">Process outside of Angular zone</button>
   *   `,
   * })
   * export class NgZoneDemo {
   *   progress: number = 0;
   *   label: string;
   *
   *   constructor(private _ngZone: NgZone) {}
   *
   *   // Loop inside the Angular zone
   *   // so the UI DOES refresh after each setTimeout cycle
   *   processWithinAngularZone() {
   *     this.label = 'inside';
   *     this.progress = 0;
   *     this._increaseProgress(() => console.log('Inside Done!'));
   *   }
   *
   *   // Loop outside of the Angular zone
   *   // so the UI DOES NOT refresh after each setTimeout cycle
   *   processOutsideOfAngularZone() {
   *     this.label = 'outside';
   *     this.progress = 0;
   *     this._ngZone.runOutsideAngular(() => {
   *       this._increaseProgress(() => {
   *         // reenter the Angular zone and display done
   *         this._ngZone.run(() => { console.log('Outside Done!'); });
   *       });
   *     });
   *   }
   *
   *   _increaseProgress(doneCallback: () => void) {
   *     this.progress += 1;
   *     console.log(`Current progress: ${this.progress}%`);
   *
   *     if (this.progress < 100) {
   *       window.setTimeout(() => this._increaseProgress(doneCallback), 10);
   *     } else {
   *       doneCallback();
   *     }
   *   }
   * }
   * ```
   *
   * \@experimental
   */
  var NgZone = /** @class */ (function () {
      function NgZone(_a) {
          var _b = _a.enableLongStackTrace, enableLongStackTrace = _b === void 0 ? false : _b;
          this.hasPendingMicrotasks = false;
          this.hasPendingMacrotasks = false;
          /**
           * Whether there are no outstanding microtasks or macrotasks.
           */
          this.isStable = true;
          /**
           * Notifies when code enters Angular Zone. This gets fired first on VM Turn.
           */
          this.onUnstable = new EventEmitter(false);
          /**
           * Notifies when there is no more microtasks enqueued in the current VM Turn.
           * This is a hint for Angular to do change detection, which may enqueue more microtasks.
           * For this reason this event can fire multiple times per VM Turn.
           */
          this.onMicrotaskEmpty = new EventEmitter(false);
          /**
           * Notifies when the last `onMicrotaskEmpty` has run and there are no more microtasks, which
           * implies we are about to relinquish VM turn.
           * This event gets called just once.
           */
          this.onStable = new EventEmitter(false);
          /**
           * Notifies that an error has been delivered.
           */
          this.onError = new EventEmitter(false);
          if (typeof Zone == 'undefined') {
              throw new Error("In this configuration Angular requires Zone.js");
          }
          Zone.assertZonePatched();
          var /** @type {?} */ self = /** @type {?} */ ((this));
          self._nesting = 0;
          self._outer = self._inner = Zone.current;
          if ((/** @type {?} */ (Zone))['wtfZoneSpec']) {
              self._inner = self._inner.fork((/** @type {?} */ (Zone))['wtfZoneSpec']);
          }
          if (enableLongStackTrace && (/** @type {?} */ (Zone))['longStackTraceZoneSpec']) {
              self._inner = self._inner.fork((/** @type {?} */ (Zone))['longStackTraceZoneSpec']);
          }
          forkInnerZoneWithAngularBehavior(self);
      }
      /**
       * @return {?}
       */
      NgZone.isInAngularZone = /**
       * @return {?}
       */
      function () { return Zone.current.get('isAngularZone') === true; };
      /**
       * @return {?}
       */
      NgZone.assertInAngularZone = /**
       * @return {?}
       */
      function () {
          if (!NgZone.isInAngularZone()) {
              throw new Error('Expected to be in Angular Zone, but it is not!');
          }
      };
      /**
       * @return {?}
       */
      NgZone.assertNotInAngularZone = /**
       * @return {?}
       */
      function () {
          if (NgZone.isInAngularZone()) {
              throw new Error('Expected to not be in Angular Zone, but it is!');
          }
      };
      /**
       * Executes the `fn` function synchronously within the Angular zone and returns value returned by
       * the function.
       *
       * Running functions via `run` allows you to reenter Angular zone from a task that was executed
       * outside of the Angular zone (typically started via {@link #runOutsideAngular}).
       *
       * Any future tasks or microtasks scheduled from within this function will continue executing from
       * within the Angular zone.
       *
       * If a synchronous error happens it will be rethrown and not reported via `onError`.
       */
      /**
       * Executes the `fn` function synchronously within the Angular zone and returns value returned by
       * the function.
       *
       * Running functions via `run` allows you to reenter Angular zone from a task that was executed
       * outside of the Angular zone (typically started via {\@link #runOutsideAngular}).
       *
       * Any future tasks or microtasks scheduled from within this function will continue executing from
       * within the Angular zone.
       *
       * If a synchronous error happens it will be rethrown and not reported via `onError`.
       * @template T
       * @param {?} fn
       * @param {?=} applyThis
       * @param {?=} applyArgs
       * @return {?}
       */
      NgZone.prototype.run = /**
       * Executes the `fn` function synchronously within the Angular zone and returns value returned by
       * the function.
       *
       * Running functions via `run` allows you to reenter Angular zone from a task that was executed
       * outside of the Angular zone (typically started via {\@link #runOutsideAngular}).
       *
       * Any future tasks or microtasks scheduled from within this function will continue executing from
       * within the Angular zone.
       *
       * If a synchronous error happens it will be rethrown and not reported via `onError`.
       * @template T
       * @param {?} fn
       * @param {?=} applyThis
       * @param {?=} applyArgs
       * @return {?}
       */
      function (fn, applyThis, applyArgs) {
          return /** @type {?} */ ((/** @type {?} */ ((this)))._inner.run(fn, applyThis, applyArgs));
      };
      /**
       * Executes the `fn` function synchronously within the Angular zone as a task and returns value
       * returned by the function.
       *
       * Running functions via `run` allows you to reenter Angular zone from a task that was executed
       * outside of the Angular zone (typically started via {@link #runOutsideAngular}).
       *
       * Any future tasks or microtasks scheduled from within this function will continue executing from
       * within the Angular zone.
       *
       * If a synchronous error happens it will be rethrown and not reported via `onError`.
       */
      /**
       * Executes the `fn` function synchronously within the Angular zone as a task and returns value
       * returned by the function.
       *
       * Running functions via `run` allows you to reenter Angular zone from a task that was executed
       * outside of the Angular zone (typically started via {\@link #runOutsideAngular}).
       *
       * Any future tasks or microtasks scheduled from within this function will continue executing from
       * within the Angular zone.
       *
       * If a synchronous error happens it will be rethrown and not reported via `onError`.
       * @template T
       * @param {?} fn
       * @param {?=} applyThis
       * @param {?=} applyArgs
       * @param {?=} name
       * @return {?}
       */
      NgZone.prototype.runTask = /**
       * Executes the `fn` function synchronously within the Angular zone as a task and returns value
       * returned by the function.
       *
       * Running functions via `run` allows you to reenter Angular zone from a task that was executed
       * outside of the Angular zone (typically started via {\@link #runOutsideAngular}).
       *
       * Any future tasks or microtasks scheduled from within this function will continue executing from
       * within the Angular zone.
       *
       * If a synchronous error happens it will be rethrown and not reported via `onError`.
       * @template T
       * @param {?} fn
       * @param {?=} applyThis
       * @param {?=} applyArgs
       * @param {?=} name
       * @return {?}
       */
      function (fn, applyThis, applyArgs, name) {
          var /** @type {?} */ zone = (/** @type {?} */ ((this)))._inner;
          var /** @type {?} */ task = zone.scheduleEventTask('NgZoneEvent: ' + name, fn, EMPTY_PAYLOAD, noop, noop);
          try {
              return /** @type {?} */ (zone.runTask(task, applyThis, applyArgs));
          }
          finally {
              zone.cancelTask(task);
          }
      };
      /**
       * Same as `run`, except that synchronous errors are caught and forwarded via `onError` and not
       * rethrown.
       */
      /**
       * Same as `run`, except that synchronous errors are caught and forwarded via `onError` and not
       * rethrown.
       * @template T
       * @param {?} fn
       * @param {?=} applyThis
       * @param {?=} applyArgs
       * @return {?}
       */
      NgZone.prototype.runGuarded = /**
       * Same as `run`, except that synchronous errors are caught and forwarded via `onError` and not
       * rethrown.
       * @template T
       * @param {?} fn
       * @param {?=} applyThis
       * @param {?=} applyArgs
       * @return {?}
       */
      function (fn, applyThis, applyArgs) {
          return /** @type {?} */ ((/** @type {?} */ ((this)))._inner.runGuarded(fn, applyThis, applyArgs));
      };
      /**
       * Executes the `fn` function synchronously in Angular's parent zone and returns value returned by
       * the function.
       *
       * Running functions via {@link #runOutsideAngular} allows you to escape Angular's zone and do
       * work that
       * doesn't trigger Angular change-detection or is subject to Angular's error handling.
       *
       * Any future tasks or microtasks scheduled from within this function will continue executing from
       * outside of the Angular zone.
       *
       * Use {@link #run} to reenter the Angular zone and do work that updates the application model.
       */
      /**
       * Executes the `fn` function synchronously in Angular's parent zone and returns value returned by
       * the function.
       *
       * Running functions via {\@link #runOutsideAngular} allows you to escape Angular's zone and do
       * work that
       * doesn't trigger Angular change-detection or is subject to Angular's error handling.
       *
       * Any future tasks or microtasks scheduled from within this function will continue executing from
       * outside of the Angular zone.
       *
       * Use {\@link #run} to reenter the Angular zone and do work that updates the application model.
       * @template T
       * @param {?} fn
       * @return {?}
       */
      NgZone.prototype.runOutsideAngular = /**
       * Executes the `fn` function synchronously in Angular's parent zone and returns value returned by
       * the function.
       *
       * Running functions via {\@link #runOutsideAngular} allows you to escape Angular's zone and do
       * work that
       * doesn't trigger Angular change-detection or is subject to Angular's error handling.
       *
       * Any future tasks or microtasks scheduled from within this function will continue executing from
       * outside of the Angular zone.
       *
       * Use {\@link #run} to reenter the Angular zone and do work that updates the application model.
       * @template T
       * @param {?} fn
       * @return {?}
       */
      function (fn) {
          return /** @type {?} */ ((/** @type {?} */ ((this)))._outer.run(fn));
      };
      return NgZone;
  }());
  /**
   * @return {?}
   */
  function noop() { }
  var EMPTY_PAYLOAD = {};
  /**
   * @param {?} zone
   * @return {?}
   */
  function checkStable(zone) {
      if (zone._nesting == 0 && !zone.hasPendingMicrotasks && !zone.isStable) {
          try {
              zone._nesting++;
              zone.onMicrotaskEmpty.emit(null);
          }
          finally {
              zone._nesting--;
              if (!zone.hasPendingMicrotasks) {
                  try {
                      zone.runOutsideAngular(function () { return zone.onStable.emit(null); });
                  }
                  finally {
                      zone.isStable = true;
                  }
              }
          }
      }
  }
  /**
   * @param {?} zone
   * @return {?}
   */
  function forkInnerZoneWithAngularBehavior(zone) {
      zone._inner = zone._inner.fork({
          name: 'angular',
          properties: /** @type {?} */ ({ 'isAngularZone': true }),
          onInvokeTask: function (delegate, current, target, task, applyThis, applyArgs) {
              try {
                  onEnter(zone);
                  return delegate.invokeTask(target, task, applyThis, applyArgs);
              }
              finally {
                  onLeave(zone);
              }
          },
          onInvoke: function (delegate, current, target, callback, applyThis, applyArgs, source) {
              try {
                  onEnter(zone);
                  return delegate.invoke(target, callback, applyThis, applyArgs, source);
              }
              finally {
                  onLeave(zone);
              }
          },
          onHasTask: function (delegate, current, target, hasTaskState) {
              delegate.hasTask(target, hasTaskState);
              if (current === target) {
                  // We are only interested in hasTask events which originate from our zone
                  // (A child hasTask event is not interesting to us)
                  if (hasTaskState.change == 'microTask') {
                      zone.hasPendingMicrotasks = hasTaskState.microTask;
                      checkStable(zone);
                  }
                  else if (hasTaskState.change == 'macroTask') {
                      zone.hasPendingMacrotasks = hasTaskState.macroTask;
                  }
              }
          },
          onHandleError: function (delegate, current, target, error) {
              delegate.handleError(target, error);
              zone.runOutsideAngular(function () { return zone.onError.emit(error); });
              return false;
          }
      });
  }
  /**
   * @param {?} zone
   * @return {?}
   */
  function onEnter(zone) {
      zone._nesting++;
      if (zone.isStable) {
          zone.isStable = false;
          zone.onUnstable.emit(null);
      }
  }
  /**
   * @param {?} zone
   * @return {?}
   */
  function onLeave(zone) {
      zone._nesting--;
      checkStable(zone);
  }
  /**
   * Provides a noop implementation of `NgZone` which does nothing. This zone requires explicit calls
   * to framework to perform rendering.
   */
  var NoopNgZone = /** @class */ (function () {
      function NoopNgZone() {
          this.hasPendingMicrotasks = false;
          this.hasPendingMacrotasks = false;
          this.isStable = true;
          this.onUnstable = new EventEmitter();
          this.onMicrotaskEmpty = new EventEmitter();
          this.onStable = new EventEmitter();
          this.onError = new EventEmitter();
      }
      /**
       * @param {?} fn
       * @return {?}
       */
      NoopNgZone.prototype.run = /**
       * @param {?} fn
       * @return {?}
       */
      function (fn) { return fn(); };
      /**
       * @param {?} fn
       * @return {?}
       */
      NoopNgZone.prototype.runGuarded = /**
       * @param {?} fn
       * @return {?}
       */
      function (fn) { return fn(); };
      /**
       * @param {?} fn
       * @return {?}
       */
      NoopNgZone.prototype.runOutsideAngular = /**
       * @param {?} fn
       * @return {?}
       */
      function (fn) { return fn(); };
      /**
       * @template T
       * @param {?} fn
       * @return {?}
       */
      NoopNgZone.prototype.runTask = /**
       * @template T
       * @param {?} fn
       * @return {?}
       */
      function (fn) { return fn(); };
      return NoopNgZone;
  }());
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  /**
   * The Testability service provides testing hooks that can be accessed from
   * the browser and by services such as Protractor. Each bootstrapped Angular
   * application on the page will have an instance of Testability.
   * \@experimental
   */
  var Testability = /** @class */ (function () {
      function Testability(_ngZone) {
          this._ngZone = _ngZone;
          /**
           * \@internal
           */
          this._pendingCount = 0;
          /**
           * \@internal
           */
          this._isZoneStable = true;
          /**
           * Whether any work was done since the last 'whenStable' callback. This is
           * useful to detect if this could have potentially destabilized another
           * component while it is stabilizing.
           * \@internal
           */
          this._didWork = false;
          /**
           * \@internal
           */
          this._callbacks = [];
          this._watchAngularEvents();
      }
      /** @internal */
      /**
       * \@internal
       * @return {?}
       */
      Testability.prototype._watchAngularEvents = /**
       * \@internal
       * @return {?}
       */
      function () {
          var _this = this;
          this._ngZone.onUnstable.subscribe({
              next: function () {
                  _this._didWork = true;
                  _this._isZoneStable = false;
              }
          });
          this._ngZone.runOutsideAngular(function () {
              _this._ngZone.onStable.subscribe({
                  next: function () {
                      NgZone.assertNotInAngularZone();
                      scheduleMicroTask(function () {
                          _this._isZoneStable = true;
                          _this._runCallbacksIfReady();
                      });
                  }
              });
          });
      };
      /**
       * Increases the number of pending request
       */
      /**
       * Increases the number of pending request
       * @return {?}
       */
      Testability.prototype.increasePendingRequestCount = /**
       * Increases the number of pending request
       * @return {?}
       */
      function () {
          this._pendingCount += 1;
          this._didWork = true;
          return this._pendingCount;
      };
      /**
       * Decreases the number of pending request
       */
      /**
       * Decreases the number of pending request
       * @return {?}
       */
      Testability.prototype.decreasePendingRequestCount = /**
       * Decreases the number of pending request
       * @return {?}
       */
      function () {
          this._pendingCount -= 1;
          if (this._pendingCount < 0) {
              throw new Error('pending async requests below zero');
          }
          this._runCallbacksIfReady();
          return this._pendingCount;
      };
      /**
       * Whether an associated application is stable
       */
      /**
       * Whether an associated application is stable
       * @return {?}
       */
      Testability.prototype.isStable = /**
       * Whether an associated application is stable
       * @return {?}
       */
      function () {
          return this._isZoneStable && this._pendingCount == 0 && !this._ngZone.hasPendingMacrotasks;
      };
      /** @internal */
      /**
       * \@internal
       * @return {?}
       */
      Testability.prototype._runCallbacksIfReady = /**
       * \@internal
       * @return {?}
       */
      function () {
          var _this = this;
          if (this.isStable()) {
              // Schedules the call backs in a new frame so that it is always async.
              scheduleMicroTask(function () {
                  while (_this._callbacks.length !== 0) {
                      (/** @type {?} */ ((_this._callbacks.pop())))(_this._didWork);
                  }
                  _this._didWork = false;
              });
          }
          else {
              // Not Ready
              this._didWork = true;
          }
      };
      /**
       * Run callback when the application is stable
       * @param callback function to be called after the application is stable
       */
      /**
       * Run callback when the application is stable
       * @param {?} callback function to be called after the application is stable
       * @return {?}
       */
      Testability.prototype.whenStable = /**
       * Run callback when the application is stable
       * @param {?} callback function to be called after the application is stable
       * @return {?}
       */
      function (callback) {
          this._callbacks.push(callback);
          this._runCallbacksIfReady();
      };
      /**
       * Get the number of pending requests
       */
      /**
       * Get the number of pending requests
       * @return {?}
       */
      Testability.prototype.getPendingRequestCount = /**
       * Get the number of pending requests
       * @return {?}
       */
      function () { return this._pendingCount; };
      /**
       * Find providers by name
       * @param using The root element to search from
       * @param provider The name of binding variable
       * @param exactMatch Whether using exactMatch
       */
      /**
       * Find providers by name
       * @param {?} using The root element to search from
       * @param {?} provider The name of binding variable
       * @param {?} exactMatch Whether using exactMatch
       * @return {?}
       */
      Testability.prototype.findProviders = /**
       * Find providers by name
       * @param {?} using The root element to search from
       * @param {?} provider The name of binding variable
       * @param {?} exactMatch Whether using exactMatch
       * @return {?}
       */
      function (using, provider, exactMatch) {
          // TODO(juliemr): implement.
          return [];
      };
      Testability.decorators = [
          { type: Injectable },
      ];
      /** @nocollapse */
      Testability.ctorParameters = function () { return [
          { type: NgZone, },
      ]; };
      return Testability;
  }());
  /**
   * A global registry of {\@link Testability} instances for specific elements.
   * \@experimental
   */
  var TestabilityRegistry = /** @class */ (function () {
      function TestabilityRegistry() {
          /**
           * \@internal
           */
          this._applications = new Map();
          _testabilityGetter.addToWindow(this);
      }
      /**
       * Registers an application with a testability hook so that it can be tracked
       * @param token token of application, root element
       * @param testability Testability hook
       */
      /**
       * Registers an application with a testability hook so that it can be tracked
       * @param {?} token token of application, root element
       * @param {?} testability Testability hook
       * @return {?}
       */
      TestabilityRegistry.prototype.registerApplication = /**
       * Registers an application with a testability hook so that it can be tracked
       * @param {?} token token of application, root element
       * @param {?} testability Testability hook
       * @return {?}
       */
      function (token, testability) {
          this._applications.set(token, testability);
      };
      /**
       * Unregisters an application.
       * @param token token of application, root element
       */
      /**
       * Unregisters an application.
       * @param {?} token token of application, root element
       * @return {?}
       */
      TestabilityRegistry.prototype.unregisterApplication = /**
       * Unregisters an application.
       * @param {?} token token of application, root element
       * @return {?}
       */
      function (token) { this._applications.delete(token); };
      /**
       * Unregisters all applications
       */
      /**
       * Unregisters all applications
       * @return {?}
       */
      TestabilityRegistry.prototype.unregisterAllApplications = /**
       * Unregisters all applications
       * @return {?}
       */
      function () { this._applications.clear(); };
      /**
       * Get a testability hook associated with the application
       * @param elem root element
       */
      /**
       * Get a testability hook associated with the application
       * @param {?} elem root element
       * @return {?}
       */
      TestabilityRegistry.prototype.getTestability = /**
       * Get a testability hook associated with the application
       * @param {?} elem root element
       * @return {?}
       */
      function (elem) { return this._applications.get(elem) || null; };
      /**
       * Get all registered testabilities
       */
      /**
       * Get all registered testabilities
       * @return {?}
       */
      TestabilityRegistry.prototype.getAllTestabilities = /**
       * Get all registered testabilities
       * @return {?}
       */
      function () { return Array.from(this._applications.values()); };
      /**
       * Get all registered applications(root elements)
       */
      /**
       * Get all registered applications(root elements)
       * @return {?}
       */
      TestabilityRegistry.prototype.getAllRootElements = /**
       * Get all registered applications(root elements)
       * @return {?}
       */
      function () { return Array.from(this._applications.keys()); };
      /**
       * Find testability of a node in the Tree
       * @param elem node
       * @param findInAncestors whether finding testability in ancestors if testability was not found in
       * current node
       */
      /**
       * Find testability of a node in the Tree
       * @param {?} elem node
       * @param {?=} findInAncestors whether finding testability in ancestors if testability was not found in
       * current node
       * @return {?}
       */
      TestabilityRegistry.prototype.findTestabilityInTree = /**
       * Find testability of a node in the Tree
       * @param {?} elem node
       * @param {?=} findInAncestors whether finding testability in ancestors if testability was not found in
       * current node
       * @return {?}
       */
      function (elem, findInAncestors) {
          if (findInAncestors === void 0) { findInAncestors = true; }
          return _testabilityGetter.findTestabilityInTree(this, elem, findInAncestors);
      };
      TestabilityRegistry.decorators = [
          { type: Injectable },
      ];
      /** @nocollapse */
      TestabilityRegistry.ctorParameters = function () { return []; };
      return TestabilityRegistry;
  }());
  /**
   * Adapter interface for retrieving the `Testability` service associated for a
   * particular context.
   *
   * \@experimental Testability apis are primarily intended to be used by e2e test tool vendors like
   * the Protractor team.
   * @record
   */
  
  var _NoopGetTestability = /** @class */ (function () {
      function _NoopGetTestability() {
      }
      /**
       * @param {?} registry
       * @return {?}
       */
      _NoopGetTestability.prototype.addToWindow = /**
       * @param {?} registry
       * @return {?}
       */
      function (registry) { };
      /**
       * @param {?} registry
       * @param {?} elem
       * @param {?} findInAncestors
       * @return {?}
       */
      _NoopGetTestability.prototype.findTestabilityInTree = /**
       * @param {?} registry
       * @param {?} elem
       * @param {?} findInAncestors
       * @return {?}
       */
      function (registry, elem, findInAncestors) {
          return null;
      };
      return _NoopGetTestability;
  }());
  /**
   * Set the {\@link GetTestability} implementation used by the Angular testing framework.
   * \@experimental
   * @param {?} getter
   * @return {?}
   */
  function setTestabilityGetter(getter) {
      _testabilityGetter = getter;
  }
  var _testabilityGetter = new _NoopGetTestability();
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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 _devMode = true;
  var _runModeLocked = false;
  var _platform;
  var ALLOW_MULTIPLE_PLATFORMS = new InjectionToken('AllowMultipleToken');
  /**
   * Disable Angular's development mode, which turns off assertions and other
   * checks within the framework.
   *
   * One important assertion this disables verifies that a change detection pass
   * does not result in additional changes to any bindings (also known as
   * unidirectional data flow).
   *
   * \@stable
   * @return {?}
   */
  function enableProdMode() {
      if (_runModeLocked) {
          throw new Error('Cannot enable prod mode after platform setup.');
      }
      _devMode = false;
  }
  /**
   * Returns whether Angular is in development mode. After called once,
   * the value is locked and won't change any more.
   *
   * By default, this is true, unless a user calls `enableProdMode` before calling this.
   *
   * \@experimental APIs related to application bootstrap are currently under review.
   * @return {?}
   */
  function isDevMode() {
      _runModeLocked = true;
      return _devMode;
  }
  /**
   * A token for third-party components that can register themselves with NgProbe.
   *
   * \@experimental
   */
  var NgProbeToken = /** @class */ (function () {
      function NgProbeToken(name, token) {
          this.name = name;
          this.token = token;
      }
      return NgProbeToken;
  }());
  /**
   * Creates a platform.
   * Platforms have to be eagerly created via this function.
   *
   * \@experimental APIs related to application bootstrap are currently under review.
   * @param {?} injector
   * @return {?}
   */
  function createPlatform(injector) {
      if (_platform && !_platform.destroyed &&
          !_platform.injector.get(ALLOW_MULTIPLE_PLATFORMS, false)) {
          throw new Error('There can be only one platform. Destroy the previous one to create a new one.');
      }
      _platform = injector.get(PlatformRef);
      var /** @type {?} */ inits = injector.get(PLATFORM_INITIALIZER, null);
      if (inits)
          inits.forEach(function (init) { return init(); });
      return _platform;
  }
  /**
   * Creates a factory for a platform
   *
   * \@experimental APIs related to application bootstrap are currently under review.
   * @param {?} parentPlatformFactory
   * @param {?} name
   * @param {?=} providers
   * @return {?}
   */
  function createPlatformFactory(parentPlatformFactory, name, providers) {
      if (providers === void 0) { providers = []; }
      var /** @type {?} */ desc = "Platform: " + name;
      var /** @type {?} */ marker = new InjectionToken(desc);
      return function (extraProviders) {
          if (extraProviders === void 0) { extraProviders = []; }
          var /** @type {?} */ platform = getPlatform();
          if (!platform || platform.injector.get(ALLOW_MULTIPLE_PLATFORMS, false)) {
              if (parentPlatformFactory) {
                  parentPlatformFactory(providers.concat(extraProviders).concat({ provide: marker, useValue: true }));
              }
              else {
                  var /** @type {?} */ injectedProviders = providers.concat(extraProviders).concat({ provide: marker, useValue: true });
                  createPlatform(Injector.create({ providers: injectedProviders, name: desc }));
              }
          }
          return assertPlatform(marker);
      };
  }
  /**
   * Checks that there currently is a platform which contains the given token as a provider.
   *
   * \@experimental APIs related to application bootstrap are currently under review.
   * @param {?} requiredToken
   * @return {?}
   */
  function assertPlatform(requiredToken) {
      var /** @type {?} */ platform = getPlatform();
      if (!platform) {
          throw new Error('No platform exists!');
      }
      if (!platform.injector.get(requiredToken, null)) {
          throw new Error('A platform with a different configuration has been created. Please destroy it first.');
      }
      return platform;
  }
  /**
   * Destroy the existing platform.
   *
   * \@experimental APIs related to application bootstrap are currently under review.
   * @return {?}
   */
  function destroyPlatform() {
      if (_platform && !_platform.destroyed) {
          _platform.destroy();
      }
  }
  /**
   * Returns the current platform.
   *
   * \@experimental APIs related to application bootstrap are currently under review.
   * @return {?}
   */
  function getPlatform() {
      return _platform && !_platform.destroyed ? _platform : null;
  }
  /**
   * Provides additional options to the bootstraping process.
   *
   * \@stable
   * @record
   */
  
  /**
   * The Angular platform is the entry point for Angular on a web page. Each page
   * has exactly one platform, and services (such as reflection) which are common
   * to every Angular application running on the page are bound in its scope.
   *
   * A page's platform is initialized implicitly when a platform is created via a platform factory
   * (e.g. {\@link platformBrowser}), or explicitly by calling the {\@link createPlatform} function.
   *
   * \@stable
   */
  var PlatformRef = /** @class */ (function () {
      /** @internal */
      function PlatformRef(_injector) {
          this._injector = _injector;
          this._modules = [];
          this._destroyListeners = [];
          this._destroyed = false;
      }
      /**
       * Creates an instance of an `@NgModule` for the given platform
       * for offline compilation.
       *
       * ## Simple Example
       *
       * ```typescript
       * my_module.ts:
       *
       * @NgModule({
       *   imports: [BrowserModule]
       * })
       * class MyModule {}
       *
       * main.ts:
       * import {MyModuleNgFactory} from './my_module.ngfactory';
       * import {platformBrowser} from '@angular/platform-browser';
       *
       * let moduleRef = platformBrowser().bootstrapModuleFactory(MyModuleNgFactory);
       * ```
       *
       * @experimental APIs related to application bootstrap are currently under review.
       */
      /**
       * Creates an instance of an `\@NgModule` for the given platform
       * for offline compilation.
       *
       * ## Simple Example
       *
       * ```typescript
       * my_module.ts:
       *
       * \@NgModule({
       *   imports: [BrowserModule]
       * })
       * class MyModule {}
       *
       * main.ts:
       * import {MyModuleNgFactory} from './my_module.ngfactory';
       * import {platformBrowser} from '\@angular/platform-browser';
       *
       * let moduleRef = platformBrowser().bootstrapModuleFactory(MyModuleNgFactory);
       * ```
       *
       * \@experimental APIs related to application bootstrap are currently under review.
       * @template M
       * @param {?} moduleFactory
       * @param {?=} options
       * @return {?}
       */
      PlatformRef.prototype.bootstrapModuleFactory = /**
       * Creates an instance of an `\@NgModule` for the given platform
       * for offline compilation.
       *
       * ## Simple Example
       *
       * ```typescript
       * my_module.ts:
       *
       * \@NgModule({
       *   imports: [BrowserModule]
       * })
       * class MyModule {}
       *
       * main.ts:
       * import {MyModuleNgFactory} from './my_module.ngfactory';
       * import {platformBrowser} from '\@angular/platform-browser';
       *
       * let moduleRef = platformBrowser().bootstrapModuleFactory(MyModuleNgFactory);
       * ```
       *
       * \@experimental APIs related to application bootstrap are currently under review.
       * @template M
       * @param {?} moduleFactory
       * @param {?=} options
       * @return {?}
       */
      function (moduleFactory, options) {
          var _this = this;
          // Note: We need to create the NgZone _before_ we instantiate the module,
          // as instantiating the module creates some providers eagerly.
          // So we create a mini parent injector that just contains the new NgZone and
          // pass that as parent to the NgModuleFactory.
          var /** @type {?} */ ngZoneOption = options ? options.ngZone : undefined;
          var /** @type {?} */ ngZone = getNgZone(ngZoneOption);
          var /** @type {?} */ providers = [{ provide: NgZone, useValue: ngZone }];
          // Attention: Don't use ApplicationRef.run here,
          // as we want to be sure that all possible constructor calls are inside `ngZone.run`!
          return ngZone.run(function () {
              var /** @type {?} */ ngZoneInjector = Injector.create({ providers: providers, parent: _this.injector, name: moduleFactory.moduleType.name });
              var /** @type {?} */ moduleRef = /** @type {?} */ (moduleFactory.create(ngZoneInjector));
              var /** @type {?} */ exceptionHandler = moduleRef.injector.get(ErrorHandler, null);
              if (!exceptionHandler) {
                  throw new Error('No ErrorHandler. Is platform module (BrowserModule) included?');
              }
              moduleRef.onDestroy(function () { return remove(_this._modules, moduleRef); }); /** @type {?} */
              ((ngZone)).runOutsideAngular(function () { return ((ngZone)).onError.subscribe({ next: function (error) { exceptionHandler.handleError(error); } }); });
              return _callAndReportToErrorHandler(exceptionHandler, /** @type {?} */ ((ngZone)), function () {
                  var /** @type {?} */ initStatus = moduleRef.injector.get(ApplicationInitStatus);
                  initStatus.runInitializers();
                  return initStatus.donePromise.then(function () {
                      _this._moduleDoBootstrap(moduleRef);
                      return moduleRef;
                  });
              });
          });
      };
      /**
       * Creates an instance of an `@NgModule` for a given platform using the given runtime compiler.
       *
       * ## Simple Example
       *
       * ```typescript
       * @NgModule({
       *   imports: [BrowserModule]
       * })
       * class MyModule {}
       *
       * let moduleRef = platformBrowser().bootstrapModule(MyModule);
       * ```
       * @stable
       */
      /**
       * Creates an instance of an `\@NgModule` for a given platform using the given runtime compiler.
       *
       * ## Simple Example
       *
       * ```typescript
       * \@NgModule({
       *   imports: [BrowserModule]
       * })
       * class MyModule {}
       *
       * let moduleRef = platformBrowser().bootstrapModule(MyModule);
       * ```
       * \@stable
       * @template M
       * @param {?} moduleType
       * @param {?=} compilerOptions
       * @return {?}
       */
      PlatformRef.prototype.bootstrapModule = /**
       * Creates an instance of an `\@NgModule` for a given platform using the given runtime compiler.
       *
       * ## Simple Example
       *
       * ```typescript
       * \@NgModule({
       *   imports: [BrowserModule]
       * })
       * class MyModule {}
       *
       * let moduleRef = platformBrowser().bootstrapModule(MyModule);
       * ```
       * \@stable
       * @template M
       * @param {?} moduleType
       * @param {?=} compilerOptions
       * @return {?}
       */
      function (moduleType, compilerOptions) {
          var _this = this;
          if (compilerOptions === void 0) { compilerOptions = []; }
          var /** @type {?} */ compilerFactory = this.injector.get(CompilerFactory);
          var /** @type {?} */ options = optionsReducer({}, compilerOptions);
          var /** @type {?} */ compiler = compilerFactory.createCompiler([options]);
          return compiler.compileModuleAsync(moduleType)
              .then(function (moduleFactory) { return _this.bootstrapModuleFactory(moduleFactory, options); });
      };
      /**
       * @param {?} moduleRef
       * @return {?}
       */
      PlatformRef.prototype._moduleDoBootstrap = /**
       * @param {?} moduleRef
       * @return {?}
       */
      function (moduleRef) {
          var /** @type {?} */ appRef = /** @type {?} */ (moduleRef.injector.get(ApplicationRef));
          if (moduleRef._bootstrapComponents.length > 0) {
              moduleRef._bootstrapComponents.forEach(function (f) { return appRef.bootstrap(f); });
          }
          else if (moduleRef.instance.ngDoBootstrap) {
              moduleRef.instance.ngDoBootstrap(appRef);
          }
          else {
              throw new Error("The module " + stringify(moduleRef.instance.constructor) + " was bootstrapped, but it does not declare \"@NgModule.bootstrap\" components nor a \"ngDoBootstrap\" method. " +
                  "Please define one of these.");
          }
          this._modules.push(moduleRef);
      };
      /**
       * Register a listener to be called when the platform is disposed.
       */
      /**
       * Register a listener to be called when the platform is disposed.
       * @param {?} callback
       * @return {?}
       */
      PlatformRef.prototype.onDestroy = /**
       * Register a listener to be called when the platform is disposed.
       * @param {?} callback
       * @return {?}
       */
      function (callback) { this._destroyListeners.push(callback); };
      Object.defineProperty(PlatformRef.prototype, "injector", {
          /**
           * Retrieve the platform {@link Injector}, which is the parent injector for
           * every Angular application on the page and provides singleton providers.
           */
          get: /**
           * Retrieve the platform {\@link Injector}, which is the parent injector for
           * every Angular application on the page and provides singleton providers.
           * @return {?}
           */
          function () { return this._injector; },
          enumerable: true,
          configurable: true
      });
      /**
       * Destroy the Angular platform and all Angular applications on the page.
       */
      /**
       * Destroy the Angular platform and all Angular applications on the page.
       * @return {?}
       */
      PlatformRef.prototype.destroy = /**
       * Destroy the Angular platform and all Angular applications on the page.
       * @return {?}
       */
      function () {
          if (this._destroyed) {
              throw new Error('The platform has already been destroyed!');
          }
          this._modules.slice().forEach(function (module) { return module.destroy(); });
          this._destroyListeners.forEach(function (listener) { return listener(); });
          this._destroyed = true;
      };
      Object.defineProperty(PlatformRef.prototype, "destroyed", {
          get: /**
           * @return {?}
           */
          function () { return this._destroyed; },
          enumerable: true,
          configurable: true
      });
      PlatformRef.decorators = [
          { type: Injectable },
      ];
      /** @nocollapse */
      PlatformRef.ctorParameters = function () { return [
          { type: Injector, },
      ]; };
      return PlatformRef;
  }());
  /**
   * @param {?=} ngZoneOption
   * @return {?}
   */
  function getNgZone(ngZoneOption) {
      var /** @type {?} */ ngZone;
      if (ngZoneOption === 'noop') {
          ngZone = new NoopNgZone();
      }
      else {
          ngZone = (ngZoneOption === 'zone.js' ? undefined : ngZoneOption) ||
              new NgZone({ enableLongStackTrace: isDevMode() });
      }
      return ngZone;
  }
  /**
   * @param {?} errorHandler
   * @param {?} ngZone
   * @param {?} callback
   * @return {?}
   */
  function _callAndReportToErrorHandler(errorHandler, ngZone, callback) {
      try {
          var /** @type {?} */ result = callback();
          if (isPromise(result)) {
              return result.catch(function (e) {
                  ngZone.runOutsideAngular(function () { return errorHandler.handleError(e); });
                  // rethrow as the exception handler might not do it
                  throw e;
              });
          }
          return result;
      }
      catch (/** @type {?} */ e) {
          ngZone.runOutsideAngular(function () { return errorHandler.handleError(e); });
          // rethrow as the exception handler might not do it
          throw e;
      }
  }
  /**
   * @template T
   * @param {?} dst
   * @param {?} objs
   * @return {?}
   */
  function optionsReducer(dst, objs) {
      if (Array.isArray(objs)) {
          dst = objs.reduce(optionsReducer, dst);
      }
      else {
          dst = __assign({}, dst, (/** @type {?} */ (objs)));
      }
      return dst;
  }
  /**
   * A reference to an Angular application running on a page.
   *
   * \@stable
   */
  var ApplicationRef = /** @class */ (function () {
      /** @internal */
      function ApplicationRef(_zone, _console, _injector, _exceptionHandler, _componentFactoryResolver, _initStatus) {
          var _this = this;
          this._zone = _zone;
          this._console = _console;
          this._injector = _injector;
          this._exceptionHandler = _exceptionHandler;
          this._componentFactoryResolver = _componentFactoryResolver;
          this._initStatus = _initStatus;
          this._bootstrapListeners = [];
          this._views = [];
          this._runningTick = false;
          this._enforceNoNewChanges = false;
          this._stable = true;
          /**
           * Get a list of component types registered to this application.
           * This list is populated even before the component is created.
           */
          this.componentTypes = [];
          /**
           * Get a list of components registered to this application.
           */
          this.components = [];
          this._enforceNoNewChanges = isDevMode();
          this._zone.onMicrotaskEmpty.subscribe({ next: function () { _this._zone.run(function () { _this.tick(); }); } });
          var /** @type {?} */ isCurrentlyStable = new rxjs_Observable.Observable(function (observer) {
              _this._stable = _this._zone.isStable && !_this._zone.hasPendingMacrotasks &&
                  !_this._zone.hasPendingMicrotasks;
              _this._zone.runOutsideAngular(function () {
                  observer.next(_this._stable);
                  observer.complete();
              });
          });
          var /** @type {?} */ isStable = new rxjs_Observable.Observable(function (observer) {
              // Create the subscription to onStable outside the Angular Zone so that
              // the callback is run outside the Angular Zone.
              var /** @type {?} */ stableSub;
              _this._zone.runOutsideAngular(function () {
                  stableSub = _this._zone.onStable.subscribe(function () {
                      NgZone.assertNotInAngularZone();
                      // Check whether there are no pending macro/micro tasks in the next tick
                      // to allow for NgZone to update the state.
                      scheduleMicroTask(function () {
                          if (!_this._stable && !_this._zone.hasPendingMacrotasks &&
                              !_this._zone.hasPendingMicrotasks) {
                              _this._stable = true;
                              observer.next(true);
                          }
                      });
                  });
              });
              var /** @type {?} */ unstableSub = _this._zone.onUnstable.subscribe(function () {
                  NgZone.assertInAngularZone();
                  if (_this._stable) {
                      _this._stable = false;
                      _this._zone.runOutsideAngular(function () { observer.next(false); });
                  }
              });
              return function () {
                  stableSub.unsubscribe();
                  unstableSub.unsubscribe();
              };
          });
          (/** @type {?} */ (this)).isStable =
              rxjs_observable_merge.merge(isCurrentlyStable, rxjs_operator_share.share.call(isStable));
      }
      /**
       * Bootstrap a new component at the root level of the application.
       *
       * ### Bootstrap process
       *
       * When bootstrapping a new root component into an application, Angular mounts the
       * specified application component onto DOM elements identified by the [componentType]'s
       * selector and kicks off automatic change detection to finish initializing the component.
       *
       * Optionally, a component can be mounted onto a DOM element that does not match the
       * [componentType]'s selector.
       *
       * ### Example
       * {@example core/ts/platform/platform.ts region='longform'}
       */
      /**
       * Bootstrap a new component at the root level of the application.
       *
       * ### Bootstrap process
       *
       * When bootstrapping a new root component into an application, Angular mounts the
       * specified application component onto DOM elements identified by the [componentType]'s
       * selector and kicks off automatic change detection to finish initializing the component.
       *
       * Optionally, a component can be mounted onto a DOM element that does not match the
       * [componentType]'s selector.
       *
       * ### Example
       * {\@example core/ts/platform/platform.ts region='longform'}
       * @template C
       * @param {?} componentOrFactory
       * @param {?=} rootSelectorOrNode
       * @return {?}
       */
      ApplicationRef.prototype.bootstrap = /**
       * Bootstrap a new component at the root level of the application.
       *
       * ### Bootstrap process
       *
       * When bootstrapping a new root component into an application, Angular mounts the
       * specified application component onto DOM elements identified by the [componentType]'s
       * selector and kicks off automatic change detection to finish initializing the component.
       *
       * Optionally, a component can be mounted onto a DOM element that does not match the
       * [componentType]'s selector.
       *
       * ### Example
       * {\@example core/ts/platform/platform.ts region='longform'}
       * @template C
       * @param {?} componentOrFactory
       * @param {?=} rootSelectorOrNode
       * @return {?}
       */
      function (componentOrFactory, rootSelectorOrNode) {
          var _this = this;
          if (!this._initStatus.done) {
              throw new Error('Cannot bootstrap as there are still asynchronous initializers running. Bootstrap components in the `ngDoBootstrap` method of the root module.');
          }
          var /** @type {?} */ componentFactory;
          if (componentOrFactory instanceof ComponentFactory) {
              componentFactory = componentOrFactory;
          }
          else {
              componentFactory =
                  /** @type {?} */ ((this._componentFactoryResolver.resolveComponentFactory(componentOrFactory)));
          }
          this.componentTypes.push(componentFactory.componentType);
          // Create a factory associated with the current module if it's not bound to some other
          var /** @type {?} */ ngModule = componentFactory instanceof ComponentFactoryBoundToModule ?
              null :
              this._injector.get(NgModuleRef);
          var /** @type {?} */ selectorOrNode = rootSelectorOrNode || componentFactory.selector;
          var /** @type {?} */ compRef = componentFactory.create(Injector.NULL, [], selectorOrNode, ngModule);
          compRef.onDestroy(function () { _this._unloadComponent(compRef); });
          var /** @type {?} */ testability = compRef.injector.get(Testability, null);
          if (testability) {
              compRef.injector.get(TestabilityRegistry)
                  .registerApplication(compRef.location.nativeElement, testability);
          }
          this._loadComponent(compRef);
          if (isDevMode()) {
              this._console.log("Angular is running in the development mode. Call enableProdMode() to enable the production mode.");
          }
          return compRef;
      };
      /**
       * Invoke this method to explicitly process change detection and its side-effects.
       *
       * In development mode, `tick()` also performs a second change detection cycle to ensure that no
       * further changes are detected. If additional changes are picked up during this second cycle,
       * bindings in the app have side-effects that cannot be resolved in a single change detection
       * pass.
       * In this case, Angular throws an error, since an Angular application can only have one change
       * detection pass during which all change detection must complete.
       */
      /**
       * Invoke this method to explicitly process change detection and its side-effects.
       *
       * In development mode, `tick()` also performs a second change detection cycle to ensure that no
       * further changes are detected. If additional changes are picked up during this second cycle,
       * bindings in the app have side-effects that cannot be resolved in a single change detection
       * pass.
       * In this case, Angular throws an error, since an Angular application can only have one change
       * detection pass during which all change detection must complete.
       * @return {?}
       */
      ApplicationRef.prototype.tick = /**
       * Invoke this method to explicitly process change detection and its side-effects.
       *
       * In development mode, `tick()` also performs a second change detection cycle to ensure that no
       * further changes are detected. If additional changes are picked up during this second cycle,
       * bindings in the app have side-effects that cannot be resolved in a single change detection
       * pass.
       * In this case, Angular throws an error, since an Angular application can only have one change
       * detection pass during which all change detection must complete.
       * @return {?}
       */
      function () {
          var _this = this;
          if (this._runningTick) {
              throw new Error('ApplicationRef.tick is called recursively');
          }
          var /** @type {?} */ scope = ApplicationRef._tickScope();
          try {
              this._runningTick = true;
              this._views.forEach(function (view) { return view.detectChanges(); });
              if (this._enforceNoNewChanges) {
                  this._views.forEach(function (view) { return view.checkNoChanges(); });
              }
          }
          catch (/** @type {?} */ e) {
              // Attention: Don't rethrow as it could cancel subscriptions to Observables!
              this._zone.runOutsideAngular(function () { return _this._exceptionHandler.handleError(e); });
          }
          finally {
              this._runningTick = false;
              wtfLeave(scope);
          }
      };
      /**
       * Attaches a view so that it will be dirty checked.
       * The view will be automatically detached when it is destroyed.
       * This will throw if the view is already attached to a ViewContainer.
       */
      /**
       * Attaches a view so that it will be dirty checked.
       * The view will be automatically detached when it is destroyed.
       * This will throw if the view is already attached to a ViewContainer.
       * @param {?} viewRef
       * @return {?}
       */
      ApplicationRef.prototype.attachView = /**
       * Attaches a view so that it will be dirty checked.
       * The view will be automatically detached when it is destroyed.
       * This will throw if the view is already attached to a ViewContainer.
       * @param {?} viewRef
       * @return {?}
       */
      function (viewRef) {
          var /** @type {?} */ view = (/** @type {?} */ (viewRef));
          this._views.push(view);
          view.attachToAppRef(this);
      };
      /**
       * Detaches a view from dirty checking again.
       */
      /**
       * Detaches a view from dirty checking again.
       * @param {?} viewRef
       * @return {?}
       */
      ApplicationRef.prototype.detachView = /**
       * Detaches a view from dirty checking again.
       * @param {?} viewRef
       * @return {?}
       */
      function (viewRef) {
          var /** @type {?} */ view = (/** @type {?} */ (viewRef));
          remove(this._views, view);
          view.detachFromAppRef();
      };
      /**
       * @param {?} componentRef
       * @return {?}
       */
      ApplicationRef.prototype._loadComponent = /**
       * @param {?} componentRef
       * @return {?}
       */
      function (componentRef) {
          this.attachView(componentRef.hostView);
          this.tick();
          this.components.push(componentRef);
          // Get the listeners lazily to prevent DI cycles.
          var /** @type {?} */ listeners = this._injector.get(APP_BOOTSTRAP_LISTENER, []).concat(this._bootstrapListeners);
          listeners.forEach(function (listener) { return listener(componentRef); });
      };
      /**
       * @param {?} componentRef
       * @return {?}
       */
      ApplicationRef.prototype._unloadComponent = /**
       * @param {?} componentRef
       * @return {?}
       */
      function (componentRef) {
          this.detachView(componentRef.hostView);
          remove(this.components, componentRef);
      };
      /** @internal */
      /**
       * \@internal
       * @return {?}
       */
      ApplicationRef.prototype.ngOnDestroy = /**
       * \@internal
       * @return {?}
       */
      function () {
          // TODO(alxhub): Dispose of the NgZone.
          this._views.slice().forEach(function (view) { return view.destroy(); });
      };
      Object.defineProperty(ApplicationRef.prototype, "viewCount", {
          /**
           * Returns the number of attached views.
           */
          get: /**
           * Returns the number of attached views.
           * @return {?}
           */
          function () { return this._views.length; },
          enumerable: true,
          configurable: true
      });
      /**
       * \@internal
       */
      ApplicationRef._tickScope = wtfCreateScope('ApplicationRef#tick()');
      ApplicationRef.decorators = [
          { type: Injectable },
      ];
      /** @nocollapse */
      ApplicationRef.ctorParameters = function () { return [
          { type: NgZone, },
          { type: Console, },
          { type: Injector, },
          { type: ErrorHandler, },
          { type: ComponentFactoryResolver, },
          { type: ApplicationInitStatus, },
      ]; };
      return ApplicationRef;
  }());
  /**
   * @template T
   * @param {?} list
   * @param {?} el
   * @return {?}
   */
  function remove(list, el) {
      var /** @type {?} */ index = list.indexOf(el);
      if (index > -1) {
          list.splice(index, 1);
      }
  }
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  /**
   * @deprecated Use `RendererType2` (and `Renderer2`) instead.
   */
  var RenderComponentType = /** @class */ (function () {
      function RenderComponentType(id, templateUrl, slotCount, encapsulation, styles, animations) {
          this.id = id;
          this.templateUrl = templateUrl;
          this.slotCount = slotCount;
          this.encapsulation = encapsulation;
          this.styles = styles;
          this.animations = animations;
      }
      return RenderComponentType;
  }());
  /**
   * @deprecated Debug info is handeled internally in the view engine now.
   * @abstract
   */
  var RenderDebugInfo = /** @class */ (function () {
      function RenderDebugInfo() {
      }
      return RenderDebugInfo;
  }());
  /**
   * @deprecated Use the `Renderer2` instead.
   * @record
   */
  
  /**
   * @deprecated Use the `Renderer2` instead.
   * @abstract
   */
  var Renderer = /** @class */ (function () {
      function Renderer() {
      }
      return Renderer;
  }());
  var Renderer2Interceptor = new InjectionToken('Renderer2Interceptor');
  /**
   * Injectable service that provides a low-level interface for modifying the UI.
   *
   * Use this service to bypass Angular's templating and make custom UI changes that can't be
   * expressed declaratively. For example if you need to set a property or an attribute whose name is
   * not statically known, use {\@link Renderer#setElementProperty setElementProperty} or
   * {\@link Renderer#setElementAttribute setElementAttribute} respectively.
   *
   * If you are implementing a custom renderer, you must implement this interface.
   *
   * The default Renderer implementation is `DomRenderer`. Also available is `WebWorkerRenderer`.
   *
   * @deprecated Use `RendererFactory2` instead.
   * @abstract
   */
  var RootRenderer = /** @class */ (function () {
      function RootRenderer() {
      }
      return RootRenderer;
  }());
  /**
   * \@experimental
   * @record
   */
  
  /**
   * \@experimental
   * @abstract
   */
  var RendererFactory2 = /** @class */ (function () {
      function RendererFactory2() {
      }
      return RendererFactory2;
  }());
  /** @enum {number} */
  var RendererStyleFlags2 = {
      Important: 1,
      DashCase: 2,
  };
  RendererStyleFlags2[RendererStyleFlags2.Important] = "Important";
  RendererStyleFlags2[RendererStyleFlags2.DashCase] = "DashCase";
  /**
   * \@experimental
   * @abstract
   */
  var Renderer2 = /** @class */ (function () {
      function Renderer2() {
      }
      return Renderer2;
  }());
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  /**
   * A wrapper around a native element inside of a View.
   *
   * An `ElementRef` is backed by a render-specific element. In the browser, this is usually a DOM
   * element.
   *
   * \@security Permitting direct access to the DOM can make your application more vulnerable to
   * XSS attacks. Carefully review any use of `ElementRef` in your code. For more detail, see the
   * [Security Guide](http://g.co/ng/security).
   *
   * \@stable
   */
  var ElementRef = /** @class */ (function () {
      function ElementRef(nativeElement) {
          this.nativeElement = nativeElement;
      }
      return ElementRef;
  }());
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  /**
   * Used to load ng module factories.
   * \@stable
   * @abstract
   */
  var NgModuleFactoryLoader = /** @class */ (function () {
      function NgModuleFactoryLoader() {
      }
      return NgModuleFactoryLoader;
  }());
  var moduleFactories = new Map();
  /**
   * Registers a loaded module. Should only be called from generated NgModuleFactory code.
   * \@experimental
   * @param {?} id
   * @param {?} factory
   * @return {?}
   */
  function registerModuleFactory(id, factory) {
      var /** @type {?} */ existing = moduleFactories.get(id);
      if (existing) {
          throw new Error("Duplicate module registered for " + id + " - " + existing.moduleType.name + " vs " + factory.moduleType.name);
      }
      moduleFactories.set(id, factory);
  }
  /**
   * @return {?}
   */
  
  /**
   * Returns the NgModuleFactory with the given id, if it exists and has been loaded.
   * Factories for modules that do not specify an `id` cannot be retrieved. Throws if the module
   * cannot be found.
   * \@experimental
   * @param {?} id
   * @return {?}
   */
  function getModuleFactory(id) {
      var /** @type {?} */ factory = moduleFactories.get(id);
      if (!factory)
          throw new Error("No module with ID " + id + " loaded");
      return factory;
  }
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  /**
   * An unmodifiable list of items that Angular keeps up to date when the state
   * of the application changes.
   *
   * The type of object that {\@link ViewChildren}, {\@link ContentChildren}, and {\@link QueryList}
   * provide.
   *
   * Implements an iterable interface, therefore it can be used in both ES6
   * javascript `for (var i of items)` loops as well as in Angular templates with
   * `*ngFor="let i of myList"`.
   *
   * Changes can be observed by subscribing to the changes `Observable`.
   *
   * NOTE: In the future this class will implement an `Observable` interface.
   *
   * ### Example ([live demo](http://plnkr.co/edit/RX8sJnQYl9FWuSCWme5z?p=preview))
   * ```typescript
   * \@Component({...})
   * class Container {
   *   \@ViewChildren(Item) items:QueryList<Item>;
   * }
   * ```
   * \@stable
   */
  var QueryList = /** @class */ (function () {
      function QueryList() {
          this.dirty = true;
          this._results = [];
          this.changes = new EventEmitter();
          this.length = 0;
      }
      /**
       * See
       * [Array.map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map)
       */
      /**
       * See
       * [Array.map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map)
       * @template U
       * @param {?} fn
       * @return {?}
       */
      QueryList.prototype.map = /**
       * See
       * [Array.map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map)
       * @template U
       * @param {?} fn
       * @return {?}
       */
      function (fn) { return this._results.map(fn); };
      /**
       * See
       * [Array.filter](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter)
       */
      /**
       * See
       * [Array.filter](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter)
       * @param {?} fn
       * @return {?}
       */
      QueryList.prototype.filter = /**
       * See
       * [Array.filter](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter)
       * @param {?} fn
       * @return {?}
       */
      function (fn) {
          return this._results.filter(fn);
      };
      /**
       * See
       * [Array.find](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find)
       */
      /**
       * See
       * [Array.find](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find)
       * @param {?} fn
       * @return {?}
       */
      QueryList.prototype.find = /**
       * See
       * [Array.find](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find)
       * @param {?} fn
       * @return {?}
       */
      function (fn) {
          return this._results.find(fn);
      };
      /**
       * See
       * [Array.reduce](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce)
       */
      /**
       * See
       * [Array.reduce](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce)
       * @template U
       * @param {?} fn
       * @param {?} init
       * @return {?}
       */
      QueryList.prototype.reduce = /**
       * See
       * [Array.reduce](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce)
       * @template U
       * @param {?} fn
       * @param {?} init
       * @return {?}
       */
      function (fn, init) {
          return this._results.reduce(fn, init);
      };
      /**
       * See
       * [Array.forEach](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach)
       */
      /**
       * See
       * [Array.forEach](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach)
       * @param {?} fn
       * @return {?}
       */
      QueryList.prototype.forEach = /**
       * See
       * [Array.forEach](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach)
       * @param {?} fn
       * @return {?}
       */
      function (fn) { this._results.forEach(fn); };
      /**
       * See
       * [Array.some](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some)
       */
      /**
       * See
       * [Array.some](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some)
       * @param {?} fn
       * @return {?}
       */
      QueryList.prototype.some = /**
       * See
       * [Array.some](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some)
       * @param {?} fn
       * @return {?}
       */
      function (fn) {
          return this._results.some(fn);
      };
      /**
       * @return {?}
       */
      QueryList.prototype.toArray = /**
       * @return {?}
       */
      function () { return this._results.slice(); };
      /**
       * @return {?}
       */
      QueryList.prototype[getSymbolIterator()] = /**
       * @return {?}
       */
      function () { return (/** @type {?} */ (this._results))[getSymbolIterator()](); };
      /**
       * @return {?}
       */
      QueryList.prototype.toString = /**
       * @return {?}
       */
      function () { return this._results.toString(); };
      /**
       * @param {?} res
       * @return {?}
       */
      QueryList.prototype.reset = /**
       * @param {?} res
       * @return {?}
       */
      function (res) {
          this._results = flatten(res);
          (/** @type {?} */ (this)).dirty = false;
          (/** @type {?} */ (this)).length = this._results.length;
          (/** @type {?} */ (this)).last = this._results[this.length - 1];
          (/** @type {?} */ (this)).first = this._results[0];
      };
      /**
       * @return {?}
       */
      QueryList.prototype.notifyOnChanges = /**
       * @return {?}
       */
      function () { (/** @type {?} */ (this.changes)).emit(this); };
      /** internal */
      /**
       * internal
       * @return {?}
       */
      QueryList.prototype.setDirty = /**
       * internal
       * @return {?}
       */
      function () { (/** @type {?} */ (this)).dirty = true; };
      /** internal */
      /**
       * internal
       * @return {?}
       */
      QueryList.prototype.destroy = /**
       * internal
       * @return {?}
       */
      function () {
          (/** @type {?} */ (this.changes)).complete();
          (/** @type {?} */ (this.changes)).unsubscribe();
      };
      return QueryList;
  }());
  /**
   * @template T
   * @param {?} list
   * @return {?}
   */
  function flatten(list) {
      return list.reduce(function (flat, item) {
          var /** @type {?} */ flatItem = Array.isArray(item) ? flatten(item) : item;
          return (/** @type {?} */ (flat)).concat(flatItem);
      }, []);
  }
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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 _SEPARATOR = '#';
  var FACTORY_CLASS_SUFFIX = 'NgFactory';
  /**
   * Configuration for SystemJsNgModuleLoader.
   * token.
   *
   * \@experimental
   * @abstract
   */
  var SystemJsNgModuleLoaderConfig = /** @class */ (function () {
      function SystemJsNgModuleLoaderConfig() {
      }
      return SystemJsNgModuleLoaderConfig;
  }());
  var DEFAULT_CONFIG = {
      factoryPathPrefix: '',
      factoryPathSuffix: '.ngfactory',
  };
  /**
   * NgModuleFactoryLoader that uses SystemJS to load NgModuleFactory
   * \@experimental
   */
  var SystemJsNgModuleLoader = /** @class */ (function () {
      function SystemJsNgModuleLoader(_compiler, config) {
          this._compiler = _compiler;
          this._config = config || DEFAULT_CONFIG;
      }
      /**
       * @param {?} path
       * @return {?}
       */
      SystemJsNgModuleLoader.prototype.load = /**
       * @param {?} path
       * @return {?}
       */
      function (path) {
          var /** @type {?} */ offlineMode = this._compiler instanceof Compiler;
          return offlineMode ? this.loadFactory(path) : this.loadAndCompile(path);
      };
      /**
       * @param {?} path
       * @return {?}
       */
      SystemJsNgModuleLoader.prototype.loadAndCompile = /**
       * @param {?} path
       * @return {?}
       */
      function (path) {
          var _this = this;
          var _a = path.split(_SEPARATOR), module = _a[0], exportName = _a[1];
          if (exportName === undefined) {
              exportName = 'default';
          }
          return System.import(module)
              .then(function (module) { return module[exportName]; })
              .then(function (type) { return checkNotEmpty(type, module, exportName); })
              .then(function (type) { return _this._compiler.compileModuleAsync(type); });
      };
      /**
       * @param {?} path
       * @return {?}
       */
      SystemJsNgModuleLoader.prototype.loadFactory = /**
       * @param {?} path
       * @return {?}
       */
      function (path) {
          var _a = path.split(_SEPARATOR), module = _a[0], exportName = _a[1];
          var /** @type {?} */ factoryClassSuffix = FACTORY_CLASS_SUFFIX;
          if (exportName === undefined) {
              exportName = 'default';
              factoryClassSuffix = '';
          }
          return System.import(this._config.factoryPathPrefix + module + this._config.factoryPathSuffix)
              .then(function (module) { return module[exportName + factoryClassSuffix]; })
              .then(function (factory) { return checkNotEmpty(factory, module, exportName); });
      };
      SystemJsNgModuleLoader.decorators = [
          { type: Injectable },
      ];
      /** @nocollapse */
      SystemJsNgModuleLoader.ctorParameters = function () { return [
          { type: Compiler, },
          { type: SystemJsNgModuleLoaderConfig, decorators: [{ type: Optional },] },
      ]; };
      return SystemJsNgModuleLoader;
  }());
  /**
   * @param {?} value
   * @param {?} modulePath
   * @param {?} exportName
   * @return {?}
   */
  function checkNotEmpty(value, modulePath, exportName) {
      if (!value) {
          throw new Error("Cannot find '" + exportName + "' in '" + modulePath + "'");
      }
      return value;
  }
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  /**
   * Represents an Embedded Template that can be used to instantiate Embedded Views.
   *
   * You can access a `TemplateRef`, in two ways. Via a directive placed on a `<ng-template>` element
   * (or directive prefixed with `*`) and have the `TemplateRef` for this Embedded View injected into
   * the constructor of the directive using the `TemplateRef` Token. Alternatively you can query for
   * the `TemplateRef` from a Component or a Directive via {\@link Query}.
   *
   * To instantiate Embedded Views based on a Template, use {\@link ViewContainerRef#
   * createEmbeddedView}, which will create the View and attach it to the View Container.
   * \@stable
   * @abstract
   */
  var TemplateRef = /** @class */ (function () {
      function TemplateRef() {
      }
      return TemplateRef;
  }());
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  /**
   * Represents a container where one or more Views can be attached.
   *
   * The container can contain two kinds of Views. Host Views, created by instantiating a
   * {\@link Component} via {\@link #createComponent}, and Embedded Views, created by instantiating an
   * {\@link TemplateRef Embedded Template} via {\@link #createEmbeddedView}.
   *
   * The location of the View Container within the containing View is specified by the Anchor
   * `element`. Each View Container can have only one Anchor Element and each Anchor Element can only
   * have a single View Container.
   *
   * Root elements of Views attached to this container become siblings of the Anchor Element in
   * the Rendered View.
   *
   * To access a `ViewContainerRef` of an Element, you can either place a {\@link Directive} injected
   * with `ViewContainerRef` on the Element, or you obtain it via a {\@link ViewChild} query.
   * \@stable
   * @abstract
   */
  var ViewContainerRef = /** @class */ (function () {
      function ViewContainerRef() {
      }
      return ViewContainerRef;
  }());
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  /**
   * \@stable
   * @abstract
   */
  var ChangeDetectorRef = /** @class */ (function () {
      function ChangeDetectorRef() {
      }
      return ChangeDetectorRef;
  }());
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  /**
   * \@stable
   * @abstract
   */
  var ViewRef = /** @class */ (function (_super) {
      __extends(ViewRef, _super);
      function ViewRef() {
          return _super !== null && _super.apply(this, arguments) || this;
      }
      return ViewRef;
  }(ChangeDetectorRef));
  /**
   * Represents an Angular View.
   *
   * <!-- TODO: move the next two paragraphs to the dev guide -->
   * A View is a fundamental building block of the application UI. It is the smallest grouping of
   * Elements which are created and destroyed together.
   *
   * Properties of elements in a View can change, but the structure (number and order) of elements in
   * a View cannot. Changing the structure of Elements can only be done by inserting, moving or
   * removing nested Views via a {\@link ViewContainerRef}. Each View can contain many View Containers.
   * <!-- /TODO -->
   *
   * ### Example
   *
   * Given this template...
   *
   * ```
   * Count: {{items.length}}
   * <ul>
   *   <li *ngFor="let  item of items">{{item}}</li>
   * </ul>
   * ```
   *
   * We have two {\@link TemplateRef}s:
   *
   * Outer {\@link TemplateRef}:
   * ```
   * Count: {{items.length}}
   * <ul>
   *   <ng-template ngFor let-item [ngForOf]="items"></ng-template>
   * </ul>
   * ```
   *
   * Inner {\@link TemplateRef}:
   * ```
   *   <li>{{item}}</li>
   * ```
   *
   * Notice that the original template is broken down into two separate {\@link TemplateRef}s.
   *
   * The outer/inner {\@link TemplateRef}s are then assembled into views like so:
   *
   * ```
   * <!-- ViewRef: outer-0 -->
   * Count: 2
   * <ul>
   *   <ng-template view-container-ref></ng-template>
   *   <!-- ViewRef: inner-1 --><li>first</li><!-- /ViewRef: inner-1 -->
   *   <!-- ViewRef: inner-2 --><li>second</li><!-- /ViewRef: inner-2 -->
   * </ul>
   * <!-- /ViewRef: outer-0 -->
   * ```
   * \@experimental
   * @abstract
   */
  var EmbeddedViewRef = /** @class */ (function (_super) {
      __extends(EmbeddedViewRef, _super);
      function EmbeddedViewRef() {
          return _super !== null && _super.apply(this, arguments) || this;
      }
      return EmbeddedViewRef;
  }(ViewRef));
  /**
   * @record
   */
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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 EventListener = /** @class */ (function () {
      function EventListener(name, callback) {
          this.name = name;
          this.callback = callback;
      }
      return EventListener;
  }());
  /**
   * \@experimental All debugging apis are currently experimental.
   */
  var DebugNode = /** @class */ (function () {
      function DebugNode(nativeNode, parent, _debugContext) {
          this._debugContext = _debugContext;
          this.nativeNode = nativeNode;
          if (parent && parent instanceof DebugElement) {
              parent.addChild(this);
          }
          else {
              this.parent = null;
          }
          this.listeners = [];
      }
      Object.defineProperty(DebugNode.prototype, "injector", {
          get: /**
           * @return {?}
           */
          function () { return this._debugContext.injector; },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(DebugNode.prototype, "componentInstance", {
          get: /**
           * @return {?}
           */
          function () { return this._debugContext.component; },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(DebugNode.prototype, "context", {
          get: /**
           * @return {?}
           */
          function () { return this._debugContext.context; },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(DebugNode.prototype, "references", {
          get: /**
           * @return {?}
           */
          function () { return this._debugContext.references; },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(DebugNode.prototype, "providerTokens", {
          get: /**
           * @return {?}
           */
          function () { return this._debugContext.providerTokens; },
          enumerable: true,
          configurable: true
      });
      return DebugNode;
  }());
  /**
   * \@experimental All debugging apis are currently experimental.
   */
  var DebugElement = /** @class */ (function (_super) {
      __extends(DebugElement, _super);
      function DebugElement(nativeNode, parent, _debugContext) {
          var _this = _super.call(this, nativeNode, parent, _debugContext) || this;
          _this.properties = {};
          _this.attributes = {};
          _this.classes = {};
          _this.styles = {};
          _this.childNodes = [];
          _this.nativeElement = nativeNode;
          return _this;
      }
      /**
       * @param {?} child
       * @return {?}
       */
      DebugElement.prototype.addChild = /**
       * @param {?} child
       * @return {?}
       */
      function (child) {
          if (child) {
              this.childNodes.push(child);
              child.parent = this;
          }
      };
      /**
       * @param {?} child
       * @return {?}
       */
      DebugElement.prototype.removeChild = /**
       * @param {?} child
       * @return {?}
       */
      function (child) {
          var /** @type {?} */ childIndex = this.childNodes.indexOf(child);
          if (childIndex !== -1) {
              child.parent = null;
              this.childNodes.splice(childIndex, 1);
          }
      };
      /**
       * @param {?} child
       * @param {?} newChildren
       * @return {?}
       */
      DebugElement.prototype.insertChildrenAfter = /**
       * @param {?} child
       * @param {?} newChildren
       * @return {?}
       */
      function (child, newChildren) {
          var _this = this;
          var /** @type {?} */ siblingIndex = this.childNodes.indexOf(child);
          if (siblingIndex !== -1) {
              (_a = this.childNodes).splice.apply(_a, [siblingIndex + 1, 0].concat(newChildren));
              newChildren.forEach(function (c) {
                  if (c.parent) {
                      c.parent.removeChild(c);
                  }
                  c.parent = _this;
              });
          }
          var _a;
      };
      /**
       * @param {?} refChild
       * @param {?} newChild
       * @return {?}
       */
      DebugElement.prototype.insertBefore = /**
       * @param {?} refChild
       * @param {?} newChild
       * @return {?}
       */
      function (refChild, newChild) {
          var /** @type {?} */ refIndex = this.childNodes.indexOf(refChild);
          if (refIndex === -1) {
              this.addChild(newChild);
          }
          else {
              if (newChild.parent) {
                  newChild.parent.removeChild(newChild);
              }
              newChild.parent = this;
              this.childNodes.splice(refIndex, 0, newChild);
          }
      };
      /**
       * @param {?} predicate
       * @return {?}
       */
      DebugElement.prototype.query = /**
       * @param {?} predicate
       * @return {?}
       */
      function (predicate) {
          var /** @type {?} */ results = this.queryAll(predicate);
          return results[0] || null;
      };
      /**
       * @param {?} predicate
       * @return {?}
       */
      DebugElement.prototype.queryAll = /**
       * @param {?} predicate
       * @return {?}
       */
      function (predicate) {
          var /** @type {?} */ matches = [];
          _queryElementChildren(this, predicate, matches);
          return matches;
      };
      /**
       * @param {?} predicate
       * @return {?}
       */
      DebugElement.prototype.queryAllNodes = /**
       * @param {?} predicate
       * @return {?}
       */
      function (predicate) {
          var /** @type {?} */ matches = [];
          _queryNodeChildren(this, predicate, matches);
          return matches;
      };
      Object.defineProperty(DebugElement.prototype, "children", {
          get: /**
           * @return {?}
           */
          function () {
              return /** @type {?} */ (this.childNodes.filter(function (node) { return node instanceof DebugElement; }));
          },
          enumerable: true,
          configurable: true
      });
      /**
       * @param {?} eventName
       * @param {?} eventObj
       * @return {?}
       */
      DebugElement.prototype.triggerEventHandler = /**
       * @param {?} eventName
       * @param {?} eventObj
       * @return {?}
       */
      function (eventName, eventObj) {
          this.listeners.forEach(function (listener) {
              if (listener.name == eventName) {
                  listener.callback(eventObj);
              }
          });
      };
      return DebugElement;
  }(DebugNode));
  /**
   * \@experimental
   * @param {?} debugEls
   * @return {?}
   */
  function asNativeElements(debugEls) {
      return debugEls.map(function (el) { return el.nativeElement; });
  }
  /**
   * @param {?} element
   * @param {?} predicate
   * @param {?} matches
   * @return {?}
   */
  function _queryElementChildren(element, predicate, matches) {
      element.childNodes.forEach(function (node) {
          if (node instanceof DebugElement) {
              if (predicate(node)) {
                  matches.push(node);
              }
              _queryElementChildren(node, predicate, matches);
          }
      });
  }
  /**
   * @param {?} parentNode
   * @param {?} predicate
   * @param {?} matches
   * @return {?}
   */
  function _queryNodeChildren(parentNode, predicate, matches) {
      if (parentNode instanceof DebugElement) {
          parentNode.childNodes.forEach(function (node) {
              if (predicate(node)) {
                  matches.push(node);
              }
              if (node instanceof DebugElement) {
                  _queryNodeChildren(node, predicate, matches);
              }
          });
      }
  }
  // Need to keep the nodes in a global Map so that multiple angular apps are supported.
  var _nativeNodeToDebugNode = new Map();
  /**
   * \@experimental
   * @param {?} nativeNode
   * @return {?}
   */
  function getDebugNode(nativeNode) {
      return _nativeNodeToDebugNode.get(nativeNode) || null;
  }
  /**
   * @return {?}
   */
  
  /**
   * @param {?} node
   * @return {?}
   */
  function indexDebugNode(node) {
      _nativeNodeToDebugNode.set(node.nativeNode, node);
  }
  /**
   * @param {?} node
   * @return {?}
   */
  function removeDebugNodeFromIndex(node) {
      _nativeNodeToDebugNode.delete(node.nativeNode);
  }
  /**
   * A boolean-valued function over a value, possibly including context information
   * regarding that value's position in an array.
   *
   * \@experimental All debugging apis are currently experimental.
   * @record
   */
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  /**
   * @param {?} a
   * @param {?} b
   * @return {?}
   */
  function devModeEqual(a, b) {
      var /** @type {?} */ isListLikeIterableA = isListLikeIterable(a);
      var /** @type {?} */ isListLikeIterableB = isListLikeIterable(b);
      if (isListLikeIterableA && isListLikeIterableB) {
          return areIterablesEqual(a, b, devModeEqual);
      }
      else {
          var /** @type {?} */ isAObject = a && (typeof a === 'object' || typeof a === 'function');
          var /** @type {?} */ isBObject = b && (typeof b === 'object' || typeof b === 'function');
          if (!isListLikeIterableA && isAObject && !isListLikeIterableB && isBObject) {
              return true;
          }
          else {
              return looseIdentical(a, b);
          }
      }
  }
  /**
   * Indicates that the result of a {\@link Pipe} transformation has changed even though the
   * reference has not changed.
   *
   * Wrapped values are unwrapped automatically during the change detection, and the unwrapped value
   * is stored.
   *
   * Example:
   *
   * ```
   * if (this._latestValue === this._latestReturnedValue) {
   *    return this._latestReturnedValue;
   *  } else {
   *    this._latestReturnedValue = this._latestValue;
   *    return WrappedValue.wrap(this._latestValue); // this will force update
   *  }
   * ```
   * \@stable
   */
  var WrappedValue = /** @class */ (function () {
      function WrappedValue(value) {
          this.wrapped = value;
      }
      /** Creates a wrapped value. */
      /**
       * Creates a wrapped value.
       * @param {?} value
       * @return {?}
       */
      WrappedValue.wrap = /**
       * Creates a wrapped value.
       * @param {?} value
       * @return {?}
       */
      function (value) { return new WrappedValue(value); };
      /**
       * Returns the underlying value of a wrapped value.
       * Returns the given `value` when it is not wrapped.
       **/
      /**
       * Returns the underlying value of a wrapped value.
       * Returns the given `value` when it is not wrapped.
       *
       * @param {?} value
       * @return {?}
       */
      WrappedValue.unwrap = /**
       * Returns the underlying value of a wrapped value.
       * Returns the given `value` when it is not wrapped.
       *
       * @param {?} value
       * @return {?}
       */
      function (value) { return WrappedValue.isWrapped(value) ? value.wrapped : value; };
      /** Returns true if `value` is a wrapped value. */
      /**
       * Returns true if `value` is a wrapped value.
       * @param {?} value
       * @return {?}
       */
      WrappedValue.isWrapped = /**
       * Returns true if `value` is a wrapped value.
       * @param {?} value
       * @return {?}
       */
      function (value) { return value instanceof WrappedValue; };
      return WrappedValue;
  }());
  /**
   * Represents a basic change from a previous to a new value.
   * \@stable
   */
  var SimpleChange = /** @class */ (function () {
      function SimpleChange(previousValue, currentValue, firstChange) {
          this.previousValue = previousValue;
          this.currentValue = currentValue;
          this.firstChange = firstChange;
      }
      /**
       * Check whether the new value is the first value assigned.
       */
      /**
       * Check whether the new value is the first value assigned.
       * @return {?}
       */
      SimpleChange.prototype.isFirstChange = /**
       * Check whether the new value is the first value assigned.
       * @return {?}
       */
      function () { return this.firstChange; };
      return SimpleChange;
  }());
  /**
   * @param {?} obj
   * @return {?}
   */
  function isListLikeIterable(obj) {
      if (!isJsObject(obj))
          return false;
      return Array.isArray(obj) ||
          (!(obj instanceof Map) && // JS Map are iterables but return entries as [k, v]
              // JS Map are iterables but return entries as [k, v]
              getSymbolIterator() in obj); // JS Iterable have a Symbol.iterator prop
  }
  /**
   * @param {?} a
   * @param {?} b
   * @param {?} comparator
   * @return {?}
   */
  function areIterablesEqual(a, b, comparator) {
      var /** @type {?} */ iterator1 = a[getSymbolIterator()]();
      var /** @type {?} */ iterator2 = b[getSymbolIterator()]();
      while (true) {
          var /** @type {?} */ item1 = iterator1.next();
          var /** @type {?} */ item2 = iterator2.next();
          if (item1.done && item2.done)
              return true;
          if (item1.done || item2.done)
              return false;
          if (!comparator(item1.value, item2.value))
              return false;
      }
  }
  /**
   * @param {?} obj
   * @param {?} fn
   * @return {?}
   */
  function iterateListLike(obj, fn) {
      if (Array.isArray(obj)) {
          for (var /** @type {?} */ i = 0; i < obj.length; i++) {
              fn(obj[i]);
          }
      }
      else {
          var /** @type {?} */ iterator = obj[getSymbolIterator()]();
          var /** @type {?} */ item = void 0;
          while (!((item = iterator.next()).done)) {
              fn(item.value);
          }
      }
  }
  /**
   * @param {?} o
   * @return {?}
   */
  function isJsObject(o) {
      return o !== null && (typeof o === 'function' || typeof o === 'object');
  }
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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 DefaultIterableDifferFactory = /** @class */ (function () {
      function DefaultIterableDifferFactory() {
      }
      /**
       * @param {?} obj
       * @return {?}
       */
      DefaultIterableDifferFactory.prototype.supports = /**
       * @param {?} obj
       * @return {?}
       */
      function (obj) { return isListLikeIterable(obj); };
      /**
       * @template V
       * @param {?=} trackByFn
       * @return {?}
       */
      DefaultIterableDifferFactory.prototype.create = /**
       * @template V
       * @param {?=} trackByFn
       * @return {?}
       */
      function (trackByFn) {
          return new DefaultIterableDiffer(trackByFn);
      };
      return DefaultIterableDifferFactory;
  }());
  var trackByIdentity = function (index, item) { return item; };
  /**
   * @deprecated v4.0.0 - Should not be part of public API.
   */
  var DefaultIterableDiffer = /** @class */ (function () {
      function DefaultIterableDiffer(trackByFn) {
          this.length = 0;
          this._linkedRecords = null;
          this._unlinkedRecords = null;
          this._previousItHead = null;
          this._itHead = null;
          this._itTail = null;
          this._additionsHead = null;
          this._additionsTail = null;
          this._movesHead = null;
          this._movesTail = null;
          this._removalsHead = null;
          this._removalsTail = null;
          this._identityChangesHead = null;
          this._identityChangesTail = null;
          this._trackByFn = trackByFn || trackByIdentity;
      }
      /**
       * @param {?} fn
       * @return {?}
       */
      DefaultIterableDiffer.prototype.forEachItem = /**
       * @param {?} fn
       * @return {?}
       */
      function (fn) {
          var /** @type {?} */ record;
          for (record = this._itHead; record !== null; record = record._next) {
              fn(record);
          }
      };
      /**
       * @param {?} fn
       * @return {?}
       */
      DefaultIterableDiffer.prototype.forEachOperation = /**
       * @param {?} fn
       * @return {?}
       */
      function (fn) {
          var /** @type {?} */ nextIt = this._itHead;
          var /** @type {?} */ nextRemove = this._removalsHead;
          var /** @type {?} */ addRemoveOffset = 0;
          var /** @type {?} */ moveOffsets = null;
          while (nextIt || nextRemove) {
              // Figure out which is the next record to process
              // Order: remove, add, move
              var /** @type {?} */ record = !nextRemove ||
                  nextIt && /** @type {?} */ ((nextIt.currentIndex)) < getPreviousIndex(nextRemove, addRemoveOffset, moveOffsets) ? /** @type {?} */
                  ((nextIt)) :
                  nextRemove;
              var /** @type {?} */ adjPreviousIndex = getPreviousIndex(record, addRemoveOffset, moveOffsets);
              var /** @type {?} */ currentIndex = record.currentIndex;
              // consume the item, and adjust the addRemoveOffset and update moveDistance if necessary
              if (record === nextRemove) {
                  addRemoveOffset--;
                  nextRemove = nextRemove._nextRemoved;
              }
              else {
                  nextIt = /** @type {?} */ ((nextIt))._next;
                  if (record.previousIndex == null) {
                      addRemoveOffset++;
                  }
                  else {
                      // INVARIANT:  currentIndex < previousIndex
                      if (!moveOffsets)
                          moveOffsets = [];
                      var /** @type {?} */ localMovePreviousIndex = adjPreviousIndex - addRemoveOffset;
                      var /** @type {?} */ localCurrentIndex = /** @type {?} */ ((currentIndex)) - addRemoveOffset;
                      if (localMovePreviousIndex != localCurrentIndex) {
                          for (var /** @type {?} */ i = 0; i < localMovePreviousIndex; i++) {
                              var /** @type {?} */ offset = i < moveOffsets.length ? moveOffsets[i] : (moveOffsets[i] = 0);
                              var /** @type {?} */ index = offset + i;
                              if (localCurrentIndex <= index && index < localMovePreviousIndex) {
                                  moveOffsets[i] = offset + 1;
                              }
                          }
                          var /** @type {?} */ previousIndex = record.previousIndex;
                          moveOffsets[previousIndex] = localCurrentIndex - localMovePreviousIndex;
                      }
                  }
              }
              if (adjPreviousIndex !== currentIndex) {
                  fn(record, adjPreviousIndex, currentIndex);
              }
          }
      };
      /**
       * @param {?} fn
       * @return {?}
       */
      DefaultIterableDiffer.prototype.forEachPreviousItem = /**
       * @param {?} fn
       * @return {?}
       */
      function (fn) {
          var /** @type {?} */ record;
          for (record = this._previousItHead; record !== null; record = record._nextPrevious) {
              fn(record);
          }
      };
      /**
       * @param {?} fn
       * @return {?}
       */
      DefaultIterableDiffer.prototype.forEachAddedItem = /**
       * @param {?} fn
       * @return {?}
       */
      function (fn) {
          var /** @type {?} */ record;
          for (record = this._additionsHead; record !== null; record = record._nextAdded) {
              fn(record);
          }
      };
      /**
       * @param {?} fn
       * @return {?}
       */
      DefaultIterableDiffer.prototype.forEachMovedItem = /**
       * @param {?} fn
       * @return {?}
       */
      function (fn) {
          var /** @type {?} */ record;
          for (record = this._movesHead; record !== null; record = record._nextMoved) {
              fn(record);
          }
      };
      /**
       * @param {?} fn
       * @return {?}
       */
      DefaultIterableDiffer.prototype.forEachRemovedItem = /**
       * @param {?} fn
       * @return {?}
       */
      function (fn) {
          var /** @type {?} */ record;
          for (record = this._removalsHead; record !== null; record = record._nextRemoved) {
              fn(record);
          }
      };
      /**
       * @param {?} fn
       * @return {?}
       */
      DefaultIterableDiffer.prototype.forEachIdentityChange = /**
       * @param {?} fn
       * @return {?}
       */
      function (fn) {
          var /** @type {?} */ record;
          for (record = this._identityChangesHead; record !== null; record = record._nextIdentityChange) {
              fn(record);
          }
      };
      /**
       * @param {?} collection
       * @return {?}
       */
      DefaultIterableDiffer.prototype.diff = /**
       * @param {?} collection
       * @return {?}
       */
      function (collection) {
          if (collection == null)
              collection = [];
          if (!isListLikeIterable(collection)) {
              throw new Error("Error trying to diff '" + stringify(collection) + "'. Only arrays and iterables are allowed");
          }
          if (this.check(collection)) {
              return this;
          }
          else {
              return null;
          }
      };
      /**
       * @return {?}
       */
      DefaultIterableDiffer.prototype.onDestroy = /**
       * @return {?}
       */
      function () { };
      /**
       * @param {?} collection
       * @return {?}
       */
      DefaultIterableDiffer.prototype.check = /**
       * @param {?} collection
       * @return {?}
       */
      function (collection) {
          var _this = this;
          this._reset();
          var /** @type {?} */ record = this._itHead;
          var /** @type {?} */ mayBeDirty = false;
          var /** @type {?} */ index;
          var /** @type {?} */ item;
          var /** @type {?} */ itemTrackBy;
          if (Array.isArray(collection)) {
              (/** @type {?} */ (this)).length = collection.length;
              for (var /** @type {?} */ index_1 = 0; index_1 < this.length; index_1++) {
                  item = collection[index_1];
                  itemTrackBy = this._trackByFn(index_1, item);
                  if (record === null || !looseIdentical(record.trackById, itemTrackBy)) {
                      record = this._mismatch(record, item, itemTrackBy, index_1);
                      mayBeDirty = true;
                  }
                  else {
                      if (mayBeDirty) {
                          // TODO(misko): can we limit this to duplicates only?
                          record = this._verifyReinsertion(record, item, itemTrackBy, index_1);
                      }
                      if (!looseIdentical(record.item, item))
                          this._addIdentityChange(record, item);
                  }
                  record = record._next;
              }
          }
          else {
              index = 0;
              iterateListLike(collection, function (item) {
                  itemTrackBy = _this._trackByFn(index, item);
                  if (record === null || !looseIdentical(record.trackById, itemTrackBy)) {
                      record = _this._mismatch(record, item, itemTrackBy, index);
                      mayBeDirty = true;
                  }
                  else {
                      if (mayBeDirty) {
                          // TODO(misko): can we limit this to duplicates only?
                          record = _this._verifyReinsertion(record, item, itemTrackBy, index);
                      }
                      if (!looseIdentical(record.item, item))
                          _this._addIdentityChange(record, item);
                  }
                  record = record._next;
                  index++;
              });
              (/** @type {?} */ (this)).length = index;
          }
          this._truncate(record);
          (/** @type {?} */ (this)).collection = collection;
          return this.isDirty;
      };
      Object.defineProperty(DefaultIterableDiffer.prototype, "isDirty", {
          /* CollectionChanges is considered dirty if it has any additions, moves, removals, or identity
           * changes.
           */
          get: /**
           * @return {?}
           */
          function () {
              return this._additionsHead !== null || this._movesHead !== null ||
                  this._removalsHead !== null || this._identityChangesHead !== null;
          },
          enumerable: true,
          configurable: true
      });
      /**
       * Reset the state of the change objects to show no changes. This means set previousKey to
       * currentKey, and clear all of the queues (additions, moves, removals).
       * Set the previousIndexes of moved and added items to their currentIndexes
       * Reset the list of additions, moves and removals
       *
       * @internal
       */
      /**
       * Reset the state of the change objects to show no changes. This means set previousKey to
       * currentKey, and clear all of the queues (additions, moves, removals).
       * Set the previousIndexes of moved and added items to their currentIndexes
       * Reset the list of additions, moves and removals
       *
       * \@internal
       * @return {?}
       */
      DefaultIterableDiffer.prototype._reset = /**
       * Reset the state of the change objects to show no changes. This means set previousKey to
       * currentKey, and clear all of the queues (additions, moves, removals).
       * Set the previousIndexes of moved and added items to their currentIndexes
       * Reset the list of additions, moves and removals
       *
       * \@internal
       * @return {?}
       */
      function () {
          if (this.isDirty) {
              var /** @type {?} */ record = void 0;
              var /** @type {?} */ nextRecord = void 0;
              for (record = this._previousItHead = this._itHead; record !== null; record = record._next) {
                  record._nextPrevious = record._next;
              }
              for (record = this._additionsHead; record !== null; record = record._nextAdded) {
                  record.previousIndex = record.currentIndex;
              }
              this._additionsHead = this._additionsTail = null;
              for (record = this._movesHead; record !== null; record = nextRecord) {
                  record.previousIndex = record.currentIndex;
                  nextRecord = record._nextMoved;
              }
              this._movesHead = this._movesTail = null;
              this._removalsHead = this._removalsTail = null;
              this._identityChangesHead = this._identityChangesTail = null;
              // todo(vicb) when assert gets supported
              // assert(!this.isDirty);
          }
      };
      /**
       * This is the core function which handles differences between collections.
       *
       * - `record` is the record which we saw at this position last time. If null then it is a new
       *   item.
       * - `item` is the current item in the collection
       * - `index` is the position of the item in the collection
       *
       * @internal
       */
      /**
       * This is the core function which handles differences between collections.
       *
       * - `record` is the record which we saw at this position last time. If null then it is a new
       *   item.
       * - `item` is the current item in the collection
       * - `index` is the position of the item in the collection
       *
       * \@internal
       * @param {?} record
       * @param {?} item
       * @param {?} itemTrackBy
       * @param {?} index
       * @return {?}
       */
      DefaultIterableDiffer.prototype._mismatch = /**
       * This is the core function which handles differences between collections.
       *
       * - `record` is the record which we saw at this position last time. If null then it is a new
       *   item.
       * - `item` is the current item in the collection
       * - `index` is the position of the item in the collection
       *
       * \@internal
       * @param {?} record
       * @param {?} item
       * @param {?} itemTrackBy
       * @param {?} index
       * @return {?}
       */
      function (record, item, itemTrackBy, index) {
          // The previous record after which we will append the current one.
          var /** @type {?} */ previousRecord;
          if (record === null) {
              previousRecord = this._itTail;
          }
          else {
              previousRecord = record._prev;
              // Remove the record from the collection since we know it does not match the item.
              this._remove(record);
          }
          // Attempt to see if we have seen the item before.
          record = this._linkedRecords === null ? null : this._linkedRecords.get(itemTrackBy, index);
          if (record !== null) {
              // We have seen this before, we need to move it forward in the collection.
              // But first we need to check if identity changed, so we can update in view if necessary
              if (!looseIdentical(record.item, item))
                  this._addIdentityChange(record, item);
              this._moveAfter(record, previousRecord, index);
          }
          else {
              // Never seen it, check evicted list.
              record = this._unlinkedRecords === null ? null : this._unlinkedRecords.get(itemTrackBy, null);
              if (record !== null) {
                  // It is an item which we have evicted earlier: reinsert it back into the list.
                  // But first we need to check if identity changed, so we can update in view if necessary
                  if (!looseIdentical(record.item, item))
                      this._addIdentityChange(record, item);
                  this._reinsertAfter(record, previousRecord, index);
              }
              else {
                  // It is a new item: add it.
                  record =
                      this._addAfter(new IterableChangeRecord_(item, itemTrackBy), previousRecord, index);
              }
          }
          return record;
      };
      /**
       * This check is only needed if an array contains duplicates. (Short circuit of nothing dirty)
       *
       * Use case: `[a, a]` => `[b, a, a]`
       *
       * If we did not have this check then the insertion of `b` would:
       *   1) evict first `a`
       *   2) insert `b` at `0` index.
       *   3) leave `a` at index `1` as is. <-- this is wrong!
       *   3) reinsert `a` at index 2. <-- this is wrong!
       *
       * The correct behavior is:
       *   1) evict first `a`
       *   2) insert `b` at `0` index.
       *   3) reinsert `a` at index 1.
       *   3) move `a` at from `1` to `2`.
       *
       *
       * Double check that we have not evicted a duplicate item. We need to check if the item type may
       * have already been removed:
       * The insertion of b will evict the first 'a'. If we don't reinsert it now it will be reinserted
       * at the end. Which will show up as the two 'a's switching position. This is incorrect, since a
       * better way to think of it is as insert of 'b' rather then switch 'a' with 'b' and then add 'a'
       * at the end.
       *
       * @internal
       */
      /**
       * This check is only needed if an array contains duplicates. (Short circuit of nothing dirty)
       *
       * Use case: `[a, a]` => `[b, a, a]`
       *
       * If we did not have this check then the insertion of `b` would:
       *   1) evict first `a`
       *   2) insert `b` at `0` index.
       *   3) leave `a` at index `1` as is. <-- this is wrong!
       *   3) reinsert `a` at index 2. <-- this is wrong!
       *
       * The correct behavior is:
       *   1) evict first `a`
       *   2) insert `b` at `0` index.
       *   3) reinsert `a` at index 1.
       *   3) move `a` at from `1` to `2`.
       *
       *
       * Double check that we have not evicted a duplicate item. We need to check if the item type may
       * have already been removed:
       * The insertion of b will evict the first 'a'. If we don't reinsert it now it will be reinserted
       * at the end. Which will show up as the two 'a's switching position. This is incorrect, since a
       * better way to think of it is as insert of 'b' rather then switch 'a' with 'b' and then add 'a'
       * at the end.
       *
       * \@internal
       * @param {?} record
       * @param {?} item
       * @param {?} itemTrackBy
       * @param {?} index
       * @return {?}
       */
      DefaultIterableDiffer.prototype._verifyReinsertion = /**
       * This check is only needed if an array contains duplicates. (Short circuit of nothing dirty)
       *
       * Use case: `[a, a]` => `[b, a, a]`
       *
       * If we did not have this check then the insertion of `b` would:
       *   1) evict first `a`
       *   2) insert `b` at `0` index.
       *   3) leave `a` at index `1` as is. <-- this is wrong!
       *   3) reinsert `a` at index 2. <-- this is wrong!
       *
       * The correct behavior is:
       *   1) evict first `a`
       *   2) insert `b` at `0` index.
       *   3) reinsert `a` at index 1.
       *   3) move `a` at from `1` to `2`.
       *
       *
       * Double check that we have not evicted a duplicate item. We need to check if the item type may
       * have already been removed:
       * The insertion of b will evict the first 'a'. If we don't reinsert it now it will be reinserted
       * at the end. Which will show up as the two 'a's switching position. This is incorrect, since a
       * better way to think of it is as insert of 'b' rather then switch 'a' with 'b' and then add 'a'
       * at the end.
       *
       * \@internal
       * @param {?} record
       * @param {?} item
       * @param {?} itemTrackBy
       * @param {?} index
       * @return {?}
       */
      function (record, item, itemTrackBy, index) {
          var /** @type {?} */ reinsertRecord = this._unlinkedRecords === null ? null : this._unlinkedRecords.get(itemTrackBy, null);
          if (reinsertRecord !== null) {
              record = this._reinsertAfter(reinsertRecord, /** @type {?} */ ((record._prev)), index);
          }
          else if (record.currentIndex != index) {
              record.currentIndex = index;
              this._addToMoves(record, index);
          }
          return record;
      };
      /**
       * Get rid of any excess {@link IterableChangeRecord_}s from the previous collection
       *
       * - `record` The first excess {@link IterableChangeRecord_}.
       *
       * @internal
       */
      /**
       * Get rid of any excess {\@link IterableChangeRecord_}s from the previous collection
       *
       * - `record` The first excess {\@link IterableChangeRecord_}.
       *
       * \@internal
       * @param {?} record
       * @return {?}
       */
      DefaultIterableDiffer.prototype._truncate = /**
       * Get rid of any excess {\@link IterableChangeRecord_}s from the previous collection
       *
       * - `record` The first excess {\@link IterableChangeRecord_}.
       *
       * \@internal
       * @param {?} record
       * @return {?}
       */
      function (record) {
          // Anything after that needs to be removed;
          while (record !== null) {
              var /** @type {?} */ nextRecord = record._next;
              this._addToRemovals(this._unlink(record));
              record = nextRecord;
          }
          if (this._unlinkedRecords !== null) {
              this._unlinkedRecords.clear();
          }
          if (this._additionsTail !== null) {
              this._additionsTail._nextAdded = null;
          }
          if (this._movesTail !== null) {
              this._movesTail._nextMoved = null;
          }
          if (this._itTail !== null) {
              this._itTail._next = null;
          }
          if (this._removalsTail !== null) {
              this._removalsTail._nextRemoved = null;
          }
          if (this._identityChangesTail !== null) {
              this._identityChangesTail._nextIdentityChange = null;
          }
      };
      /** @internal */
      /**
       * \@internal
       * @param {?} record
       * @param {?} prevRecord
       * @param {?} index
       * @return {?}
       */
      DefaultIterableDiffer.prototype._reinsertAfter = /**
       * \@internal
       * @param {?} record
       * @param {?} prevRecord
       * @param {?} index
       * @return {?}
       */
      function (record, prevRecord, index) {
          if (this._unlinkedRecords !== null) {
              this._unlinkedRecords.remove(record);
          }
          var /** @type {?} */ prev = record._prevRemoved;
          var /** @type {?} */ next = record._nextRemoved;
          if (prev === null) {
              this._removalsHead = next;
          }
          else {
              prev._nextRemoved = next;
          }
          if (next === null) {
              this._removalsTail = prev;
          }
          else {
              next._prevRemoved = prev;
          }
          this._insertAfter(record, prevRecord, index);
          this._addToMoves(record, index);
          return record;
      };
      /** @internal */
      /**
       * \@internal
       * @param {?} record
       * @param {?} prevRecord
       * @param {?} index
       * @return {?}
       */
      DefaultIterableDiffer.prototype._moveAfter = /**
       * \@internal
       * @param {?} record
       * @param {?} prevRecord
       * @param {?} index
       * @return {?}
       */
      function (record, prevRecord, index) {
          this._unlink(record);
          this._insertAfter(record, prevRecord, index);
          this._addToMoves(record, index);
          return record;
      };
      /** @internal */
      /**
       * \@internal
       * @param {?} record
       * @param {?} prevRecord
       * @param {?} index
       * @return {?}
       */
      DefaultIterableDiffer.prototype._addAfter = /**
       * \@internal
       * @param {?} record
       * @param {?} prevRecord
       * @param {?} index
       * @return {?}
       */
      function (record, prevRecord, index) {
          this._insertAfter(record, prevRecord, index);
          if (this._additionsTail === null) {
              // todo(vicb)
              // assert(this._additionsHead === null);
              this._additionsTail = this._additionsHead = record;
          }
          else {
              // todo(vicb)
              // assert(_additionsTail._nextAdded === null);
              // assert(record._nextAdded === null);
              this._additionsTail = this._additionsTail._nextAdded = record;
          }
          return record;
      };
      /** @internal */
      /**
       * \@internal
       * @param {?} record
       * @param {?} prevRecord
       * @param {?} index
       * @return {?}
       */
      DefaultIterableDiffer.prototype._insertAfter = /**
       * \@internal
       * @param {?} record
       * @param {?} prevRecord
       * @param {?} index
       * @return {?}
       */
      function (record, prevRecord, index) {
          // todo(vicb)
          // assert(record != prevRecord);
          // assert(record._next === null);
          // assert(record._prev === null);
          var /** @type {?} */ next = prevRecord === null ? this._itHead : prevRecord._next;
          // todo(vicb)
          // assert(next != record);
          // assert(prevRecord != record);
          record._next = next;
          record._prev = prevRecord;
          if (next === null) {
              this._itTail = record;
          }
          else {
              next._prev = record;
          }
          if (prevRecord === null) {
              this._itHead = record;
          }
          else {
              prevRecord._next = record;
          }
          if (this._linkedRecords === null) {
              this._linkedRecords = new _DuplicateMap();
          }
          this._linkedRecords.put(record);
          record.currentIndex = index;
          return record;
      };
      /** @internal */
      /**
       * \@internal
       * @param {?} record
       * @return {?}
       */
      DefaultIterableDiffer.prototype._remove = /**
       * \@internal
       * @param {?} record
       * @return {?}
       */
      function (record) {
          return this._addToRemovals(this._unlink(record));
      };
      /** @internal */
      /**
       * \@internal
       * @param {?} record
       * @return {?}
       */
      DefaultIterableDiffer.prototype._unlink = /**
       * \@internal
       * @param {?} record
       * @return {?}
       */
      function (record) {
          if (this._linkedRecords !== null) {
              this._linkedRecords.remove(record);
          }
          var /** @type {?} */ prev = record._prev;
          var /** @type {?} */ next = record._next;
          // todo(vicb)
          // assert((record._prev = null) === null);
          // assert((record._next = null) === null);
          if (prev === null) {
              this._itHead = next;
          }
          else {
              prev._next = next;
          }
          if (next === null) {
              this._itTail = prev;
          }
          else {
              next._prev = prev;
          }
          return record;
      };
      /** @internal */
      /**
       * \@internal
       * @param {?} record
       * @param {?} toIndex
       * @return {?}
       */
      DefaultIterableDiffer.prototype._addToMoves = /**
       * \@internal
       * @param {?} record
       * @param {?} toIndex
       * @return {?}
       */
      function (record, toIndex) {
          // todo(vicb)
          // assert(record._nextMoved === null);
          if (record.previousIndex === toIndex) {
              return record;
          }
          if (this._movesTail === null) {
              // todo(vicb)
              // assert(_movesHead === null);
              this._movesTail = this._movesHead = record;
          }
          else {
              // todo(vicb)
              // assert(_movesTail._nextMoved === null);
              this._movesTail = this._movesTail._nextMoved = record;
          }
          return record;
      };
      /**
       * @param {?} record
       * @return {?}
       */
      DefaultIterableDiffer.prototype._addToRemovals = /**
       * @param {?} record
       * @return {?}
       */
      function (record) {
          if (this._unlinkedRecords === null) {
              this._unlinkedRecords = new _DuplicateMap();
          }
          this._unlinkedRecords.put(record);
          record.currentIndex = null;
          record._nextRemoved = null;
          if (this._removalsTail === null) {
              // todo(vicb)
              // assert(_removalsHead === null);
              this._removalsTail = this._removalsHead = record;
              record._prevRemoved = null;
          }
          else {
              // todo(vicb)
              // assert(_removalsTail._nextRemoved === null);
              // assert(record._nextRemoved === null);
              record._prevRemoved = this._removalsTail;
              this._removalsTail = this._removalsTail._nextRemoved = record;
          }
          return record;
      };
      /** @internal */
      /**
       * \@internal
       * @param {?} record
       * @param {?} item
       * @return {?}
       */
      DefaultIterableDiffer.prototype._addIdentityChange = /**
       * \@internal
       * @param {?} record
       * @param {?} item
       * @return {?}
       */
      function (record, item) {
          record.item = item;
          if (this._identityChangesTail === null) {
              this._identityChangesTail = this._identityChangesHead = record;
          }
          else {
              this._identityChangesTail = this._identityChangesTail._nextIdentityChange = record;
          }
          return record;
      };
      return DefaultIterableDiffer;
  }());
  /**
   * \@stable
   */
  var IterableChangeRecord_ = /** @class */ (function () {
      function IterableChangeRecord_(item, trackById) {
          this.item = item;
          this.trackById = trackById;
          this.currentIndex = null;
          this.previousIndex = null;
          /**
           * \@internal
           */
          this._nextPrevious = null;
          /**
           * \@internal
           */
          this._prev = null;
          /**
           * \@internal
           */
          this._next = null;
          /**
           * \@internal
           */
          this._prevDup = null;
          /**
           * \@internal
           */
          this._nextDup = null;
          /**
           * \@internal
           */
          this._prevRemoved = null;
          /**
           * \@internal
           */
          this._nextRemoved = null;
          /**
           * \@internal
           */
          this._nextAdded = null;
          /**
           * \@internal
           */
          this._nextMoved = null;
          /**
           * \@internal
           */
          this._nextIdentityChange = null;
      }
      return IterableChangeRecord_;
  }());
  var _DuplicateItemRecordList = /** @class */ (function () {
      function _DuplicateItemRecordList() {
          /**
           * \@internal
           */
          this._head = null;
          /**
           * \@internal
           */
          this._tail = null;
      }
      /**
       * Append the record to the list of duplicates.
       *
       * Note: by design all records in the list of duplicates hold the same value in record.item.
       */
      /**
       * Append the record to the list of duplicates.
       *
       * Note: by design all records in the list of duplicates hold the same value in record.item.
       * @param {?} record
       * @return {?}
       */
      _DuplicateItemRecordList.prototype.add = /**
       * Append the record to the list of duplicates.
       *
       * Note: by design all records in the list of duplicates hold the same value in record.item.
       * @param {?} record
       * @return {?}
       */
      function (record) {
          if (this._head === null) {
              this._head = this._tail = record;
              record._nextDup = null;
              record._prevDup = null;
          }
          else {
              /** @type {?} */ ((
              // todo(vicb)
              // assert(record.item ==  _head.item ||
              //       record.item is num && record.item.isNaN && _head.item is num && _head.item.isNaN);
              this._tail))._nextDup = record;
              record._prevDup = this._tail;
              record._nextDup = null;
              this._tail = record;
          }
      };
      // Returns a IterableChangeRecord_ having IterableChangeRecord_.trackById == trackById and
      // IterableChangeRecord_.currentIndex >= atOrAfterIndex
      /**
       * @param {?} trackById
       * @param {?} atOrAfterIndex
       * @return {?}
       */
      _DuplicateItemRecordList.prototype.get = /**
       * @param {?} trackById
       * @param {?} atOrAfterIndex
       * @return {?}
       */
      function (trackById, atOrAfterIndex) {
          var /** @type {?} */ record;
          for (record = this._head; record !== null; record = record._nextDup) {
              if ((atOrAfterIndex === null || atOrAfterIndex <= /** @type {?} */ ((record.currentIndex))) &&
                  looseIdentical(record.trackById, trackById)) {
                  return record;
              }
          }
          return null;
      };
      /**
       * Remove one {@link IterableChangeRecord_} from the list of duplicates.
       *
       * Returns whether the list of duplicates is empty.
       */
      /**
       * Remove one {\@link IterableChangeRecord_} from the list of duplicates.
       *
       * Returns whether the list of duplicates is empty.
       * @param {?} record
       * @return {?}
       */
      _DuplicateItemRecordList.prototype.remove = /**
       * Remove one {\@link IterableChangeRecord_} from the list of duplicates.
       *
       * Returns whether the list of duplicates is empty.
       * @param {?} record
       * @return {?}
       */
      function (record) {
          // todo(vicb)
          // assert(() {
          //  // verify that the record being removed is in the list.
          //  for (IterableChangeRecord_ cursor = _head; cursor != null; cursor = cursor._nextDup) {
          //    if (identical(cursor, record)) return true;
          //  }
          //  return false;
          //});
          var /** @type {?} */ prev = record._prevDup;
          var /** @type {?} */ next = record._nextDup;
          if (prev === null) {
              this._head = next;
          }
          else {
              prev._nextDup = next;
          }
          if (next === null) {
              this._tail = prev;
          }
          else {
              next._prevDup = prev;
          }
          return this._head === null;
      };
      return _DuplicateItemRecordList;
  }());
  var _DuplicateMap = /** @class */ (function () {
      function _DuplicateMap() {
          this.map = new Map();
      }
      /**
       * @param {?} record
       * @return {?}
       */
      _DuplicateMap.prototype.put = /**
       * @param {?} record
       * @return {?}
       */
      function (record) {
          var /** @type {?} */ key = record.trackById;
          var /** @type {?} */ duplicates = this.map.get(key);
          if (!duplicates) {
              duplicates = new _DuplicateItemRecordList();
              this.map.set(key, duplicates);
          }
          duplicates.add(record);
      };
      /**
       * Retrieve the `value` using key. Because the IterableChangeRecord_ value may be one which we
       * have already iterated over, we use the `atOrAfterIndex` to pretend it is not there.
       *
       * Use case: `[a, b, c, a, a]` if we are at index `3` which is the second `a` then asking if we
       * have any more `a`s needs to return the second `a`.
       */
      /**
       * Retrieve the `value` using key. Because the IterableChangeRecord_ value may be one which we
       * have already iterated over, we use the `atOrAfterIndex` to pretend it is not there.
       *
       * Use case: `[a, b, c, a, a]` if we are at index `3` which is the second `a` then asking if we
       * have any more `a`s needs to return the second `a`.
       * @param {?} trackById
       * @param {?} atOrAfterIndex
       * @return {?}
       */
      _DuplicateMap.prototype.get = /**
       * Retrieve the `value` using key. Because the IterableChangeRecord_ value may be one which we
       * have already iterated over, we use the `atOrAfterIndex` to pretend it is not there.
       *
       * Use case: `[a, b, c, a, a]` if we are at index `3` which is the second `a` then asking if we
       * have any more `a`s needs to return the second `a`.
       * @param {?} trackById
       * @param {?} atOrAfterIndex
       * @return {?}
       */
      function (trackById, atOrAfterIndex) {
          var /** @type {?} */ key = trackById;
          var /** @type {?} */ recordList = this.map.get(key);
          return recordList ? recordList.get(trackById, atOrAfterIndex) : null;
      };
      /**
       * Removes a {@link IterableChangeRecord_} from the list of duplicates.
       *
       * The list of duplicates also is removed from the map if it gets empty.
       */
      /**
       * Removes a {\@link IterableChangeRecord_} from the list of duplicates.
       *
       * The list of duplicates also is removed from the map if it gets empty.
       * @param {?} record
       * @return {?}
       */
      _DuplicateMap.prototype.remove = /**
       * Removes a {\@link IterableChangeRecord_} from the list of duplicates.
       *
       * The list of duplicates also is removed from the map if it gets empty.
       * @param {?} record
       * @return {?}
       */
      function (record) {
          var /** @type {?} */ key = record.trackById;
          var /** @type {?} */ recordList = /** @type {?} */ ((this.map.get(key)));
          // Remove the list of duplicates when it gets empty
          if (recordList.remove(record)) {
              this.map.delete(key);
          }
          return record;
      };
      Object.defineProperty(_DuplicateMap.prototype, "isEmpty", {
          get: /**
           * @return {?}
           */
          function () { return this.map.size === 0; },
          enumerable: true,
          configurable: true
      });
      /**
       * @return {?}
       */
      _DuplicateMap.prototype.clear = /**
       * @return {?}
       */
      function () { this.map.clear(); };
      return _DuplicateMap;
  }());
  /**
   * @param {?} item
   * @param {?} addRemoveOffset
   * @param {?} moveOffsets
   * @return {?}
   */
  function getPreviousIndex(item, addRemoveOffset, moveOffsets) {
      var /** @type {?} */ previousIndex = item.previousIndex;
      if (previousIndex === null)
          return previousIndex;
      var /** @type {?} */ moveOffset = 0;
      if (moveOffsets && previousIndex < moveOffsets.length) {
          moveOffset = moveOffsets[previousIndex];
      }
      return previousIndex + addRemoveOffset + moveOffset;
  }
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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 DefaultKeyValueDifferFactory = /** @class */ (function () {
      function DefaultKeyValueDifferFactory() {
      }
      /**
       * @param {?} obj
       * @return {?}
       */
      DefaultKeyValueDifferFactory.prototype.supports = /**
       * @param {?} obj
       * @return {?}
       */
      function (obj) { return obj instanceof Map || isJsObject(obj); };
      /**
       * @template K, V
       * @return {?}
       */
      DefaultKeyValueDifferFactory.prototype.create = /**
       * @template K, V
       * @return {?}
       */
      function () { return new DefaultKeyValueDiffer(); };
      return DefaultKeyValueDifferFactory;
  }());
  var DefaultKeyValueDiffer = /** @class */ (function () {
      function DefaultKeyValueDiffer() {
          this._records = new Map();
          this._mapHead = null;
          this._appendAfter = null;
          this._previousMapHead = null;
          this._changesHead = null;
          this._changesTail = null;
          this._additionsHead = null;
          this._additionsTail = null;
          this._removalsHead = null;
          this._removalsTail = null;
      }
      Object.defineProperty(DefaultKeyValueDiffer.prototype, "isDirty", {
          get: /**
           * @return {?}
           */
          function () {
              return this._additionsHead !== null || this._changesHead !== null ||
                  this._removalsHead !== null;
          },
          enumerable: true,
          configurable: true
      });
      /**
       * @param {?} fn
       * @return {?}
       */
      DefaultKeyValueDiffer.prototype.forEachItem = /**
       * @param {?} fn
       * @return {?}
       */
      function (fn) {
          var /** @type {?} */ record;
          for (record = this._mapHead; record !== null; record = record._next) {
              fn(record);
          }
      };
      /**
       * @param {?} fn
       * @return {?}
       */
      DefaultKeyValueDiffer.prototype.forEachPreviousItem = /**
       * @param {?} fn
       * @return {?}
       */
      function (fn) {
          var /** @type {?} */ record;
          for (record = this._previousMapHead; record !== null; record = record._nextPrevious) {
              fn(record);
          }
      };
      /**
       * @param {?} fn
       * @return {?}
       */
      DefaultKeyValueDiffer.prototype.forEachChangedItem = /**
       * @param {?} fn
       * @return {?}
       */
      function (fn) {
          var /** @type {?} */ record;
          for (record = this._changesHead; record !== null; record = record._nextChanged) {
              fn(record);
          }
      };
      /**
       * @param {?} fn
       * @return {?}
       */
      DefaultKeyValueDiffer.prototype.forEachAddedItem = /**
       * @param {?} fn
       * @return {?}
       */
      function (fn) {
          var /** @type {?} */ record;
          for (record = this._additionsHead; record !== null; record = record._nextAdded) {
              fn(record);
          }
      };
      /**
       * @param {?} fn
       * @return {?}
       */
      DefaultKeyValueDiffer.prototype.forEachRemovedItem = /**
       * @param {?} fn
       * @return {?}
       */
      function (fn) {
          var /** @type {?} */ record;
          for (record = this._removalsHead; record !== null; record = record._nextRemoved) {
              fn(record);
          }
      };
      /**
       * @param {?=} map
       * @return {?}
       */
      DefaultKeyValueDiffer.prototype.diff = /**
       * @param {?=} map
       * @return {?}
       */
      function (map) {
          if (!map) {
              map = new Map();
          }
          else if (!(map instanceof Map || isJsObject(map))) {
              throw new Error("Error trying to diff '" + stringify(map) + "'. Only maps and objects are allowed");
          }
          return this.check(map) ? this : null;
      };
      /**
       * @return {?}
       */
      DefaultKeyValueDiffer.prototype.onDestroy = /**
       * @return {?}
       */
      function () { };
      /**
       * Check the current state of the map vs the previous.
       * The algorithm is optimised for when the keys do no change.
       */
      /**
       * Check the current state of the map vs the previous.
       * The algorithm is optimised for when the keys do no change.
       * @param {?} map
       * @return {?}
       */
      DefaultKeyValueDiffer.prototype.check = /**
       * Check the current state of the map vs the previous.
       * The algorithm is optimised for when the keys do no change.
       * @param {?} map
       * @return {?}
       */
      function (map) {
          var _this = this;
          this._reset();
          var /** @type {?} */ insertBefore = this._mapHead;
          this._appendAfter = null;
          this._forEach(map, function (value, key) {
              if (insertBefore && insertBefore.key === key) {
                  _this._maybeAddToChanges(insertBefore, value);
                  _this._appendAfter = insertBefore;
                  insertBefore = insertBefore._next;
              }
              else {
                  var /** @type {?} */ record = _this._getOrCreateRecordForKey(key, value);
                  insertBefore = _this._insertBeforeOrAppend(insertBefore, record);
              }
          });
          // Items remaining at the end of the list have been deleted
          if (insertBefore) {
              if (insertBefore._prev) {
                  insertBefore._prev._next = null;
              }
              this._removalsHead = insertBefore;
              for (var /** @type {?} */ record = insertBefore; record !== null; record = record._nextRemoved) {
                  if (record === this._mapHead) {
                      this._mapHead = null;
                  }
                  this._records.delete(record.key);
                  record._nextRemoved = record._next;
                  record.previousValue = record.currentValue;
                  record.currentValue = null;
                  record._prev = null;
                  record._next = null;
              }
          }
          // Make sure tails have no next records from previous runs
          if (this._changesTail)
              this._changesTail._nextChanged = null;
          if (this._additionsTail)
              this._additionsTail._nextAdded = null;
          return this.isDirty;
      };
      /**
       * Inserts a record before `before` or append at the end of the list when `before` is null.
       *
       * Notes:
       * - This method appends at `this._appendAfter`,
       * - This method updates `this._appendAfter`,
       * - The return value is the new value for the insertion pointer.
       * @param {?} before
       * @param {?} record
       * @return {?}
       */
      DefaultKeyValueDiffer.prototype._insertBeforeOrAppend = /**
       * Inserts a record before `before` or append at the end of the list when `before` is null.
       *
       * Notes:
       * - This method appends at `this._appendAfter`,
       * - This method updates `this._appendAfter`,
       * - The return value is the new value for the insertion pointer.
       * @param {?} before
       * @param {?} record
       * @return {?}
       */
      function (before, record) {
          if (before) {
              var /** @type {?} */ prev = before._prev;
              record._next = before;
              record._prev = prev;
              before._prev = record;
              if (prev) {
                  prev._next = record;
              }
              if (before === this._mapHead) {
                  this._mapHead = record;
              }
              this._appendAfter = before;
              return before;
          }
          if (this._appendAfter) {
              this._appendAfter._next = record;
              record._prev = this._appendAfter;
          }
          else {
              this._mapHead = record;
          }
          this._appendAfter = record;
          return null;
      };
      /**
       * @param {?} key
       * @param {?} value
       * @return {?}
       */
      DefaultKeyValueDiffer.prototype._getOrCreateRecordForKey = /**
       * @param {?} key
       * @param {?} value
       * @return {?}
       */
      function (key, value) {
          if (this._records.has(key)) {
              var /** @type {?} */ record_1 = /** @type {?} */ ((this._records.get(key)));
              this._maybeAddToChanges(record_1, value);
              var /** @type {?} */ prev = record_1._prev;
              var /** @type {?} */ next = record_1._next;
              if (prev) {
                  prev._next = next;
              }
              if (next) {
                  next._prev = prev;
              }
              record_1._next = null;
              record_1._prev = null;
              return record_1;
          }
          var /** @type {?} */ record = new KeyValueChangeRecord_(key);
          this._records.set(key, record);
          record.currentValue = value;
          this._addToAdditions(record);
          return record;
      };
      /** @internal */
      /**
       * \@internal
       * @return {?}
       */
      DefaultKeyValueDiffer.prototype._reset = /**
       * \@internal
       * @return {?}
       */
      function () {
          if (this.isDirty) {
              var /** @type {?} */ record = void 0;
              // let `_previousMapHead` contain the state of the map before the changes
              this._previousMapHead = this._mapHead;
              for (record = this._previousMapHead; record !== null; record = record._next) {
                  record._nextPrevious = record._next;
              }
              // Update `record.previousValue` with the value of the item before the changes
              // We need to update all changed items (that's those which have been added and changed)
              for (record = this._changesHead; record !== null; record = record._nextChanged) {
                  record.previousValue = record.currentValue;
              }
              for (record = this._additionsHead; record != null; record = record._nextAdded) {
                  record.previousValue = record.currentValue;
              }
              this._changesHead = this._changesTail = null;
              this._additionsHead = this._additionsTail = null;
              this._removalsHead = null;
          }
      };
      /**
       * @param {?} record
       * @param {?} newValue
       * @return {?}
       */
      DefaultKeyValueDiffer.prototype._maybeAddToChanges = /**
       * @param {?} record
       * @param {?} newValue
       * @return {?}
       */
      function (record, newValue) {
          if (!looseIdentical(newValue, record.currentValue)) {
              record.previousValue = record.currentValue;
              record.currentValue = newValue;
              this._addToChanges(record);
          }
      };
      /**
       * @param {?} record
       * @return {?}
       */
      DefaultKeyValueDiffer.prototype._addToAdditions = /**
       * @param {?} record
       * @return {?}
       */
      function (record) {
          if (this._additionsHead === null) {
              this._additionsHead = this._additionsTail = record;
          }
          else {
              /** @type {?} */ ((this._additionsTail))._nextAdded = record;
              this._additionsTail = record;
          }
      };
      /**
       * @param {?} record
       * @return {?}
       */
      DefaultKeyValueDiffer.prototype._addToChanges = /**
       * @param {?} record
       * @return {?}
       */
      function (record) {
          if (this._changesHead === null) {
              this._changesHead = this._changesTail = record;
          }
          else {
              /** @type {?} */ ((this._changesTail))._nextChanged = record;
              this._changesTail = record;
          }
      };
      /**
       * \@internal
       * @template K, V
       * @param {?} obj
       * @param {?} fn
       * @return {?}
       */
      DefaultKeyValueDiffer.prototype._forEach = /**
       * \@internal
       * @template K, V
       * @param {?} obj
       * @param {?} fn
       * @return {?}
       */
      function (obj, fn) {
          if (obj instanceof Map) {
              obj.forEach(fn);
          }
          else {
              Object.keys(obj).forEach(function (k) { return fn(obj[k], k); });
          }
      };
      return DefaultKeyValueDiffer;
  }());
  /**
   * \@stable
   */
  var KeyValueChangeRecord_ = /** @class */ (function () {
      function KeyValueChangeRecord_(key) {
          this.key = key;
          this.previousValue = null;
          this.currentValue = null;
          /**
           * \@internal
           */
          this._nextPrevious = null;
          /**
           * \@internal
           */
          this._next = null;
          /**
           * \@internal
           */
          this._prev = null;
          /**
           * \@internal
           */
          this._nextAdded = null;
          /**
           * \@internal
           */
          this._nextRemoved = null;
          /**
           * \@internal
           */
          this._nextChanged = null;
      }
      return KeyValueChangeRecord_;
  }());
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  /**
   * A strategy for tracking changes over time to an iterable. Used by {\@link NgForOf} to
   * respond to changes in an iterable by effecting equivalent changes in the DOM.
   *
   * \@stable
   * @record
   */
  
  /**
   * An object describing the changes in the `Iterable` collection since last time
   * `IterableDiffer#diff()` was invoked.
   *
   * \@stable
   * @record
   */
  
  /**
   * Record representing the item change information.
   *
   * \@stable
   * @record
   */
  
  /**
   * @deprecated v4.0.0 - Use IterableChangeRecord instead.
   * @record
   */
  
  /**
   * An optional function passed into {\@link NgForOf} that defines how to track
   * items in an iterable (e.g. fby index or id)
   *
   * \@stable
   * @record
   */
  
  /**
   * Provides a factory for {\@link IterableDiffer}.
   *
   * \@stable
   * @record
   */
  
  /**
   * A repository of different iterable diffing strategies used by NgFor, NgClass, and others.
   * \@stable
   */
  var IterableDiffers = /** @class */ (function () {
      function IterableDiffers(factories) {
          this.factories = factories;
      }
      /**
       * @param {?} factories
       * @param {?=} parent
       * @return {?}
       */
      IterableDiffers.create = /**
       * @param {?} factories
       * @param {?=} parent
       * @return {?}
       */
      function (factories, parent) {
          if (parent != null) {
              var /** @type {?} */ copied = parent.factories.slice();
              factories = factories.concat(copied);
              return new IterableDiffers(factories);
          }
          else {
              return new IterableDiffers(factories);
          }
      };
      /**
       * Takes an array of {@link IterableDifferFactory} and returns a provider used to extend the
       * inherited {@link IterableDiffers} instance with the provided factories and return a new
       * {@link IterableDiffers} instance.
       *
       * The following example shows how to extend an existing list of factories,
       * which will only be applied to the injector for this component and its children.
       * This step is all that's required to make a new {@link IterableDiffer} available.
       *
       * ### Example
       *
       * ```
       * @Component({
       *   viewProviders: [
       *     IterableDiffers.extend([new ImmutableListDiffer()])
       *   ]
       * })
       * ```
       */
      /**
       * Takes an array of {\@link IterableDifferFactory} and returns a provider used to extend the
       * inherited {\@link IterableDiffers} instance with the provided factories and return a new
       * {\@link IterableDiffers} instance.
       *
       * The following example shows how to extend an existing list of factories,
       * which will only be applied to the injector for this component and its children.
       * This step is all that's required to make a new {\@link IterableDiffer} available.
       *
       * ### Example
       *
       * ```
       * \@Component({
       *   viewProviders: [
       *     IterableDiffers.extend([new ImmutableListDiffer()])
       *   ]
       * })
       * ```
       * @param {?} factories
       * @return {?}
       */
      IterableDiffers.extend = /**
       * Takes an array of {\@link IterableDifferFactory} and returns a provider used to extend the
       * inherited {\@link IterableDiffers} instance with the provided factories and return a new
       * {\@link IterableDiffers} instance.
       *
       * The following example shows how to extend an existing list of factories,
       * which will only be applied to the injector for this component and its children.
       * This step is all that's required to make a new {\@link IterableDiffer} available.
       *
       * ### Example
       *
       * ```
       * \@Component({
       *   viewProviders: [
       *     IterableDiffers.extend([new ImmutableListDiffer()])
       *   ]
       * })
       * ```
       * @param {?} factories
       * @return {?}
       */
      function (factories) {
          return {
              provide: IterableDiffers,
              useFactory: function (parent) {
                  if (!parent) {
                      // Typically would occur when calling IterableDiffers.extend inside of dependencies passed
                      // to
                      // bootstrap(), which would override default pipes instead of extending them.
                      throw new Error('Cannot extend IterableDiffers without a parent injector');
                  }
                  return IterableDiffers.create(factories, parent);
              },
              // Dependency technically isn't optional, but we can provide a better error message this way.
              deps: [[IterableDiffers, new SkipSelf(), new Optional()]]
          };
      };
      /**
       * @param {?} iterable
       * @return {?}
       */
      IterableDiffers.prototype.find = /**
       * @param {?} iterable
       * @return {?}
       */
      function (iterable) {
          var /** @type {?} */ factory = this.factories.find(function (f) { return f.supports(iterable); });
          if (factory != null) {
              return factory;
          }
          else {
              throw new Error("Cannot find a differ supporting object '" + iterable + "' of type '" + getTypeNameForDebugging(iterable) + "'");
          }
      };
      return IterableDiffers;
  }());
  /**
   * @param {?} type
   * @return {?}
   */
  function getTypeNameForDebugging(type) {
      return type['name'] || typeof type;
  }
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  /**
   * A differ that tracks changes made to an object over time.
   *
   * \@stable
   * @record
   */
  
  /**
   * An object describing the changes in the `Map` or `{[k:string]: string}` since last time
   * `KeyValueDiffer#diff()` was invoked.
   *
   * \@stable
   * @record
   */
  
  /**
   * Record representing the item change information.
   *
   * \@stable
   * @record
   */
  
  /**
   * Provides a factory for {\@link KeyValueDiffer}.
   *
   * \@stable
   * @record
   */
  
  /**
   * A repository of different Map diffing strategies used by NgClass, NgStyle, and others.
   * \@stable
   */
  var KeyValueDiffers = /** @class */ (function () {
      function KeyValueDiffers(factories) {
          this.factories = factories;
      }
      /**
       * @template S
       * @param {?} factories
       * @param {?=} parent
       * @return {?}
       */
      KeyValueDiffers.create = /**
       * @template S
       * @param {?} factories
       * @param {?=} parent
       * @return {?}
       */
      function (factories, parent) {
          if (parent) {
              var /** @type {?} */ copied = parent.factories.slice();
              factories = factories.concat(copied);
          }
          return new KeyValueDiffers(factories);
      };
      /**
       * Takes an array of {@link KeyValueDifferFactory} and returns a provider used to extend the
       * inherited {@link KeyValueDiffers} instance with the provided factories and return a new
       * {@link KeyValueDiffers} instance.
       *
       * The following example shows how to extend an existing list of factories,
       * which will only be applied to the injector for this component and its children.
       * This step is all that's required to make a new {@link KeyValueDiffer} available.
       *
       * ### Example
       *
       * ```
       * @Component({
       *   viewProviders: [
       *     KeyValueDiffers.extend([new ImmutableMapDiffer()])
       *   ]
       * })
       * ```
       */
      /**
       * Takes an array of {\@link KeyValueDifferFactory} and returns a provider used to extend the
       * inherited {\@link KeyValueDiffers} instance with the provided factories and return a new
       * {\@link KeyValueDiffers} instance.
       *
       * The following example shows how to extend an existing list of factories,
       * which will only be applied to the injector for this component and its children.
       * This step is all that's required to make a new {\@link KeyValueDiffer} available.
       *
       * ### Example
       *
       * ```
       * \@Component({
       *   viewProviders: [
       *     KeyValueDiffers.extend([new ImmutableMapDiffer()])
       *   ]
       * })
       * ```
       * @template S
       * @param {?} factories
       * @return {?}
       */
      KeyValueDiffers.extend = /**
       * Takes an array of {\@link KeyValueDifferFactory} and returns a provider used to extend the
       * inherited {\@link KeyValueDiffers} instance with the provided factories and return a new
       * {\@link KeyValueDiffers} instance.
       *
       * The following example shows how to extend an existing list of factories,
       * which will only be applied to the injector for this component and its children.
       * This step is all that's required to make a new {\@link KeyValueDiffer} available.
       *
       * ### Example
       *
       * ```
       * \@Component({
       *   viewProviders: [
       *     KeyValueDiffers.extend([new ImmutableMapDiffer()])
       *   ]
       * })
       * ```
       * @template S
       * @param {?} factories
       * @return {?}
       */
      function (factories) {
          return {
              provide: KeyValueDiffers,
              useFactory: function (parent) {
                  if (!parent) {
                      // Typically would occur when calling KeyValueDiffers.extend inside of dependencies passed
                      // to bootstrap(), which would override default pipes instead of extending them.
                      throw new Error('Cannot extend KeyValueDiffers without a parent injector');
                  }
                  return KeyValueDiffers.create(factories, parent);
              },
              // Dependency technically isn't optional, but we can provide a better error message this way.
              deps: [[KeyValueDiffers, new SkipSelf(), new Optional()]]
          };
      };
      /**
       * @param {?} kv
       * @return {?}
       */
      KeyValueDiffers.prototype.find = /**
       * @param {?} kv
       * @return {?}
       */
      function (kv) {
          var /** @type {?} */ factory = this.factories.find(function (f) { return f.supports(kv); });
          if (factory) {
              return factory;
          }
          throw new Error("Cannot find a differ supporting object '" + kv + "'");
      };
      return KeyValueDiffers;
  }());
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  /**
   * Structural diffing for `Object`s and `Map`s.
   */
  var keyValDiff = [new DefaultKeyValueDifferFactory()];
  /**
   * Structural diffing for `Iterable` types such as `Array`s.
   */
  var iterableDiff = [new DefaultIterableDifferFactory()];
  var defaultIterableDiffers = new IterableDiffers(iterableDiff);
  var defaultKeyValueDiffers = new KeyValueDiffers(keyValDiff);
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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 _CORE_PLATFORM_PROVIDERS = [
      // Set a default platform name for platforms that don't set it explicitly.
      { provide: PLATFORM_ID, useValue: 'unknown' },
      { provide: PlatformRef, deps: [Injector] },
      { provide: TestabilityRegistry, deps: [] },
      { provide: Console, deps: [] },
  ];
  /**
   * This platform has to be included in any other platform
   *
   * \@experimental
   */
  var platformCore = createPlatformFactory(null, 'core', _CORE_PLATFORM_PROVIDERS);
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  /**
   * Provide this token to set the locale of your application.
   * It is used for i18n extraction, by i18n pipes (DatePipe, I18nPluralPipe, CurrencyPipe,
   * DecimalPipe and PercentPipe) and by ICU expressions.
   *
   * See the {\@linkDocs guide/i18n#setting-up-locale i18n guide} for more information.
   *
   * ### Example
   *
   * ```typescript
   * import { LOCALE_ID } from '\@angular/core';
   * import { platformBrowserDynamic } from '\@angular/platform-browser-dynamic';
   * import { AppModule } from './app/app.module';
   *
   * platformBrowserDynamic().bootstrapModule(AppModule, {
   *   providers: [{provide: LOCALE_ID, useValue: 'en-US' }]
   * });
   * ```
   *
   * \@experimental i18n support is experimental.
   */
  var LOCALE_ID = new InjectionToken('LocaleId');
  /**
   * Use this token at bootstrap to provide the content of your translation file (`xtb`,
   * `xlf` or `xlf2`) when you want to translate your application in another language.
   *
   * See the {\@linkDocs guide/i18n#merge i18n guide} for more information.
   *
   * ### Example
   *
   * ```typescript
   * import { TRANSLATIONS } from '\@angular/core';
   * import { platformBrowserDynamic } from '\@angular/platform-browser-dynamic';
   * import { AppModule } from './app/app.module';
   *
   * // content of your translation file
   * const translations = '....';
   *
   * platformBrowserDynamic().bootstrapModule(AppModule, {
   *   providers: [{provide: TRANSLATIONS, useValue: translations }]
   * });
   * ```
   *
   * \@experimental i18n support is experimental.
   */
  var TRANSLATIONS = new InjectionToken('Translations');
  /**
   * Provide this token at bootstrap to set the format of your {\@link TRANSLATIONS}: `xtb`,
   * `xlf` or `xlf2`.
   *
   * See the {\@linkDocs guide/i18n#merge i18n guide} for more information.
   *
   * ### Example
   *
   * ```typescript
   * import { TRANSLATIONS_FORMAT } from '\@angular/core';
   * import { platformBrowserDynamic } from '\@angular/platform-browser-dynamic';
   * import { AppModule } from './app/app.module';
   *
   * platformBrowserDynamic().bootstrapModule(AppModule, {
   *   providers: [{provide: TRANSLATIONS_FORMAT, useValue: 'xlf' }]
   * });
   * ```
   *
   * \@experimental i18n support is experimental.
   */
  var TRANSLATIONS_FORMAT = new InjectionToken('TranslationsFormat');
  /** @enum {number} */
  var MissingTranslationStrategy = {
      Error: 0,
      Warning: 1,
      Ignore: 2,
  };
  MissingTranslationStrategy[MissingTranslationStrategy.Error] = "Error";
  MissingTranslationStrategy[MissingTranslationStrategy.Warning] = "Warning";
  MissingTranslationStrategy[MissingTranslationStrategy.Ignore] = "Ignore";
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  /**
   * @return {?}
   */
  function _iterableDiffersFactory() {
      return defaultIterableDiffers;
  }
  /**
   * @return {?}
   */
  function _keyValueDiffersFactory() {
      return defaultKeyValueDiffers;
  }
  /**
   * @param {?=} locale
   * @return {?}
   */
  function _localeFactory(locale) {
      return locale || 'en-US';
  }
  /**
   * This module includes the providers of \@angular/core that are needed
   * to bootstrap components via `ApplicationRef`.
   *
   * \@experimental
   */
  var ApplicationModule = /** @class */ (function () {
      // Inject ApplicationRef to make it eager...
      function ApplicationModule(appRef) {
      }
      ApplicationModule.decorators = [
          { type: NgModule, args: [{
                      providers: [
                          ApplicationRef,
                          ApplicationInitStatus,
                          Compiler,
                          APP_ID_RANDOM_PROVIDER,
                          { provide: IterableDiffers, useFactory: _iterableDiffersFactory },
                          { provide: KeyValueDiffers, useFactory: _keyValueDiffersFactory },
                          {
                              provide: LOCALE_ID,
                              useFactory: _localeFactory,
                              deps: [[new Inject(LOCALE_ID), new Optional(), new SkipSelf()]]
                          },
                      ]
                  },] },
      ];
      /** @nocollapse */
      ApplicationModule.ctorParameters = function () { return [
          { type: ApplicationRef, },
      ]; };
      return ApplicationModule;
  }());
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  /** @enum {number} */
  var SecurityContext = {
      NONE: 0,
      HTML: 1,
      STYLE: 2,
      SCRIPT: 3,
      URL: 4,
      RESOURCE_URL: 5,
  };
  SecurityContext[SecurityContext.NONE] = "NONE";
  SecurityContext[SecurityContext.HTML] = "HTML";
  SecurityContext[SecurityContext.STYLE] = "STYLE";
  SecurityContext[SecurityContext.SCRIPT] = "SCRIPT";
  SecurityContext[SecurityContext.URL] = "URL";
  SecurityContext[SecurityContext.RESOURCE_URL] = "RESOURCE_URL";
  /**
   * Sanitizer is used by the views to sanitize potentially dangerous values.
   *
   * \@stable
   * @abstract
   */
  var Sanitizer = /** @class */ (function () {
      function Sanitizer() {
      }
      return Sanitizer;
  }());
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  /**
   * Factory for ViewDefinitions/NgModuleDefinitions.
   * We use a function so we can reexeute it in case an error happens and use the given logger
   * function to log the error from the definition of the node, which is shown in all browser
   * logs.
   * @record
   */
  
  /**
   * Function to call console.error at the right source location. This is an indirection
   * via another function as browser will log the location that actually called
   * `console.error`.
   * @record
   */
  
  /**
   * @record
   */
  
  /**
   * @record
   */
  
  /**
   * @record
   */
  
  /**
   * @record
   */
  
  /**
   * @record
   */
  
  /**
   * @record
   */
  
  /**
   * @record
   */
  
  /**
   * @record
   */
  
  /**
   * A node definition in the view.
   *
   * Note: We use one type for all nodes so that loops that loop over all nodes
   * of a ViewDefinition stay monomorphic!
   * @record
   */
  
  /**
   * @record
   */
  
  /**
   * @record
   */
  
  /**
   * @record
   */
  
  /**
   * @record
   */
  
  /**
   * @record
   */
  
  /**
   * @record
   */
  
  /**
   * @record
   */
  
  /**
   * @record
   */
  
  /**
   * @record
   */
  
  /**
   * @record
   */
  
  /**
   * @record
   */
  
  /**
   * @record
   */
  
  /**
   * View instance data.
   * Attention: Adding fields to this is performance sensitive!
   * @record
   */
  
  /**
   * @param {?} view
   * @param {?} priorInitState
   * @param {?} newInitState
   * @return {?}
   */
  function shiftInitState(view, priorInitState, newInitState) {
      // Only update the InitState if we are currently in the prior state.
      // For example, only move into CallingInit if we are in BeforeInit. Only
      // move into CallingContentInit if we are in CallingInit. Normally this will
      // always be true because of how checkCycle is called in checkAndUpdateView.
      // However, if checkAndUpdateView is called recursively or if an exception is
      // thrown while checkAndUpdateView is running, checkAndUpdateView starts over
      // from the beginning. This ensures the state is monotonically increasing,
      // terminating in the AfterInit state, which ensures the Init methods are called
      // at least once and only once.
      var /** @type {?} */ state = view.state;
      var /** @type {?} */ initState = state & 1792;
      if (initState === priorInitState) {
          view.state = (state & ~1792 /* InitState_Mask */) | newInitState;
          view.initIndex = -1;
          return true;
      }
      return initState === newInitState;
  }
  /**
   * @param {?} view
   * @param {?} initState
   * @param {?} index
   * @return {?}
   */
  function shouldCallLifecycleInitHook(view, initState, index) {
      if ((view.state & 1792 /* InitState_Mask */) === initState && view.initIndex <= index) {
          view.initIndex = index + 1;
          return true;
      }
      return false;
  }
  /**
   * @record
   */
  
  /**
   * Data for an instantiated NodeType.Text.
   *
   * Attention: Adding fields to this is performance sensitive!
   * @record
   */
  
  /**
   * Accessor for view.nodes, enforcing that every usage site stays monomorphic.
   * @param {?} view
   * @param {?} index
   * @return {?}
   */
  function asTextData(view, index) {
      return /** @type {?} */ (view.nodes[index]);
  }
  /**
   * Data for an instantiated NodeType.Element.
   *
   * Attention: Adding fields to this is performance sensitive!
   * @record
   */
  
  /**
   * @record
   */
  
  /**
   * @record
   */
  
  /**
   * Accessor for view.nodes, enforcing that every usage site stays monomorphic.
   * @param {?} view
   * @param {?} index
   * @return {?}
   */
  function asElementData(view, index) {
      return /** @type {?} */ (view.nodes[index]);
  }
  /**
   * Data for an instantiated NodeType.Provider.
   *
   * Attention: Adding fields to this is performance sensitive!
   * @record
   */
  
  /**
   * Accessor for view.nodes, enforcing that every usage site stays monomorphic.
   * @param {?} view
   * @param {?} index
   * @return {?}
   */
  function asProviderData(view, index) {
      return /** @type {?} */ (view.nodes[index]);
  }
  /**
   * Data for an instantiated NodeType.PureExpression.
   *
   * Attention: Adding fields to this is performance sensitive!
   * @record
   */
  
  /**
   * Accessor for view.nodes, enforcing that every usage site stays monomorphic.
   * @param {?} view
   * @param {?} index
   * @return {?}
   */
  function asPureExpressionData(view, index) {
      return /** @type {?} */ (view.nodes[index]);
  }
  /**
   * Accessor for view.nodes, enforcing that every usage site stays monomorphic.
   * @param {?} view
   * @param {?} index
   * @return {?}
   */
  function asQueryList(view, index) {
      return /** @type {?} */ (view.nodes[index]);
  }
  /**
   * @record
   */
  
  /**
   * @abstract
   */
  var DebugContext = /** @class */ (function () {
      function DebugContext() {
      }
      return DebugContext;
  }());
  /**
   * @record
   */
  
  /**
   * This object is used to prevent cycles in the source files and to have a place where
   * debug mode can hook it. It is lazily filled when `isDevMode` is known.
   */
  var Services = {
      setCurrentNode: /** @type {?} */ ((undefined)),
      createRootView: /** @type {?} */ ((undefined)),
      createEmbeddedView: /** @type {?} */ ((undefined)),
      createComponentView: /** @type {?} */ ((undefined)),
      createNgModuleRef: /** @type {?} */ ((undefined)),
      overrideProvider: /** @type {?} */ ((undefined)),
      overrideComponentView: /** @type {?} */ ((undefined)),
      clearOverrides: /** @type {?} */ ((undefined)),
      checkAndUpdateView: /** @type {?} */ ((undefined)),
      checkNoChangesView: /** @type {?} */ ((undefined)),
      destroyView: /** @type {?} */ ((undefined)),
      resolveDep: /** @type {?} */ ((undefined)),
      createDebugContext: /** @type {?} */ ((undefined)),
      handleEvent: /** @type {?} */ ((undefined)),
      updateDirectives: /** @type {?} */ ((undefined)),
      updateRenderer: /** @type {?} */ ((undefined)),
      dirtyParentQueries: /** @type {?} */ ((undefined)),
  };
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  /**
   * @param {?} context
   * @param {?} oldValue
   * @param {?} currValue
   * @param {?} isFirstCheck
   * @return {?}
   */
  function expressionChangedAfterItHasBeenCheckedError(context, oldValue, currValue, isFirstCheck) {
      var /** @type {?} */ msg = "ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: '" + oldValue + "'. Current value: '" + currValue + "'.";
      if (isFirstCheck) {
          msg +=
              " It seems like the view has been created after its parent and its children have been dirty checked." +
                  " Has it been created in a change detection hook ?";
      }
      return viewDebugError(msg, context);
  }
  /**
   * @param {?} err
   * @param {?} context
   * @return {?}
   */
  function viewWrappedDebugError(err, context) {
      if (!(err instanceof Error)) {
          // errors that are not Error instances don't have a stack,
          // so it is ok to wrap them into a new Error object...
          err = new Error(err.toString());
      }
      _addDebugContext(err, context);
      return err;
  }
  /**
   * @param {?} msg
   * @param {?} context
   * @return {?}
   */
  function viewDebugError(msg, context) {
      var /** @type {?} */ err = new Error(msg);
      _addDebugContext(err, context);
      return err;
  }
  /**
   * @param {?} err
   * @param {?} context
   * @return {?}
   */
  function _addDebugContext(err, context) {
      (/** @type {?} */ (err))[ERROR_DEBUG_CONTEXT] = context;
      (/** @type {?} */ (err))[ERROR_LOGGER] = context.logError.bind(context);
  }
  /**
   * @param {?} err
   * @return {?}
   */
  function isViewDebugError(err) {
      return !!getDebugContext(err);
  }
  /**
   * @param {?} action
   * @return {?}
   */
  function viewDestroyedError(action) {
      return new Error("ViewDestroyedError: Attempt to use a destroyed view: " + action);
  }
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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 NOOP = function () { };
  var _tokenKeyCache = new Map();
  /**
   * @param {?} token
   * @return {?}
   */
  function tokenKey(token) {
      var /** @type {?} */ key = _tokenKeyCache.get(token);
      if (!key) {
          key = stringify(token) + '_' + _tokenKeyCache.size;
          _tokenKeyCache.set(token, key);
      }
      return key;
  }
  /**
   * @param {?} view
   * @param {?} nodeIdx
   * @param {?} bindingIdx
   * @param {?} value
   * @return {?}
   */
  function unwrapValue(view, nodeIdx, bindingIdx, value) {
      if (WrappedValue.isWrapped(value)) {
          value = WrappedValue.unwrap(value);
          var /** @type {?} */ globalBindingIdx = view.def.nodes[nodeIdx].bindingIndex + bindingIdx;
          var /** @type {?} */ oldValue = WrappedValue.unwrap(view.oldValues[globalBindingIdx]);
          view.oldValues[globalBindingIdx] = new WrappedValue(oldValue);
      }
      return value;
  }
  var UNDEFINED_RENDERER_TYPE_ID = '$$undefined';
  var EMPTY_RENDERER_TYPE_ID = '$$empty';
  /**
   * @param {?} values
   * @return {?}
   */
  function createRendererType2(values) {
      return {
          id: UNDEFINED_RENDERER_TYPE_ID,
          styles: values.styles,
          encapsulation: values.encapsulation,
          data: values.data
      };
  }
  var _renderCompCount = 0;
  /**
   * @param {?=} type
   * @return {?}
   */
  function resolveRendererType2(type) {
      if (type && type.id === UNDEFINED_RENDERER_TYPE_ID) {
          // first time we see this RendererType2. Initialize it...
          var /** @type {?} */ isFilled = ((type.encapsulation != null && type.encapsulation !== ViewEncapsulation.None) ||
              type.styles.length || Object.keys(type.data).length);
          if (isFilled) {
              type.id = "c" + _renderCompCount++;
          }
          else {
              type.id = EMPTY_RENDERER_TYPE_ID;
          }
      }
      if (type && type.id === EMPTY_RENDERER_TYPE_ID) {
          type = null;
      }
      return type || null;
  }
  /**
   * @param {?} view
   * @param {?} def
   * @param {?} bindingIdx
   * @param {?} value
   * @return {?}
   */
  function checkBinding(view, def, bindingIdx, value) {
      var /** @type {?} */ oldValues = view.oldValues;
      if ((view.state & 2 /* FirstCheck */) ||
          !looseIdentical(oldValues[def.bindingIndex + bindingIdx], value)) {
          return true;
      }
      return false;
  }
  /**
   * @param {?} view
   * @param {?} def
   * @param {?} bindingIdx
   * @param {?} value
   * @return {?}
   */
  function checkAndUpdateBinding(view, def, bindingIdx, value) {
      if (checkBinding(view, def, bindingIdx, value)) {
          view.oldValues[def.bindingIndex + bindingIdx] = value;
          return true;
      }
      return false;
  }
  /**
   * @param {?} view
   * @param {?} def
   * @param {?} bindingIdx
   * @param {?} value
   * @return {?}
   */
  function checkBindingNoChanges(view, def, bindingIdx, value) {
      var /** @type {?} */ oldValue = view.oldValues[def.bindingIndex + bindingIdx];
      if ((view.state & 1 /* BeforeFirstCheck */) || !devModeEqual(oldValue, value)) {
          var /** @type {?} */ bindingName = def.bindings[bindingIdx].name;
          throw expressionChangedAfterItHasBeenCheckedError(Services.createDebugContext(view, def.nodeIndex), bindingName + ": " + oldValue, bindingName + ": " + value, (view.state & 1 /* BeforeFirstCheck */) !== 0);
      }
  }
  /**
   * @param {?} view
   * @return {?}
   */
  function markParentViewsForCheck(view) {
      var /** @type {?} */ currView = view;
      while (currView) {
          if (currView.def.flags & 2 /* OnPush */) {
              currView.state |= 8 /* ChecksEnabled */;
          }
          currView = currView.viewContainerParent || currView.parent;
      }
  }
  /**
   * @param {?} view
   * @param {?} endView
   * @return {?}
   */
  function markParentViewsForCheckProjectedViews(view, endView) {
      var /** @type {?} */ currView = view;
      while (currView && currView !== endView) {
          currView.state |= 64 /* CheckProjectedViews */;
          currView = currView.viewContainerParent || currView.parent;
      }
  }
  /**
   * @param {?} view
   * @param {?} nodeIndex
   * @param {?} eventName
   * @param {?} event
   * @return {?}
   */
  function dispatchEvent(view, nodeIndex, eventName, event) {
      try {
          var /** @type {?} */ nodeDef = view.def.nodes[nodeIndex];
          var /** @type {?} */ startView = nodeDef.flags & 33554432 /* ComponentView */ ?
              asElementData(view, nodeIndex).componentView :
              view;
          markParentViewsForCheck(startView);
          return Services.handleEvent(view, nodeIndex, eventName, event);
      }
      catch (/** @type {?} */ e) {
          // Attention: Don't rethrow, as it would cancel Observable subscriptions!
          view.root.errorHandler.handleError(e);
      }
  }
  /**
   * @param {?} view
   * @return {?}
   */
  function declaredViewContainer(view) {
      if (view.parent) {
          var /** @type {?} */ parentView = view.parent;
          return asElementData(parentView, /** @type {?} */ ((view.parentNodeDef)).nodeIndex);
      }
      return null;
  }
  /**
   * for component views, this is the host element.
   * for embedded views, this is the index of the parent node
   * that contains the view container.
   * @param {?} view
   * @return {?}
   */
  function viewParentEl(view) {
      var /** @type {?} */ parentView = view.parent;
      if (parentView) {
          return /** @type {?} */ ((view.parentNodeDef)).parent;
      }
      else {
          return null;
      }
  }
  /**
   * @param {?} view
   * @param {?} def
   * @return {?}
   */
  function renderNode(view, def) {
      switch (def.flags & 201347067 /* Types */) {
          case 1 /* TypeElement */:
              return asElementData(view, def.nodeIndex).renderElement;
          case 2 /* TypeText */:
              return asTextData(view, def.nodeIndex).renderText;
      }
  }
  /**
   * @param {?} target
   * @param {?} name
   * @return {?}
   */
  function elementEventFullName(target, name) {
      return target ? target + ":" + name : name;
  }
  /**
   * @param {?} view
   * @return {?}
   */
  function isComponentView(view) {
      return !!view.parent && !!(/** @type {?} */ ((view.parentNodeDef)).flags & 32768 /* Component */);
  }
  /**
   * @param {?} view
   * @return {?}
   */
  function isEmbeddedView(view) {
      return !!view.parent && !(/** @type {?} */ ((view.parentNodeDef)).flags & 32768 /* Component */);
  }
  /**
   * @param {?} queryId
   * @return {?}
   */
  function filterQueryId(queryId) {
      return 1 << (queryId % 32);
  }
  /**
   * @param {?} matchedQueriesDsl
   * @return {?}
   */
  function splitMatchedQueriesDsl(matchedQueriesDsl) {
      var /** @type {?} */ matchedQueries = {};
      var /** @type {?} */ matchedQueryIds = 0;
      var /** @type {?} */ references = {};
      if (matchedQueriesDsl) {
          matchedQueriesDsl.forEach(function (_a) {
              var queryId = _a[0], valueType = _a[1];
              if (typeof queryId === 'number') {
                  matchedQueries[queryId] = valueType;
                  matchedQueryIds |= filterQueryId(queryId);
              }
              else {
                  references[queryId] = valueType;
              }
          });
      }
      return { matchedQueries: matchedQueries, references: references, matchedQueryIds: matchedQueryIds };
  }
  /**
   * @param {?} deps
   * @param {?=} sourceName
   * @return {?}
   */
  function splitDepsDsl(deps, sourceName) {
      return deps.map(function (value) {
          var /** @type {?} */ token;
          var /** @type {?} */ flags;
          if (Array.isArray(value)) {
              flags = value[0], token = value[1];
          }
          else {
              flags = 0 /* None */;
              token = value;
          }
          if (token && (typeof token === 'function' || typeof token === 'object') && sourceName) {
              Object.defineProperty(token, SOURCE, { value: sourceName, configurable: true });
          }
          return { flags: flags, token: token, tokenKey: tokenKey(token) };
      });
  }
  /**
   * @param {?} view
   * @param {?} renderHost
   * @param {?} def
   * @return {?}
   */
  function getParentRenderElement(view, renderHost, def) {
      var /** @type {?} */ renderParent = def.renderParent;
      if (renderParent) {
          if ((renderParent.flags & 1 /* TypeElement */) === 0 ||
              (renderParent.flags & 33554432 /* ComponentView */) === 0 ||
              (/** @type {?} */ ((renderParent.element)).componentRendererType && /** @type {?} */ ((/** @type {?} */ ((renderParent.element)).componentRendererType)).encapsulation === ViewEncapsulation.Native)) {
              // only children of non components, or children of components with native encapsulation should
              // be attached.
              return asElementData(view, /** @type {?} */ ((def.renderParent)).nodeIndex).renderElement;
          }
      }
      else {
          return renderHost;
      }
  }
  var DEFINITION_CACHE = new WeakMap();
  /**
   * @template D
   * @param {?} factory
   * @return {?}
   */
  function resolveDefinition(factory) {
      var /** @type {?} */ value = /** @type {?} */ (((DEFINITION_CACHE.get(factory))));
      if (!value) {
          value = factory(function () { return NOOP; });
          value.factory = factory;
          DEFINITION_CACHE.set(factory, value);
      }
      return value;
  }
  /**
   * @param {?} view
   * @return {?}
   */
  function rootRenderNodes(view) {
      var /** @type {?} */ renderNodes = [];
      visitRootRenderNodes(view, 0 /* Collect */, undefined, undefined, renderNodes);
      return renderNodes;
  }
  /**
   * @param {?} view
   * @param {?} action
   * @param {?} parentNode
   * @param {?} nextSibling
   * @param {?=} target
   * @return {?}
   */
  function visitRootRenderNodes(view, action, parentNode, nextSibling, target) {
      // We need to re-compute the parent node in case the nodes have been moved around manually
      if (action === 3 /* RemoveChild */) {
          parentNode = view.renderer.parentNode(renderNode(view, /** @type {?} */ ((view.def.lastRenderRootNode))));
      }
      visitSiblingRenderNodes(view, action, 0, view.def.nodes.length - 1, parentNode, nextSibling, target);
  }
  /**
   * @param {?} view
   * @param {?} action
   * @param {?} startIndex
   * @param {?} endIndex
   * @param {?} parentNode
   * @param {?} nextSibling
   * @param {?=} target
   * @return {?}
   */
  function visitSiblingRenderNodes(view, action, startIndex, endIndex, parentNode, nextSibling, target) {
      for (var /** @type {?} */ i = startIndex; i <= endIndex; i++) {
          var /** @type {?} */ nodeDef = view.def.nodes[i];
          if (nodeDef.flags & (1 /* TypeElement */ | 2 /* TypeText */ | 8 /* TypeNgContent */)) {
              visitRenderNode(view, nodeDef, action, parentNode, nextSibling, target);
          }
          // jump to next sibling
          i += nodeDef.childCount;
      }
  }
  /**
   * @param {?} view
   * @param {?} ngContentIndex
   * @param {?} action
   * @param {?} parentNode
   * @param {?} nextSibling
   * @param {?=} target
   * @return {?}
   */
  function visitProjectedRenderNodes(view, ngContentIndex, action, parentNode, nextSibling, target) {
      var /** @type {?} */ compView = view;
      while (compView && !isComponentView(compView)) {
          compView = compView.parent;
      }
      var /** @type {?} */ hostView = /** @type {?} */ ((compView)).parent;
      var /** @type {?} */ hostElDef = viewParentEl(/** @type {?} */ ((compView)));
      var /** @type {?} */ startIndex = /** @type {?} */ ((hostElDef)).nodeIndex + 1;
      var /** @type {?} */ endIndex = /** @type {?} */ ((hostElDef)).nodeIndex + /** @type {?} */ ((hostElDef)).childCount;
      for (var /** @type {?} */ i = startIndex; i <= endIndex; i++) {
          var /** @type {?} */ nodeDef = /** @type {?} */ ((hostView)).def.nodes[i];
          if (nodeDef.ngContentIndex === ngContentIndex) {
              visitRenderNode(/** @type {?} */ ((hostView)), nodeDef, action, parentNode, nextSibling, target);
          }
          // jump to next sibling
          i += nodeDef.childCount;
      }
      if (!/** @type {?} */ ((hostView)).parent) {
          // a root view
          var /** @type {?} */ projectedNodes = view.root.projectableNodes[ngContentIndex];
          if (projectedNodes) {
              for (var /** @type {?} */ i = 0; i < projectedNodes.length; i++) {
                  execRenderNodeAction(view, projectedNodes[i], action, parentNode, nextSibling, target);
              }
          }
      }
  }
  /**
   * @param {?} view
   * @param {?} nodeDef
   * @param {?} action
   * @param {?} parentNode
   * @param {?} nextSibling
   * @param {?=} target
   * @return {?}
   */
  function visitRenderNode(view, nodeDef, action, parentNode, nextSibling, target) {
      if (nodeDef.flags & 8 /* TypeNgContent */) {
          visitProjectedRenderNodes(view, /** @type {?} */ ((nodeDef.ngContent)).index, action, parentNode, nextSibling, target);
      }
      else {
          var /** @type {?} */ rn = renderNode(view, nodeDef);
          if (action === 3 /* RemoveChild */ && (nodeDef.flags & 33554432 /* ComponentView */) &&
              (nodeDef.bindingFlags & 48 /* CatSyntheticProperty */)) {
              // Note: we might need to do both actions.
              if (nodeDef.bindingFlags & (16 /* SyntheticProperty */)) {
                  execRenderNodeAction(view, rn, action, parentNode, nextSibling, target);
              }
              if (nodeDef.bindingFlags & (32 /* SyntheticHostProperty */)) {
                  var /** @type {?} */ compView = asElementData(view, nodeDef.nodeIndex).componentView;
                  execRenderNodeAction(compView, rn, action, parentNode, nextSibling, target);
              }
          }
          else {
              execRenderNodeAction(view, rn, action, parentNode, nextSibling, target);
          }
          if (nodeDef.flags & 16777216 /* EmbeddedViews */) {
              var /** @type {?} */ embeddedViews = /** @type {?} */ ((asElementData(view, nodeDef.nodeIndex).viewContainer))._embeddedViews;
              for (var /** @type {?} */ k = 0; k < embeddedViews.length; k++) {
                  visitRootRenderNodes(embeddedViews[k], action, parentNode, nextSibling, target);
              }
          }
          if (nodeDef.flags & 1 /* TypeElement */ && !/** @type {?} */ ((nodeDef.element)).name) {
              visitSiblingRenderNodes(view, action, nodeDef.nodeIndex + 1, nodeDef.nodeIndex + nodeDef.childCount, parentNode, nextSibling, target);
          }
      }
  }
  /**
   * @param {?} view
   * @param {?} renderNode
   * @param {?} action
   * @param {?} parentNode
   * @param {?} nextSibling
   * @param {?=} target
   * @return {?}
   */
  function execRenderNodeAction(view, renderNode, action, parentNode, nextSibling, target) {
      var /** @type {?} */ renderer = view.renderer;
      switch (action) {
          case 1 /* AppendChild */:
              renderer.appendChild(parentNode, renderNode);
              break;
          case 2 /* InsertBefore */:
              renderer.insertBefore(parentNode, renderNode, nextSibling);
              break;
          case 3 /* RemoveChild */:
              renderer.removeChild(parentNode, renderNode);
              break;
          case 0 /* Collect */:
              /** @type {?} */ ((target)).push(renderNode);
              break;
      }
  }
  var NS_PREFIX_RE = /^:([^:]+):(.+)$/;
  /**
   * @param {?} name
   * @return {?}
   */
  function splitNamespace(name) {
      if (name[0] === ':') {
          var /** @type {?} */ match = /** @type {?} */ ((name.match(NS_PREFIX_RE)));
          return [match[1], match[2]];
      }
      return ['', name];
  }
  /**
   * @param {?} bindings
   * @return {?}
   */
  function calcBindingFlags(bindings) {
      var /** @type {?} */ flags = 0;
      for (var /** @type {?} */ i = 0; i < bindings.length; i++) {
          flags |= bindings[i].flags;
      }
      return flags;
  }
  /**
   * @param {?} valueCount
   * @param {?} constAndInterp
   * @return {?}
   */
  function interpolate(valueCount, constAndInterp) {
      var /** @type {?} */ result = '';
      for (var /** @type {?} */ i = 0; i < valueCount * 2; i = i + 2) {
          result = result + constAndInterp[i] + _toStringWithNull(constAndInterp[i + 1]);
      }
      return result + constAndInterp[valueCount * 2];
  }
  /**
   * @param {?} valueCount
   * @param {?} c0
   * @param {?} a1
   * @param {?} c1
   * @param {?=} a2
   * @param {?=} c2
   * @param {?=} a3
   * @param {?=} c3
   * @param {?=} a4
   * @param {?=} c4
   * @param {?=} a5
   * @param {?=} c5
   * @param {?=} a6
   * @param {?=} c6
   * @param {?=} a7
   * @param {?=} c7
   * @param {?=} a8
   * @param {?=} c8
   * @param {?=} a9
   * @param {?=} c9
   * @return {?}
   */
  function inlineInterpolate(valueCount, c0, a1, c1, a2, c2, a3, c3, a4, c4, a5, c5, a6, c6, a7, c7, a8, c8, a9, c9) {
      switch (valueCount) {
          case 1:
              return c0 + _toStringWithNull(a1) + c1;
          case 2:
              return c0 + _toStringWithNull(a1) + c1 + _toStringWithNull(a2) + c2;
          case 3:
              return c0 + _toStringWithNull(a1) + c1 + _toStringWithNull(a2) + c2 + _toStringWithNull(a3) +
                  c3;
          case 4:
              return c0 + _toStringWithNull(a1) + c1 + _toStringWithNull(a2) + c2 + _toStringWithNull(a3) +
                  c3 + _toStringWithNull(a4) + c4;
          case 5:
              return c0 + _toStringWithNull(a1) + c1 + _toStringWithNull(a2) + c2 + _toStringWithNull(a3) +
                  c3 + _toStringWithNull(a4) + c4 + _toStringWithNull(a5) + c5;
          case 6:
              return c0 + _toStringWithNull(a1) + c1 + _toStringWithNull(a2) + c2 + _toStringWithNull(a3) +
                  c3 + _toStringWithNull(a4) + c4 + _toStringWithNull(a5) + c5 + _toStringWithNull(a6) + c6;
          case 7:
              return c0 + _toStringWithNull(a1) + c1 + _toStringWithNull(a2) + c2 + _toStringWithNull(a3) +
                  c3 + _toStringWithNull(a4) + c4 + _toStringWithNull(a5) + c5 + _toStringWithNull(a6) +
                  c6 + _toStringWithNull(a7) + c7;
          case 8:
              return c0 + _toStringWithNull(a1) + c1 + _toStringWithNull(a2) + c2 + _toStringWithNull(a3) +
                  c3 + _toStringWithNull(a4) + c4 + _toStringWithNull(a5) + c5 + _toStringWithNull(a6) +
                  c6 + _toStringWithNull(a7) + c7 + _toStringWithNull(a8) + c8;
          case 9:
              return c0 + _toStringWithNull(a1) + c1 + _toStringWithNull(a2) + c2 + _toStringWithNull(a3) +
                  c3 + _toStringWithNull(a4) + c4 + _toStringWithNull(a5) + c5 + _toStringWithNull(a6) +
                  c6 + _toStringWithNull(a7) + c7 + _toStringWithNull(a8) + c8 + _toStringWithNull(a9) + c9;
          default:
              throw new Error("Does not support more than 9 expressions");
      }
  }
  /**
   * @param {?} v
   * @return {?}
   */
  function _toStringWithNull(v) {
      return v != null ? v.toString() : '';
  }
  var EMPTY_ARRAY = [];
  var EMPTY_MAP = {};
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  /**
   * @param {?} flags
   * @param {?} matchedQueriesDsl
   * @param {?} ngContentIndex
   * @param {?} childCount
   * @param {?=} handleEvent
   * @param {?=} templateFactory
   * @return {?}
   */
  function anchorDef(flags, matchedQueriesDsl, ngContentIndex, childCount, handleEvent, templateFactory) {
      flags |= 1 /* TypeElement */;
      var _a = splitMatchedQueriesDsl(matchedQueriesDsl), matchedQueries = _a.matchedQueries, references = _a.references, matchedQueryIds = _a.matchedQueryIds;
      var /** @type {?} */ template = templateFactory ? resolveDefinition(templateFactory) : null;
      return {
          // will bet set by the view definition
          nodeIndex: -1,
          parent: null,
          renderParent: null,
          bindingIndex: -1,
          outputIndex: -1,
          // regular values
          flags: flags,
          checkIndex: -1,
          childFlags: 0,
          directChildFlags: 0,
          childMatchedQueries: 0, matchedQueries: matchedQueries, matchedQueryIds: matchedQueryIds, references: references, ngContentIndex: ngContentIndex, childCount: childCount,
          bindings: [],
          bindingFlags: 0,
          outputs: [],
          element: {
              ns: null,
              name: null,
              attrs: null, template: template,
              componentProvider: null,
              componentView: null,
              componentRendererType: null,
              publicProviders: null,
              allProviders: null,
              handleEvent: handleEvent || NOOP
          },
          provider: null,
          text: null,
          query: null,
          ngContent: null
      };
  }
  /**
   * @param {?} checkIndex
   * @param {?} flags
   * @param {?} matchedQueriesDsl
   * @param {?} ngContentIndex
   * @param {?} childCount
   * @param {?} namespaceAndName
   * @param {?=} fixedAttrs
   * @param {?=} bindings
   * @param {?=} outputs
   * @param {?=} handleEvent
   * @param {?=} componentView
   * @param {?=} componentRendererType
   * @return {?}
   */
  function elementDef(checkIndex, flags, matchedQueriesDsl, ngContentIndex, childCount, namespaceAndName, fixedAttrs, bindings, outputs, handleEvent, componentView, componentRendererType) {
      if (fixedAttrs === void 0) { fixedAttrs = []; }
      if (!handleEvent) {
          handleEvent = NOOP;
      }
      var _a = splitMatchedQueriesDsl(matchedQueriesDsl), matchedQueries = _a.matchedQueries, references = _a.references, matchedQueryIds = _a.matchedQueryIds;
      var /** @type {?} */ ns = /** @type {?} */ ((null));
      var /** @type {?} */ name = /** @type {?} */ ((null));
      if (namespaceAndName) {
          _b = splitNamespace(namespaceAndName), ns = _b[0], name = _b[1];
      }
      bindings = bindings || [];
      var /** @type {?} */ bindingDefs = new Array(bindings.length);
      for (var /** @type {?} */ i = 0; i < bindings.length; i++) {
          var _c = bindings[i], bindingFlags = _c[0], namespaceAndName_1 = _c[1], suffixOrSecurityContext = _c[2];
          var _d = splitNamespace(namespaceAndName_1), ns_1 = _d[0], name_1 = _d[1];
          var /** @type {?} */ securityContext = /** @type {?} */ ((undefined));
          var /** @type {?} */ suffix = /** @type {?} */ ((undefined));
          switch (bindingFlags & 15 /* Types */) {
              case 4 /* TypeElementStyle */:
                  suffix = /** @type {?} */ (suffixOrSecurityContext);
                  break;
              case 1 /* TypeElementAttribute */:
              case 8 /* TypeProperty */:
                  securityContext = /** @type {?} */ (suffixOrSecurityContext);
                  break;
          }
          bindingDefs[i] =
              { flags: bindingFlags, ns: ns_1, name: name_1, nonMinifiedName: name_1, securityContext: securityContext, suffix: suffix };
      }
      outputs = outputs || [];
      var /** @type {?} */ outputDefs = new Array(outputs.length);
      for (var /** @type {?} */ i = 0; i < outputs.length; i++) {
          var _e = outputs[i], target = _e[0], eventName = _e[1];
          outputDefs[i] = {
              type: 0 /* ElementOutput */,
              target: /** @type {?} */ (target), eventName: eventName,
              propName: null
          };
      }
      fixedAttrs = fixedAttrs || [];
      var /** @type {?} */ attrs = /** @type {?} */ (fixedAttrs.map(function (_a) {
          var namespaceAndName = _a[0], value = _a[1];
          var _b = splitNamespace(namespaceAndName), ns = _b[0], name = _b[1];
          return [ns, name, value];
      }));
      componentRendererType = resolveRendererType2(componentRendererType);
      if (componentView) {
          flags |= 33554432 /* ComponentView */;
      }
      flags |= 1 /* TypeElement */;
      return {
          // will bet set by the view definition
          nodeIndex: -1,
          parent: null,
          renderParent: null,
          bindingIndex: -1,
          outputIndex: -1,
          // regular values
          checkIndex: checkIndex,
          flags: flags,
          childFlags: 0,
          directChildFlags: 0,
          childMatchedQueries: 0, matchedQueries: matchedQueries, matchedQueryIds: matchedQueryIds, references: references, ngContentIndex: ngContentIndex, childCount: childCount,
          bindings: bindingDefs,
          bindingFlags: calcBindingFlags(bindingDefs),
          outputs: outputDefs,
          element: {
              ns: ns,
              name: name,
              attrs: attrs,
              template: null,
              // will bet set by the view definition
              componentProvider: null,
              componentView: componentView || null,
              componentRendererType: componentRendererType,
              publicProviders: null,
              allProviders: null,
              handleEvent: handleEvent || NOOP,
          },
          provider: null,
          text: null,
          query: null,
          ngContent: null
      };
      var _b;
  }
  /**
   * @param {?} view
   * @param {?} renderHost
   * @param {?} def
   * @return {?}
   */
  function createElement(view, renderHost, def) {
      var /** @type {?} */ elDef = /** @type {?} */ ((def.element));
      var /** @type {?} */ rootSelectorOrNode = view.root.selectorOrNode;
      var /** @type {?} */ renderer = view.renderer;
      var /** @type {?} */ el;
      if (view.parent || !rootSelectorOrNode) {
          if (elDef.name) {
              el = renderer.createElement(elDef.name, elDef.ns);
          }
          else {
              el = renderer.createComment('');
          }
          var /** @type {?} */ parentEl = getParentRenderElement(view, renderHost, def);
          if (parentEl) {
              renderer.appendChild(parentEl, el);
          }
      }
      else {
          el = renderer.selectRootElement(rootSelectorOrNode);
      }
      if (elDef.attrs) {
          for (var /** @type {?} */ i = 0; i < elDef.attrs.length; i++) {
              var _a = elDef.attrs[i], ns = _a[0], name_2 = _a[1], value = _a[2];
              renderer.setAttribute(el, name_2, value, ns);
          }
      }
      return el;
  }
  /**
   * @param {?} view
   * @param {?} compView
   * @param {?} def
   * @param {?} el
   * @return {?}
   */
  function listenToElementOutputs(view, compView, def, el) {
      for (var /** @type {?} */ i = 0; i < def.outputs.length; i++) {
          var /** @type {?} */ output = def.outputs[i];
          var /** @type {?} */ handleEventClosure = renderEventHandlerClosure(view, def.nodeIndex, elementEventFullName(output.target, output.eventName));
          var /** @type {?} */ listenTarget = output.target;
          var /** @type {?} */ listenerView = view;
          if (output.target === 'component') {
              listenTarget = null;
              listenerView = compView;
          }
          var /** @type {?} */ disposable = /** @type {?} */ (listenerView.renderer.listen(listenTarget || el, output.eventName, handleEventClosure)); /** @type {?} */
          ((view.disposables))[def.outputIndex + i] = disposable;
      }
  }
  /**
   * @param {?} view
   * @param {?} index
   * @param {?} eventName
   * @return {?}
   */
  function renderEventHandlerClosure(view, index, eventName) {
      return function (event) { return dispatchEvent(view, index, eventName, event); };
  }
  /**
   * @param {?} view
   * @param {?} def
   * @param {?} v0
   * @param {?} v1
   * @param {?} v2
   * @param {?} v3
   * @param {?} v4
   * @param {?} v5
   * @param {?} v6
   * @param {?} v7
   * @param {?} v8
   * @param {?} v9
   * @return {?}
   */
  function checkAndUpdateElementInline(view, def, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9) {
      var /** @type {?} */ bindLen = def.bindings.length;
      var /** @type {?} */ changed = false;
      if (bindLen > 0 && checkAndUpdateElementValue(view, def, 0, v0))
          changed = true;
      if (bindLen > 1 && checkAndUpdateElementValue(view, def, 1, v1))
          changed = true;
      if (bindLen > 2 && checkAndUpdateElementValue(view, def, 2, v2))
          changed = true;
      if (bindLen > 3 && checkAndUpdateElementValue(view, def, 3, v3))
          changed = true;
      if (bindLen > 4 && checkAndUpdateElementValue(view, def, 4, v4))
          changed = true;
      if (bindLen > 5 && checkAndUpdateElementValue(view, def, 5, v5))
          changed = true;
      if (bindLen > 6 && checkAndUpdateElementValue(view, def, 6, v6))
          changed = true;
      if (bindLen > 7 && checkAndUpdateElementValue(view, def, 7, v7))
          changed = true;
      if (bindLen > 8 && checkAndUpdateElementValue(view, def, 8, v8))
          changed = true;
      if (bindLen > 9 && checkAndUpdateElementValue(view, def, 9, v9))
          changed = true;
      return changed;
  }
  /**
   * @param {?} view
   * @param {?} def
   * @param {?} values
   * @return {?}
   */
  function checkAndUpdateElementDynamic(view, def, values) {
      var /** @type {?} */ changed = false;
      for (var /** @type {?} */ i = 0; i < values.length; i++) {
          if (checkAndUpdateElementValue(view, def, i, values[i]))
              changed = true;
      }
      return changed;
  }
  /**
   * @param {?} view
   * @param {?} def
   * @param {?} bindingIdx
   * @param {?} value
   * @return {?}
   */
  function checkAndUpdateElementValue(view, def, bindingIdx, value) {
      if (!checkAndUpdateBinding(view, def, bindingIdx, value)) {
          return false;
      }
      var /** @type {?} */ binding = def.bindings[bindingIdx];
      var /** @type {?} */ elData = asElementData(view, def.nodeIndex);
      var /** @type {?} */ renderNode$$1 = elData.renderElement;
      var /** @type {?} */ name = /** @type {?} */ ((binding.name));
      switch (binding.flags & 15 /* Types */) {
          case 1 /* TypeElementAttribute */:
              setElementAttribute(view, binding, renderNode$$1, binding.ns, name, value);
              break;
          case 2 /* TypeElementClass */:
              setElementClass(view, renderNode$$1, name, value);
              break;
          case 4 /* TypeElementStyle */:
              setElementStyle(view, binding, renderNode$$1, name, value);
              break;
          case 8 /* TypeProperty */:
              var /** @type {?} */ bindView = (def.flags & 33554432 /* ComponentView */ &&
                  binding.flags & 32 /* SyntheticHostProperty */) ?
                  elData.componentView :
                  view;
              setElementProperty(bindView, binding, renderNode$$1, name, value);
              break;
      }
      return true;
  }
  /**
   * @param {?} view
   * @param {?} binding
   * @param {?} renderNode
   * @param {?} ns
   * @param {?} name
   * @param {?} value
   * @return {?}
   */
  function setElementAttribute(view, binding, renderNode$$1, ns, name, value) {
      var /** @type {?} */ securityContext = binding.securityContext;
      var /** @type {?} */ renderValue = securityContext ? view.root.sanitizer.sanitize(securityContext, value) : value;
      renderValue = renderValue != null ? renderValue.toString() : null;
      var /** @type {?} */ renderer = view.renderer;
      if (value != null) {
          renderer.setAttribute(renderNode$$1, name, renderValue, ns);
      }
      else {
          renderer.removeAttribute(renderNode$$1, name, ns);
      }
  }
  /**
   * @param {?} view
   * @param {?} renderNode
   * @param {?} name
   * @param {?} value
   * @return {?}
   */
  function setElementClass(view, renderNode$$1, name, value) {
      var /** @type {?} */ renderer = view.renderer;
      if (value) {
          renderer.addClass(renderNode$$1, name);
      }
      else {
          renderer.removeClass(renderNode$$1, name);
      }
  }
  /**
   * @param {?} view
   * @param {?} binding
   * @param {?} renderNode
   * @param {?} name
   * @param {?} value
   * @return {?}
   */
  function setElementStyle(view, binding, renderNode$$1, name, value) {
      var /** @type {?} */ renderValue = view.root.sanitizer.sanitize(SecurityContext.STYLE, /** @type {?} */ (value));
      if (renderValue != null) {
          renderValue = renderValue.toString();
          var /** @type {?} */ unit = binding.suffix;
          if (unit != null) {
              renderValue = renderValue + unit;
          }
      }
      else {
          renderValue = null;
      }
      var /** @type {?} */ renderer = view.renderer;
      if (renderValue != null) {
          renderer.setStyle(renderNode$$1, name, renderValue);
      }
      else {
          renderer.removeStyle(renderNode$$1, name);
      }
  }
  /**
   * @param {?} view
   * @param {?} binding
   * @param {?} renderNode
   * @param {?} name
   * @param {?} value
   * @return {?}
   */
  function setElementProperty(view, binding, renderNode$$1, name, value) {
      var /** @type {?} */ securityContext = binding.securityContext;
      var /** @type {?} */ renderValue = securityContext ? view.root.sanitizer.sanitize(securityContext, value) : value;
      view.renderer.setProperty(renderNode$$1, name, renderValue);
  }
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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 UNDEFINED_VALUE = new Object();
  var InjectorRefTokenKey$1 = tokenKey(Injector);
  var NgModuleRefTokenKey = tokenKey(NgModuleRef);
  /**
   * @param {?} flags
   * @param {?} token
   * @param {?} value
   * @param {?} deps
   * @return {?}
   */
  function moduleProvideDef(flags, token, value, deps) {
      // Need to resolve forwardRefs as e.g. for `useValue` we
      // lowered the expression and then stopped evaluating it,
      // i.e. also didn't unwrap it.
      value = resolveForwardRef(value);
      var /** @type {?} */ depDefs = splitDepsDsl(deps, stringify(token));
      return {
          // will bet set by the module definition
          index: -1,
          deps: depDefs, flags: flags, token: token, value: value
      };
  }
  /**
   * @param {?} providers
   * @return {?}
   */
  function moduleDef(providers) {
      var /** @type {?} */ providersByKey = {};
      for (var /** @type {?} */ i = 0; i < providers.length; i++) {
          var /** @type {?} */ provider = providers[i];
          provider.index = i;
          providersByKey[tokenKey(provider.token)] = provider;
      }
      return {
          // Will be filled later...
          factory: null,
          providersByKey: providersByKey,
          providers: providers
      };
  }
  /**
   * @param {?} data
   * @return {?}
   */
  function initNgModule(data) {
      var /** @type {?} */ def = data._def;
      var /** @type {?} */ providers = data._providers = new Array(def.providers.length);
      for (var /** @type {?} */ i = 0; i < def.providers.length; i++) {
          var /** @type {?} */ provDef = def.providers[i];
          if (!(provDef.flags & 4096 /* LazyProvider */)) {
              providers[i] = _createProviderInstance$1(data, provDef);
          }
      }
  }
  /**
   * @param {?} data
   * @param {?} depDef
   * @param {?=} notFoundValue
   * @return {?}
   */
  function resolveNgModuleDep(data, depDef, notFoundValue) {
      if (notFoundValue === void 0) { notFoundValue = Injector.THROW_IF_NOT_FOUND; }
      if (depDef.flags & 8 /* Value */) {
          return depDef.token;
      }
      if (depDef.flags & 2 /* Optional */) {
          notFoundValue = null;
      }
      if (depDef.flags & 1 /* SkipSelf */) {
          return data._parent.get(depDef.token, notFoundValue);
      }
      var /** @type {?} */ tokenKey$$1 = depDef.tokenKey;
      switch (tokenKey$$1) {
          case InjectorRefTokenKey$1:
          case NgModuleRefTokenKey:
              return data;
      }
      var /** @type {?} */ providerDef = data._def.providersByKey[tokenKey$$1];
      if (providerDef) {
          var /** @type {?} */ providerInstance = data._providers[providerDef.index];
          if (providerInstance === undefined) {
              providerInstance = data._providers[providerDef.index] =
                  _createProviderInstance$1(data, providerDef);
          }
          return providerInstance === UNDEFINED_VALUE ? undefined : providerInstance;
      }
      return data._parent.get(depDef.token, notFoundValue);
  }
  /**
   * @param {?} ngModule
   * @param {?} providerDef
   * @return {?}
   */
  function _createProviderInstance$1(ngModule, providerDef) {
      var /** @type {?} */ injectable;
      switch (providerDef.flags & 201347067 /* Types */) {
          case 512 /* TypeClassProvider */:
              injectable = _createClass(ngModule, providerDef.value, providerDef.deps);
              break;
          case 1024 /* TypeFactoryProvider */:
              injectable = _callFactory(ngModule, providerDef.value, providerDef.deps);
              break;
          case 2048 /* TypeUseExistingProvider */:
              injectable = resolveNgModuleDep(ngModule, providerDef.deps[0]);
              break;
          case 256 /* TypeValueProvider */:
              injectable = providerDef.value;
              break;
      }
      return injectable === undefined ? UNDEFINED_VALUE : injectable;
  }
  /**
   * @param {?} ngModule
   * @param {?} ctor
   * @param {?} deps
   * @return {?}
   */
  function _createClass(ngModule, ctor, deps) {
      var /** @type {?} */ len = deps.length;
      switch (len) {
          case 0:
              return new ctor();
          case 1:
              return new ctor(resolveNgModuleDep(ngModule, deps[0]));
          case 2:
              return new ctor(resolveNgModuleDep(ngModule, deps[0]), resolveNgModuleDep(ngModule, deps[1]));
          case 3:
              return new ctor(resolveNgModuleDep(ngModule, deps[0]), resolveNgModuleDep(ngModule, deps[1]), resolveNgModuleDep(ngModule, deps[2]));
          default:
              var /** @type {?} */ depValues = new Array(len);
              for (var /** @type {?} */ i = 0; i < len; i++) {
                  depValues[i] = resolveNgModuleDep(ngModule, deps[i]);
              }
              return new (ctor.bind.apply(ctor, [void 0].concat(depValues)))();
      }
  }
  /**
   * @param {?} ngModule
   * @param {?} factory
   * @param {?} deps
   * @return {?}
   */
  function _callFactory(ngModule, factory, deps) {
      var /** @type {?} */ len = deps.length;
      switch (len) {
          case 0:
              return factory();
          case 1:
              return factory(resolveNgModuleDep(ngModule, deps[0]));
          case 2:
              return factory(resolveNgModuleDep(ngModule, deps[0]), resolveNgModuleDep(ngModule, deps[1]));
          case 3:
              return factory(resolveNgModuleDep(ngModule, deps[0]), resolveNgModuleDep(ngModule, deps[1]), resolveNgModuleDep(ngModule, deps[2]));
          default:
              var /** @type {?} */ depValues = Array(len);
              for (var /** @type {?} */ i = 0; i < len; i++) {
                  depValues[i] = resolveNgModuleDep(ngModule, deps[i]);
              }
              return factory.apply(void 0, depValues);
      }
  }
  /**
   * @param {?} ngModule
   * @param {?} lifecycles
   * @return {?}
   */
  function callNgModuleLifecycle(ngModule, lifecycles) {
      var /** @type {?} */ def = ngModule._def;
      for (var /** @type {?} */ i = 0; i < def.providers.length; i++) {
          var /** @type {?} */ provDef = def.providers[i];
          if (provDef.flags & 131072 /* OnDestroy */) {
              var /** @type {?} */ instance = ngModule._providers[i];
              if (instance && instance !== UNDEFINED_VALUE) {
                  instance.ngOnDestroy();
              }
          }
      }
  }
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  /**
   * @param {?} parentView
   * @param {?} elementData
   * @param {?} viewIndex
   * @param {?} view
   * @return {?}
   */
  function attachEmbeddedView(parentView, elementData, viewIndex, view) {
      var /** @type {?} */ embeddedViews = /** @type {?} */ ((elementData.viewContainer))._embeddedViews;
      if (viewIndex === null || viewIndex === undefined) {
          viewIndex = embeddedViews.length;
      }
      view.viewContainerParent = parentView;
      addToArray(embeddedViews, /** @type {?} */ ((viewIndex)), view);
      attachProjectedView(elementData, view);
      Services.dirtyParentQueries(view);
      var /** @type {?} */ prevView = /** @type {?} */ ((viewIndex)) > 0 ? embeddedViews[/** @type {?} */ ((viewIndex)) - 1] : null;
      renderAttachEmbeddedView(elementData, prevView, view);
  }
  /**
   * @param {?} vcElementData
   * @param {?} view
   * @return {?}
   */
  function attachProjectedView(vcElementData, view) {
      var /** @type {?} */ dvcElementData = declaredViewContainer(view);
      if (!dvcElementData || dvcElementData === vcElementData ||
          view.state & 16 /* IsProjectedView */) {
          return;
      }
      // Note: For performance reasons, we
      // - add a view to template._projectedViews only 1x throughout its lifetime,
      //   and remove it not until the view is destroyed.
      //   (hard, as when a parent view is attached/detached we would need to attach/detach all
      //    nested projected views as well, even accross component boundaries).
      // - don't track the insertion order of views in the projected views array
      //   (hard, as when the views of the same template are inserted different view containers)
      view.state |= 16 /* IsProjectedView */;
      var /** @type {?} */ projectedViews = dvcElementData.template._projectedViews;
      if (!projectedViews) {
          projectedViews = dvcElementData.template._projectedViews = [];
      }
      projectedViews.push(view);
      // Note: we are changing the NodeDef here as we cannot calculate
      // the fact whether a template is used for projection during compilation.
      markNodeAsProjectedTemplate(/** @type {?} */ ((view.parent)).def, /** @type {?} */ ((view.parentNodeDef)));
  }
  /**
   * @param {?} viewDef
   * @param {?} nodeDef
   * @return {?}
   */
  function markNodeAsProjectedTemplate(viewDef, nodeDef) {
      if (nodeDef.flags & 4 /* ProjectedTemplate */) {
          return;
      }
      viewDef.nodeFlags |= 4 /* ProjectedTemplate */;
      nodeDef.flags |= 4 /* ProjectedTemplate */;
      var /** @type {?} */ parentNodeDef = nodeDef.parent;
      while (parentNodeDef) {
          parentNodeDef.childFlags |= 4 /* ProjectedTemplate */;
          parentNodeDef = parentNodeDef.parent;
      }
  }
  /**
   * @param {?} elementData
   * @param {?=} viewIndex
   * @return {?}
   */
  function detachEmbeddedView(elementData, viewIndex) {
      var /** @type {?} */ embeddedViews = /** @type {?} */ ((elementData.viewContainer))._embeddedViews;
      if (viewIndex == null || viewIndex >= embeddedViews.length) {
          viewIndex = embeddedViews.length - 1;
      }
      if (viewIndex < 0) {
          return null;
      }
      var /** @type {?} */ view = embeddedViews[viewIndex];
      view.viewContainerParent = null;
      removeFromArray(embeddedViews, viewIndex);
      // See attachProjectedView for why we don't update projectedViews here.
      Services.dirtyParentQueries(view);
      renderDetachView(view);
      return view;
  }
  /**
   * @param {?} view
   * @return {?}
   */
  function detachProjectedView(view) {
      if (!(view.state & 16 /* IsProjectedView */)) {
          return;
      }
      var /** @type {?} */ dvcElementData = declaredViewContainer(view);
      if (dvcElementData) {
          var /** @type {?} */ projectedViews = dvcElementData.template._projectedViews;
          if (projectedViews) {
              removeFromArray(projectedViews, projectedViews.indexOf(view));
              Services.dirtyParentQueries(view);
          }
      }
  }
  /**
   * @param {?} elementData
   * @param {?} oldViewIndex
   * @param {?} newViewIndex
   * @return {?}
   */
  function moveEmbeddedView(elementData, oldViewIndex, newViewIndex) {
      var /** @type {?} */ embeddedViews = /** @type {?} */ ((elementData.viewContainer))._embeddedViews;
      var /** @type {?} */ view = embeddedViews[oldViewIndex];
      removeFromArray(embeddedViews, oldViewIndex);
      if (newViewIndex == null) {
          newViewIndex = embeddedViews.length;
      }
      addToArray(embeddedViews, newViewIndex, view);
      // Note: Don't need to change projectedViews as the order in there
      // as always invalid...
      Services.dirtyParentQueries(view);
      renderDetachView(view);
      var /** @type {?} */ prevView = newViewIndex > 0 ? embeddedViews[newViewIndex - 1] : null;
      renderAttachEmbeddedView(elementData, prevView, view);
      return view;
  }
  /**
   * @param {?} elementData
   * @param {?} prevView
   * @param {?} view
   * @return {?}
   */
  function renderAttachEmbeddedView(elementData, prevView, view) {
      var /** @type {?} */ prevRenderNode = prevView ? renderNode(prevView, /** @type {?} */ ((prevView.def.lastRenderRootNode))) :
          elementData.renderElement;
      var /** @type {?} */ parentNode = view.renderer.parentNode(prevRenderNode);
      var /** @type {?} */ nextSibling = view.renderer.nextSibling(prevRenderNode);
      // Note: We can't check if `nextSibling` is present, as on WebWorkers it will always be!
      // However, browsers automatically do `appendChild` when there is no `nextSibling`.
      visitRootRenderNodes(view, 2 /* InsertBefore */, parentNode, nextSibling, undefined);
  }
  /**
   * @param {?} view
   * @return {?}
   */
  function renderDetachView(view) {
      visitRootRenderNodes(view, 3 /* RemoveChild */, null, null, undefined);
  }
  /**
   * @param {?} arr
   * @param {?} index
   * @param {?} value
   * @return {?}
   */
  function addToArray(arr, index, value) {
      // perf: array.push is faster than array.splice!
      if (index >= arr.length) {
          arr.push(value);
      }
      else {
          arr.splice(index, 0, value);
      }
  }
  /**
   * @param {?} arr
   * @param {?} index
   * @return {?}
   */
  function removeFromArray(arr, index) {
      // perf: array.pop is faster than array.splice!
      if (index >= arr.length - 1) {
          arr.pop();
      }
      else {
          arr.splice(index, 1);
      }
  }
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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 EMPTY_CONTEXT = new Object();
  /**
   * @param {?} selector
   * @param {?} componentType
   * @param {?} viewDefFactory
   * @param {?} inputs
   * @param {?} outputs
   * @param {?} ngContentSelectors
   * @return {?}
   */
  function createComponentFactory(selector, componentType, viewDefFactory, inputs, outputs, ngContentSelectors) {
      return new ComponentFactory_(selector, componentType, viewDefFactory, inputs, outputs, ngContentSelectors);
  }
  /**
   * @param {?} componentFactory
   * @return {?}
   */
  function getComponentViewDefinitionFactory(componentFactory) {
      return (/** @type {?} */ (componentFactory)).viewDefFactory;
  }
  var ComponentFactory_ = /** @class */ (function (_super) {
      __extends(ComponentFactory_, _super);
      function ComponentFactory_(selector, componentType, viewDefFactory, _inputs, _outputs, ngContentSelectors) {
          var _this = 
          // Attention: this ctor is called as top level function.
          // Putting any logic in here will destroy closure tree shaking!
          _super.call(this) || this;
          _this.selector = selector;
          _this.componentType = componentType;
          _this._inputs = _inputs;
          _this._outputs = _outputs;
          _this.ngContentSelectors = ngContentSelectors;
          _this.viewDefFactory = viewDefFactory;
          return _this;
      }
      Object.defineProperty(ComponentFactory_.prototype, "inputs", {
          get: /**
           * @return {?}
           */
          function () {
              var /** @type {?} */ inputsArr = [];
              var /** @type {?} */ inputs = /** @type {?} */ ((this._inputs));
              for (var /** @type {?} */ propName in inputs) {
                  var /** @type {?} */ templateName = inputs[propName];
                  inputsArr.push({ propName: propName, templateName: templateName });
              }
              return inputsArr;
          },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(ComponentFactory_.prototype, "outputs", {
          get: /**
           * @return {?}
           */
          function () {
              var /** @type {?} */ outputsArr = [];
              for (var /** @type {?} */ propName in this._outputs) {
                  var /** @type {?} */ templateName = this._outputs[propName];
                  outputsArr.push({ propName: propName, templateName: templateName });
              }
              return outputsArr;
          },
          enumerable: true,
          configurable: true
      });
      /**
       * Creates a new component.
       */
      /**
       * Creates a new component.
       * @param {?} injector
       * @param {?=} projectableNodes
       * @param {?=} rootSelectorOrNode
       * @param {?=} ngModule
       * @return {?}
       */
      ComponentFactory_.prototype.create = /**
       * Creates a new component.
       * @param {?} injector
       * @param {?=} projectableNodes
       * @param {?=} rootSelectorOrNode
       * @param {?=} ngModule
       * @return {?}
       */
      function (injector, projectableNodes, rootSelectorOrNode, ngModule) {
          if (!ngModule) {
              throw new Error('ngModule should be provided');
          }
          var /** @type {?} */ viewDef = resolveDefinition(this.viewDefFactory);
          var /** @type {?} */ componentNodeIndex = /** @type {?} */ ((/** @type {?} */ ((viewDef.nodes[0].element)).componentProvider)).nodeIndex;
          var /** @type {?} */ view = Services.createRootView(injector, projectableNodes || [], rootSelectorOrNode, viewDef, ngModule, EMPTY_CONTEXT);
          var /** @type {?} */ component = asProviderData(view, componentNodeIndex).instance;
          if (rootSelectorOrNode) {
              view.renderer.setAttribute(asElementData(view, 0).renderElement, 'ng-version', VERSION.full);
          }
          return new ComponentRef_(view, new ViewRef_(view), component);
      };
      return ComponentFactory_;
  }(ComponentFactory));
  var ComponentRef_ = /** @class */ (function (_super) {
      __extends(ComponentRef_, _super);
      function ComponentRef_(_view, _viewRef, _component) {
          var _this = _super.call(this) || this;
          _this._view = _view;
          _this._viewRef = _viewRef;
          _this._component = _component;
          _this._elDef = _this._view.def.nodes[0];
          _this.hostView = _viewRef;
          _this.changeDetectorRef = _viewRef;
          _this.instance = _component;
          return _this;
      }
      Object.defineProperty(ComponentRef_.prototype, "location", {
          get: /**
           * @return {?}
           */
          function () {
              return new ElementRef(asElementData(this._view, this._elDef.nodeIndex).renderElement);
          },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(ComponentRef_.prototype, "injector", {
          get: /**
           * @return {?}
           */
          function () { return new Injector_(this._view, this._elDef); },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(ComponentRef_.prototype, "componentType", {
          get: /**
           * @return {?}
           */
          function () { return /** @type {?} */ (this._component.constructor); },
          enumerable: true,
          configurable: true
      });
      /**
       * @return {?}
       */
      ComponentRef_.prototype.destroy = /**
       * @return {?}
       */
      function () { this._viewRef.destroy(); };
      /**
       * @param {?} callback
       * @return {?}
       */
      ComponentRef_.prototype.onDestroy = /**
       * @param {?} callback
       * @return {?}
       */
      function (callback) { this._viewRef.onDestroy(callback); };
      return ComponentRef_;
  }(ComponentRef));
  /**
   * @param {?} view
   * @param {?} elDef
   * @param {?} elData
   * @return {?}
   */
  function createViewContainerData(view, elDef, elData) {
      return new ViewContainerRef_(view, elDef, elData);
  }
  var ViewContainerRef_ = /** @class */ (function () {
      function ViewContainerRef_(_view, _elDef, _data) {
          this._view = _view;
          this._elDef = _elDef;
          this._data = _data;
          /**
           * \@internal
           */
          this._embeddedViews = [];
      }
      Object.defineProperty(ViewContainerRef_.prototype, "element", {
          get: /**
           * @return {?}
           */
          function () { return new ElementRef(this._data.renderElement); },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(ViewContainerRef_.prototype, "injector", {
          get: /**
           * @return {?}
           */
          function () { return new Injector_(this._view, this._elDef); },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(ViewContainerRef_.prototype, "parentInjector", {
          get: /**
           * @return {?}
           */
          function () {
              var /** @type {?} */ view = this._view;
              var /** @type {?} */ elDef = this._elDef.parent;
              while (!elDef && view) {
                  elDef = viewParentEl(view);
                  view = /** @type {?} */ ((view.parent));
              }
              return view ? new Injector_(view, elDef) : new Injector_(this._view, null);
          },
          enumerable: true,
          configurable: true
      });
      /**
       * @return {?}
       */
      ViewContainerRef_.prototype.clear = /**
       * @return {?}
       */
      function () {
          var /** @type {?} */ len = this._embeddedViews.length;
          for (var /** @type {?} */ i = len - 1; i >= 0; i--) {
              var /** @type {?} */ view = /** @type {?} */ ((detachEmbeddedView(this._data, i)));
              Services.destroyView(view);
          }
      };
      /**
       * @param {?} index
       * @return {?}
       */
      ViewContainerRef_.prototype.get = /**
       * @param {?} index
       * @return {?}
       */
      function (index) {
          var /** @type {?} */ view = this._embeddedViews[index];
          if (view) {
              var /** @type {?} */ ref = new ViewRef_(view);
              ref.attachToViewContainerRef(this);
              return ref;
          }
          return null;
      };
      Object.defineProperty(ViewContainerRef_.prototype, "length", {
          get: /**
           * @return {?}
           */
          function () { return this._embeddedViews.length; },
          enumerable: true,
          configurable: true
      });
      /**
       * @template C
       * @param {?} templateRef
       * @param {?=} context
       * @param {?=} index
       * @return {?}
       */
      ViewContainerRef_.prototype.createEmbeddedView = /**
       * @template C
       * @param {?} templateRef
       * @param {?=} context
       * @param {?=} index
       * @return {?}
       */
      function (templateRef, context, index) {
          var /** @type {?} */ viewRef = templateRef.createEmbeddedView(context || /** @type {?} */ ({}));
          this.insert(viewRef, index);
          return viewRef;
      };
      /**
       * @template C
       * @param {?} componentFactory
       * @param {?=} index
       * @param {?=} injector
       * @param {?=} projectableNodes
       * @param {?=} ngModuleRef
       * @return {?}
       */
      ViewContainerRef_.prototype.createComponent = /**
       * @template C
       * @param {?} componentFactory
       * @param {?=} index
       * @param {?=} injector
       * @param {?=} projectableNodes
       * @param {?=} ngModuleRef
       * @return {?}
       */
      function (componentFactory, index, injector, projectableNodes, ngModuleRef) {
          var /** @type {?} */ contextInjector = injector || this.parentInjector;
          if (!ngModuleRef && !(componentFactory instanceof ComponentFactoryBoundToModule)) {
              ngModuleRef = contextInjector.get(NgModuleRef);
          }
          var /** @type {?} */ componentRef = componentFactory.create(contextInjector, projectableNodes, undefined, ngModuleRef);
          this.insert(componentRef.hostView, index);
          return componentRef;
      };
      /**
       * @param {?} viewRef
       * @param {?=} index
       * @return {?}
       */
      ViewContainerRef_.prototype.insert = /**
       * @param {?} viewRef
       * @param {?=} index
       * @return {?}
       */
      function (viewRef, index) {
          if (viewRef.destroyed) {
              throw new Error('Cannot insert a destroyed View in a ViewContainer!');
          }
          var /** @type {?} */ viewRef_ = /** @type {?} */ (viewRef);
          var /** @type {?} */ viewData = viewRef_._view;
          attachEmbeddedView(this._view, this._data, index, viewData);
          viewRef_.attachToViewContainerRef(this);
          return viewRef;
      };
      /**
       * @param {?} viewRef
       * @param {?} currentIndex
       * @return {?}
       */
      ViewContainerRef_.prototype.move = /**
       * @param {?} viewRef
       * @param {?} currentIndex
       * @return {?}
       */
      function (viewRef, currentIndex) {
          if (viewRef.destroyed) {
              throw new Error('Cannot move a destroyed View in a ViewContainer!');
          }
          var /** @type {?} */ previousIndex = this._embeddedViews.indexOf(viewRef._view);
          moveEmbeddedView(this._data, previousIndex, currentIndex);
          return viewRef;
      };
      /**
       * @param {?} viewRef
       * @return {?}
       */
      ViewContainerRef_.prototype.indexOf = /**
       * @param {?} viewRef
       * @return {?}
       */
      function (viewRef) {
          return this._embeddedViews.indexOf((/** @type {?} */ (viewRef))._view);
      };
      /**
       * @param {?=} index
       * @return {?}
       */
      ViewContainerRef_.prototype.remove = /**
       * @param {?=} index
       * @return {?}
       */
      function (index) {
          var /** @type {?} */ viewData = detachEmbeddedView(this._data, index);
          if (viewData) {
              Services.destroyView(viewData);
          }
      };
      /**
       * @param {?=} index
       * @return {?}
       */
      ViewContainerRef_.prototype.detach = /**
       * @param {?=} index
       * @return {?}
       */
      function (index) {
          var /** @type {?} */ view = detachEmbeddedView(this._data, index);
          return view ? new ViewRef_(view) : null;
      };
      return ViewContainerRef_;
  }());
  /**
   * @param {?} view
   * @return {?}
   */
  function createChangeDetectorRef(view) {
      return new ViewRef_(view);
  }
  var ViewRef_ = /** @class */ (function () {
      function ViewRef_(_view) {
          this._view = _view;
          this._viewContainerRef = null;
          this._appRef = null;
      }
      Object.defineProperty(ViewRef_.prototype, "rootNodes", {
          get: /**
           * @return {?}
           */
          function () { return rootRenderNodes(this._view); },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(ViewRef_.prototype, "context", {
          get: /**
           * @return {?}
           */
          function () { return this._view.context; },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(ViewRef_.prototype, "destroyed", {
          get: /**
           * @return {?}
           */
          function () { return (this._view.state & 128 /* Destroyed */) !== 0; },
          enumerable: true,
          configurable: true
      });
      /**
       * @return {?}
       */
      ViewRef_.prototype.markForCheck = /**
       * @return {?}
       */
      function () { markParentViewsForCheck(this._view); };
      /**
       * @return {?}
       */
      ViewRef_.prototype.detach = /**
       * @return {?}
       */
      function () { this._view.state &= ~4 /* Attached */; };
      /**
       * @return {?}
       */
      ViewRef_.prototype.detectChanges = /**
       * @return {?}
       */
      function () {
          var /** @type {?} */ fs = this._view.root.rendererFactory;
          if (fs.begin) {
              fs.begin();
          }
          try {
              Services.checkAndUpdateView(this._view);
          }
          finally {
              if (fs.end) {
                  fs.end();
              }
          }
      };
      /**
       * @return {?}
       */
      ViewRef_.prototype.checkNoChanges = /**
       * @return {?}
       */
      function () { Services.checkNoChangesView(this._view); };
      /**
       * @return {?}
       */
      ViewRef_.prototype.reattach = /**
       * @return {?}
       */
      function () { this._view.state |= 4 /* Attached */; };
      /**
       * @param {?} callback
       * @return {?}
       */
      ViewRef_.prototype.onDestroy = /**
       * @param {?} callback
       * @return {?}
       */
      function (callback) {
          if (!this._view.disposables) {
              this._view.disposables = [];
          }
          this._view.disposables.push(/** @type {?} */ (callback));
      };
      /**
       * @return {?}
       */
      ViewRef_.prototype.destroy = /**
       * @return {?}
       */
      function () {
          if (this._appRef) {
              this._appRef.detachView(this);
          }
          else if (this._viewContainerRef) {
              this._viewContainerRef.detach(this._viewContainerRef.indexOf(this));
          }
          Services.destroyView(this._view);
      };
      /**
       * @return {?}
       */
      ViewRef_.prototype.detachFromAppRef = /**
       * @return {?}
       */
      function () {
          this._appRef = null;
          renderDetachView(this._view);
          Services.dirtyParentQueries(this._view);
      };
      /**
       * @param {?} appRef
       * @return {?}
       */
      ViewRef_.prototype.attachToAppRef = /**
       * @param {?} appRef
       * @return {?}
       */
      function (appRef) {
          if (this._viewContainerRef) {
              throw new Error('This view is already attached to a ViewContainer!');
          }
          this._appRef = appRef;
      };
      /**
       * @param {?} vcRef
       * @return {?}
       */
      ViewRef_.prototype.attachToViewContainerRef = /**
       * @param {?} vcRef
       * @return {?}
       */
      function (vcRef) {
          if (this._appRef) {
              throw new Error('This view is already attached directly to the ApplicationRef!');
          }
          this._viewContainerRef = vcRef;
      };
      return ViewRef_;
  }());
  /**
   * @param {?} view
   * @param {?} def
   * @return {?}
   */
  function createTemplateData(view, def) {
      return new TemplateRef_(view, def);
  }
  var TemplateRef_ = /** @class */ (function (_super) {
      __extends(TemplateRef_, _super);
      function TemplateRef_(_parentView, _def) {
          var _this = _super.call(this) || this;
          _this._parentView = _parentView;
          _this._def = _def;
          return _this;
      }
      /**
       * @param {?} context
       * @return {?}
       */
      TemplateRef_.prototype.createEmbeddedView = /**
       * @param {?} context
       * @return {?}
       */
      function (context) {
          return new ViewRef_(Services.createEmbeddedView(this._parentView, this._def, /** @type {?} */ ((/** @type {?} */ ((this._def.element)).template)), context));
      };
      Object.defineProperty(TemplateRef_.prototype, "elementRef", {
          get: /**
           * @return {?}
           */
          function () {
              return new ElementRef(asElementData(this._parentView, this._def.nodeIndex).renderElement);
          },
          enumerable: true,
          configurable: true
      });
      return TemplateRef_;
  }(TemplateRef));
  /**
   * @param {?} view
   * @param {?} elDef
   * @return {?}
   */
  function createInjector(view, elDef) {
      return new Injector_(view, elDef);
  }
  var Injector_ = /** @class */ (function () {
      function Injector_(view, elDef) {
          this.view = view;
          this.elDef = elDef;
      }
      /**
       * @param {?} token
       * @param {?=} notFoundValue
       * @return {?}
       */
      Injector_.prototype.get = /**
       * @param {?} token
       * @param {?=} notFoundValue
       * @return {?}
       */
      function (token, notFoundValue) {
          if (notFoundValue === void 0) { notFoundValue = Injector.THROW_IF_NOT_FOUND; }
          var /** @type {?} */ allowPrivateServices = this.elDef ? (this.elDef.flags & 33554432 /* ComponentView */) !== 0 : false;
          return Services.resolveDep(this.view, this.elDef, allowPrivateServices, { flags: 0 /* None */, token: token, tokenKey: tokenKey(token) }, notFoundValue);
      };
      return Injector_;
  }());
  /**
   * @param {?} view
   * @param {?} index
   * @return {?}
   */
  function nodeValue(view, index) {
      var /** @type {?} */ def = view.def.nodes[index];
      if (def.flags & 1 /* TypeElement */) {
          var /** @type {?} */ elData = asElementData(view, def.nodeIndex);
          return /** @type {?} */ ((def.element)).template ? elData.template : elData.renderElement;
      }
      else if (def.flags & 2 /* TypeText */) {
          return asTextData(view, def.nodeIndex).renderText;
      }
      else if (def.flags & (20224 /* CatProvider */ | 16 /* TypePipe */)) {
          return asProviderData(view, def.nodeIndex).instance;
      }
      throw new Error("Illegal state: read nodeValue for node index " + index);
  }
  /**
   * @param {?} view
   * @return {?}
   */
  function createRendererV1(view) {
      return new RendererAdapter(view.renderer);
  }
  var RendererAdapter = /** @class */ (function () {
      function RendererAdapter(delegate) {
          this.delegate = delegate;
      }
      /**
       * @param {?} selectorOrNode
       * @return {?}
       */
      RendererAdapter.prototype.selectRootElement = /**
       * @param {?} selectorOrNode
       * @return {?}
       */
      function (selectorOrNode) {
          return this.delegate.selectRootElement(selectorOrNode);
      };
      /**
       * @param {?} parent
       * @param {?} namespaceAndName
       * @return {?}
       */
      RendererAdapter.prototype.createElement = /**
       * @param {?} parent
       * @param {?} namespaceAndName
       * @return {?}
       */
      function (parent, namespaceAndName) {
          var _a = splitNamespace(namespaceAndName), ns = _a[0], name = _a[1];
          var /** @type {?} */ el = this.delegate.createElement(name, ns);
          if (parent) {
              this.delegate.appendChild(parent, el);
          }
          return el;
      };
      /**
       * @param {?} hostElement
       * @return {?}
       */
      RendererAdapter.prototype.createViewRoot = /**
       * @param {?} hostElement
       * @return {?}
       */
      function (hostElement) { return hostElement; };
      /**
       * @param {?} parentElement
       * @return {?}
       */
      RendererAdapter.prototype.createTemplateAnchor = /**
       * @param {?} parentElement
       * @return {?}
       */
      function (parentElement) {
          var /** @type {?} */ comment = this.delegate.createComment('');
          if (parentElement) {
              this.delegate.appendChild(parentElement, comment);
          }
          return comment;
      };
      /**
       * @param {?} parentElement
       * @param {?} value
       * @return {?}
       */
      RendererAdapter.prototype.createText = /**
       * @param {?} parentElement
       * @param {?} value
       * @return {?}
       */
      function (parentElement, value) {
          var /** @type {?} */ node = this.delegate.createText(value);
          if (parentElement) {
              this.delegate.appendChild(parentElement, node);
          }
          return node;
      };
      /**
       * @param {?} parentElement
       * @param {?} nodes
       * @return {?}
       */
      RendererAdapter.prototype.projectNodes = /**
       * @param {?} parentElement
       * @param {?} nodes
       * @return {?}
       */
      function (parentElement, nodes) {
          for (var /** @type {?} */ i = 0; i < nodes.length; i++) {
              this.delegate.appendChild(parentElement, nodes[i]);
          }
      };
      /**
       * @param {?} node
       * @param {?} viewRootNodes
       * @return {?}
       */
      RendererAdapter.prototype.attachViewAfter = /**
       * @param {?} node
       * @param {?} viewRootNodes
       * @return {?}
       */
      function (node, viewRootNodes) {
          var /** @type {?} */ parentElement = this.delegate.parentNode(node);
          var /** @type {?} */ nextSibling = this.delegate.nextSibling(node);
          for (var /** @type {?} */ i = 0; i < viewRootNodes.length; i++) {
              this.delegate.insertBefore(parentElement, viewRootNodes[i], nextSibling);
          }
      };
      /**
       * @param {?} viewRootNodes
       * @return {?}
       */
      RendererAdapter.prototype.detachView = /**
       * @param {?} viewRootNodes
       * @return {?}
       */
      function (viewRootNodes) {
          for (var /** @type {?} */ i = 0; i < viewRootNodes.length; i++) {
              var /** @type {?} */ node = viewRootNodes[i];
              var /** @type {?} */ parentElement = this.delegate.parentNode(node);
              this.delegate.removeChild(parentElement, node);
          }
      };
      /**
       * @param {?} hostElement
       * @param {?} viewAllNodes
       * @return {?}
       */
      RendererAdapter.prototype.destroyView = /**
       * @param {?} hostElement
       * @param {?} viewAllNodes
       * @return {?}
       */
      function (hostElement, viewAllNodes) {
          for (var /** @type {?} */ i = 0; i < viewAllNodes.length; i++) {
              /** @type {?} */ ((this.delegate.destroyNode))(viewAllNodes[i]);
          }
      };
      /**
       * @param {?} renderElement
       * @param {?} name
       * @param {?} callback
       * @return {?}
       */
      RendererAdapter.prototype.listen = /**
       * @param {?} renderElement
       * @param {?} name
       * @param {?} callback
       * @return {?}
       */
      function (renderElement, name, callback) {
          return this.delegate.listen(renderElement, name, /** @type {?} */ (callback));
      };
      /**
       * @param {?} target
       * @param {?} name
       * @param {?} callback
       * @return {?}
       */
      RendererAdapter.prototype.listenGlobal = /**
       * @param {?} target
       * @param {?} name
       * @param {?} callback
       * @return {?}
       */
      function (target, name, callback) {
          return this.delegate.listen(target, name, /** @type {?} */ (callback));
      };
      /**
       * @param {?} renderElement
       * @param {?} propertyName
       * @param {?} propertyValue
       * @return {?}
       */
      RendererAdapter.prototype.setElementProperty = /**
       * @param {?} renderElement
       * @param {?} propertyName
       * @param {?} propertyValue
       * @return {?}
       */
      function (renderElement, propertyName, propertyValue) {
          this.delegate.setProperty(renderElement, propertyName, propertyValue);
      };
      /**
       * @param {?} renderElement
       * @param {?} namespaceAndName
       * @param {?} attributeValue
       * @return {?}
       */
      RendererAdapter.prototype.setElementAttribute = /**
       * @param {?} renderElement
       * @param {?} namespaceAndName
       * @param {?} attributeValue
       * @return {?}
       */
      function (renderElement, namespaceAndName, attributeValue) {
          var _a = splitNamespace(namespaceAndName), ns = _a[0], name = _a[1];
          if (attributeValue != null) {
              this.delegate.setAttribute(renderElement, name, attributeValue, ns);
          }
          else {
              this.delegate.removeAttribute(renderElement, name, ns);
          }
      };
      /**
       * @param {?} renderElement
       * @param {?} propertyName
       * @param {?} propertyValue
       * @return {?}
       */
      RendererAdapter.prototype.setBindingDebugInfo = /**
       * @param {?} renderElement
       * @param {?} propertyName
       * @param {?} propertyValue
       * @return {?}
       */
      function (renderElement, propertyName, propertyValue) { };
      /**
       * @param {?} renderElement
       * @param {?} className
       * @param {?} isAdd
       * @return {?}
       */
      RendererAdapter.prototype.setElementClass = /**
       * @param {?} renderElement
       * @param {?} className
       * @param {?} isAdd
       * @return {?}
       */
      function (renderElement, className, isAdd) {
          if (isAdd) {
              this.delegate.addClass(renderElement, className);
          }
          else {
              this.delegate.removeClass(renderElement, className);
          }
      };
      /**
       * @param {?} renderElement
       * @param {?} styleName
       * @param {?} styleValue
       * @return {?}
       */
      RendererAdapter.prototype.setElementStyle = /**
       * @param {?} renderElement
       * @param {?} styleName
       * @param {?} styleValue
       * @return {?}
       */
      function (renderElement, styleName, styleValue) {
          if (styleValue != null) {
              this.delegate.setStyle(renderElement, styleName, styleValue);
          }
          else {
              this.delegate.removeStyle(renderElement, styleName);
          }
      };
      /**
       * @param {?} renderElement
       * @param {?} methodName
       * @param {?} args
       * @return {?}
       */
      RendererAdapter.prototype.invokeElementMethod = /**
       * @param {?} renderElement
       * @param {?} methodName
       * @param {?} args
       * @return {?}
       */
      function (renderElement, methodName, args) {
          (/** @type {?} */ (renderElement))[methodName].apply(renderElement, args);
      };
      /**
       * @param {?} renderNode
       * @param {?} text
       * @return {?}
       */
      RendererAdapter.prototype.setText = /**
       * @param {?} renderNode
       * @param {?} text
       * @return {?}
       */
      function (renderNode$$1, text) { this.delegate.setValue(renderNode$$1, text); };
      /**
       * @return {?}
       */
      RendererAdapter.prototype.animate = /**
       * @return {?}
       */
      function () { throw new Error('Renderer.animate is no longer supported!'); };
      return RendererAdapter;
  }());
  /**
   * @param {?} moduleType
   * @param {?} parent
   * @param {?} bootstrapComponents
   * @param {?} def
   * @return {?}
   */
  function createNgModuleRef(moduleType, parent, bootstrapComponents, def) {
      return new NgModuleRef_(moduleType, parent, bootstrapComponents, def);
  }
  var NgModuleRef_ = /** @class */ (function () {
      function NgModuleRef_(_moduleType, _parent, _bootstrapComponents, _def) {
          this._moduleType = _moduleType;
          this._parent = _parent;
          this._bootstrapComponents = _bootstrapComponents;
          this._def = _def;
          this._destroyListeners = [];
          this._destroyed = false;
          this.injector = this;
          initNgModule(this);
      }
      /**
       * @param {?} token
       * @param {?=} notFoundValue
       * @return {?}
       */
      NgModuleRef_.prototype.get = /**
       * @param {?} token
       * @param {?=} notFoundValue
       * @return {?}
       */
      function (token, notFoundValue) {
          if (notFoundValue === void 0) { notFoundValue = Injector.THROW_IF_NOT_FOUND; }
          return resolveNgModuleDep(this, { token: token, tokenKey: tokenKey(token), flags: 0 /* None */ }, notFoundValue);
      };
      Object.defineProperty(NgModuleRef_.prototype, "instance", {
          get: /**
           * @return {?}
           */
          function () { return this.get(this._moduleType); },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(NgModuleRef_.prototype, "componentFactoryResolver", {
          get: /**
           * @return {?}
           */
          function () { return this.get(ComponentFactoryResolver); },
          enumerable: true,
          configurable: true
      });
      /**
       * @return {?}
       */
      NgModuleRef_.prototype.destroy = /**
       * @return {?}
       */
      function () {
          if (this._destroyed) {
              throw new Error("The ng module " + stringify(this.instance.constructor) + " has already been destroyed.");
          }
          this._destroyed = true;
          callNgModuleLifecycle(this, 131072 /* OnDestroy */);
          this._destroyListeners.forEach(function (listener) { return listener(); });
      };
      /**
       * @param {?} callback
       * @return {?}
       */
      NgModuleRef_.prototype.onDestroy = /**
       * @param {?} callback
       * @return {?}
       */
      function (callback) { this._destroyListeners.push(callback); };
      return NgModuleRef_;
  }());
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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 RendererV1TokenKey = tokenKey(Renderer);
  var Renderer2TokenKey = tokenKey(Renderer2);
  var ElementRefTokenKey = tokenKey(ElementRef);
  var ViewContainerRefTokenKey = tokenKey(ViewContainerRef);
  var TemplateRefTokenKey = tokenKey(TemplateRef);
  var ChangeDetectorRefTokenKey = tokenKey(ChangeDetectorRef);
  var InjectorRefTokenKey = tokenKey(Injector);
  /**
   * @param {?} checkIndex
   * @param {?} flags
   * @param {?} matchedQueries
   * @param {?} childCount
   * @param {?} ctor
   * @param {?} deps
   * @param {?=} props
   * @param {?=} outputs
   * @return {?}
   */
  function directiveDef(checkIndex, flags, matchedQueries, childCount, ctor, deps, props, outputs) {
      var /** @type {?} */ bindings = [];
      if (props) {
          for (var /** @type {?} */ prop in props) {
              var _a = props[prop], bindingIndex = _a[0], nonMinifiedName = _a[1];
              bindings[bindingIndex] = {
                  flags: 8 /* TypeProperty */,
                  name: prop, nonMinifiedName: nonMinifiedName,
                  ns: null,
                  securityContext: null,
                  suffix: null
              };
          }
      }
      var /** @type {?} */ outputDefs = [];
      if (outputs) {
          for (var /** @type {?} */ propName in outputs) {
              outputDefs.push({ type: 1 /* DirectiveOutput */, propName: propName, target: null, eventName: outputs[propName] });
          }
      }
      flags |= 16384 /* TypeDirective */;
      return _def(checkIndex, flags, matchedQueries, childCount, ctor, ctor, deps, bindings, outputDefs);
  }
  /**
   * @param {?} flags
   * @param {?} ctor
   * @param {?} deps
   * @return {?}
   */
  function pipeDef(flags, ctor, deps) {
      flags |= 16 /* TypePipe */;
      return _def(-1, flags, null, 0, ctor, ctor, deps);
  }
  /**
   * @param {?} flags
   * @param {?} matchedQueries
   * @param {?} token
   * @param {?} value
   * @param {?} deps
   * @return {?}
   */
  function providerDef(flags, matchedQueries, token, value, deps) {
      return _def(-1, flags, matchedQueries, 0, token, value, deps);
  }
  /**
   * @param {?} checkIndex
   * @param {?} flags
   * @param {?} matchedQueriesDsl
   * @param {?} childCount
   * @param {?} token
   * @param {?} value
   * @param {?} deps
   * @param {?=} bindings
   * @param {?=} outputs
   * @return {?}
   */
  function _def(checkIndex, flags, matchedQueriesDsl, childCount, token, value, deps, bindings, outputs) {
      var _a = splitMatchedQueriesDsl(matchedQueriesDsl), matchedQueries = _a.matchedQueries, references = _a.references, matchedQueryIds = _a.matchedQueryIds;
      if (!outputs) {
          outputs = [];
      }
      if (!bindings) {
          bindings = [];
      }
      // Need to resolve forwardRefs as e.g. for `useValue` we
      // lowered the expression and then stopped evaluating it,
      // i.e. also didn't unwrap it.
      value = resolveForwardRef(value);
      var /** @type {?} */ depDefs = splitDepsDsl(deps, stringify(token));
      return {
          // will bet set by the view definition
          nodeIndex: -1,
          parent: null,
          renderParent: null,
          bindingIndex: -1,
          outputIndex: -1,
          // regular values
          checkIndex: checkIndex,
          flags: flags,
          childFlags: 0,
          directChildFlags: 0,
          childMatchedQueries: 0, matchedQueries: matchedQueries, matchedQueryIds: matchedQueryIds, references: references,
          ngContentIndex: -1, childCount: childCount, bindings: bindings,
          bindingFlags: calcBindingFlags(bindings), outputs: outputs,
          element: null,
          provider: { token: token, value: value, deps: depDefs },
          text: null,
          query: null,
          ngContent: null
      };
  }
  /**
   * @param {?} view
   * @param {?} def
   * @return {?}
   */
  function createProviderInstance(view, def) {
      return _createProviderInstance(view, def);
  }
  /**
   * @param {?} view
   * @param {?} def
   * @return {?}
   */
  function createPipeInstance(view, def) {
      // deps are looked up from component.
      var /** @type {?} */ compView = view;
      while (compView.parent && !isComponentView(compView)) {
          compView = compView.parent;
      }
      // pipes can see the private services of the component
      var /** @type {?} */ allowPrivateServices = true;
      // pipes are always eager and classes!
      return createClass(/** @type {?} */ ((compView.parent)), /** @type {?} */ ((viewParentEl(compView))), allowPrivateServices, /** @type {?} */ ((def.provider)).value, /** @type {?} */ ((def.provider)).deps);
  }
  /**
   * @param {?} view
   * @param {?} def
   * @return {?}
   */
  function createDirectiveInstance(view, def) {
      // components can see other private services, other directives can't.
      var /** @type {?} */ allowPrivateServices = (def.flags & 32768 /* Component */) > 0;
      // directives are always eager and classes!
      var /** @type {?} */ instance = createClass(view, /** @type {?} */ ((def.parent)), allowPrivateServices, /** @type {?} */ ((def.provider)).value, /** @type {?} */ ((def.provider)).deps);
      if (def.outputs.length) {
          for (var /** @type {?} */ i = 0; i < def.outputs.length; i++) {
              var /** @type {?} */ output = def.outputs[i];
              var /** @type {?} */ subscription = instance[/** @type {?} */ ((output.propName))].subscribe(eventHandlerClosure(view, /** @type {?} */ ((def.parent)).nodeIndex, output.eventName)); /** @type {?} */
              ((view.disposables))[def.outputIndex + i] = subscription.unsubscribe.bind(subscription);
          }
      }
      return instance;
  }
  /**
   * @param {?} view
   * @param {?} index
   * @param {?} eventName
   * @return {?}
   */
  function eventHandlerClosure(view, index, eventName) {
      return function (event) { return dispatchEvent(view, index, eventName, event); };
  }
  /**
   * @param {?} view
   * @param {?} def
   * @param {?} v0
   * @param {?} v1
   * @param {?} v2
   * @param {?} v3
   * @param {?} v4
   * @param {?} v5
   * @param {?} v6
   * @param {?} v7
   * @param {?} v8
   * @param {?} v9
   * @return {?}
   */
  function checkAndUpdateDirectiveInline(view, def, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9) {
      var /** @type {?} */ providerData = asProviderData(view, def.nodeIndex);
      var /** @type {?} */ directive = providerData.instance;
      var /** @type {?} */ changed = false;
      var /** @type {?} */ changes = /** @type {?} */ ((undefined));
      var /** @type {?} */ bindLen = def.bindings.length;
      if (bindLen > 0 && checkBinding(view, def, 0, v0)) {
          changed = true;
          changes = updateProp(view, providerData, def, 0, v0, changes);
      }
      if (bindLen > 1 && checkBinding(view, def, 1, v1)) {
          changed = true;
          changes = updateProp(view, providerData, def, 1, v1, changes);
      }
      if (bindLen > 2 && checkBinding(view, def, 2, v2)) {
          changed = true;
          changes = updateProp(view, providerData, def, 2, v2, changes);
      }
      if (bindLen > 3 && checkBinding(view, def, 3, v3)) {
          changed = true;
          changes = updateProp(view, providerData, def, 3, v3, changes);
      }
      if (bindLen > 4 && checkBinding(view, def, 4, v4)) {
          changed = true;
          changes = updateProp(view, providerData, def, 4, v4, changes);
      }
      if (bindLen > 5 && checkBinding(view, def, 5, v5)) {
          changed = true;
          changes = updateProp(view, providerData, def, 5, v5, changes);
      }
      if (bindLen > 6 && checkBinding(view, def, 6, v6)) {
          changed = true;
          changes = updateProp(view, providerData, def, 6, v6, changes);
      }
      if (bindLen > 7 && checkBinding(view, def, 7, v7)) {
          changed = true;
          changes = updateProp(view, providerData, def, 7, v7, changes);
      }
      if (bindLen > 8 && checkBinding(view, def, 8, v8)) {
          changed = true;
          changes = updateProp(view, providerData, def, 8, v8, changes);
      }
      if (bindLen > 9 && checkBinding(view, def, 9, v9)) {
          changed = true;
          changes = updateProp(view, providerData, def, 9, v9, changes);
      }
      if (changes) {
          directive.ngOnChanges(changes);
      }
      if ((def.flags & 65536 /* OnInit */) &&
          shouldCallLifecycleInitHook(view, 256 /* InitState_CallingOnInit */, def.nodeIndex)) {
          directive.ngOnInit();
      }
      if (def.flags & 262144 /* DoCheck */) {
          directive.ngDoCheck();
      }
      return changed;
  }
  /**
   * @param {?} view
   * @param {?} def
   * @param {?} values
   * @return {?}
   */
  function checkAndUpdateDirectiveDynamic(view, def, values) {
      var /** @type {?} */ providerData = asProviderData(view, def.nodeIndex);
      var /** @type {?} */ directive = providerData.instance;
      var /** @type {?} */ changed = false;
      var /** @type {?} */ changes = /** @type {?} */ ((undefined));
      for (var /** @type {?} */ i = 0; i < values.length; i++) {
          if (checkBinding(view, def, i, values[i])) {
              changed = true;
              changes = updateProp(view, providerData, def, i, values[i], changes);
          }
      }
      if (changes) {
          directive.ngOnChanges(changes);
      }
      if ((def.flags & 65536 /* OnInit */) &&
          shouldCallLifecycleInitHook(view, 256 /* InitState_CallingOnInit */, def.nodeIndex)) {
          directive.ngOnInit();
      }
      if (def.flags & 262144 /* DoCheck */) {
          directive.ngDoCheck();
      }
      return changed;
  }
  /**
   * @param {?} view
   * @param {?} def
   * @return {?}
   */
  function _createProviderInstance(view, def) {
      // private services can see other private services
      var /** @type {?} */ allowPrivateServices = (def.flags & 8192 /* PrivateProvider */) > 0;
      var /** @type {?} */ providerDef = def.provider;
      switch (def.flags & 201347067 /* Types */) {
          case 512 /* TypeClassProvider */:
              return createClass(view, /** @type {?} */ ((def.parent)), allowPrivateServices, /** @type {?} */ ((providerDef)).value, /** @type {?} */ ((providerDef)).deps);
          case 1024 /* TypeFactoryProvider */:
              return callFactory(view, /** @type {?} */ ((def.parent)), allowPrivateServices, /** @type {?} */ ((providerDef)).value, /** @type {?} */ ((providerDef)).deps);
          case 2048 /* TypeUseExistingProvider */:
              return resolveDep(view, /** @type {?} */ ((def.parent)), allowPrivateServices, /** @type {?} */ ((providerDef)).deps[0]);
          case 256 /* TypeValueProvider */:
              return /** @type {?} */ ((providerDef)).value;
      }
  }
  /**
   * @param {?} view
   * @param {?} elDef
   * @param {?} allowPrivateServices
   * @param {?} ctor
   * @param {?} deps
   * @return {?}
   */
  function createClass(view, elDef, allowPrivateServices, ctor, deps) {
      var /** @type {?} */ len = deps.length;
      switch (len) {
          case 0:
              return new ctor();
          case 1:
              return new ctor(resolveDep(view, elDef, allowPrivateServices, deps[0]));
          case 2:
              return new ctor(resolveDep(view, elDef, allowPrivateServices, deps[0]), resolveDep(view, elDef, allowPrivateServices, deps[1]));
          case 3:
              return new ctor(resolveDep(view, elDef, allowPrivateServices, deps[0]), resolveDep(view, elDef, allowPrivateServices, deps[1]), resolveDep(view, elDef, allowPrivateServices, deps[2]));
          default:
              var /** @type {?} */ depValues = new Array(len);
              for (var /** @type {?} */ i = 0; i < len; i++) {
                  depValues[i] = resolveDep(view, elDef, allowPrivateServices, deps[i]);
              }
              return new (ctor.bind.apply(ctor, [void 0].concat(depValues)))();
      }
  }
  /**
   * @param {?} view
   * @param {?} elDef
   * @param {?} allowPrivateServices
   * @param {?} factory
   * @param {?} deps
   * @return {?}
   */
  function callFactory(view, elDef, allowPrivateServices, factory, deps) {
      var /** @type {?} */ len = deps.length;
      switch (len) {
          case 0:
              return factory();
          case 1:
              return factory(resolveDep(view, elDef, allowPrivateServices, deps[0]));
          case 2:
              return factory(resolveDep(view, elDef, allowPrivateServices, deps[0]), resolveDep(view, elDef, allowPrivateServices, deps[1]));
          case 3:
              return factory(resolveDep(view, elDef, allowPrivateServices, deps[0]), resolveDep(view, elDef, allowPrivateServices, deps[1]), resolveDep(view, elDef, allowPrivateServices, deps[2]));
          default:
              var /** @type {?} */ depValues = Array(len);
              for (var /** @type {?} */ i = 0; i < len; i++) {
                  depValues[i] = resolveDep(view, elDef, allowPrivateServices, deps[i]);
              }
              return factory.apply(void 0, depValues);
      }
  }
  // This default value is when checking the hierarchy for a token.
  //
  // It means both:
  // - the token is not provided by the current injector,
  // - only the element injectors should be checked (ie do not check module injectors
  //
  //          mod1
  //         /
  //       el1   mod2
  //         \  /
  //         el2
  //
  // When requesting el2.injector.get(token), we should check in the following order and return the
  // first found value:
  // - el2.injector.get(token, default)
  // - el1.injector.get(token, NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR) -> do not check the module
  // - mod2.injector.get(token, default)
  var NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR = {};
  /**
   * @param {?} view
   * @param {?} elDef
   * @param {?} allowPrivateServices
   * @param {?} depDef
   * @param {?=} notFoundValue
   * @return {?}
   */
  function resolveDep(view, elDef, allowPrivateServices, depDef, notFoundValue) {
      if (notFoundValue === void 0) { notFoundValue = Injector.THROW_IF_NOT_FOUND; }
      if (depDef.flags & 8 /* Value */) {
          return depDef.token;
      }
      var /** @type {?} */ startView = view;
      if (depDef.flags & 2 /* Optional */) {
          notFoundValue = null;
      }
      var /** @type {?} */ tokenKey$$1 = depDef.tokenKey;
      if (tokenKey$$1 === ChangeDetectorRefTokenKey) {
          // directives on the same element as a component should be able to control the change detector
          // of that component as well.
          allowPrivateServices = !!(elDef && /** @type {?} */ ((elDef.element)).componentView);
      }
      if (elDef && (depDef.flags & 1 /* SkipSelf */)) {
          allowPrivateServices = false;
          elDef = /** @type {?} */ ((elDef.parent));
      }
      while (view) {
          if (elDef) {
              switch (tokenKey$$1) {
                  case RendererV1TokenKey: {
                      var /** @type {?} */ compView = findCompView(view, elDef, allowPrivateServices);
                      return createRendererV1(compView);
                  }
                  case Renderer2TokenKey: {
                      var /** @type {?} */ compView = findCompView(view, elDef, allowPrivateServices);
                      return compView.renderer;
                  }
                  case ElementRefTokenKey:
                      return new ElementRef(asElementData(view, elDef.nodeIndex).renderElement);
                  case ViewContainerRefTokenKey:
                      return asElementData(view, elDef.nodeIndex).viewContainer;
                  case TemplateRefTokenKey: {
                      if (/** @type {?} */ ((elDef.element)).template) {
                          return asElementData(view, elDef.nodeIndex).template;
                      }
                      break;
                  }
                  case ChangeDetectorRefTokenKey: {
                      var /** @type {?} */ cdView = findCompView(view, elDef, allowPrivateServices);
                      return createChangeDetectorRef(cdView);
                  }
                  case InjectorRefTokenKey:
                      return createInjector(view, elDef);
                  default:
                      var /** @type {?} */ providerDef_1 = /** @type {?} */ (((allowPrivateServices ? /** @type {?} */ ((elDef.element)).allProviders : /** @type {?} */ ((elDef.element)).publicProviders)))[tokenKey$$1];
                      if (providerDef_1) {
                          var /** @type {?} */ providerData = asProviderData(view, providerDef_1.nodeIndex);
                          if (!providerData) {
                              providerData = { instance: _createProviderInstance(view, providerDef_1) };
                              view.nodes[providerDef_1.nodeIndex] = /** @type {?} */ (providerData);
                          }
                          return providerData.instance;
                      }
              }
          }
          allowPrivateServices = isComponentView(view);
          elDef = /** @type {?} */ ((viewParentEl(view)));
          view = /** @type {?} */ ((view.parent));
      }
      var /** @type {?} */ value = startView.root.injector.get(depDef.token, NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR);
      if (value !== NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR ||
          notFoundValue === NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR) {
          // Return the value from the root element injector when
          // - it provides it
          //   (value !== NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR)
          // - the module injector should not be checked
          //   (notFoundValue === NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR)
          return value;
      }
      return startView.root.ngModule.injector.get(depDef.token, notFoundValue);
  }
  /**
   * @param {?} view
   * @param {?} elDef
   * @param {?} allowPrivateServices
   * @return {?}
   */
  function findCompView(view, elDef, allowPrivateServices) {
      var /** @type {?} */ compView;
      if (allowPrivateServices) {
          compView = asElementData(view, elDef.nodeIndex).componentView;
      }
      else {
          compView = view;
          while (compView.parent && !isComponentView(compView)) {
              compView = compView.parent;
          }
      }
      return compView;
  }
  /**
   * @param {?} view
   * @param {?} providerData
   * @param {?} def
   * @param {?} bindingIdx
   * @param {?} value
   * @param {?} changes
   * @return {?}
   */
  function updateProp(view, providerData, def, bindingIdx, value, changes) {
      if (def.flags & 32768 /* Component */) {
          var /** @type {?} */ compView = asElementData(view, /** @type {?} */ ((def.parent)).nodeIndex).componentView;
          if (compView.def.flags & 2 /* OnPush */) {
              compView.state |= 8 /* ChecksEnabled */;
          }
      }
      var /** @type {?} */ binding = def.bindings[bindingIdx];
      var /** @type {?} */ propName = /** @type {?} */ ((binding.name));
      // Note: This is still safe with Closure Compiler as
      // the user passed in the property name as an object has to `providerDef`,
      // so Closure Compiler will have renamed the property correctly already.
      providerData.instance[propName] = value;
      if (def.flags & 524288 /* OnChanges */) {
          changes = changes || {};
          var /** @type {?} */ oldValue = WrappedValue.unwrap(view.oldValues[def.bindingIndex + bindingIdx]);
          var /** @type {?} */ binding_1 = def.bindings[bindingIdx];
          changes[/** @type {?} */ ((binding_1.nonMinifiedName))] =
              new SimpleChange(oldValue, value, (view.state & 2 /* FirstCheck */) !== 0);
      }
      view.oldValues[def.bindingIndex + bindingIdx] = value;
      return changes;
  }
  /**
   * @param {?} view
   * @param {?} lifecycles
   * @return {?}
   */
  function callLifecycleHooksChildrenFirst(view, lifecycles) {
      if (!(view.def.nodeFlags & lifecycles)) {
          return;
      }
      var /** @type {?} */ nodes = view.def.nodes;
      var /** @type {?} */ initIndex = 0;
      for (var /** @type {?} */ i = 0; i < nodes.length; i++) {
          var /** @type {?} */ nodeDef = nodes[i];
          var /** @type {?} */ parent_1 = nodeDef.parent;
          if (!parent_1 && nodeDef.flags & lifecycles) {
              // matching root node (e.g. a pipe)
              callProviderLifecycles(view, i, nodeDef.flags & lifecycles, initIndex++);
          }
          if ((nodeDef.childFlags & lifecycles) === 0) {
              // no child matches one of the lifecycles
              i += nodeDef.childCount;
          }
          while (parent_1 && (parent_1.flags & 1 /* TypeElement */) &&
              i === parent_1.nodeIndex + parent_1.childCount) {
              // last child of an element
              if (parent_1.directChildFlags & lifecycles) {
                  initIndex = callElementProvidersLifecycles(view, parent_1, lifecycles, initIndex);
              }
              parent_1 = parent_1.parent;
          }
      }
  }
  /**
   * @param {?} view
   * @param {?} elDef
   * @param {?} lifecycles
   * @param {?} initIndex
   * @return {?}
   */
  function callElementProvidersLifecycles(view, elDef, lifecycles, initIndex) {
      for (var /** @type {?} */ i = elDef.nodeIndex + 1; i <= elDef.nodeIndex + elDef.childCount; i++) {
          var /** @type {?} */ nodeDef = view.def.nodes[i];
          if (nodeDef.flags & lifecycles) {
              callProviderLifecycles(view, i, nodeDef.flags & lifecycles, initIndex++);
          }
          // only visit direct children
          i += nodeDef.childCount;
      }
      return initIndex;
  }
  /**
   * @param {?} view
   * @param {?} index
   * @param {?} lifecycles
   * @param {?} initIndex
   * @return {?}
   */
  function callProviderLifecycles(view, index, lifecycles, initIndex) {
      var /** @type {?} */ providerData = asProviderData(view, index);
      if (!providerData) {
          return;
      }
      var /** @type {?} */ provider = providerData.instance;
      if (!provider) {
          return;
      }
      Services.setCurrentNode(view, index);
      if (lifecycles & 1048576 /* AfterContentInit */ &&
          shouldCallLifecycleInitHook(view, 512 /* InitState_CallingAfterContentInit */, initIndex)) {
          provider.ngAfterContentInit();
      }
      if (lifecycles & 2097152 /* AfterContentChecked */) {
          provider.ngAfterContentChecked();
      }
      if (lifecycles & 4194304 /* AfterViewInit */ &&
          shouldCallLifecycleInitHook(view, 768 /* InitState_CallingAfterViewInit */, initIndex)) {
          provider.ngAfterViewInit();
      }
      if (lifecycles & 8388608 /* AfterViewChecked */) {
          provider.ngAfterViewChecked();
      }
      if (lifecycles & 131072 /* OnDestroy */) {
          provider.ngOnDestroy();
      }
  }
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  /**
   * @param {?} flags
   * @param {?} id
   * @param {?} bindings
   * @return {?}
   */
  function queryDef(flags, id, bindings) {
      var /** @type {?} */ bindingDefs = [];
      for (var /** @type {?} */ propName in bindings) {
          var /** @type {?} */ bindingType = bindings[propName];
          bindingDefs.push({ propName: propName, bindingType: bindingType });
      }
      return {
          // will bet set by the view definition
          nodeIndex: -1,
          parent: null,
          renderParent: null,
          bindingIndex: -1,
          outputIndex: -1,
          // regular values
          // TODO(vicb): check
          checkIndex: -1, flags: flags,
          childFlags: 0,
          directChildFlags: 0,
          childMatchedQueries: 0,
          ngContentIndex: -1,
          matchedQueries: {},
          matchedQueryIds: 0,
          references: {},
          childCount: 0,
          bindings: [],
          bindingFlags: 0,
          outputs: [],
          element: null,
          provider: null,
          text: null,
          query: { id: id, filterId: filterQueryId(id), bindings: bindingDefs },
          ngContent: null
      };
  }
  /**
   * @return {?}
   */
  function createQuery() {
      return new QueryList();
  }
  /**
   * @param {?} view
   * @return {?}
   */
  function dirtyParentQueries(view) {
      var /** @type {?} */ queryIds = view.def.nodeMatchedQueries;
      while (view.parent && isEmbeddedView(view)) {
          var /** @type {?} */ tplDef = /** @type {?} */ ((view.parentNodeDef));
          view = view.parent;
          // content queries
          var /** @type {?} */ end = tplDef.nodeIndex + tplDef.childCount;
          for (var /** @type {?} */ i = 0; i <= end; i++) {
              var /** @type {?} */ nodeDef = view.def.nodes[i];
              if ((nodeDef.flags & 67108864 /* TypeContentQuery */) &&
                  (nodeDef.flags & 536870912 /* DynamicQuery */) &&
                  (/** @type {?} */ ((nodeDef.query)).filterId & queryIds) === /** @type {?} */ ((nodeDef.query)).filterId) {
                  asQueryList(view, i).setDirty();
              }
              if ((nodeDef.flags & 1 /* TypeElement */ && i + nodeDef.childCount < tplDef.nodeIndex) ||
                  !(nodeDef.childFlags & 67108864 /* TypeContentQuery */) ||
                  !(nodeDef.childFlags & 536870912 /* DynamicQuery */)) {
                  // skip elements that don't contain the template element or no query.
                  i += nodeDef.childCount;
              }
          }
      }
      // view queries
      if (view.def.nodeFlags & 134217728 /* TypeViewQuery */) {
          for (var /** @type {?} */ i = 0; i < view.def.nodes.length; i++) {
              var /** @type {?} */ nodeDef = view.def.nodes[i];
              if ((nodeDef.flags & 134217728 /* TypeViewQuery */) && (nodeDef.flags & 536870912 /* DynamicQuery */)) {
                  asQueryList(view, i).setDirty();
              }
              // only visit the root nodes
              i += nodeDef.childCount;
          }
      }
  }
  /**
   * @param {?} view
   * @param {?} nodeDef
   * @return {?}
   */
  function checkAndUpdateQuery(view, nodeDef) {
      var /** @type {?} */ queryList = asQueryList(view, nodeDef.nodeIndex);
      if (!queryList.dirty) {
          return;
      }
      var /** @type {?} */ directiveInstance;
      var /** @type {?} */ newValues = /** @type {?} */ ((undefined));
      if (nodeDef.flags & 67108864 /* TypeContentQuery */) {
          var /** @type {?} */ elementDef = /** @type {?} */ ((/** @type {?} */ ((nodeDef.parent)).parent));
          newValues = calcQueryValues(view, elementDef.nodeIndex, elementDef.nodeIndex + elementDef.childCount, /** @type {?} */ ((nodeDef.query)), []);
          directiveInstance = asProviderData(view, /** @type {?} */ ((nodeDef.parent)).nodeIndex).instance;
      }
      else if (nodeDef.flags & 134217728 /* TypeViewQuery */) {
          newValues = calcQueryValues(view, 0, view.def.nodes.length - 1, /** @type {?} */ ((nodeDef.query)), []);
          directiveInstance = view.component;
      }
      queryList.reset(newValues);
      var /** @type {?} */ bindings = /** @type {?} */ ((nodeDef.query)).bindings;
      var /** @type {?} */ notify = false;
      for (var /** @type {?} */ i = 0; i < bindings.length; i++) {
          var /** @type {?} */ binding = bindings[i];
          var /** @type {?} */ boundValue = void 0;
          switch (binding.bindingType) {
              case 0 /* First */:
                  boundValue = queryList.first;
                  break;
              case 1 /* All */:
                  boundValue = queryList;
                  notify = true;
                  break;
          }
          directiveInstance[binding.propName] = boundValue;
      }
      if (notify) {
          queryList.notifyOnChanges();
      }
  }
  /**
   * @param {?} view
   * @param {?} startIndex
   * @param {?} endIndex
   * @param {?} queryDef
   * @param {?} values
   * @return {?}
   */
  function calcQueryValues(view, startIndex, endIndex, queryDef, values) {
      for (var /** @type {?} */ i = startIndex; i <= endIndex; i++) {
          var /** @type {?} */ nodeDef = view.def.nodes[i];
          var /** @type {?} */ valueType = nodeDef.matchedQueries[queryDef.id];
          if (valueType != null) {
              values.push(getQueryValue(view, nodeDef, valueType));
          }
          if (nodeDef.flags & 1 /* TypeElement */ && /** @type {?} */ ((nodeDef.element)).template &&
              (/** @type {?} */ ((/** @type {?} */ ((nodeDef.element)).template)).nodeMatchedQueries & queryDef.filterId) ===
                  queryDef.filterId) {
              var /** @type {?} */ elementData = asElementData(view, i);
              // check embedded views that were attached at the place of their template,
              // but process child nodes first if some match the query (see issue #16568)
              if ((nodeDef.childMatchedQueries & queryDef.filterId) === queryDef.filterId) {
                  calcQueryValues(view, i + 1, i + nodeDef.childCount, queryDef, values);
                  i += nodeDef.childCount;
              }
              if (nodeDef.flags & 16777216 /* EmbeddedViews */) {
                  var /** @type {?} */ embeddedViews = /** @type {?} */ ((elementData.viewContainer))._embeddedViews;
                  for (var /** @type {?} */ k = 0; k < embeddedViews.length; k++) {
                      var /** @type {?} */ embeddedView = embeddedViews[k];
                      var /** @type {?} */ dvc = declaredViewContainer(embeddedView);
                      if (dvc && dvc === elementData) {
                          calcQueryValues(embeddedView, 0, embeddedView.def.nodes.length - 1, queryDef, values);
                      }
                  }
              }
              var /** @type {?} */ projectedViews = elementData.template._projectedViews;
              if (projectedViews) {
                  for (var /** @type {?} */ k = 0; k < projectedViews.length; k++) {
                      var /** @type {?} */ projectedView = projectedViews[k];
                      calcQueryValues(projectedView, 0, projectedView.def.nodes.length - 1, queryDef, values);
                  }
              }
          }
          if ((nodeDef.childMatchedQueries & queryDef.filterId) !== queryDef.filterId) {
              // if no child matches the query, skip the children.
              i += nodeDef.childCount;
          }
      }
      return values;
  }
  /**
   * @param {?} view
   * @param {?} nodeDef
   * @param {?} queryValueType
   * @return {?}
   */
  function getQueryValue(view, nodeDef, queryValueType) {
      if (queryValueType != null) {
          // a match
          switch (queryValueType) {
              case 1 /* RenderElement */:
                  return asElementData(view, nodeDef.nodeIndex).renderElement;
              case 0 /* ElementRef */:
                  return new ElementRef(asElementData(view, nodeDef.nodeIndex).renderElement);
              case 2 /* TemplateRef */:
                  return asElementData(view, nodeDef.nodeIndex).template;
              case 3 /* ViewContainerRef */:
                  return asElementData(view, nodeDef.nodeIndex).viewContainer;
              case 4 /* Provider */:
                  return asProviderData(view, nodeDef.nodeIndex).instance;
          }
      }
  }
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  /**
   * @param {?} ngContentIndex
   * @param {?} index
   * @return {?}
   */
  function ngContentDef(ngContentIndex, index) {
      return {
          // will bet set by the view definition
          nodeIndex: -1,
          parent: null,
          renderParent: null,
          bindingIndex: -1,
          outputIndex: -1,
          // regular values
          checkIndex: -1,
          flags: 8 /* TypeNgContent */,
          childFlags: 0,
          directChildFlags: 0,
          childMatchedQueries: 0,
          matchedQueries: {},
          matchedQueryIds: 0,
          references: {}, ngContentIndex: ngContentIndex,
          childCount: 0,
          bindings: [],
          bindingFlags: 0,
          outputs: [],
          element: null,
          provider: null,
          text: null,
          query: null,
          ngContent: { index: index }
      };
  }
  /**
   * @param {?} view
   * @param {?} renderHost
   * @param {?} def
   * @return {?}
   */
  function appendNgContent(view, renderHost, def) {
      var /** @type {?} */ parentEl = getParentRenderElement(view, renderHost, def);
      if (!parentEl) {
          // Nothing to do if there is no parent element.
          return;
      }
      var /** @type {?} */ ngContentIndex = /** @type {?} */ ((def.ngContent)).index;
      visitProjectedRenderNodes(view, ngContentIndex, 1 /* AppendChild */, parentEl, null, undefined);
  }
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  /**
   * @param {?} checkIndex
   * @param {?} argCount
   * @return {?}
   */
  function purePipeDef(checkIndex, argCount) {
      // argCount + 1 to include the pipe as first arg
      return _pureExpressionDef(128 /* TypePurePipe */, checkIndex, new Array(argCount + 1));
  }
  /**
   * @param {?} checkIndex
   * @param {?} argCount
   * @return {?}
   */
  function pureArrayDef(checkIndex, argCount) {
      return _pureExpressionDef(32 /* TypePureArray */, checkIndex, new Array(argCount));
  }
  /**
   * @param {?} checkIndex
   * @param {?} propToIndex
   * @return {?}
   */
  function pureObjectDef(checkIndex, propToIndex) {
      var /** @type {?} */ keys = Object.keys(propToIndex);
      var /** @type {?} */ nbKeys = keys.length;
      var /** @type {?} */ propertyNames = new Array(nbKeys);
      for (var /** @type {?} */ i = 0; i < nbKeys; i++) {
          var /** @type {?} */ key = keys[i];
          var /** @type {?} */ index = propToIndex[key];
          propertyNames[index] = key;
      }
      return _pureExpressionDef(64 /* TypePureObject */, checkIndex, propertyNames);
  }
  /**
   * @param {?} flags
   * @param {?} checkIndex
   * @param {?} propertyNames
   * @return {?}
   */
  function _pureExpressionDef(flags, checkIndex, propertyNames) {
      var /** @type {?} */ bindings = new Array(propertyNames.length);
      for (var /** @type {?} */ i = 0; i < propertyNames.length; i++) {
          var /** @type {?} */ prop = propertyNames[i];
          bindings[i] = {
              flags: 8 /* TypeProperty */,
              name: prop,
              ns: null,
              nonMinifiedName: prop,
              securityContext: null,
              suffix: null
          };
      }
      return {
          // will bet set by the view definition
          nodeIndex: -1,
          parent: null,
          renderParent: null,
          bindingIndex: -1,
          outputIndex: -1,
          // regular values
          checkIndex: checkIndex,
          flags: flags,
          childFlags: 0,
          directChildFlags: 0,
          childMatchedQueries: 0,
          matchedQueries: {},
          matchedQueryIds: 0,
          references: {},
          ngContentIndex: -1,
          childCount: 0, bindings: bindings,
          bindingFlags: calcBindingFlags(bindings),
          outputs: [],
          element: null,
          provider: null,
          text: null,
          query: null,
          ngContent: null
      };
  }
  /**
   * @param {?} view
   * @param {?} def
   * @return {?}
   */
  function createPureExpression(view, def) {
      return { value: undefined };
  }
  /**
   * @param {?} view
   * @param {?} def
   * @param {?} v0
   * @param {?} v1
   * @param {?} v2
   * @param {?} v3
   * @param {?} v4
   * @param {?} v5
   * @param {?} v6
   * @param {?} v7
   * @param {?} v8
   * @param {?} v9
   * @return {?}
   */
  function checkAndUpdatePureExpressionInline(view, def, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9) {
      var /** @type {?} */ bindings = def.bindings;
      var /** @type {?} */ changed = false;
      var /** @type {?} */ bindLen = bindings.length;
      if (bindLen > 0 && checkAndUpdateBinding(view, def, 0, v0))
          changed = true;
      if (bindLen > 1 && checkAndUpdateBinding(view, def, 1, v1))
          changed = true;
      if (bindLen > 2 && checkAndUpdateBinding(view, def, 2, v2))
          changed = true;
      if (bindLen > 3 && checkAndUpdateBinding(view, def, 3, v3))
          changed = true;
      if (bindLen > 4 && checkAndUpdateBinding(view, def, 4, v4))
          changed = true;
      if (bindLen > 5 && checkAndUpdateBinding(view, def, 5, v5))
          changed = true;
      if (bindLen > 6 && checkAndUpdateBinding(view, def, 6, v6))
          changed = true;
      if (bindLen > 7 && checkAndUpdateBinding(view, def, 7, v7))
          changed = true;
      if (bindLen > 8 && checkAndUpdateBinding(view, def, 8, v8))
          changed = true;
      if (bindLen > 9 && checkAndUpdateBinding(view, def, 9, v9))
          changed = true;
      if (changed) {
          var /** @type {?} */ data = asPureExpressionData(view, def.nodeIndex);
          var /** @type {?} */ value = void 0;
          switch (def.flags & 201347067 /* Types */) {
              case 32 /* TypePureArray */:
                  value = new Array(bindings.length);
                  if (bindLen > 0)
                      value[0] = v0;
                  if (bindLen > 1)
                      value[1] = v1;
                  if (bindLen > 2)
                      value[2] = v2;
                  if (bindLen > 3)
                      value[3] = v3;
                  if (bindLen > 4)
                      value[4] = v4;
                  if (bindLen > 5)
                      value[5] = v5;
                  if (bindLen > 6)
                      value[6] = v6;
                  if (bindLen > 7)
                      value[7] = v7;
                  if (bindLen > 8)
                      value[8] = v8;
                  if (bindLen > 9)
                      value[9] = v9;
                  break;
              case 64 /* TypePureObject */:
                  value = {};
                  if (bindLen > 0)
                      value[/** @type {?} */ ((bindings[0].name))] = v0;
                  if (bindLen > 1)
                      value[/** @type {?} */ ((bindings[1].name))] = v1;
                  if (bindLen > 2)
                      value[/** @type {?} */ ((bindings[2].name))] = v2;
                  if (bindLen > 3)
                      value[/** @type {?} */ ((bindings[3].name))] = v3;
                  if (bindLen > 4)
                      value[/** @type {?} */ ((bindings[4].name))] = v4;
                  if (bindLen > 5)
                      value[/** @type {?} */ ((bindings[5].name))] = v5;
                  if (bindLen > 6)
                      value[/** @type {?} */ ((bindings[6].name))] = v6;
                  if (bindLen > 7)
                      value[/** @type {?} */ ((bindings[7].name))] = v7;
                  if (bindLen > 8)
                      value[/** @type {?} */ ((bindings[8].name))] = v8;
                  if (bindLen > 9)
                      value[/** @type {?} */ ((bindings[9].name))] = v9;
                  break;
              case 128 /* TypePurePipe */:
                  var /** @type {?} */ pipe = v0;
                  switch (bindLen) {
                      case 1:
                          value = pipe.transform(v0);
                          break;
                      case 2:
                          value = pipe.transform(v1);
                          break;
                      case 3:
                          value = pipe.transform(v1, v2);
                          break;
                      case 4:
                          value = pipe.transform(v1, v2, v3);
                          break;
                      case 5:
                          value = pipe.transform(v1, v2, v3, v4);
                          break;
                      case 6:
                          value = pipe.transform(v1, v2, v3, v4, v5);
                          break;
                      case 7:
                          value = pipe.transform(v1, v2, v3, v4, v5, v6);
                          break;
                      case 8:
                          value = pipe.transform(v1, v2, v3, v4, v5, v6, v7);
                          break;
                      case 9:
                          value = pipe.transform(v1, v2, v3, v4, v5, v6, v7, v8);
                          break;
                      case 10:
                          value = pipe.transform(v1, v2, v3, v4, v5, v6, v7, v8, v9);
                          break;
                  }
                  break;
          }
          data.value = value;
      }
      return changed;
  }
  /**
   * @param {?} view
   * @param {?} def
   * @param {?} values
   * @return {?}
   */
  function checkAndUpdatePureExpressionDynamic(view, def, values) {
      var /** @type {?} */ bindings = def.bindings;
      var /** @type {?} */ changed = false;
      for (var /** @type {?} */ i = 0; i < values.length; i++) {
          // Note: We need to loop over all values, so that
          // the old values are updates as well!
          if (checkAndUpdateBinding(view, def, i, values[i])) {
              changed = true;
          }
      }
      if (changed) {
          var /** @type {?} */ data = asPureExpressionData(view, def.nodeIndex);
          var /** @type {?} */ value = void 0;
          switch (def.flags & 201347067 /* Types */) {
              case 32 /* TypePureArray */:
                  value = values;
                  break;
              case 64 /* TypePureObject */:
                  value = {};
                  for (var /** @type {?} */ i = 0; i < values.length; i++) {
                      value[/** @type {?} */ ((bindings[i].name))] = values[i];
                  }
                  break;
              case 128 /* TypePurePipe */:
                  var /** @type {?} */ pipe = values[0];
                  var /** @type {?} */ params = values.slice(1);
                  value = pipe.transform.apply(pipe, params);
                  break;
          }
          data.value = value;
      }
      return changed;
  }
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  /**
   * @param {?} checkIndex
   * @param {?} ngContentIndex
   * @param {?} staticText
   * @return {?}
   */
  function textDef(checkIndex, ngContentIndex, staticText) {
      var /** @type {?} */ bindings = new Array(staticText.length - 1);
      for (var /** @type {?} */ i = 1; i < staticText.length; i++) {
          bindings[i - 1] = {
              flags: 8 /* TypeProperty */,
              name: null,
              ns: null,
              nonMinifiedName: null,
              securityContext: null,
              suffix: staticText[i],
          };
      }
      return {
          // will bet set by the view definition
          nodeIndex: -1,
          parent: null,
          renderParent: null,
          bindingIndex: -1,
          outputIndex: -1,
          // regular values
          checkIndex: checkIndex,
          flags: 2 /* TypeText */,
          childFlags: 0,
          directChildFlags: 0,
          childMatchedQueries: 0,
          matchedQueries: {},
          matchedQueryIds: 0,
          references: {}, ngContentIndex: ngContentIndex,
          childCount: 0, bindings: bindings,
          bindingFlags: 8 /* TypeProperty */,
          outputs: [],
          element: null,
          provider: null,
          text: { prefix: staticText[0] },
          query: null,
          ngContent: null,
      };
  }
  /**
   * @param {?} view
   * @param {?} renderHost
   * @param {?} def
   * @return {?}
   */
  function createText(view, renderHost, def) {
      var /** @type {?} */ renderNode$$1;
      var /** @type {?} */ renderer = view.renderer;
      renderNode$$1 = renderer.createText(/** @type {?} */ ((def.text)).prefix);
      var /** @type {?} */ parentEl = getParentRenderElement(view, renderHost, def);
      if (parentEl) {
          renderer.appendChild(parentEl, renderNode$$1);
      }
      return { renderText: renderNode$$1 };
  }
  /**
   * @param {?} view
   * @param {?} def
   * @param {?} v0
   * @param {?} v1
   * @param {?} v2
   * @param {?} v3
   * @param {?} v4
   * @param {?} v5
   * @param {?} v6
   * @param {?} v7
   * @param {?} v8
   * @param {?} v9
   * @return {?}
   */
  function checkAndUpdateTextInline(view, def, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9) {
      var /** @type {?} */ changed = false;
      var /** @type {?} */ bindings = def.bindings;
      var /** @type {?} */ bindLen = bindings.length;
      if (bindLen > 0 && checkAndUpdateBinding(view, def, 0, v0))
          changed = true;
      if (bindLen > 1 && checkAndUpdateBinding(view, def, 1, v1))
          changed = true;
      if (bindLen > 2 && checkAndUpdateBinding(view, def, 2, v2))
          changed = true;
      if (bindLen > 3 && checkAndUpdateBinding(view, def, 3, v3))
          changed = true;
      if (bindLen > 4 && checkAndUpdateBinding(view, def, 4, v4))
          changed = true;
      if (bindLen > 5 && checkAndUpdateBinding(view, def, 5, v5))
          changed = true;
      if (bindLen > 6 && checkAndUpdateBinding(view, def, 6, v6))
          changed = true;
      if (bindLen > 7 && checkAndUpdateBinding(view, def, 7, v7))
          changed = true;
      if (bindLen > 8 && checkAndUpdateBinding(view, def, 8, v8))
          changed = true;
      if (bindLen > 9 && checkAndUpdateBinding(view, def, 9, v9))
          changed = true;
      if (changed) {
          var /** @type {?} */ value = /** @type {?} */ ((def.text)).prefix;
          if (bindLen > 0)
              value += _addInterpolationPart(v0, bindings[0]);
          if (bindLen > 1)
              value += _addInterpolationPart(v1, bindings[1]);
          if (bindLen > 2)
              value += _addInterpolationPart(v2, bindings[2]);
          if (bindLen > 3)
              value += _addInterpolationPart(v3, bindings[3]);
          if (bindLen > 4)
              value += _addInterpolationPart(v4, bindings[4]);
          if (bindLen > 5)
              value += _addInterpolationPart(v5, bindings[5]);
          if (bindLen > 6)
              value += _addInterpolationPart(v6, bindings[6]);
          if (bindLen > 7)
              value += _addInterpolationPart(v7, bindings[7]);
          if (bindLen > 8)
              value += _addInterpolationPart(v8, bindings[8]);
          if (bindLen > 9)
              value += _addInterpolationPart(v9, bindings[9]);
          var /** @type {?} */ renderNode$$1 = asTextData(view, def.nodeIndex).renderText;
          view.renderer.setValue(renderNode$$1, value);
      }
      return changed;
  }
  /**
   * @param {?} view
   * @param {?} def
   * @param {?} values
   * @return {?}
   */
  function checkAndUpdateTextDynamic(view, def, values) {
      var /** @type {?} */ bindings = def.bindings;
      var /** @type {?} */ changed = false;
      for (var /** @type {?} */ i = 0; i < values.length; i++) {
          // Note: We need to loop over all values, so that
          // the old values are updates as well!
          if (checkAndUpdateBinding(view, def, i, values[i])) {
              changed = true;
          }
      }
      if (changed) {
          var /** @type {?} */ value = '';
          for (var /** @type {?} */ i = 0; i < values.length; i++) {
              value = value + _addInterpolationPart(values[i], bindings[i]);
          }
          value = /** @type {?} */ ((def.text)).prefix + value;
          var /** @type {?} */ renderNode$$1 = asTextData(view, def.nodeIndex).renderText;
          view.renderer.setValue(renderNode$$1, value);
      }
      return changed;
  }
  /**
   * @param {?} value
   * @param {?} binding
   * @return {?}
   */
  function _addInterpolationPart(value, binding) {
      var /** @type {?} */ valueStr = value != null ? value.toString() : '';
      return valueStr + binding.suffix;
  }
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  /**
   * @param {?} flags
   * @param {?} nodes
   * @param {?=} updateDirectives
   * @param {?=} updateRenderer
   * @return {?}
   */
  function viewDef(flags, nodes, updateDirectives, updateRenderer) {
      // clone nodes and set auto calculated values
      var /** @type {?} */ viewBindingCount = 0;
      var /** @type {?} */ viewDisposableCount = 0;
      var /** @type {?} */ viewNodeFlags = 0;
      var /** @type {?} */ viewRootNodeFlags = 0;
      var /** @type {?} */ viewMatchedQueries = 0;
      var /** @type {?} */ currentParent = null;
      var /** @type {?} */ currentRenderParent = null;
      var /** @type {?} */ currentElementHasPublicProviders = false;
      var /** @type {?} */ currentElementHasPrivateProviders = false;
      var /** @type {?} */ lastRenderRootNode = null;
      for (var /** @type {?} */ i = 0; i < nodes.length; i++) {
          var /** @type {?} */ node = nodes[i];
          node.nodeIndex = i;
          node.parent = currentParent;
          node.bindingIndex = viewBindingCount;
          node.outputIndex = viewDisposableCount;
          node.renderParent = currentRenderParent;
          viewNodeFlags |= node.flags;
          viewMatchedQueries |= node.matchedQueryIds;
          if (node.element) {
              var /** @type {?} */ elDef = node.element;
              elDef.publicProviders =
                  currentParent ? /** @type {?} */ ((currentParent.element)).publicProviders : Object.create(null);
              elDef.allProviders = elDef.publicProviders;
              // Note: We assume that all providers of an element are before any child element!
              currentElementHasPublicProviders = false;
              currentElementHasPrivateProviders = false;
              if (node.element.template) {
                  viewMatchedQueries |= node.element.template.nodeMatchedQueries;
              }
          }
          validateNode(currentParent, node, nodes.length);
          viewBindingCount += node.bindings.length;
          viewDisposableCount += node.outputs.length;
          if (!currentRenderParent && (node.flags & 3 /* CatRenderNode */)) {
              lastRenderRootNode = node;
          }
          if (node.flags & 20224 /* CatProvider */) {
              if (!currentElementHasPublicProviders) {
                  currentElementHasPublicProviders = true; /** @type {?} */
                  ((/** @type {?} */ ((currentParent)).element)).publicProviders = Object.create(/** @type {?} */ ((/** @type {?} */ ((currentParent)).element)).publicProviders); /** @type {?} */
                  ((/** @type {?} */ ((currentParent)).element)).allProviders = /** @type {?} */ ((/** @type {?} */ ((currentParent)).element)).publicProviders;
              }
              var /** @type {?} */ isPrivateService = (node.flags & 8192 /* PrivateProvider */) !== 0;
              var /** @type {?} */ isComponent = (node.flags & 32768 /* Component */) !== 0;
              if (!isPrivateService || isComponent) {
                  /** @type {?} */ ((/** @type {?} */ ((/** @type {?} */ ((currentParent)).element)).publicProviders))[tokenKey(/** @type {?} */ ((node.provider)).token)] = node;
              }
              else {
                  if (!currentElementHasPrivateProviders) {
                      currentElementHasPrivateProviders = true; /** @type {?} */
                      ((/** @type {?} */ ((currentParent)).element)).allProviders = Object.create(/** @type {?} */ ((/** @type {?} */ ((currentParent)).element)).publicProviders);
                  } /** @type {?} */
                  ((/** @type {?} */ ((/** @type {?} */ ((currentParent)).element)).allProviders))[tokenKey(/** @type {?} */ ((node.provider)).token)] = node;
              }
              if (isComponent) {
                  /** @type {?} */ ((/** @type {?} */ ((currentParent)).element)).componentProvider = node;
              }
          }
          if (currentParent) {
              currentParent.childFlags |= node.flags;
              currentParent.directChildFlags |= node.flags;
              currentParent.childMatchedQueries |= node.matchedQueryIds;
              if (node.element && node.element.template) {
                  currentParent.childMatchedQueries |= node.element.template.nodeMatchedQueries;
              }
          }
          else {
              viewRootNodeFlags |= node.flags;
          }
          if (node.childCount > 0) {
              currentParent = node;
              if (!isNgContainer(node)) {
                  currentRenderParent = node;
              }
          }
          else {
              // When the current node has no children, check if it is the last children of its parent.
              // When it is, propagate the flags up.
              // The loop is required because an element could be the last transitive children of several
              // elements. We loop to either the root or the highest opened element (= with remaining
              // children)
              while (currentParent && i === currentParent.nodeIndex + currentParent.childCount) {
                  var /** @type {?} */ newParent = currentParent.parent;
                  if (newParent) {
                      newParent.childFlags |= currentParent.childFlags;
                      newParent.childMatchedQueries |= currentParent.childMatchedQueries;
                  }
                  currentParent = newParent;
                  // We also need to update the render parent & account for ng-container
                  if (currentParent && isNgContainer(currentParent)) {
                      currentRenderParent = currentParent.renderParent;
                  }
                  else {
                      currentRenderParent = currentParent;
                  }
              }
          }
      }
      var /** @type {?} */ handleEvent = function (view, nodeIndex, eventName, event) { return ((/** @type {?} */ ((nodes[nodeIndex].element)).handleEvent))(view, eventName, event); };
      return {
          // Will be filled later...
          factory: null,
          nodeFlags: viewNodeFlags,
          rootNodeFlags: viewRootNodeFlags,
          nodeMatchedQueries: viewMatchedQueries, flags: flags,
          nodes: nodes,
          updateDirectives: updateDirectives || NOOP,
          updateRenderer: updateRenderer || NOOP, handleEvent: handleEvent,
          bindingCount: viewBindingCount,
          outputCount: viewDisposableCount, lastRenderRootNode: lastRenderRootNode
      };
  }
  /**
   * @param {?} node
   * @return {?}
   */
  function isNgContainer(node) {
      return (node.flags & 1 /* TypeElement */) !== 0 && /** @type {?} */ ((node.element)).name === null;
  }
  /**
   * @param {?} parent
   * @param {?} node
   * @param {?} nodeCount
   * @return {?}
   */
  function validateNode(parent, node, nodeCount) {
      var /** @type {?} */ template = node.element && node.element.template;
      if (template) {
          if (!template.lastRenderRootNode) {
              throw new Error("Illegal State: Embedded templates without nodes are not allowed!");
          }
          if (template.lastRenderRootNode &&
              template.lastRenderRootNode.flags & 16777216 /* EmbeddedViews */) {
              throw new Error("Illegal State: Last root node of a template can't have embedded views, at index " + node.nodeIndex + "!");
          }
      }
      if (node.flags & 20224 /* CatProvider */) {
          var /** @type {?} */ parentFlags = parent ? parent.flags : 0;
          if ((parentFlags & 1 /* TypeElement */) === 0) {
              throw new Error("Illegal State: StaticProvider/Directive nodes need to be children of elements or anchors, at index " + node.nodeIndex + "!");
          }
      }
      if (node.query) {
          if (node.flags & 67108864 /* TypeContentQuery */ &&
              (!parent || (parent.flags & 16384 /* TypeDirective */) === 0)) {
              throw new Error("Illegal State: Content Query nodes need to be children of directives, at index " + node.nodeIndex + "!");
          }
          if (node.flags & 134217728 /* TypeViewQuery */ && parent) {
              throw new Error("Illegal State: View Query nodes have to be top level nodes, at index " + node.nodeIndex + "!");
          }
      }
      if (node.childCount) {
          var /** @type {?} */ parentEnd = parent ? parent.nodeIndex + parent.childCount : nodeCount - 1;
          if (node.nodeIndex <= parentEnd && node.nodeIndex + node.childCount > parentEnd) {
              throw new Error("Illegal State: childCount of node leads outside of parent, at index " + node.nodeIndex + "!");
          }
      }
  }
  /**
   * @param {?} parent
   * @param {?} anchorDef
   * @param {?} viewDef
   * @param {?=} context
   * @return {?}
   */
  function createEmbeddedView(parent, anchorDef$$1, viewDef, context) {
      // embedded views are seen as siblings to the anchor, so we need
      // to get the parent of the anchor and use it as parentIndex.
      var /** @type {?} */ view = createView(parent.root, parent.renderer, parent, anchorDef$$1, viewDef);
      initView(view, parent.component, context);
      createViewNodes(view);
      return view;
  }
  /**
   * @param {?} root
   * @param {?} def
   * @param {?=} context
   * @return {?}
   */
  function createRootView(root, def, context) {
      var /** @type {?} */ view = createView(root, root.renderer, null, null, def);
      initView(view, context, context);
      createViewNodes(view);
      return view;
  }
  /**
   * @param {?} parentView
   * @param {?} nodeDef
   * @param {?} viewDef
   * @param {?} hostElement
   * @return {?}
   */
  function createComponentView(parentView, nodeDef, viewDef, hostElement) {
      var /** @type {?} */ rendererType = /** @type {?} */ ((nodeDef.element)).componentRendererType;
      var /** @type {?} */ compRenderer;
      if (!rendererType) {
          compRenderer = parentView.root.renderer;
      }
      else {
          compRenderer = parentView.root.rendererFactory.createRenderer(hostElement, rendererType);
      }
      return createView(parentView.root, compRenderer, parentView, /** @type {?} */ ((nodeDef.element)).componentProvider, viewDef);
  }
  /**
   * @param {?} root
   * @param {?} renderer
   * @param {?} parent
   * @param {?} parentNodeDef
   * @param {?} def
   * @return {?}
   */
  function createView(root, renderer, parent, parentNodeDef, def) {
      var /** @type {?} */ nodes = new Array(def.nodes.length);
      var /** @type {?} */ disposables = def.outputCount ? new Array(def.outputCount) : null;
      var /** @type {?} */ view = {
          def: def,
          parent: parent,
          viewContainerParent: null, parentNodeDef: parentNodeDef,
          context: null,
          component: null, nodes: nodes,
          state: 13 /* CatInit */, root: root, renderer: renderer,
          oldValues: new Array(def.bindingCount), disposables: disposables,
          initIndex: -1
      };
      return view;
  }
  /**
   * @param {?} view
   * @param {?} component
   * @param {?} context
   * @return {?}
   */
  function initView(view, component, context) {
      view.component = component;
      view.context = context;
  }
  /**
   * @param {?} view
   * @return {?}
   */
  function createViewNodes(view) {
      var /** @type {?} */ renderHost;
      if (isComponentView(view)) {
          var /** @type {?} */ hostDef = view.parentNodeDef;
          renderHost = asElementData(/** @type {?} */ ((view.parent)), /** @type {?} */ ((/** @type {?} */ ((hostDef)).parent)).nodeIndex).renderElement;
      }
      var /** @type {?} */ def = view.def;
      var /** @type {?} */ nodes = view.nodes;
      for (var /** @type {?} */ i = 0; i < def.nodes.length; i++) {
          var /** @type {?} */ nodeDef = def.nodes[i];
          Services.setCurrentNode(view, i);
          var /** @type {?} */ nodeData = void 0;
          switch (nodeDef.flags & 201347067 /* Types */) {
              case 1 /* TypeElement */:
                  var /** @type {?} */ el = /** @type {?} */ (createElement(view, renderHost, nodeDef));
                  var /** @type {?} */ componentView = /** @type {?} */ ((undefined));
                  if (nodeDef.flags & 33554432 /* ComponentView */) {
                      var /** @type {?} */ compViewDef = resolveDefinition(/** @type {?} */ ((/** @type {?} */ ((nodeDef.element)).componentView)));
                      componentView = Services.createComponentView(view, nodeDef, compViewDef, el);
                  }
                  listenToElementOutputs(view, componentView, nodeDef, el);
                  nodeData = /** @type {?} */ ({
                      renderElement: el,
                      componentView: componentView,
                      viewContainer: null,
                      template: /** @type {?} */ ((nodeDef.element)).template ? createTemplateData(view, nodeDef) : undefined
                  });
                  if (nodeDef.flags & 16777216 /* EmbeddedViews */) {
                      nodeData.viewContainer = createViewContainerData(view, nodeDef, nodeData);
                  }
                  break;
              case 2 /* TypeText */:
                  nodeData = /** @type {?} */ (createText(view, renderHost, nodeDef));
                  break;
              case 512 /* TypeClassProvider */:
              case 1024 /* TypeFactoryProvider */:
              case 2048 /* TypeUseExistingProvider */:
              case 256 /* TypeValueProvider */: {
                  nodeData = nodes[i];
                  if (!nodeData && !(nodeDef.flags & 4096 /* LazyProvider */)) {
                      var /** @type {?} */ instance = createProviderInstance(view, nodeDef);
                      nodeData = /** @type {?} */ ({ instance: instance });
                  }
                  break;
              }
              case 16 /* TypePipe */: {
                  var /** @type {?} */ instance = createPipeInstance(view, nodeDef);
                  nodeData = /** @type {?} */ ({ instance: instance });
                  break;
              }
              case 16384 /* TypeDirective */: {
                  nodeData = nodes[i];
                  if (!nodeData) {
                      var /** @type {?} */ instance = createDirectiveInstance(view, nodeDef);
                      nodeData = /** @type {?} */ ({ instance: instance });
                  }
                  if (nodeDef.flags & 32768 /* Component */) {
                      var /** @type {?} */ compView = asElementData(view, /** @type {?} */ ((nodeDef.parent)).nodeIndex).componentView;
                      initView(compView, nodeData.instance, nodeData.instance);
                  }
                  break;
              }
              case 32 /* TypePureArray */:
              case 64 /* TypePureObject */:
              case 128 /* TypePurePipe */:
                  nodeData = /** @type {?} */ (createPureExpression(view, nodeDef));
                  break;
              case 67108864 /* TypeContentQuery */:
              case 134217728 /* TypeViewQuery */:
                  nodeData = /** @type {?} */ (createQuery());
                  break;
              case 8 /* TypeNgContent */:
                  appendNgContent(view, renderHost, nodeDef);
                  // no runtime data needed for NgContent...
                  nodeData = undefined;
                  break;
          }
          nodes[i] = nodeData;
      }
      // Create the ViewData.nodes of component views after we created everything else,
      // so that e.g. ng-content works
      execComponentViewsAction(view, ViewAction.CreateViewNodes);
      // fill static content and view queries
      execQueriesAction(view, 67108864 /* TypeContentQuery */ | 134217728 /* TypeViewQuery */, 268435456 /* StaticQuery */, 0 /* CheckAndUpdate */);
  }
  /**
   * @param {?} view
   * @return {?}
   */
  function checkNoChangesView(view) {
      markProjectedViewsForCheck(view);
      Services.updateDirectives(view, 1 /* CheckNoChanges */);
      execEmbeddedViewsAction(view, ViewAction.CheckNoChanges);
      Services.updateRenderer(view, 1 /* CheckNoChanges */);
      execComponentViewsAction(view, ViewAction.CheckNoChanges);
      // Note: We don't check queries for changes as we didn't do this in v2.x.
      // TODO(tbosch): investigate if we can enable the check again in v5.x with a nicer error message.
      view.state &= ~(64 /* CheckProjectedViews */ | 32 /* CheckProjectedView */);
  }
  /**
   * @param {?} view
   * @return {?}
   */
  function checkAndUpdateView(view) {
      if (view.state & 1 /* BeforeFirstCheck */) {
          view.state &= ~1 /* BeforeFirstCheck */;
          view.state |= 2 /* FirstCheck */;
      }
      else {
          view.state &= ~2 /* FirstCheck */;
      }
      shiftInitState(view, 0 /* InitState_BeforeInit */, 256 /* InitState_CallingOnInit */);
      markProjectedViewsForCheck(view);
      Services.updateDirectives(view, 0 /* CheckAndUpdate */);
      execEmbeddedViewsAction(view, ViewAction.CheckAndUpdate);
      execQueriesAction(view, 67108864 /* TypeContentQuery */, 536870912 /* DynamicQuery */, 0 /* CheckAndUpdate */);
      var /** @type {?} */ callInit = shiftInitState(view, 256 /* InitState_CallingOnInit */, 512 /* InitState_CallingAfterContentInit */);
      callLifecycleHooksChildrenFirst(view, 2097152 /* AfterContentChecked */ | (callInit ? 1048576 /* AfterContentInit */ : 0));
      Services.updateRenderer(view, 0 /* CheckAndUpdate */);
      execComponentViewsAction(view, ViewAction.CheckAndUpdate);
      execQueriesAction(view, 134217728 /* TypeViewQuery */, 536870912 /* DynamicQuery */, 0 /* CheckAndUpdate */);
      callInit = shiftInitState(view, 512 /* InitState_CallingAfterContentInit */, 768 /* InitState_CallingAfterViewInit */);
      callLifecycleHooksChildrenFirst(view, 8388608 /* AfterViewChecked */ | (callInit ? 4194304 /* AfterViewInit */ : 0));
      if (view.def.flags & 2 /* OnPush */) {
          view.state &= ~8 /* ChecksEnabled */;
      }
      view.state &= ~(64 /* CheckProjectedViews */ | 32 /* CheckProjectedView */);
      shiftInitState(view, 768 /* InitState_CallingAfterViewInit */, 1024 /* InitState_AfterInit */);
  }
  /**
   * @param {?} view
   * @param {?} nodeDef
   * @param {?} argStyle
   * @param {?=} v0
   * @param {?=} v1
   * @param {?=} v2
   * @param {?=} v3
   * @param {?=} v4
   * @param {?=} v5
   * @param {?=} v6
   * @param {?=} v7
   * @param {?=} v8
   * @param {?=} v9
   * @return {?}
   */
  function checkAndUpdateNode(view, nodeDef, argStyle, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9) {
      if (argStyle === 0 /* Inline */) {
          return checkAndUpdateNodeInline(view, nodeDef, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9);
      }
      else {
          return checkAndUpdateNodeDynamic(view, nodeDef, v0);
      }
  }
  /**
   * @param {?} view
   * @return {?}
   */
  function markProjectedViewsForCheck(view) {
      var /** @type {?} */ def = view.def;
      if (!(def.nodeFlags & 4 /* ProjectedTemplate */)) {
          return;
      }
      for (var /** @type {?} */ i = 0; i < def.nodes.length; i++) {
          var /** @type {?} */ nodeDef = def.nodes[i];
          if (nodeDef.flags & 4 /* ProjectedTemplate */) {
              var /** @type {?} */ projectedViews = asElementData(view, i).template._projectedViews;
              if (projectedViews) {
                  for (var /** @type {?} */ i_1 = 0; i_1 < projectedViews.length; i_1++) {
                      var /** @type {?} */ projectedView = projectedViews[i_1];
                      projectedView.state |= 32 /* CheckProjectedView */;
                      markParentViewsForCheckProjectedViews(projectedView, view);
                  }
              }
          }
          else if ((nodeDef.childFlags & 4 /* ProjectedTemplate */) === 0) {
              // a parent with leafs
              // no child is a component,
              // then skip the children
              i += nodeDef.childCount;
          }
      }
  }
  /**
   * @param {?} view
   * @param {?} nodeDef
   * @param {?=} v0
   * @param {?=} v1
   * @param {?=} v2
   * @param {?=} v3
   * @param {?=} v4
   * @param {?=} v5
   * @param {?=} v6
   * @param {?=} v7
   * @param {?=} v8
   * @param {?=} v9
   * @return {?}
   */
  function checkAndUpdateNodeInline(view, nodeDef, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9) {
      switch (nodeDef.flags & 201347067 /* Types */) {
          case 1 /* TypeElement */:
              return checkAndUpdateElementInline(view, nodeDef, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9);
          case 2 /* TypeText */:
              return checkAndUpdateTextInline(view, nodeDef, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9);
          case 16384 /* TypeDirective */:
              return checkAndUpdateDirectiveInline(view, nodeDef, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9);
          case 32 /* TypePureArray */:
          case 64 /* TypePureObject */:
          case 128 /* TypePurePipe */:
              return checkAndUpdatePureExpressionInline(view, nodeDef, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9);
          default:
              throw 'unreachable';
      }
  }
  /**
   * @param {?} view
   * @param {?} nodeDef
   * @param {?} values
   * @return {?}
   */
  function checkAndUpdateNodeDynamic(view, nodeDef, values) {
      switch (nodeDef.flags & 201347067 /* Types */) {
          case 1 /* TypeElement */:
              return checkAndUpdateElementDynamic(view, nodeDef, values);
          case 2 /* TypeText */:
              return checkAndUpdateTextDynamic(view, nodeDef, values);
          case 16384 /* TypeDirective */:
              return checkAndUpdateDirectiveDynamic(view, nodeDef, values);
          case 32 /* TypePureArray */:
          case 64 /* TypePureObject */:
          case 128 /* TypePurePipe */:
              return checkAndUpdatePureExpressionDynamic(view, nodeDef, values);
          default:
              throw 'unreachable';
      }
  }
  /**
   * @param {?} view
   * @param {?} nodeDef
   * @param {?} argStyle
   * @param {?=} v0
   * @param {?=} v1
   * @param {?=} v2
   * @param {?=} v3
   * @param {?=} v4
   * @param {?=} v5
   * @param {?=} v6
   * @param {?=} v7
   * @param {?=} v8
   * @param {?=} v9
   * @return {?}
   */
  function checkNoChangesNode(view, nodeDef, argStyle, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9) {
      if (argStyle === 0 /* Inline */) {
          checkNoChangesNodeInline(view, nodeDef, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9);
      }
      else {
          checkNoChangesNodeDynamic(view, nodeDef, v0);
      }
      // Returning false is ok here as we would have thrown in case of a change.
      return false;
  }
  /**
   * @param {?} view
   * @param {?} nodeDef
   * @param {?} v0
   * @param {?} v1
   * @param {?} v2
   * @param {?} v3
   * @param {?} v4
   * @param {?} v5
   * @param {?} v6
   * @param {?} v7
   * @param {?} v8
   * @param {?} v9
   * @return {?}
   */
  function checkNoChangesNodeInline(view, nodeDef, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9) {
      var /** @type {?} */ bindLen = nodeDef.bindings.length;
      if (bindLen > 0)
          checkBindingNoChanges(view, nodeDef, 0, v0);
      if (bindLen > 1)
          checkBindingNoChanges(view, nodeDef, 1, v1);
      if (bindLen > 2)
          checkBindingNoChanges(view, nodeDef, 2, v2);
      if (bindLen > 3)
          checkBindingNoChanges(view, nodeDef, 3, v3);
      if (bindLen > 4)
          checkBindingNoChanges(view, nodeDef, 4, v4);
      if (bindLen > 5)
          checkBindingNoChanges(view, nodeDef, 5, v5);
      if (bindLen > 6)
          checkBindingNoChanges(view, nodeDef, 6, v6);
      if (bindLen > 7)
          checkBindingNoChanges(view, nodeDef, 7, v7);
      if (bindLen > 8)
          checkBindingNoChanges(view, nodeDef, 8, v8);
      if (bindLen > 9)
          checkBindingNoChanges(view, nodeDef, 9, v9);
  }
  /**
   * @param {?} view
   * @param {?} nodeDef
   * @param {?} values
   * @return {?}
   */
  function checkNoChangesNodeDynamic(view, nodeDef, values) {
      for (var /** @type {?} */ i = 0; i < values.length; i++) {
          checkBindingNoChanges(view, nodeDef, i, values[i]);
      }
  }
  /**
   * Workaround https://github.com/angular/tsickle/issues/497
   * @suppress {misplacedTypeAnnotation}
   * @param {?} view
   * @param {?} nodeDef
   * @return {?}
   */
  function checkNoChangesQuery(view, nodeDef) {
      var /** @type {?} */ queryList = asQueryList(view, nodeDef.nodeIndex);
      if (queryList.dirty) {
          throw expressionChangedAfterItHasBeenCheckedError(Services.createDebugContext(view, nodeDef.nodeIndex), "Query " + (/** @type {?} */ ((nodeDef.query))).id + " not dirty", "Query " + (/** @type {?} */ ((nodeDef.query))).id + " dirty", (view.state & 1 /* BeforeFirstCheck */) !== 0);
      }
  }
  /**
   * @param {?} view
   * @return {?}
   */
  function destroyView(view) {
      if (view.state & 128 /* Destroyed */) {
          return;
      }
      execEmbeddedViewsAction(view, ViewAction.Destroy);
      execComponentViewsAction(view, ViewAction.Destroy);
      callLifecycleHooksChildrenFirst(view, 131072 /* OnDestroy */);
      if (view.disposables) {
          for (var /** @type {?} */ i = 0; i < view.disposables.length; i++) {
              view.disposables[i]();
          }
      }
      detachProjectedView(view);
      if (view.renderer.destroyNode) {
          destroyViewNodes(view);
      }
      if (isComponentView(view)) {
          view.renderer.destroy();
      }
      view.state |= 128 /* Destroyed */;
  }
  /**
   * @param {?} view
   * @return {?}
   */
  function destroyViewNodes(view) {
      var /** @type {?} */ len = view.def.nodes.length;
      for (var /** @type {?} */ i = 0; i < len; i++) {
          var /** @type {?} */ def = view.def.nodes[i];
          if (def.flags & 1 /* TypeElement */) {
              /** @type {?} */ ((view.renderer.destroyNode))(asElementData(view, i).renderElement);
          }
          else if (def.flags & 2 /* TypeText */) {
              /** @type {?} */ ((view.renderer.destroyNode))(asTextData(view, i).renderText);
          }
          else if (def.flags & 67108864 /* TypeContentQuery */ || def.flags & 134217728 /* TypeViewQuery */) {
              asQueryList(view, i).destroy();
          }
      }
  }
  /** @enum {number} */
  var ViewAction = {
      CreateViewNodes: 0,
      CheckNoChanges: 1,
      CheckNoChangesProjectedViews: 2,
      CheckAndUpdate: 3,
      CheckAndUpdateProjectedViews: 4,
      Destroy: 5,
  };
  ViewAction[ViewAction.CreateViewNodes] = "CreateViewNodes";
  ViewAction[ViewAction.CheckNoChanges] = "CheckNoChanges";
  ViewAction[ViewAction.CheckNoChangesProjectedViews] = "CheckNoChangesProjectedViews";
  ViewAction[ViewAction.CheckAndUpdate] = "CheckAndUpdate";
  ViewAction[ViewAction.CheckAndUpdateProjectedViews] = "CheckAndUpdateProjectedViews";
  ViewAction[ViewAction.Destroy] = "Destroy";
  /**
   * @param {?} view
   * @param {?} action
   * @return {?}
   */
  function execComponentViewsAction(view, action) {
      var /** @type {?} */ def = view.def;
      if (!(def.nodeFlags & 33554432 /* ComponentView */)) {
          return;
      }
      for (var /** @type {?} */ i = 0; i < def.nodes.length; i++) {
          var /** @type {?} */ nodeDef = def.nodes[i];
          if (nodeDef.flags & 33554432 /* ComponentView */) {
              // a leaf
              callViewAction(asElementData(view, i).componentView, action);
          }
          else if ((nodeDef.childFlags & 33554432 /* ComponentView */) === 0) {
              // a parent with leafs
              // no child is a component,
              // then skip the children
              i += nodeDef.childCount;
          }
      }
  }
  /**
   * @param {?} view
   * @param {?} action
   * @return {?}
   */
  function execEmbeddedViewsAction(view, action) {
      var /** @type {?} */ def = view.def;
      if (!(def.nodeFlags & 16777216 /* EmbeddedViews */)) {
          return;
      }
      for (var /** @type {?} */ i = 0; i < def.nodes.length; i++) {
          var /** @type {?} */ nodeDef = def.nodes[i];
          if (nodeDef.flags & 16777216 /* EmbeddedViews */) {
              // a leaf
              var /** @type {?} */ embeddedViews = /** @type {?} */ ((asElementData(view, i).viewContainer))._embeddedViews;
              for (var /** @type {?} */ k = 0; k < embeddedViews.length; k++) {
                  callViewAction(embeddedViews[k], action);
              }
          }
          else if ((nodeDef.childFlags & 16777216 /* EmbeddedViews */) === 0) {
              // a parent with leafs
              // no child is a component,
              // then skip the children
              i += nodeDef.childCount;
          }
      }
  }
  /**
   * @param {?} view
   * @param {?} action
   * @return {?}
   */
  function callViewAction(view, action) {
      var /** @type {?} */ viewState = view.state;
      switch (action) {
          case ViewAction.CheckNoChanges:
              if ((viewState & 128 /* Destroyed */) === 0) {
                  if ((viewState & 12 /* CatDetectChanges */) === 12 /* CatDetectChanges */) {
                      checkNoChangesView(view);
                  }
                  else if (viewState & 64 /* CheckProjectedViews */) {
                      execProjectedViewsAction(view, ViewAction.CheckNoChangesProjectedViews);
                  }
              }
              break;
          case ViewAction.CheckNoChangesProjectedViews:
              if ((viewState & 128 /* Destroyed */) === 0) {
                  if (viewState & 32 /* CheckProjectedView */) {
                      checkNoChangesView(view);
                  }
                  else if (viewState & 64 /* CheckProjectedViews */) {
                      execProjectedViewsAction(view, action);
                  }
              }
              break;
          case ViewAction.CheckAndUpdate:
              if ((viewState & 128 /* Destroyed */) === 0) {
                  if ((viewState & 12 /* CatDetectChanges */) === 12 /* CatDetectChanges */) {
                      checkAndUpdateView(view);
                  }
                  else if (viewState & 64 /* CheckProjectedViews */) {
                      execProjectedViewsAction(view, ViewAction.CheckAndUpdateProjectedViews);
                  }
              }
              break;
          case ViewAction.CheckAndUpdateProjectedViews:
              if ((viewState & 128 /* Destroyed */) === 0) {
                  if (viewState & 32 /* CheckProjectedView */) {
                      checkAndUpdateView(view);
                  }
                  else if (viewState & 64 /* CheckProjectedViews */) {
                      execProjectedViewsAction(view, action);
                  }
              }
              break;
          case ViewAction.Destroy:
              // Note: destroyView recurses over all views,
              // so we don't need to special case projected views here.
              destroyView(view);
              break;
          case ViewAction.CreateViewNodes:
              createViewNodes(view);
              break;
      }
  }
  /**
   * @param {?} view
   * @param {?} action
   * @return {?}
   */
  function execProjectedViewsAction(view, action) {
      execEmbeddedViewsAction(view, action);
      execComponentViewsAction(view, action);
  }
  /**
   * @param {?} view
   * @param {?} queryFlags
   * @param {?} staticDynamicQueryFlag
   * @param {?} checkType
   * @return {?}
   */
  function execQueriesAction(view, queryFlags, staticDynamicQueryFlag, checkType) {
      if (!(view.def.nodeFlags & queryFlags) || !(view.def.nodeFlags & staticDynamicQueryFlag)) {
          return;
      }
      var /** @type {?} */ nodeCount = view.def.nodes.length;
      for (var /** @type {?} */ i = 0; i < nodeCount; i++) {
          var /** @type {?} */ nodeDef = view.def.nodes[i];
          if ((nodeDef.flags & queryFlags) && (nodeDef.flags & staticDynamicQueryFlag)) {
              Services.setCurrentNode(view, nodeDef.nodeIndex);
              switch (checkType) {
                  case 0 /* CheckAndUpdate */:
                      checkAndUpdateQuery(view, nodeDef);
                      break;
                  case 1 /* CheckNoChanges */:
                      checkNoChangesQuery(view, nodeDef);
                      break;
              }
          }
          if (!(nodeDef.childFlags & queryFlags) || !(nodeDef.childFlags & staticDynamicQueryFlag)) {
              // no child has a matching query
              // then skip the children
              i += nodeDef.childCount;
          }
      }
  }
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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 initialized = false;
  /**
   * @return {?}
   */
  function initServicesIfNeeded() {
      if (initialized) {
          return;
      }
      initialized = true;
      var /** @type {?} */ services = isDevMode() ? createDebugServices() : createProdServices();
      Services.setCurrentNode = services.setCurrentNode;
      Services.createRootView = services.createRootView;
      Services.createEmbeddedView = services.createEmbeddedView;
      Services.createComponentView = services.createComponentView;
      Services.createNgModuleRef = services.createNgModuleRef;
      Services.overrideProvider = services.overrideProvider;
      Services.overrideComponentView = services.overrideComponentView;
      Services.clearOverrides = services.clearOverrides;
      Services.checkAndUpdateView = services.checkAndUpdateView;
      Services.checkNoChangesView = services.checkNoChangesView;
      Services.destroyView = services.destroyView;
      Services.resolveDep = resolveDep;
      Services.createDebugContext = services.createDebugContext;
      Services.handleEvent = services.handleEvent;
      Services.updateDirectives = services.updateDirectives;
      Services.updateRenderer = services.updateRenderer;
      Services.dirtyParentQueries = dirtyParentQueries;
  }
  /**
   * @return {?}
   */
  function createProdServices() {
      return {
          setCurrentNode: function () { },
          createRootView: createProdRootView,
          createEmbeddedView: createEmbeddedView,
          createComponentView: createComponentView,
          createNgModuleRef: createNgModuleRef,
          overrideProvider: NOOP,
          overrideComponentView: NOOP,
          clearOverrides: NOOP,
          checkAndUpdateView: checkAndUpdateView,
          checkNoChangesView: checkNoChangesView,
          destroyView: destroyView,
          createDebugContext: function (view, nodeIndex) { return new DebugContext_(view, nodeIndex); },
          handleEvent: function (view, nodeIndex, eventName, event) {
              return view.def.handleEvent(view, nodeIndex, eventName, event);
          },
          updateDirectives: function (view, checkType) {
              return view.def.updateDirectives(checkType === 0 /* CheckAndUpdate */ ? prodCheckAndUpdateNode :
                  prodCheckNoChangesNode, view);
          },
          updateRenderer: function (view, checkType) {
              return view.def.updateRenderer(checkType === 0 /* CheckAndUpdate */ ? prodCheckAndUpdateNode :
                  prodCheckNoChangesNode, view);
          },
      };
  }
  /**
   * @return {?}
   */
  function createDebugServices() {
      return {
          setCurrentNode: debugSetCurrentNode,
          createRootView: debugCreateRootView,
          createEmbeddedView: debugCreateEmbeddedView,
          createComponentView: debugCreateComponentView,
          createNgModuleRef: debugCreateNgModuleRef,
          overrideProvider: debugOverrideProvider,
          overrideComponentView: debugOverrideComponentView,
          clearOverrides: debugClearOverrides,
          checkAndUpdateView: debugCheckAndUpdateView,
          checkNoChangesView: debugCheckNoChangesView,
          destroyView: debugDestroyView,
          createDebugContext: function (view, nodeIndex) { return new DebugContext_(view, nodeIndex); },
          handleEvent: debugHandleEvent,
          updateDirectives: debugUpdateDirectives,
          updateRenderer: debugUpdateRenderer,
      };
  }
  /**
   * @param {?} elInjector
   * @param {?} projectableNodes
   * @param {?} rootSelectorOrNode
   * @param {?} def
   * @param {?} ngModule
   * @param {?=} context
   * @return {?}
   */
  function createProdRootView(elInjector, projectableNodes, rootSelectorOrNode, def, ngModule, context) {
      var /** @type {?} */ rendererFactory = ngModule.injector.get(RendererFactory2);
      return createRootView(createRootData(elInjector, ngModule, rendererFactory, projectableNodes, rootSelectorOrNode), def, context);
  }
  /**
   * @param {?} elInjector
   * @param {?} projectableNodes
   * @param {?} rootSelectorOrNode
   * @param {?} def
   * @param {?} ngModule
   * @param {?=} context
   * @return {?}
   */
  function debugCreateRootView(elInjector, projectableNodes, rootSelectorOrNode, def, ngModule, context) {
      var /** @type {?} */ rendererFactory = ngModule.injector.get(RendererFactory2);
      var /** @type {?} */ root = createRootData(elInjector, ngModule, new DebugRendererFactory2(rendererFactory), projectableNodes, rootSelectorOrNode);
      var /** @type {?} */ defWithOverride = applyProviderOverridesToView(def);
      return callWithDebugContext(DebugAction.create, createRootView, null, [root, defWithOverride, context]);
  }
  /**
   * @param {?} elInjector
   * @param {?} ngModule
   * @param {?} rendererFactory
   * @param {?} projectableNodes
   * @param {?} rootSelectorOrNode
   * @return {?}
   */
  function createRootData(elInjector, ngModule, rendererFactory, projectableNodes, rootSelectorOrNode) {
      var /** @type {?} */ sanitizer = ngModule.injector.get(Sanitizer);
      var /** @type {?} */ errorHandler = ngModule.injector.get(ErrorHandler);
      var /** @type {?} */ renderer = rendererFactory.createRenderer(null, null);
      return {
          ngModule: ngModule,
          injector: elInjector, projectableNodes: projectableNodes,
          selectorOrNode: rootSelectorOrNode, sanitizer: sanitizer, rendererFactory: rendererFactory, renderer: renderer, errorHandler: errorHandler
      };
  }
  /**
   * @param {?} parentView
   * @param {?} anchorDef
   * @param {?} viewDef
   * @param {?=} context
   * @return {?}
   */
  function debugCreateEmbeddedView(parentView, anchorDef, viewDef$$1, context) {
      var /** @type {?} */ defWithOverride = applyProviderOverridesToView(viewDef$$1);
      return callWithDebugContext(DebugAction.create, createEmbeddedView, null, [parentView, anchorDef, defWithOverride, context]);
  }
  /**
   * @param {?} parentView
   * @param {?} nodeDef
   * @param {?} viewDef
   * @param {?} hostElement
   * @return {?}
   */
  function debugCreateComponentView(parentView, nodeDef, viewDef$$1, hostElement) {
      var /** @type {?} */ overrideComponentView = viewDefOverrides.get(/** @type {?} */ ((/** @type {?} */ ((/** @type {?} */ ((nodeDef.element)).componentProvider)).provider)).token);
      if (overrideComponentView) {
          viewDef$$1 = overrideComponentView;
      }
      else {
          viewDef$$1 = applyProviderOverridesToView(viewDef$$1);
      }
      return callWithDebugContext(DebugAction.create, createComponentView, null, [parentView, nodeDef, viewDef$$1, hostElement]);
  }
  /**
   * @param {?} moduleType
   * @param {?} parentInjector
   * @param {?} bootstrapComponents
   * @param {?} def
   * @return {?}
   */
  function debugCreateNgModuleRef(moduleType, parentInjector, bootstrapComponents, def) {
      var /** @type {?} */ defWithOverride = applyProviderOverridesToNgModule(def);
      return createNgModuleRef(moduleType, parentInjector, bootstrapComponents, defWithOverride);
  }
  var providerOverrides = new Map();
  var viewDefOverrides = new Map();
  /**
   * @param {?} override
   * @return {?}
   */
  function debugOverrideProvider(override) {
      providerOverrides.set(override.token, override);
  }
  /**
   * @param {?} comp
   * @param {?} compFactory
   * @return {?}
   */
  function debugOverrideComponentView(comp, compFactory) {
      var /** @type {?} */ hostViewDef = resolveDefinition(getComponentViewDefinitionFactory(compFactory));
      var /** @type {?} */ compViewDef = resolveDefinition(/** @type {?} */ ((/** @type {?} */ ((hostViewDef.nodes[0].element)).componentView)));
      viewDefOverrides.set(comp, compViewDef);
  }
  /**
   * @return {?}
   */
  function debugClearOverrides() {
      providerOverrides.clear();
      viewDefOverrides.clear();
  }
  /**
   * @param {?} def
   * @return {?}
   */
  function applyProviderOverridesToView(def) {
      if (providerOverrides.size === 0) {
          return def;
      }
      var /** @type {?} */ elementIndicesWithOverwrittenProviders = findElementIndicesWithOverwrittenProviders(def);
      if (elementIndicesWithOverwrittenProviders.length === 0) {
          return def;
      }
      // clone the whole view definition,
      // as it maintains references between the nodes that are hard to update.
      def = /** @type {?} */ ((def.factory))(function () { return NOOP; });
      for (var /** @type {?} */ i = 0; i < elementIndicesWithOverwrittenProviders.length; i++) {
          applyProviderOverridesToElement(def, elementIndicesWithOverwrittenProviders[i]);
      }
      return def;
      /**
       * @param {?} def
       * @return {?}
       */
      function findElementIndicesWithOverwrittenProviders(def) {
          var /** @type {?} */ elIndicesWithOverwrittenProviders = [];
          var /** @type {?} */ lastElementDef = null;
          for (var /** @type {?} */ i = 0; i < def.nodes.length; i++) {
              var /** @type {?} */ nodeDef = def.nodes[i];
              if (nodeDef.flags & 1 /* TypeElement */) {
                  lastElementDef = nodeDef;
              }
              if (lastElementDef && nodeDef.flags & 3840 /* CatProviderNoDirective */ &&
                  providerOverrides.has(/** @type {?} */ ((nodeDef.provider)).token)) {
                  elIndicesWithOverwrittenProviders.push(/** @type {?} */ ((lastElementDef)).nodeIndex);
                  lastElementDef = null;
              }
          }
          return elIndicesWithOverwrittenProviders;
      }
      /**
       * @param {?} viewDef
       * @param {?} elIndex
       * @return {?}
       */
      function applyProviderOverridesToElement(viewDef$$1, elIndex) {
          for (var /** @type {?} */ i = elIndex + 1; i < viewDef$$1.nodes.length; i++) {
              var /** @type {?} */ nodeDef = viewDef$$1.nodes[i];
              if (nodeDef.flags & 1 /* TypeElement */) {
                  // stop at the next element
                  return;
              }
              if (nodeDef.flags & 3840 /* CatProviderNoDirective */) {
                  var /** @type {?} */ provider = /** @type {?} */ ((nodeDef.provider));
                  var /** @type {?} */ override = providerOverrides.get(provider.token);
                  if (override) {
                      nodeDef.flags = (nodeDef.flags & ~3840 /* CatProviderNoDirective */) | override.flags;
                      provider.deps = splitDepsDsl(override.deps);
                      provider.value = override.value;
                  }
              }
          }
      }
  }
  /**
   * @param {?} def
   * @return {?}
   */
  function applyProviderOverridesToNgModule(def) {
      var _a = calcHasOverrides(def), hasOverrides = _a.hasOverrides, hasDeprecatedOverrides = _a.hasDeprecatedOverrides;
      if (!hasOverrides) {
          return def;
      }
      // clone the whole view definition,
      // as it maintains references between the nodes that are hard to update.
      def = /** @type {?} */ ((def.factory))(function () { return NOOP; });
      applyProviderOverrides(def);
      return def;
      /**
       * @param {?} def
       * @return {?}
       */
      function calcHasOverrides(def) {
          var /** @type {?} */ hasOverrides = false;
          var /** @type {?} */ hasDeprecatedOverrides = false;
          if (providerOverrides.size === 0) {
              return { hasOverrides: hasOverrides, hasDeprecatedOverrides: hasDeprecatedOverrides };
          }
          def.providers.forEach(function (node) {
              var /** @type {?} */ override = providerOverrides.get(node.token);
              if ((node.flags & 3840 /* CatProviderNoDirective */) && override) {
                  hasOverrides = true;
                  hasDeprecatedOverrides = hasDeprecatedOverrides || override.deprecatedBehavior;
              }
          });
          return { hasOverrides: hasOverrides, hasDeprecatedOverrides: hasDeprecatedOverrides };
      }
      /**
       * @param {?} def
       * @return {?}
       */
      function applyProviderOverrides(def) {
          for (var /** @type {?} */ i = 0; i < def.providers.length; i++) {
              var /** @type {?} */ provider = def.providers[i];
              if (hasDeprecatedOverrides) {
                  // We had a bug where me made
                  // all providers lazy. Keep this logic behind a flag
                  // for migrating existing users.
                  provider.flags |= 4096 /* LazyProvider */;
              }
              var /** @type {?} */ override = providerOverrides.get(provider.token);
              if (override) {
                  provider.flags = (provider.flags & ~3840 /* CatProviderNoDirective */) | override.flags;
                  provider.deps = splitDepsDsl(override.deps);
                  provider.value = override.value;
              }
          }
      }
  }
  /**
   * @param {?} view
   * @param {?} checkIndex
   * @param {?} argStyle
   * @param {?=} v0
   * @param {?=} v1
   * @param {?=} v2
   * @param {?=} v3
   * @param {?=} v4
   * @param {?=} v5
   * @param {?=} v6
   * @param {?=} v7
   * @param {?=} v8
   * @param {?=} v9
   * @return {?}
   */
  function prodCheckAndUpdateNode(view, checkIndex, argStyle, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9) {
      var /** @type {?} */ nodeDef = view.def.nodes[checkIndex];
      checkAndUpdateNode(view, nodeDef, argStyle, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9);
      return (nodeDef.flags & 224 /* CatPureExpression */) ?
          asPureExpressionData(view, checkIndex).value :
          undefined;
  }
  /**
   * @param {?} view
   * @param {?} checkIndex
   * @param {?} argStyle
   * @param {?=} v0
   * @param {?=} v1
   * @param {?=} v2
   * @param {?=} v3
   * @param {?=} v4
   * @param {?=} v5
   * @param {?=} v6
   * @param {?=} v7
   * @param {?=} v8
   * @param {?=} v9
   * @return {?}
   */
  function prodCheckNoChangesNode(view, checkIndex, argStyle, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9) {
      var /** @type {?} */ nodeDef = view.def.nodes[checkIndex];
      checkNoChangesNode(view, nodeDef, argStyle, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9);
      return (nodeDef.flags & 224 /* CatPureExpression */) ?
          asPureExpressionData(view, checkIndex).value :
          undefined;
  }
  /**
   * @param {?} view
   * @return {?}
   */
  function debugCheckAndUpdateView(view) {
      return callWithDebugContext(DebugAction.detectChanges, checkAndUpdateView, null, [view]);
  }
  /**
   * @param {?} view
   * @return {?}
   */
  function debugCheckNoChangesView(view) {
      return callWithDebugContext(DebugAction.checkNoChanges, checkNoChangesView, null, [view]);
  }
  /**
   * @param {?} view
   * @return {?}
   */
  function debugDestroyView(view) {
      return callWithDebugContext(DebugAction.destroy, destroyView, null, [view]);
  }
  /** @enum {number} */
  var DebugAction = {
      create: 0,
      detectChanges: 1,
      checkNoChanges: 2,
      destroy: 3,
      handleEvent: 4,
  };
  DebugAction[DebugAction.create] = "create";
  DebugAction[DebugAction.detectChanges] = "detectChanges";
  DebugAction[DebugAction.checkNoChanges] = "checkNoChanges";
  DebugAction[DebugAction.destroy] = "destroy";
  DebugAction[DebugAction.handleEvent] = "handleEvent";
  var _currentAction;
  var _currentView;
  var _currentNodeIndex;
  /**
   * @param {?} view
   * @param {?} nodeIndex
   * @return {?}
   */
  function debugSetCurrentNode(view, nodeIndex) {
      _currentView = view;
      _currentNodeIndex = nodeIndex;
  }
  /**
   * @param {?} view
   * @param {?} nodeIndex
   * @param {?} eventName
   * @param {?} event
   * @return {?}
   */
  function debugHandleEvent(view, nodeIndex, eventName, event) {
      debugSetCurrentNode(view, nodeIndex);
      return callWithDebugContext(DebugAction.handleEvent, view.def.handleEvent, null, [view, nodeIndex, eventName, event]);
  }
  /**
   * @param {?} view
   * @param {?} checkType
   * @return {?}
   */
  function debugUpdateDirectives(view, checkType) {
      if (view.state & 128 /* Destroyed */) {
          throw viewDestroyedError(DebugAction[_currentAction]);
      }
      debugSetCurrentNode(view, nextDirectiveWithBinding(view, 0));
      return view.def.updateDirectives(debugCheckDirectivesFn, view);
      /**
       * @param {?} view
       * @param {?} nodeIndex
       * @param {?} argStyle
       * @param {...?} values
       * @return {?}
       */
      function debugCheckDirectivesFn(view, nodeIndex, argStyle) {
          var values = [];
          for (var _i = 3; _i < arguments.length; _i++) {
              values[_i - 3] = arguments[_i];
          }
          var /** @type {?} */ nodeDef = view.def.nodes[nodeIndex];
          if (checkType === 0 /* CheckAndUpdate */) {
              debugCheckAndUpdateNode(view, nodeDef, argStyle, values);
          }
          else {
              debugCheckNoChangesNode(view, nodeDef, argStyle, values);
          }
          if (nodeDef.flags & 16384 /* TypeDirective */) {
              debugSetCurrentNode(view, nextDirectiveWithBinding(view, nodeIndex));
          }
          return (nodeDef.flags & 224 /* CatPureExpression */) ?
              asPureExpressionData(view, nodeDef.nodeIndex).value :
              undefined;
      }
  }
  /**
   * @param {?} view
   * @param {?} checkType
   * @return {?}
   */
  function debugUpdateRenderer(view, checkType) {
      if (view.state & 128 /* Destroyed */) {
          throw viewDestroyedError(DebugAction[_currentAction]);
      }
      debugSetCurrentNode(view, nextRenderNodeWithBinding(view, 0));
      return view.def.updateRenderer(debugCheckRenderNodeFn, view);
      /**
       * @param {?} view
       * @param {?} nodeIndex
       * @param {?} argStyle
       * @param {...?} values
       * @return {?}
       */
      function debugCheckRenderNodeFn(view, nodeIndex, argStyle) {
          var values = [];
          for (var _i = 3; _i < arguments.length; _i++) {
              values[_i - 3] = arguments[_i];
          }
          var /** @type {?} */ nodeDef = view.def.nodes[nodeIndex];
          if (checkType === 0 /* CheckAndUpdate */) {
              debugCheckAndUpdateNode(view, nodeDef, argStyle, values);
          }
          else {
              debugCheckNoChangesNode(view, nodeDef, argStyle, values);
          }
          if (nodeDef.flags & 3 /* CatRenderNode */) {
              debugSetCurrentNode(view, nextRenderNodeWithBinding(view, nodeIndex));
          }
          return (nodeDef.flags & 224 /* CatPureExpression */) ?
              asPureExpressionData(view, nodeDef.nodeIndex).value :
              undefined;
      }
  }
  /**
   * @param {?} view
   * @param {?} nodeDef
   * @param {?} argStyle
   * @param {?} givenValues
   * @return {?}
   */
  function debugCheckAndUpdateNode(view, nodeDef, argStyle, givenValues) {
      var /** @type {?} */ changed = (/** @type {?} */ (checkAndUpdateNode)).apply(void 0, [view, nodeDef, argStyle].concat(givenValues));
      if (changed) {
          var /** @type {?} */ values = argStyle === 1 /* Dynamic */ ? givenValues[0] : givenValues;
          if (nodeDef.flags & 16384 /* TypeDirective */) {
              var /** @type {?} */ bindingValues = {};
              for (var /** @type {?} */ i = 0; i < nodeDef.bindings.length; i++) {
                  var /** @type {?} */ binding = nodeDef.bindings[i];
                  var /** @type {?} */ value = values[i];
                  if (binding.flags & 8 /* TypeProperty */) {
                      bindingValues[normalizeDebugBindingName(/** @type {?} */ ((binding.nonMinifiedName)))] =
                          normalizeDebugBindingValue(value);
                  }
              }
              var /** @type {?} */ elDef = /** @type {?} */ ((nodeDef.parent));
              var /** @type {?} */ el = asElementData(view, elDef.nodeIndex).renderElement;
              if (!/** @type {?} */ ((elDef.element)).name) {
                  // a comment.
                  view.renderer.setValue(el, "bindings=" + JSON.stringify(bindingValues, null, 2));
              }
              else {
                  // a regular element.
                  for (var /** @type {?} */ attr in bindingValues) {
                      var /** @type {?} */ value = bindingValues[attr];
                      if (value != null) {
                          view.renderer.setAttribute(el, attr, value);
                      }
                      else {
                          view.renderer.removeAttribute(el, attr);
                      }
                  }
              }
          }
      }
  }
  /**
   * @param {?} view
   * @param {?} nodeDef
   * @param {?} argStyle
   * @param {?} values
   * @return {?}
   */
  function debugCheckNoChangesNode(view, nodeDef, argStyle, values) {
      (/** @type {?} */ (checkNoChangesNode)).apply(void 0, [view, nodeDef, argStyle].concat(values));
  }
  /**
   * @param {?} name
   * @return {?}
   */
  function normalizeDebugBindingName(name) {
      // Attribute names with `$` (eg `x-y$`) are valid per spec, but unsupported by some browsers
      name = camelCaseToDashCase(name.replace(/[$@]/g, '_'));
      return "ng-reflect-" + name;
  }
  var CAMEL_CASE_REGEXP = /([A-Z])/g;
  /**
   * @param {?} input
   * @return {?}
   */
  function camelCaseToDashCase(input) {
      return input.replace(CAMEL_CASE_REGEXP, function () {
          var m = [];
          for (var _i = 0; _i < arguments.length; _i++) {
              m[_i] = arguments[_i];
          }
          return '-' + m[1].toLowerCase();
      });
  }
  /**
   * @param {?} value
   * @return {?}
   */
  function normalizeDebugBindingValue(value) {
      try {
          // Limit the size of the value as otherwise the DOM just gets polluted.
          return value != null ? value.toString().slice(0, 30) : value;
      }
      catch (/** @type {?} */ e) {
          return '[ERROR] Exception while trying to serialize the value';
      }
  }
  /**
   * @param {?} view
   * @param {?} nodeIndex
   * @return {?}
   */
  function nextDirectiveWithBinding(view, nodeIndex) {
      for (var /** @type {?} */ i = nodeIndex; i < view.def.nodes.length; i++) {
          var /** @type {?} */ nodeDef = view.def.nodes[i];
          if (nodeDef.flags & 16384 /* TypeDirective */ && nodeDef.bindings && nodeDef.bindings.length) {
              return i;
          }
      }
      return null;
  }
  /**
   * @param {?} view
   * @param {?} nodeIndex
   * @return {?}
   */
  function nextRenderNodeWithBinding(view, nodeIndex) {
      for (var /** @type {?} */ i = nodeIndex; i < view.def.nodes.length; i++) {
          var /** @type {?} */ nodeDef = view.def.nodes[i];
          if ((nodeDef.flags & 3 /* CatRenderNode */) && nodeDef.bindings && nodeDef.bindings.length) {
              return i;
          }
      }
      return null;
  }
  var DebugContext_ = /** @class */ (function () {
      function DebugContext_(view, nodeIndex) {
          this.view = view;
          this.nodeIndex = nodeIndex;
          if (nodeIndex == null) {
              this.nodeIndex = nodeIndex = 0;
          }
          this.nodeDef = view.def.nodes[nodeIndex];
          var /** @type {?} */ elDef = this.nodeDef;
          var /** @type {?} */ elView = view;
          while (elDef && (elDef.flags & 1 /* TypeElement */) === 0) {
              elDef = /** @type {?} */ ((elDef.parent));
          }
          if (!elDef) {
              while (!elDef && elView) {
                  elDef = /** @type {?} */ ((viewParentEl(elView)));
                  elView = /** @type {?} */ ((elView.parent));
              }
          }
          this.elDef = elDef;
          this.elView = elView;
      }
      Object.defineProperty(DebugContext_.prototype, "elOrCompView", {
          get: /**
           * @return {?}
           */
          function () {
              // Has to be done lazily as we use the DebugContext also during creation of elements...
              return asElementData(this.elView, this.elDef.nodeIndex).componentView || this.view;
          },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(DebugContext_.prototype, "injector", {
          get: /**
           * @return {?}
           */
          function () { return createInjector(this.elView, this.elDef); },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(DebugContext_.prototype, "component", {
          get: /**
           * @return {?}
           */
          function () { return this.elOrCompView.component; },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(DebugContext_.prototype, "context", {
          get: /**
           * @return {?}
           */
          function () { return this.elOrCompView.context; },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(DebugContext_.prototype, "providerTokens", {
          get: /**
           * @return {?}
           */
          function () {
              var /** @type {?} */ tokens = [];
              if (this.elDef) {
                  for (var /** @type {?} */ i = this.elDef.nodeIndex + 1; i <= this.elDef.nodeIndex + this.elDef.childCount; i++) {
                      var /** @type {?} */ childDef = this.elView.def.nodes[i];
                      if (childDef.flags & 20224 /* CatProvider */) {
                          tokens.push(/** @type {?} */ ((childDef.provider)).token);
                      }
                      i += childDef.childCount;
                  }
              }
              return tokens;
          },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(DebugContext_.prototype, "references", {
          get: /**
           * @return {?}
           */
          function () {
              var /** @type {?} */ references = {};
              if (this.elDef) {
                  collectReferences(this.elView, this.elDef, references);
                  for (var /** @type {?} */ i = this.elDef.nodeIndex + 1; i <= this.elDef.nodeIndex + this.elDef.childCount; i++) {
                      var /** @type {?} */ childDef = this.elView.def.nodes[i];
                      if (childDef.flags & 20224 /* CatProvider */) {
                          collectReferences(this.elView, childDef, references);
                      }
                      i += childDef.childCount;
                  }
              }
              return references;
          },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(DebugContext_.prototype, "componentRenderElement", {
          get: /**
           * @return {?}
           */
          function () {
              var /** @type {?} */ elData = findHostElement(this.elOrCompView);
              return elData ? elData.renderElement : undefined;
          },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(DebugContext_.prototype, "renderNode", {
          get: /**
           * @return {?}
           */
          function () {
              return this.nodeDef.flags & 2 /* TypeText */ ? renderNode(this.view, this.nodeDef) :
                  renderNode(this.elView, this.elDef);
          },
          enumerable: true,
          configurable: true
      });
      /**
       * @param {?} console
       * @param {...?} values
       * @return {?}
       */
      DebugContext_.prototype.logError = /**
       * @param {?} console
       * @param {...?} values
       * @return {?}
       */
      function (console) {
          var values = [];
          for (var _i = 1; _i < arguments.length; _i++) {
              values[_i - 1] = arguments[_i];
          }
          var /** @type {?} */ logViewDef;
          var /** @type {?} */ logNodeIndex;
          if (this.nodeDef.flags & 2 /* TypeText */) {
              logViewDef = this.view.def;
              logNodeIndex = this.nodeDef.nodeIndex;
          }
          else {
              logViewDef = this.elView.def;
              logNodeIndex = this.elDef.nodeIndex;
          }
          // Note: we only generate a log function for text and element nodes
          // to make the generated code as small as possible.
          var /** @type {?} */ renderNodeIndex = getRenderNodeIndex(logViewDef, logNodeIndex);
          var /** @type {?} */ currRenderNodeIndex = -1;
          var /** @type {?} */ nodeLogger = function () {
              currRenderNodeIndex++;
              if (currRenderNodeIndex === renderNodeIndex) {
                  return (_a = console.error).bind.apply(_a, [console].concat(values));
              }
              else {
                  return NOOP;
              }
              var _a;
          }; /** @type {?} */
          ((logViewDef.factory))(nodeLogger);
          if (currRenderNodeIndex < renderNodeIndex) {
              console.error('Illegal state: the ViewDefinitionFactory did not call the logger!');
              console.error.apply(console, values);
          }
      };
      return DebugContext_;
  }());
  /**
   * @param {?} viewDef
   * @param {?} nodeIndex
   * @return {?}
   */
  function getRenderNodeIndex(viewDef$$1, nodeIndex) {
      var /** @type {?} */ renderNodeIndex = -1;
      for (var /** @type {?} */ i = 0; i <= nodeIndex; i++) {
          var /** @type {?} */ nodeDef = viewDef$$1.nodes[i];
          if (nodeDef.flags & 3 /* CatRenderNode */) {
              renderNodeIndex++;
          }
      }
      return renderNodeIndex;
  }
  /**
   * @param {?} view
   * @return {?}
   */
  function findHostElement(view) {
      while (view && !isComponentView(view)) {
          view = /** @type {?} */ ((view.parent));
      }
      if (view.parent) {
          return asElementData(view.parent, /** @type {?} */ ((viewParentEl(view))).nodeIndex);
      }
      return null;
  }
  /**
   * @param {?} view
   * @param {?} nodeDef
   * @param {?} references
   * @return {?}
   */
  function collectReferences(view, nodeDef, references) {
      for (var /** @type {?} */ refName in nodeDef.references) {
          references[refName] = getQueryValue(view, nodeDef, nodeDef.references[refName]);
      }
  }
  /**
   * @param {?} action
   * @param {?} fn
   * @param {?} self
   * @param {?} args
   * @return {?}
   */
  function callWithDebugContext(action, fn, self, args) {
      var /** @type {?} */ oldAction = _currentAction;
      var /** @type {?} */ oldView = _currentView;
      var /** @type {?} */ oldNodeIndex = _currentNodeIndex;
      try {
          _currentAction = action;
          var /** @type {?} */ result = fn.apply(self, args);
          _currentView = oldView;
          _currentNodeIndex = oldNodeIndex;
          _currentAction = oldAction;
          return result;
      }
      catch (/** @type {?} */ e) {
          if (isViewDebugError(e) || !_currentView) {
              throw e;
          }
          throw viewWrappedDebugError(e, /** @type {?} */ ((getCurrentDebugContext())));
      }
  }
  /**
   * @return {?}
   */
  function getCurrentDebugContext() {
      return _currentView ? new DebugContext_(_currentView, _currentNodeIndex) : null;
  }
  var DebugRendererFactory2 = /** @class */ (function () {
      function DebugRendererFactory2(delegate) {
          this.delegate = delegate;
      }
      /**
       * @param {?} element
       * @param {?} renderData
       * @return {?}
       */
      DebugRendererFactory2.prototype.createRenderer = /**
       * @param {?} element
       * @param {?} renderData
       * @return {?}
       */
      function (element, renderData) {
          return new DebugRenderer2(this.delegate.createRenderer(element, renderData));
      };
      /**
       * @return {?}
       */
      DebugRendererFactory2.prototype.begin = /**
       * @return {?}
       */
      function () {
          if (this.delegate.begin) {
              this.delegate.begin();
          }
      };
      /**
       * @return {?}
       */
      DebugRendererFactory2.prototype.end = /**
       * @return {?}
       */
      function () {
          if (this.delegate.end) {
              this.delegate.end();
          }
      };
      /**
       * @return {?}
       */
      DebugRendererFactory2.prototype.whenRenderingDone = /**
       * @return {?}
       */
      function () {
          if (this.delegate.whenRenderingDone) {
              return this.delegate.whenRenderingDone();
          }
          return Promise.resolve(null);
      };
      return DebugRendererFactory2;
  }());
  var DebugRenderer2 = /** @class */ (function () {
      function DebugRenderer2(delegate) {
          this.delegate = delegate;
          this.data = this.delegate.data;
      }
      /**
       * @param {?} node
       * @return {?}
       */
      DebugRenderer2.prototype.destroyNode = /**
       * @param {?} node
       * @return {?}
       */
      function (node) {
          removeDebugNodeFromIndex(/** @type {?} */ ((getDebugNode(node))));
          if (this.delegate.destroyNode) {
              this.delegate.destroyNode(node);
          }
      };
      /**
       * @return {?}
       */
      DebugRenderer2.prototype.destroy = /**
       * @return {?}
       */
      function () { this.delegate.destroy(); };
      /**
       * @param {?} name
       * @param {?=} namespace
       * @return {?}
       */
      DebugRenderer2.prototype.createElement = /**
       * @param {?} name
       * @param {?=} namespace
       * @return {?}
       */
      function (name, namespace) {
          var /** @type {?} */ el = this.delegate.createElement(name, namespace);
          var /** @type {?} */ debugCtx = getCurrentDebugContext();
          if (debugCtx) {
              var /** @type {?} */ debugEl = new DebugElement(el, null, debugCtx);
              debugEl.name = name;
              indexDebugNode(debugEl);
          }
          return el;
      };
      /**
       * @param {?} value
       * @return {?}
       */
      DebugRenderer2.prototype.createComment = /**
       * @param {?} value
       * @return {?}
       */
      function (value) {
          var /** @type {?} */ comment = this.delegate.createComment(value);
          var /** @type {?} */ debugCtx = getCurrentDebugContext();
          if (debugCtx) {
              indexDebugNode(new DebugNode(comment, null, debugCtx));
          }
          return comment;
      };
      /**
       * @param {?} value
       * @return {?}
       */
      DebugRenderer2.prototype.createText = /**
       * @param {?} value
       * @return {?}
       */
      function (value) {
          var /** @type {?} */ text = this.delegate.createText(value);
          var /** @type {?} */ debugCtx = getCurrentDebugContext();
          if (debugCtx) {
              indexDebugNode(new DebugNode(text, null, debugCtx));
          }
          return text;
      };
      /**
       * @param {?} parent
       * @param {?} newChild
       * @return {?}
       */
      DebugRenderer2.prototype.appendChild = /**
       * @param {?} parent
       * @param {?} newChild
       * @return {?}
       */
      function (parent, newChild) {
          var /** @type {?} */ debugEl = getDebugNode(parent);
          var /** @type {?} */ debugChildEl = getDebugNode(newChild);
          if (debugEl && debugChildEl && debugEl instanceof DebugElement) {
              debugEl.addChild(debugChildEl);
          }
          this.delegate.appendChild(parent, newChild);
      };
      /**
       * @param {?} parent
       * @param {?} newChild
       * @param {?} refChild
       * @return {?}
       */
      DebugRenderer2.prototype.insertBefore = /**
       * @param {?} parent
       * @param {?} newChild
       * @param {?} refChild
       * @return {?}
       */
      function (parent, newChild, refChild) {
          var /** @type {?} */ debugEl = getDebugNode(parent);
          var /** @type {?} */ debugChildEl = getDebugNode(newChild);
          var /** @type {?} */ debugRefEl = /** @type {?} */ ((getDebugNode(refChild)));
          if (debugEl && debugChildEl && debugEl instanceof DebugElement) {
              debugEl.insertBefore(debugRefEl, debugChildEl);
          }
          this.delegate.insertBefore(parent, newChild, refChild);
      };
      /**
       * @param {?} parent
       * @param {?} oldChild
       * @return {?}
       */
      DebugRenderer2.prototype.removeChild = /**
       * @param {?} parent
       * @param {?} oldChild
       * @return {?}
       */
      function (parent, oldChild) {
          var /** @type {?} */ debugEl = getDebugNode(parent);
          var /** @type {?} */ debugChildEl = getDebugNode(oldChild);
          if (debugEl && debugChildEl && debugEl instanceof DebugElement) {
              debugEl.removeChild(debugChildEl);
          }
          this.delegate.removeChild(parent, oldChild);
      };
      /**
       * @param {?} selectorOrNode
       * @return {?}
       */
      DebugRenderer2.prototype.selectRootElement = /**
       * @param {?} selectorOrNode
       * @return {?}
       */
      function (selectorOrNode) {
          var /** @type {?} */ el = this.delegate.selectRootElement(selectorOrNode);
          var /** @type {?} */ debugCtx = getCurrentDebugContext();
          if (debugCtx) {
              indexDebugNode(new DebugElement(el, null, debugCtx));
          }
          return el;
      };
      /**
       * @param {?} el
       * @param {?} name
       * @param {?} value
       * @param {?=} namespace
       * @return {?}
       */
      DebugRenderer2.prototype.setAttribute = /**
       * @param {?} el
       * @param {?} name
       * @param {?} value
       * @param {?=} namespace
       * @return {?}
       */
      function (el, name, value, namespace) {
          var /** @type {?} */ debugEl = getDebugNode(el);
          if (debugEl && debugEl instanceof DebugElement) {
              var /** @type {?} */ fullName = namespace ? namespace + ':' + name : name;
              debugEl.attributes[fullName] = value;
          }
          this.delegate.setAttribute(el, name, value, namespace);
      };
      /**
       * @param {?} el
       * @param {?} name
       * @param {?=} namespace
       * @return {?}
       */
      DebugRenderer2.prototype.removeAttribute = /**
       * @param {?} el
       * @param {?} name
       * @param {?=} namespace
       * @return {?}
       */
      function (el, name, namespace) {
          var /** @type {?} */ debugEl = getDebugNode(el);
          if (debugEl && debugEl instanceof DebugElement) {
              var /** @type {?} */ fullName = namespace ? namespace + ':' + name : name;
              debugEl.attributes[fullName] = null;
          }
          this.delegate.removeAttribute(el, name, namespace);
      };
      /**
       * @param {?} el
       * @param {?} name
       * @return {?}
       */
      DebugRenderer2.prototype.addClass = /**
       * @param {?} el
       * @param {?} name
       * @return {?}
       */
      function (el, name) {
          var /** @type {?} */ debugEl = getDebugNode(el);
          if (debugEl && debugEl instanceof DebugElement) {
              debugEl.classes[name] = true;
          }
          this.delegate.addClass(el, name);
      };
      /**
       * @param {?} el
       * @param {?} name
       * @return {?}
       */
      DebugRenderer2.prototype.removeClass = /**
       * @param {?} el
       * @param {?} name
       * @return {?}
       */
      function (el, name) {
          var /** @type {?} */ debugEl = getDebugNode(el);
          if (debugEl && debugEl instanceof DebugElement) {
              debugEl.classes[name] = false;
          }
          this.delegate.removeClass(el, name);
      };
      /**
       * @param {?} el
       * @param {?} style
       * @param {?} value
       * @param {?} flags
       * @return {?}
       */
      DebugRenderer2.prototype.setStyle = /**
       * @param {?} el
       * @param {?} style
       * @param {?} value
       * @param {?} flags
       * @return {?}
       */
      function (el, style, value, flags) {
          var /** @type {?} */ debugEl = getDebugNode(el);
          if (debugEl && debugEl instanceof DebugElement) {
              debugEl.styles[style] = value;
          }
          this.delegate.setStyle(el, style, value, flags);
      };
      /**
       * @param {?} el
       * @param {?} style
       * @param {?} flags
       * @return {?}
       */
      DebugRenderer2.prototype.removeStyle = /**
       * @param {?} el
       * @param {?} style
       * @param {?} flags
       * @return {?}
       */
      function (el, style, flags) {
          var /** @type {?} */ debugEl = getDebugNode(el);
          if (debugEl && debugEl instanceof DebugElement) {
              debugEl.styles[style] = null;
          }
          this.delegate.removeStyle(el, style, flags);
      };
      /**
       * @param {?} el
       * @param {?} name
       * @param {?} value
       * @return {?}
       */
      DebugRenderer2.prototype.setProperty = /**
       * @param {?} el
       * @param {?} name
       * @param {?} value
       * @return {?}
       */
      function (el, name, value) {
          var /** @type {?} */ debugEl = getDebugNode(el);
          if (debugEl && debugEl instanceof DebugElement) {
              debugEl.properties[name] = value;
          }
          this.delegate.setProperty(el, name, value);
      };
      /**
       * @param {?} target
       * @param {?} eventName
       * @param {?} callback
       * @return {?}
       */
      DebugRenderer2.prototype.listen = /**
       * @param {?} target
       * @param {?} eventName
       * @param {?} callback
       * @return {?}
       */
      function (target, eventName, callback) {
          if (typeof target !== 'string') {
              var /** @type {?} */ debugEl = getDebugNode(target);
              if (debugEl) {
                  debugEl.listeners.push(new EventListener(eventName, callback));
              }
          }
          return this.delegate.listen(target, eventName, callback);
      };
      /**
       * @param {?} node
       * @return {?}
       */
      DebugRenderer2.prototype.parentNode = /**
       * @param {?} node
       * @return {?}
       */
      function (node) { return this.delegate.parentNode(node); };
      /**
       * @param {?} node
       * @return {?}
       */
      DebugRenderer2.prototype.nextSibling = /**
       * @param {?} node
       * @return {?}
       */
      function (node) { return this.delegate.nextSibling(node); };
      /**
       * @param {?} node
       * @param {?} value
       * @return {?}
       */
      DebugRenderer2.prototype.setValue = /**
       * @param {?} node
       * @param {?} value
       * @return {?}
       */
      function (node, value) { return this.delegate.setValue(node, value); };
      return DebugRenderer2;
  }());
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  /**
   * @param {?} override
   * @return {?}
   */
  function overrideProvider(override) {
      initServicesIfNeeded();
      return Services.overrideProvider(override);
  }
  /**
   * @param {?} comp
   * @param {?} componentFactory
   * @return {?}
   */
  function overrideComponentView(comp, componentFactory) {
      initServicesIfNeeded();
      return Services.overrideComponentView(comp, componentFactory);
  }
  /**
   * @return {?}
   */
  function clearOverrides() {
      initServicesIfNeeded();
      return Services.clearOverrides();
  }
  /**
   * @param {?} ngModuleType
   * @param {?} bootstrapComponents
   * @param {?} defFactory
   * @return {?}
   */
  function createNgModuleFactory(ngModuleType, bootstrapComponents, defFactory) {
      return new NgModuleFactory_(ngModuleType, bootstrapComponents, defFactory);
  }
  var NgModuleFactory_ = /** @class */ (function (_super) {
      __extends(NgModuleFactory_, _super);
      function NgModuleFactory_(moduleType, _bootstrapComponents, _ngModuleDefFactory) {
          var _this = 
          // Attention: this ctor is called as top level function.
          // Putting any logic in here will destroy closure tree shaking!
          _super.call(this) || this;
          _this.moduleType = moduleType;
          _this._bootstrapComponents = _bootstrapComponents;
          _this._ngModuleDefFactory = _ngModuleDefFactory;
          return _this;
      }
      /**
       * @param {?} parentInjector
       * @return {?}
       */
      NgModuleFactory_.prototype.create = /**
       * @param {?} parentInjector
       * @return {?}
       */
      function (parentInjector) {
          initServicesIfNeeded();
          var /** @type {?} */ def = resolveDefinition(this._ngModuleDefFactory);
          return Services.createNgModuleRef(this.moduleType, parentInjector || Injector.NULL, this._bootstrapComponents, def);
      };
      return NgModuleFactory_;
  }(NgModuleFactory));
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  // The functions in this file verify that the assumptions we are making
  // about state in an instruction are correct before implementing any logic.
  // They are meant only to be called in dev mode as sanity checks.
  /**
   * Stringifies values such that strings are wrapped in explicit quotation marks and
   * other types are stringified normally. Used in error messages (e.g. assertThrow)
   * to make it clear that certain values are of the string type when comparing.
   *
   * e.g. `expected "3" to be 3` is easier to understand than `expected 3 to be 3`.
   *
   * @param {?} value The value to be stringified
   * @return {?} The stringified value
   */
  function stringifyValueForError(value) {
      return typeof value === 'string' ? "\"" + value + "\"" : '' + value;
  }
  /**
   * @param {?} actual
   * @param {?} name
   * @return {?}
   */
  
  /**
   * @template T
   * @param {?} actual
   * @param {?} expected
   * @param {?} name
   * @param {?=} serializer
   * @return {?}
   */
  function assertEqual(actual, expected, name, serializer) {
      (actual != expected) && assertThrow(actual, expected, name, '==', serializer);
  }
  /**
   * @template T
   * @param {?} actual
   * @param {?} expected
   * @param {?} name
   * @return {?}
   */
  function assertLessThan(actual, expected, name) {
      (actual < expected) && assertThrow(actual, expected, name, '>');
  }
  /**
   * @template T
   * @param {?} actual
   * @param {?} name
   * @return {?}
   */
  function assertNotNull(actual, name) {
      assertNotEqual(actual, null, name);
  }
  /**
   * @template T
   * @param {?} actual
   * @param {?} expected
   * @param {?} name
   * @return {?}
   */
  function assertNotEqual(actual, expected, name) {
      (actual == expected) && assertThrow(actual, expected, name, '!=');
  }
  /**
   * Throws an error with a message constructed from the arguments.
   *
   * @template T
   * @param {?} actual The actual value (e.g. 3)
   * @param {?} expected The expected value (e.g. 5)
   * @param {?} name The name of the value being checked (e.g. attrs.length)
   * @param {?} operator The comparison operator (e.g. <, >, ==)
   * @param {?=} serializer Function that maps a value to its display value
   * @return {?}
   */
  function assertThrow(actual, expected, name, operator, serializer) {
      if (serializer === void 0) { serializer = stringifyValueForError; }
      throw new Error("ASSERT: expected " + name + " " + operator + " " + serializer(expected) + " but was " + serializer(actual) + "!");
  }
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  if (typeof ngDevMode == 'undefined') {
      if (typeof window != 'undefined')
          (/** @type {?} */ (window)).ngDevMode = true;
      if (typeof self != 'undefined')
          (/** @type {?} */ (self)).ngDevMode = true;
      if (typeof global != 'undefined')
          (/** @type {?} */ (global)).ngDevMode = true;
  }
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  /**
   * @param {?} node
   * @param {?} type
   * @return {?}
   */
  function assertNodeType(node, type) {
      assertNotEqual(node, null, 'node');
      assertEqual(node.flags & 3 /* TYPE_MASK */, type, 'Node.type', typeSerializer);
  }
  /**
   * @param {?} node
   * @param {...?} types
   * @return {?}
   */
  
  /**
   * @param {?} type
   * @return {?}
   */
  function typeSerializer(type) {
      if (type == 1 /* Projection */)
          return 'Projection';
      if (type == 0 /* Container */)
          return 'Container';
      if (type == 2 /* View */)
          return 'View';
      if (type == 3 /* Element */)
          return 'Element';
      return '??? ' + type + ' ???';
  }
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  /**
   * Finds the closest DOM node above a given container in the hierarchy.
   *
   * This is necessary to add or remove elements from the DOM when a view
   * is added or removed from the container. e.g. parent.removeChild(...)
   *
   * @param {?} containerNode The container node whose parent must be found
   * @return {?} Closest DOM node above the container
   */
  function findNativeParent(containerNode) {
      var /** @type {?} */ container = containerNode;
      while (container) {
          ngDevMode && assertNodeType(container, 0 /* Container */);
          var /** @type {?} */ renderParent = container.data.renderParent;
          if (renderParent !== null) {
              return renderParent.native;
          }
          var /** @type {?} */ viewOrElement = /** @type {?} */ ((container.parent));
          ngDevMode && assertNotNull(viewOrElement, 'container.parent');
          if ((viewOrElement.flags & 3 /* TYPE_MASK */) === 3 /* Element */) {
              // we are an LElement, which means we are past the last LContainer.
              // This means than we have not been projected so just ignore.
              return null;
          }
          ngDevMode && assertNodeType(viewOrElement, 2 /* View */);
          container = (/** @type {?} */ (viewOrElement)).parent;
      }
      return null;
  }
  /**
   * Finds the DOM element before which a certain view should be inserting its
   * child elements.
   *
   * If the view has a next (e.g. for loop), elements should be inserted before
   * the next view's first child element. Otherwise, the container's comment
   * anchor is the marker.
   *
   * @param {?} index The index of the view to check
   * @param {?} state ContainerState of the parent container
   * @param {?} native Comment anchor for container
   * @return {?} The DOM element for which the view should insert elements
   */
  function findBeforeNode(index, state, native) {
      var /** @type {?} */ views = state.views;
      // Find the node to insert in front of
      return index + 1 < views.length ?
          (/** @type {?} */ (views[index + 1].child)).native :
          native;
  }
  /**
   * @param {?} container
   * @param {?} rootNode
   * @param {?} insertMode
   * @param {?=} beforeNode
   * @return {?}
   */
  function addRemoveViewFromContainer(container, rootNode, insertMode, beforeNode) {
      ngDevMode && assertNodeType(container, 0 /* Container */);
      ngDevMode && assertNodeType(rootNode, 2 /* View */);
      var /** @type {?} */ parent = findNativeParent(container);
      var /** @type {?} */ node = rootNode.child;
      if (parent) {
          while (node) {
              var /** @type {?} */ type = node.flags & 3;
              var /** @type {?} */ nextNode = null;
              var /** @type {?} */ renderer = container.view.renderer;
              var /** @type {?} */ isFnRenderer = (/** @type {?} */ (renderer)).listen;
              if (type === 3 /* Element */) {
                  insertMode ? (isFnRenderer ? /** @type {?} */ (((/** @type {?} */ (renderer))
                      .insertBefore))(parent, /** @type {?} */ ((node.native)), /** @type {?} */ (beforeNode)) :
                      parent.insertBefore(/** @type {?} */ ((node.native)), /** @type {?} */ (beforeNode), true)) :
                      (isFnRenderer ? /** @type {?} */ (((/** @type {?} */ (renderer))
                          .removeChild))(/** @type {?} */ (parent), /** @type {?} */ ((node.native))) :
                          parent.removeChild(/** @type {?} */ ((node.native))));
                  nextNode = node.next;
              }
              else if (type === 0 /* Container */) {
                  // if we get to a container, it must be a root node of a view because we are only
                  // propagating down into child views / containers and not child elements
                  var /** @type {?} */ childContainerData = (/** @type {?} */ (node)).data;
                  insertMode ? (isFnRenderer ? /** @type {?} */ (((/** @type {?} */ (renderer))
                      .appendChild))(/** @type {?} */ (parent), /** @type {?} */ ((node.native))) :
                      parent.appendChild(/** @type {?} */ ((node.native)))) :
                      (isFnRenderer ? /** @type {?} */ (((/** @type {?} */ (renderer))
                          .removeChild))(/** @type {?} */ (parent), /** @type {?} */ ((node.native))) :
                          parent.removeChild(/** @type {?} */ ((node.native))));
                  nextNode = childContainerData.views.length ? childContainerData.views[0].child : null;
              }
              else if (type === 1 /* Projection */) {
                  nextNode = (/** @type {?} */ (node)).data[0];
              }
              else {
                  nextNode = (/** @type {?} */ (node)).child;
              }
              if (nextNode === null) {
                  while (node && !node.next) {
                      node = node.parent;
                      if (node === rootNode)
                          node = null;
                  }
                  node = node && node.next;
              }
              else {
                  node = nextNode;
              }
          }
      }
  }
  /**
   * Traverses the tree of component views and containers to remove listeners and
   * call onDestroy callbacks.
   *
   * Notes:
   *  - Because it's used for onDestroy calls, it needs to be bottom-up.
   *  - Must process containers instead of their views to avoid splicing
   *  when views are destroyed and re-added.
   *  - Using a while loop because it's faster than recursion
   *  - Destroy only called on movement to sibling or movement to parent (laterally or up)
   *
   *  \@param rootView The view to destroy
   * @param {?} rootView
   * @return {?}
   */
  function destroyViewTree(rootView) {
      var /** @type {?} */ viewOrContainerState = rootView;
      while (viewOrContainerState) {
          var /** @type {?} */ next = null;
          if (viewOrContainerState.views && viewOrContainerState.views.length) {
              next = viewOrContainerState.views[0].data;
          }
          else if (viewOrContainerState.child) {
              next = viewOrContainerState.child;
          }
          else if (viewOrContainerState.next) {
              cleanUpView(/** @type {?} */ (viewOrContainerState));
              next = viewOrContainerState.next;
          }
          if (next == null) {
              while (viewOrContainerState && !/** @type {?} */ ((viewOrContainerState)).next) {
                  cleanUpView(/** @type {?} */ (viewOrContainerState));
                  viewOrContainerState = getParentState(viewOrContainerState, rootView);
              }
              cleanUpView(/** @type {?} */ (viewOrContainerState) || rootView);
              next = viewOrContainerState && viewOrContainerState.next;
          }
          viewOrContainerState = next;
      }
  }
  /**
   * Inserts a view into a container.
   *
   * This adds the view to the container's array of active views in the correct
   * position. It also adds the view's elements to the DOM if the container isn't a
   * root node of another view (in that case, the view's elements will be added when
   * the container's parent view is added later).
   *
   * @param {?} container The container into which the view should be inserted
   * @param {?} newView The view to insert
   * @param {?} index The index at which to insert the view
   * @return {?} The inserted view
   */
  function insertView(container, newView, index) {
      var /** @type {?} */ state = container.data;
      var /** @type {?} */ views = state.views;
      if (index > 0) {
          // This is a new view, we need to add it to the children.
          setViewNext(views[index - 1], newView);
      }
      if (index < views.length && views[index].data.id !== newView.data.id) {
          // View ID change replace the view.
          setViewNext(newView, views[index]);
          views.splice(index, 0, newView);
      }
      else if (index >= views.length) {
          views.push(newView);
      }
      if (state.nextIndex <= index) {
          state.nextIndex++;
      }
      // If the container's renderParent is null, we know that it is a root node of its own parent view
      // and we should wait until that parent processes its nodes (otherwise, we will insert this view's
      // nodes twice - once now and once when its parent inserts its views).
      if (container.data.renderParent !== null) {
          addRemoveViewFromContainer(container, newView, true, findBeforeNode(index, state, container.native));
      }
      // Notify query that view has been inserted
      container.query && container.query.insertView(container, newView, index);
      return newView;
  }
  /**
   * Removes a view from a container.
   *
   * This method splices the view from the container's array of active views. It also
   * removes the view's elements from the DOM and conducts cleanup (e.g. removing
   * listeners, calling onDestroys).
   *
   * @param {?} container The container from which to remove a view
   * @param {?} removeIndex The index of the view to remove
   * @return {?} The removed view
   */
  function removeView(container, removeIndex) {
      var /** @type {?} */ views = container.data.views;
      var /** @type {?} */ viewNode = views[removeIndex];
      if (removeIndex > 0) {
          setViewNext(views[removeIndex - 1], viewNode.next);
      }
      views.splice(removeIndex, 1);
      destroyViewTree(viewNode.data);
      addRemoveViewFromContainer(container, viewNode, false);
      // Notify query that view has been removed
      container.query && container.query.removeView(container, viewNode, removeIndex);
      return viewNode;
  }
  /**
   * Sets a next on the view node, so views in for loops can easily jump from
   * one view to the next to add/remove elements. Also adds the ViewState (view.data)
   * to the view tree for easy traversal when cleaning up the view.
   *
   * @param {?} view The view to set up
   * @param {?} next The view's new next
   * @return {?}
   */
  function setViewNext(view, next) {
      view.next = next;
      view.data.next = next ? next.data : null;
  }
  /**
   * Determines which ViewOrContainerState to jump to when traversing back up the
   * tree in destroyViewTree.
   *
   * Normally, the view's parent ViewState should be checked, but in the case of
   * embedded views, the container (which is the view node's parent, but not the
   * ViewState's parent) needs to be checked for a possible next property.
   *
   * @param {?} state The ViewOrContainerState for which we need a parent state
   * @param {?} rootView The rootView, so we don't propagate too far up the view tree
   * @return {?} The correct parent ViewOrContainerState
   */
  function getParentState(state, rootView) {
      var /** @type {?} */ node;
      if ((node = /** @type {?} */ (((/** @type {?} */ (state)))).node) &&
          (node.flags & 3 /* TYPE_MASK */) === 2 /* View */) {
          // if it's an embedded view, the state needs to go up to the container, in case the
          // container has a next
          return /** @type {?} */ (((node.parent)).data);
      }
      else {
          // otherwise, use parent view for containers or component views
          return state.parent === rootView ? null : state.parent;
      }
  }
  /**
   * Removes all listeners and call all onDestroys in a given view.
   *
   * @param {?} viewState The ViewState of the view to clean up
   * @return {?}
   */
  function cleanUpView(viewState) {
      if (!viewState.cleanup)
          return;
      var /** @type {?} */ cleanup = /** @type {?} */ ((viewState.cleanup));
      for (var /** @type {?} */ i = 0; i < cleanup.length - 1; i += 2) {
          if (typeof cleanup[i] === 'string') {
              /** @type {?} */ ((cleanup))[i + 1].removeEventListener(cleanup[i], cleanup[i + 2], cleanup[i + 3]);
              i += 2;
          }
          else {
              cleanup[i].call(cleanup[i + 1]);
          }
      }
      viewState.cleanup = null;
  }
  /**
   * Appends the provided child element to the provided parent, if appropriate.
   *
   * If the parent is a view, the element will be appended as part of viewEnd(), so
   * the element should not be appended now. Similarly, if the child is a content child
   * of a parent component, the child will be appended to the right position later by
   * the content projection system. Otherwise, append normally.
   *
   * @param {?} parent The parent to which to append the child
   * @param {?} child The child that should be appended
   * @param {?} currentView The current view's ViewState
   * @return {?} Whether or not the child was appended
   */
  function appendChild(parent, child, currentView) {
      // Only add native child element to parent element if the parent element is regular Element.
      // If parent is:
      // - Regular element => add child
      // - Component host element =>
      //    - Current View, and parent view same => content => don't add -> parent component will
      //    re-project if needed.
      //    - Current View, and parent view different => view => add Child
      // - View element => View's get added separately.
      if (child !== null && (parent.flags & 3 /* TYPE_MASK */) === 3 /* Element */ &&
          (parent.view !==
              currentView /* Crossing View Boundaries, it is Component, but add Element of View */
              || parent.data === null /* Regular Element. */)) {
          // We only add element if not in View or not projected.
          var /** @type {?} */ renderer = currentView.renderer;
          (/** @type {?} */ (renderer)).listen ? /** @type {?} */ (((/** @type {?} */ (renderer)).appendChild))(/** @type {?} */ (((parent.native))), child) : /** @type {?} */ ((parent.native)).appendChild(child);
          return true;
      }
      return false;
  }
  /**
   * Inserts the provided node before the correct element in the DOM, if appropriate.
   *
   * If the parent is a view, the element will be inserted as part of viewEnd(), so
   * the element should not be inserted now. Similarly, if the child is a content child
   * of a parent component, the child will be inserted to the right position later by
   * the content projection system. Otherwise, insertBefore normally.
   *
   * @param {?} node Node to insert
   * @param {?} currentView The current view's ViewState
   * @return {?}
   */
  function insertChild(node, currentView) {
      var /** @type {?} */ parent = /** @type {?} */ ((node.parent));
      // Only add child element to parent element if the parent element is regular Element.
      // If parent is:
      // - Normal element => add child
      // - Component element =>
      //    - Current View, and parent view same => content don't add -> parent component will
      //    re-project if needed.
      //    - Current View, and parent view different => view => add Child
      // - View element => View's get added separately.
      if ((parent.flags & 3 /* TYPE_MASK */) === 3 /* Element */ &&
          (parent.view !==
              currentView /* Crossing View Boundaries, its Component, but add Element of View */
              || parent.data === null /* Regular Element. */)) {
          // We only add element if not in View or not projected.
          var /** @type {?} */ sibling = node.next;
          var /** @type {?} */ nativeSibling = null;
          while (sibling && (nativeSibling = sibling.native) === null) {
              sibling = sibling.next;
          }
          var /** @type {?} */ renderer = currentView.renderer;
          (/** @type {?} */ (renderer)).listen ? /** @type {?} */ (((/** @type {?} */ (renderer))
              .insertBefore))(/** @type {?} */ ((parent.native)), /** @type {?} */ ((node.native)), nativeSibling) : /** @type {?} */ ((parent.native)).insertBefore(/** @type {?} */ ((node.native)), nativeSibling, false);
      }
  }
  /**
   * Appends a projected node to the DOM, or in the case of a projected container,
   * appends the nodes from all of the container's active views to the DOM. Also stores the
   * node in the given projectedNodes array.
   *
   * @param {?} projectedNodes Array to store the projected node
   * @param {?} node The node to process
   * @param {?} currentParent The last parent element to be processed
   * @param {?} currentView The current view's ViewState
   * @return {?}
   */
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  /**
   * A utility function to match an Ivy node static data against a simple CSS selector
   *
   * @param {?} lNodeStaticData
   * @param {?} selector
   * @return {?} true if node matches the selector.
   */
  
  /**
   * @param {?} lNodeStaticData
   * @param {?} selector
   * @return {?}
   */
  
  /**
   * @param {?} lNodeStaticData
   * @param {?} selector
   * @return {?}
   */
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  /**
   * Must use this method for CD (instead of === ) since NaN !== NaN
   * @param {?} a
   * @param {?} b
   * @return {?}
   */
  function isDifferent(a, b) {
      // NaN is the only value that is not equal to itself so the first
      // test checks if both a and b are not NaN
      return !(a !== a && b !== b) && a !== b;
  }
  /**
   * @param {?} value
   * @return {?}
   */
  function stringify$1(value) {
      if (typeof value == 'function')
          return value.name || value;
      if (typeof value == 'string')
          return value;
      if (value == null)
          return '';
      return '' + value;
  }
  /**
   * Creates an ElementRef for a given node injector and stores it on the injector.
   * Or, if the ElementRef already exists, retrieves the existing ElementRef.
   *
   * @param {?} di The node injector where we should store a created ElementRef
   * @return {?} The ElementRef instance to use
   */
  
  /**
   * Creates a TemplateRef and stores it on the injector. Or, if the TemplateRef already
   * exists, retrieves the existing TemplateRef.
   *
   * @template T
   * @param {?} di The node injector where we should store a created TemplateRef
   * @return {?} The TemplateRef instance to use
   */
  
  /**
   * Creates a ViewContainerRef and stores it on the injector. Or, if the ViewContainerRef
   * already exists, retrieves the existing ViewContainerRef.
   *
   * @param {?} di
   * @return {?} The ViewContainerRef instance to use
   */
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  /**
   * A predicate which determines if a given element/directive should be included in the query
   * @record
   */
  
  var QueryList_ = /** @class */ (function () {
      function QueryList_() {
          this.dirty = false;
          /**
           * \@internal
           */
          this._valuesTree = null;
          /**
           * \@internal
           */
          this._values = null;
      }
      Object.defineProperty(QueryList_.prototype, "length", {
          get: /**
           * @return {?}
           */
          function () {
              ngDevMode && assertNotNull(this._values, 'refreshed');
              return /** @type {?} */ ((this._values)).length;
          },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(QueryList_.prototype, "first", {
          get: /**
           * @return {?}
           */
          function () {
              ngDevMode && assertNotNull(this._values, 'refreshed');
              var /** @type {?} */ values = /** @type {?} */ ((this._values));
              return values.length ? values[0] : null;
          },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(QueryList_.prototype, "last", {
          get: /**
           * @return {?}
           */
          function () {
              ngDevMode && assertNotNull(this._values, 'refreshed');
              var /** @type {?} */ values = /** @type {?} */ ((this._values));
              return values.length ? values[values.length - 1] : null;
          },
          enumerable: true,
          configurable: true
      });
      /** @internal */
      /**
       * \@internal
       * @return {?}
       */
      QueryList_.prototype._refresh = /**
       * \@internal
       * @return {?}
       */
      function () {
          // TODO(misko): needs more logic to flatten tree.
          if (this._values === null) {
              this._values = this._valuesTree;
              return true;
          }
          return false;
      };
      /**
       * @template U
       * @param {?} fn
       * @return {?}
       */
      QueryList_.prototype.map = /**
       * @template U
       * @param {?} fn
       * @return {?}
       */
      function (fn) {
          throw new Error('Method not implemented.');
      };
      /**
       * @param {?} fn
       * @return {?}
       */
      QueryList_.prototype.filter = /**
       * @param {?} fn
       * @return {?}
       */
      function (fn) {
          throw new Error('Method not implemented.');
      };
      /**
       * @param {?} fn
       * @return {?}
       */
      QueryList_.prototype.find = /**
       * @param {?} fn
       * @return {?}
       */
      function (fn) {
          throw new Error('Method not implemented.');
      };
      /**
       * @template U
       * @param {?} fn
       * @param {?} init
       * @return {?}
       */
      QueryList_.prototype.reduce = /**
       * @template U
       * @param {?} fn
       * @param {?} init
       * @return {?}
       */
      function (fn, init) {
          throw new Error('Method not implemented.');
      };
      /**
       * @param {?} fn
       * @return {?}
       */
      QueryList_.prototype.forEach = /**
       * @param {?} fn
       * @return {?}
       */
      function (fn) {
          throw new Error('Method not implemented.');
      };
      /**
       * @param {?} fn
       * @return {?}
       */
      QueryList_.prototype.some = /**
       * @param {?} fn
       * @return {?}
       */
      function (fn) {
          throw new Error('Method not implemented.');
      };
      /**
       * @return {?}
       */
      QueryList_.prototype.toArray = /**
       * @return {?}
       */
      function () {
          ngDevMode && assertNotNull(this._values, 'refreshed');
          return /** @type {?} */ ((this._values));
      };
      /**
       * @return {?}
       */
      QueryList_.prototype.toString = /**
       * @return {?}
       */
      function () { throw new Error('Method not implemented.'); };
      /**
       * @param {?} res
       * @return {?}
       */
      QueryList_.prototype.reset = /**
       * @param {?} res
       * @return {?}
       */
      function (res) { throw new Error('Method not implemented.'); };
      /**
       * @return {?}
       */
      QueryList_.prototype.notifyOnChanges = /**
       * @return {?}
       */
      function () { throw new Error('Method not implemented.'); };
      /**
       * @return {?}
       */
      QueryList_.prototype.setDirty = /**
       * @return {?}
       */
      function () { throw new Error('Method not implemented.'); };
      /**
       * @return {?}
       */
      QueryList_.prototype.destroy = /**
       * @return {?}
       */
      function () { throw new Error('Method not implemented.'); };
      return QueryList_;
  }());
  
  /**
   * @param {?} query
   * @return {?}
   */
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  /** @enum {number} */
  var RendererStyleFlags3 = {
      Important: 1,
      DashCase: 2,
  };
  RendererStyleFlags3[RendererStyleFlags3.Important] = "Important";
  RendererStyleFlags3[RendererStyleFlags3.DashCase] = "DashCase";
  /**
   * Object Oriented style of API needed to create elements and text nodes.
   *
   * This is the native browser API style, e.g. operations are methods on individual objects
   * like HTMLElement. With this style, no additional code is needed as a facade
   * (reducing payload size).
   *
   * @record
   */
  
  /**
   * Procedural style of API needed to create elements and text nodes.
   *
   * In non-native browser environments (e.g. platforms such as web-workers), this is the
   * facade that enables element manipulation. This also facilitates backwards compatibility
   * with Renderer2.
   * @record
   */
  
  /**
   * @record
   */
  
  var domRendererFactory3 = {
      createRenderer: function (hostElement, rendererType) { return document; }
  };
  /**
   * Subset of API needed for appending elements and text nodes.
   * @record
   */
  
  /**
   * Subset of API needed for writing attributes, properties, and setting up
   * listeners on Element.
   * @record
   */
  
  /**
   * @record
   */
  
  /**
   * @record
   */
  
  /**
   * @record
   */
  
  /**
   * @record
   */
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  /**
   * Directive (D) sets a property on all component instances using this constant as a key and the
   * component's host node (LElement) as the value. This is used in methods like detectChanges to
   * facilitate jumping from an instance to the host node.
   */
  var NG_HOST_SYMBOL = '__ngHostLNode__';
  /**
   * This property gets set before entering a template.
   *
   * This renderer can be one of two varieties of Renderer3:
   *
   * - ObjectedOrientedRenderer3
   *
   * This is the native browser API style, e.g. operations are methods on individual objects
   * like HTMLElement. With this style, no additional code is needed as a facade (reducing payload
   * size).
   *
   * - ProceduralRenderer3
   *
   * In non-native browser environments (e.g. platforms such as web-workers), this is the facade
   * that enables element manipulation. This also facilitates backwards compatibility with
   * Renderer2.
   */
  var renderer;
  var rendererFactory;
  /**
   * Used to set the parent property when nodes are created.
   */
  var previousOrParentNode;
  /**
   * If `isParent` is:
   *  - `true`: then `previousOrParentNode` points to a parent node.
   *  - `false`: then `previousOrParentNode` points to previous node (sibling).
   */
  var isParent;
  /**
   * The current template's static data (shared between all templates of a
   * given type).
   *
   * Each node's static data is stored at the same index that it's stored
   * in the data array. Any nodes that do not have static data store a null
   * value to avoid a sparse array.
   */
  var ngStaticData;
  /**
   * State of the current view being processed.
   */
  var currentView;
  // The initialization has to be after the `let`, otherwise `createViewState` can't see `let`.
  currentView = createViewState(/** @type {?} */ ((null)), /** @type {?} */ ((null)), []);
  var currentQuery;
  /**
   * This property gets set before entering a template.
   */
  var creationMode;
  /**
   * An array of nodes (text, element, container, etc), their bindings, and
   * any local variables that need to be stored between invocations.
   */
  var data;
  /**
   * Points to the next binding index to read or write to.
   */
  var bindingIndex;
  /**
   * When a view is destroyed, listeners need to be released
   * and onDestroy callbacks need to be called. This cleanup array
   * stores both listener data (in chunks of 4) and onDestroy data
   * (in chunks of 2), as they'll be processed at the same time.
   *
   * If it's a listener being stored:
   * 1st index is: event name to remove
   * 2nd index is: native element
   * 3rd index is: listener function
   * 4th index is: useCapture boolean
   *
   * If it's an onDestroy function:
   * 1st index is: onDestroy function
   * 2nd index is: context for function
   */
  var cleanup;
  /**
   * Index in the data array at which view hooks begin to be stored.
   */
  var viewHookStartIndex;
  /**
   * Swap the current state with a new state.
   *
   * For performance reasons we store the state in the top level of the module.
   * This way we minimize the number of properties to read. Whenever a new view
   * is entered we have to store the state for later, and when the view is
   * exited the state has to be restored
   *
   * @param {?} newViewState New state to become active
   * @param {?} host Element to which the View is a child of
   * @return {?} the previous state;
   */
  function enterView(newViewState, host) {
      var /** @type {?} */ oldViewState = currentView;
      data = newViewState.data;
      bindingIndex = newViewState.bindingStartIndex || 0;
      ngStaticData = newViewState.ngStaticData;
      creationMode = newViewState.creationMode;
      viewHookStartIndex = newViewState.viewHookStartIndex;
      cleanup = newViewState.cleanup;
      renderer = newViewState.renderer;
      if (host != null) {
          previousOrParentNode = host;
          isParent = true;
      }
      currentView = newViewState;
      return /** @type {?} */ ((oldViewState));
  }
  /**
   * Used in lieu of enterView to make it clear when we are exiting a child view. This makes
   * the direction of traversal (up or down the view tree) a bit clearer.
   * @param {?} newViewState
   * @return {?}
   */
  function leaveView(newViewState) {
      executeViewHooks();
      enterView(newViewState, null);
  }
  /**
   * @param {?} viewId
   * @param {?} renderer
   * @param {?} ngStaticData
   * @return {?}
   */
  function createViewState(viewId, renderer, ngStaticData) {
      var /** @type {?} */ newView = {
          parent: currentView,
          id: viewId,
          // -1 for component views
          node: /** @type {?} */ ((null)),
          // until we initialize it in createNode.
          data: [],
          ngStaticData: ngStaticData,
          cleanup: null,
          renderer: renderer,
          child: null,
          tail: null,
          next: null,
          bindingStartIndex: null,
          creationMode: true,
          viewHookStartIndex: null
      };
      return newView;
  }
  /**
   * @param {?} index
   * @param {?} type
   * @param {?} native
   * @param {?=} state
   * @return {?}
   */
  function createLNode(index, type, native, state) {
      var /** @type {?} */ parent = isParent ? previousOrParentNode :
          previousOrParentNode && /** @type {?} */ (previousOrParentNode.parent);
      var /** @type {?} */ query = (isParent ? currentQuery : previousOrParentNode && previousOrParentNode.query) ||
          parent && parent.query && parent.query.child();
      var /** @type {?} */ isState = state != null;
      var /** @type {?} */ node = {
          flags: type,
          native: /** @type {?} */ (native),
          view: currentView,
          parent: /** @type {?} */ (parent),
          child: null,
          next: null,
          nodeInjector: parent ? parent.nodeInjector : null,
          data: isState ? /** @type {?} */ (state) : null,
          query: query,
          staticData: null
      };
      if ((type & 2 /* ViewOrElement */) === 2 /* ViewOrElement */ && isState) {
          // Bit of a hack to bust through the readonly because there is a circular dep between
          // ViewState and LNode.
          ngDevMode && assertEqual((/** @type {?} */ (state)).node, null, 'viewState.node');
          (/** @type {?} */ ((state))).node = node;
      }
      if (index != null) {
          // We are Element or Container
          ngDevMode && assertEqual(data.length, index, 'data.length not in sequence');
          data[index] = node;
          // Every node adds a value to the static data array to avoid a sparse array
          if (index >= ngStaticData.length) {
              ngStaticData[index] = null;
          }
          else {
              node.staticData = /** @type {?} */ (ngStaticData[index]);
          }
          // Now link ourselves into the tree.
          if (isParent) {
              currentQuery = null;
              if (previousOrParentNode.view === currentView ||
                  (previousOrParentNode.flags & 3 /* TYPE_MASK */) === 2 /* View */) {
                  // We are in the same view, which means we are adding content node to the parent View.
                  ngDevMode && assertEqual(previousOrParentNode.child, null, 'previousNode.child');
                  previousOrParentNode.child = node;
              }
              else {
                  // We are adding component view, so we don't link parent node child to this node.
              }
          }
          else if (previousOrParentNode) {
              ngDevMode && assertEqual(previousOrParentNode.next, null, 'previousNode.next');
              previousOrParentNode.next = node;
          }
      }
      previousOrParentNode = node;
      isParent = true;
      return node;
  }
  /**
   * Resets the application state.
   * @return {?}
   */
  function resetApplicationState() {
      isParent = false;
      previousOrParentNode = /** @type {?} */ ((null));
  }
  /**
   *
   * @template T
   * @param {?} hostNode
   * @param {?} template Template function with the instructions.
   * @param {?} context to pass into the template.
   * @param {?} providedRendererFactory
   * @param {?} host Existing node to render into.
   * @return {?}
   */
  
  /**
   * @template T
   * @param {?} node
   * @param {?} viewState
   * @param {?} componentOrContext
   * @param {?=} template
   * @return {?}
   */
  function renderComponentOrTemplate(node, viewState, componentOrContext, template) {
      var /** @type {?} */ oldView = enterView(viewState, node);
      try {
          if (rendererFactory.begin) {
              rendererFactory.begin();
          }
          if (template) {
              ngStaticData = template.ngStaticData || (template.ngStaticData = /** @type {?} */ ([]));
              template(/** @type {?} */ ((componentOrContext)), creationMode);
          }
          else {
              // Element was stored at 0 and directive was stored at 1 in renderComponent
              // so to refresh the component, r() needs to be called with (1, 0)
              (/** @type {?} */ (componentOrContext.constructor)).ngComponentDef.r(1, 0);
          }
      }
      finally {
          if (rendererFactory.end) {
              rendererFactory.end();
          }
          viewState.creationMode = false;
          leaveView(oldView);
      }
  }
  /**
   * @return {?}
   */
  
  /**
   * Makes a directive public to the DI system by adding it to an injector's bloom filter.
   *
   * @param {?} def The definition of the directive to be made public
   * @return {?}
   */
  
  /**
   * Searches for an instance of the given directive type up the injector tree and returns
   * that instance if found.
   *
   * If not found, it will propagate up to the next parent injector until the token
   * is found or the top is reached.
   *
   * Usage example (in factory function):
   *
   * class SomeDirective {
   *   constructor(directive: DirectiveA) {}
   *
   *   static ngDirectiveDef = defineDirective({
   *     type: SomeDirective,
   *     factory: () => new SomeDirective(inject(DirectiveA))
   *   });
   * }
   *
   * @template T
   * @param {?} token The directive type to search for
   * @param {?=} flags Injection flags (e.g. CheckParent)
   * @return {?} The instance found
   */
  
  /**
   * Creates an ElementRef and stores it on the injector.
   * Or, if the ElementRef already exists, retrieves the existing ElementRef.
   *
   * @return {?} The ElementRef instance to use
   */
  
  /**
   * Creates a TemplateRef and stores it on the injector. Or, if the TemplateRef already
   * exists, retrieves the existing TemplateRef.
   *
   * @template T
   * @return {?} The TemplateRef instance to use
   */
  
  /**
   * Creates a ViewContainerRef and stores it on the injector. Or, if the ViewContainerRef
   * already exists, retrieves the existing ViewContainerRef.
   *
   * @return {?} The ViewContainerRef instance to use
   */
  
  /**
   * Create DOM element. The instruction must later be followed by `elementEnd()` call.
   *
   * @param {?} index Index of the element in the data array
   * @param {?=} nameOrComponentDef Name of the DOM Node or `ComponentDef`.
   * @param {?=} attrs Statically bound set of attributes to be written into the DOM element on creation.
   * @param {?=} localName A name under which a given element is exported.
   *
   * Attributes are passed as an array of strings where elements with an even index hold an attribute
   * name and elements with an odd index hold an attribute value, ex.:
   * ['id', 'warning5', 'class', 'alert']
   * @return {?}
   */
  function elementStart(index, nameOrComponentDef, attrs, localName) {
      var /** @type {?} */ node;
      var /** @type {?} */ native;
      if (nameOrComponentDef == null) {
          // native node retrieval - used for exporting elements as tpl local variables (<div #foo>)
          var /** @type {?} */ node_1 = /** @type {?} */ ((data[index]));
          native = node_1 && (/** @type {?} */ (node_1)).native;
      }
      else {
          ngDevMode && assertEqual(currentView.bindingStartIndex, null, 'bindingStartIndex');
          var /** @type {?} */ isHostElement = typeof nameOrComponentDef !== 'string';
          var /** @type {?} */ name_1 = isHostElement ? (/** @type {?} */ (nameOrComponentDef)).tag : /** @type {?} */ (nameOrComponentDef);
          if (name_1 === null) {
              // TODO: future support for nameless components.
              throw 'for now name is required';
          }
          else {
              native = renderer.createElement(name_1);
              var /** @type {?} */ componentView = null;
              if (isHostElement) {
                  var /** @type {?} */ ngStaticData_1 = getTemplateStatic((/** @type {?} */ (nameOrComponentDef)).template);
                  componentView = addToViewTree(createViewState(-1, rendererFactory.createRenderer(native, (/** @type {?} */ (nameOrComponentDef)).rendererType), ngStaticData_1));
              }
              // Only component views should be added to the view tree directly. Embedded views are
              // accessed through their containers because they may be removed / re-added later.
              node = createLNode(index, 3 /* Element */, native, componentView);
              if (node.staticData == null) {
                  ngDevMode && assertDataInRange(index - 1);
                  node.staticData = ngStaticData[index] =
                      createNodeStatic(name_1, attrs || null, null, localName || null);
              }
              if (attrs)
                  setUpAttributes(native, attrs);
              appendChild(/** @type {?} */ ((node.parent)), native, currentView);
          }
      }
      return native;
  }
  /**
   * Gets static data from a template function or creates a new static
   * data array if it doesn't already exist.
   *
   * @param {?} template The template from which to get static data
   * @return {?} NgStaticData
   */
  function getTemplateStatic(template) {
      return template.ngStaticData || (template.ngStaticData = /** @type {?} */ ([]));
  }
  /**
   * @param {?} native
   * @param {?} attrs
   * @return {?}
   */
  function setUpAttributes(native, attrs) {
      ngDevMode && assertEqual(attrs.length % 2, 0, 'attrs.length % 2');
      var /** @type {?} */ isProceduralRenderer = (/** @type {?} */ (renderer)).setAttribute;
      for (var /** @type {?} */ i = 0; i < attrs.length; i += 2) {
          isProceduralRenderer ? /** @type {?} */ (((/** @type {?} */ (renderer)).setAttribute))(native, attrs[i], attrs[i | 1]) :
              native.setAttribute(attrs[i], attrs[i | 1]);
      }
  }
  /**
   * @param {?} text
   * @param {?} token
   * @return {?}
   */
  function createError(text, token) {
      return new Error("Renderer: " + text + " [" + stringify$1(token) + "]");
  }
  /**
   * Locates the host native element, used for bootstrapping existing nodes into rendering pipeline.
   *
   * @param {?} factory
   * @param {?} elementOrSelector Render element or CSS selector to locate the element.
   * @return {?}
   */
  function locateHostElement(factory, elementOrSelector) {
      ngDevMode && assertDataInRange(-1);
      rendererFactory = factory;
      var /** @type {?} */ defaultRenderer = factory.createRenderer(null, null);
      var /** @type {?} */ rNode = typeof elementOrSelector === 'string' ?
          ((/** @type {?} */ (defaultRenderer)).selectRootElement ?
              (/** @type {?} */ (defaultRenderer)).selectRootElement(elementOrSelector) : /** @type {?} */ (((/** @type {?} */ (defaultRenderer)).querySelector))(elementOrSelector)) :
          elementOrSelector;
      if (ngDevMode && !rNode) {
          if (typeof elementOrSelector === 'string') {
              throw createError('Host node with selector not found:', elementOrSelector);
          }
          else {
              throw createError('Host node is required:', elementOrSelector);
          }
      }
      return rNode;
  }
  /**
   * Creates the host LNode..
   *
   * @param {?} rNode Render host element.
   * @param {?} def
   * @return {?}
   */
  function hostElement(rNode, def) {
      resetApplicationState();
      createLNode(0, 3 /* Element */, rNode, createViewState(-1, renderer, getTemplateStatic(def.template)));
  }
  /**
   * Adds an event listener to the current node.
   *
   * If an output exists on one of the node's directives, it also subscribes to the output
   * and saves the subscription for later cleanup.
   *
   * @param {?} eventName Name of the event
   * @param {?} listener The function to be called when event emits
   * @param {?=} useCapture Whether or not to use capture in event listener.
   * @return {?}
   */
  
  /**
   * Mark the end of the element.
   * @return {?}
   */
  function elementEnd() {
      if (isParent) {
          isParent = false;
      }
      else {
          ngDevMode && assertHasParent();
          previousOrParentNode = /** @type {?} */ ((previousOrParentNode.parent));
      }
      ngDevMode && assertNodeType(previousOrParentNode, 3 /* Element */);
      var /** @type {?} */ query = previousOrParentNode.query;
      query && query.addNode(previousOrParentNode);
  }
  /**
   * Update an attribute on an Element. This is used with a `bind` instruction.
   *
   * @param {?} index The index of the element to update in the data array
   * @param {?} attrName Name of attribute. Because it is going to DOM, this is not subject to
   *        renaming as port of minification.
   * @param {?} value Value to write. This value will go through stringification.
   * @return {?}
   */
  
  /**
   * Update a property on an Element.
   *
   * If the property name also exists as an input property on one of the element's directives,
   * the component property will be set instead of the element property. This check must
   * be conducted at runtime so child components that add new \@Inputs don't have to be re-compiled.
   *
   * @template T
   * @param {?} index The index of the element to update in the data array
   * @param {?} propName Name of property. Because it is going to DOM, this is not subject to
   *        renaming as part of minification.
   * @param {?} value New value to write.
   * @return {?}
   */
  function elementProperty(index, propName, value) {
      if (value === NO_CHANGE)
          return;
      var /** @type {?} */ node = /** @type {?} */ (data[index]);
      var /** @type {?} */ staticData = /** @type {?} */ ((node.staticData));
      // if staticData.inputs is undefined, a listener has created output staticData, but inputs haven't
      // yet been checked
      if (staticData.inputs === undefined) {
          // mark inputs as checked
          staticData.inputs = null;
          staticData = generatePropertyAliases(node.flags, staticData, true);
      }
      var /** @type {?} */ inputData = staticData.inputs;
      var /** @type {?} */ dataValue;
      if (inputData && (dataValue = inputData[propName])) {
          setInputsForProperty(dataValue, value);
      }
      else {
          var /** @type {?} */ native = node.native;
          (/** @type {?} */ (renderer)).setProperty ?
              (/** @type {?} */ (renderer)).setProperty(native, propName, value) :
              native.setProperty ? native.setProperty(propName, value) :
                  (/** @type {?} */ (native))[propName] = value;
      }
  }
  /**
   * Constructs a LNodeStatic object from the arguments.
   *
   * @param {?} tagName
   * @param {?} attrs
   * @param {?} containerStatic
   * @param {?} localName
   * @return {?} the LNodeStatic object
   */
  function createNodeStatic(tagName, attrs, containerStatic, localName) {
      return {
          tagName: tagName,
          attrs: attrs,
          localNames: localName ? [localName, -1] : null,
          initialInputs: undefined,
          inputs: undefined,
          outputs: undefined,
          containerStatic: containerStatic
      };
  }
  /**
   * Given a list of directive indices and minified input names, sets the
   * input properties on the corresponding directives.
   * @param {?} inputs
   * @param {?} value
   * @return {?}
   */
  function setInputsForProperty(inputs, value) {
      for (var /** @type {?} */ i = 0; i < inputs.length; i += 2) {
          ngDevMode && assertDataInRange(/** @type {?} */ (inputs[i]));
          data[/** @type {?} */ (inputs[i])][inputs[i | 1]] = value;
      }
  }
  /**
   * This function consolidates all the inputs or outputs defined by directives
   * on this node into one object and stores it in ngStaticData so it can
   * be shared between all templates of this type.
   *
   * @param {?} flags
   * @param {?} data
   * @param {?=} isInputData
   * @return {?}
   */
  function generatePropertyAliases(flags, data, isInputData) {
      if (isInputData === void 0) { isInputData = false; }
      var /** @type {?} */ start = flags >> 12;
      var /** @type {?} */ size = (flags & 4092 /* SIZE_MASK */) >> 2;
      for (var /** @type {?} */ i = start, /** @type {?} */ ii = start + size; i < ii; i++) {
          var /** @type {?} */ directiveDef = /** @type {?} */ (((ngStaticData))[i]);
          var /** @type {?} */ propertyAliasMap = isInputData ? directiveDef.inputs : directiveDef.outputs;
          for (var /** @type {?} */ publicName in propertyAliasMap) {
              if (propertyAliasMap.hasOwnProperty(publicName)) {
                  var /** @type {?} */ internalName = propertyAliasMap[publicName];
                  var /** @type {?} */ staticDirData = isInputData ? (data.inputs || (data.inputs = {})) :
                      (data.outputs || (data.outputs = {}));
                  var /** @type {?} */ hasProperty = staticDirData.hasOwnProperty(publicName);
                  hasProperty ? staticDirData[publicName].push(i, internalName) :
                      (staticDirData[publicName] = [i, internalName]);
              }
          }
      }
      return data;
  }
  /**
   * Add or remove a class in a classList.
   *
   * This instruction is meant to handle the [class.foo]="exp" case
   *
   * @template T
   * @param {?} index The index of the element to update in the data array
   * @param {?} className Name of class to toggle. Because it is going to DOM, this is not subject to
   *        renaming as part of minification.
   * @param {?} value A value indicating if a given class should be added or removed.
   * @return {?}
   */
  
  /**
   * Update a given style on an Element.
   *
   * @template T
   * @param {?} index Index of the element to change in the data array
   * @param {?} styleName Name of property. Because it is going to DOM this is not subject to
   *        renaming as part of minification.
   * @param {?} value New value to write (null to remove).
   * @param {?=} suffix Suffix to add to style's value (optional).
   * @return {?}
   */
  function elementStyle(index, styleName, value, suffix) {
      if (value !== NO_CHANGE) {
          var /** @type {?} */ lElement = /** @type {?} */ (data[index]);
          if (value == null) {
              (/** @type {?} */ (renderer)).removeStyle ?
                  (/** @type {?} */ (renderer))
                      .removeStyle(lElement.native, styleName, RendererStyleFlags3.DashCase) :
                  lElement.native.style.removeProperty(styleName);
          }
          else {
              (/** @type {?} */ (renderer)).setStyle ?
                  (/** @type {?} */ (renderer))
                      .setStyle(lElement.native, styleName, suffix ? stringify$1(value) + suffix : stringify$1(value), RendererStyleFlags3.DashCase) :
                  lElement.native.style.setProperty(styleName, suffix ? stringify$1(value) + suffix : stringify$1(value));
          }
      }
  }
  /**
   * Create static text node
   *
   * @param {?} index Index of the node in the data array.
   * @param {?=} value Value to write. This value will be stringified.
   *   If value is not provided than the actual creation of the text node is delayed.
   * @return {?}
   */
  function text(index, value) {
      ngDevMode && assertEqual(currentView.bindingStartIndex, null, 'bindingStartIndex');
      var /** @type {?} */ textNode = value != null ?
          ((/** @type {?} */ (renderer)).createText ?
              (/** @type {?} */ (renderer)).createText(stringify$1(value)) : /** @type {?} */ (((/** @type {?} */ (renderer)).createTextNode))(stringify$1(value))) :
          null;
      var /** @type {?} */ node = createLNode(index, 3 /* Element */, textNode);
      // Text nodes are self closing.
      isParent = false;
      appendChild(/** @type {?} */ ((node.parent)), textNode, currentView);
  }
  /**
   * Create text node with binding
   * Bindings should be handled externally with the proper bind(1-8) method
   *
   * @template T
   * @param {?} index Index of the node in the data array.
   * @param {?} value Stringified value to write.
   * @return {?}
   */
  function textBinding(index, value) {
      // TODO(misko): I don't think index < nodes.length check is needed here.
      var /** @type {?} */ existingNode = index < data.length && /** @type {?} */ (data[index]);
      if (existingNode && existingNode.native) {
          // If DOM node exists and value changed, update textContent
          value !== NO_CHANGE &&
              ((/** @type {?} */ (renderer)).setValue ?
                  (/** @type {?} */ (renderer)).setValue(existingNode.native, stringify$1(value)) :
                  existingNode.native.textContent = stringify$1(value));
      }
      else if (existingNode) {
          // Node was created but DOM node creation was delayed. Create and append now.
          existingNode.native =
              ((/** @type {?} */ (renderer)).createText ?
                  (/** @type {?} */ (renderer)).createText(stringify$1(value)) : /** @type {?} */ (((/** @type {?} */ (renderer)).createTextNode))(stringify$1(value)));
          insertChild(existingNode, currentView);
      }
      else {
          text(index, value);
      }
  }
  /**
   * @template T
   * @param {?} index
   * @param {?=} directive
   * @param {?=} directiveDef
   * @param {?=} localName
   * @return {?}
   */
  function directive(index, directive, directiveDef, localName) {
      var /** @type {?} */ instance;
      if (directive == null) {
          // return existing
          ngDevMode && assertDataInRange(index);
          instance = data[index];
      }
      else {
          ngDevMode && assertEqual(currentView.bindingStartIndex, null, 'bindingStartIndex');
          ngDevMode && assertPreviousIsParent();
          var /** @type {?} */ flags = /** @type {?} */ ((previousOrParentNode)).flags;
          var /** @type {?} */ size = flags & 4092;
          if (size === 0) {
              flags =
                  (index << 12 /* INDX_SHIFT */) | 4 /* SIZE_SKIP */ | flags & 3 /* TYPE_MASK */;
          }
          else {
              flags += 4 /* SIZE_SKIP */;
          } /** @type {?} */
          ((previousOrParentNode)).flags = flags;
          ngDevMode && assertDataInRange(index - 1);
          Object.defineProperty(directive, NG_HOST_SYMBOL, { enumerable: false, value: previousOrParentNode });
          data[index] = instance = directive;
          if (index >= ngStaticData.length) {
              ngStaticData[index] = /** @type {?} */ ((directiveDef));
              if (localName) {
                  ngDevMode &&
                      assertNotNull(previousOrParentNode.staticData, 'previousOrParentNode.staticData');
                  var /** @type {?} */ nodeStaticData = /** @type {?} */ ((/** @type {?} */ ((previousOrParentNode)).staticData));
                  (nodeStaticData.localNames || (nodeStaticData.localNames = [])).push(localName, index);
              }
          }
          var /** @type {?} */ diPublic_1 = /** @type {?} */ ((directiveDef)).diPublic;
          if (diPublic_1) {
              diPublic_1(/** @type {?} */ ((directiveDef)));
          }
          var /** @type {?} */ staticData = /** @type {?} */ ((previousOrParentNode.staticData));
          if (staticData && staticData.attrs) {
              setInputsFromAttrs(instance, /** @type {?} */ ((directiveDef)).inputs, staticData);
          }
      }
      return instance;
  }
  /**
   * Sets initial input properties on directive instances from attribute data
   *
   * @template T
   * @param {?} instance Instance of the directive on which to set the initial inputs
   * @param {?} inputs The list of inputs from the directive def
   * @param {?} staticData The static data for this node
   * @return {?}
   */
  function setInputsFromAttrs(instance, inputs, staticData) {
      var /** @type {?} */ directiveIndex = ((previousOrParentNode.flags & 4092 /* SIZE_MASK */) >> 2 /* SIZE_SHIFT */) - 1;
      var /** @type {?} */ initialInputData = /** @type {?} */ (staticData.initialInputs);
      if (initialInputData === undefined || directiveIndex >= initialInputData.length) {
          initialInputData = generateInitialInputs(directiveIndex, inputs, staticData);
      }
      var /** @type {?} */ initialInputs = initialInputData[directiveIndex];
      if (initialInputs) {
          for (var /** @type {?} */ i = 0; i < initialInputs.length; i += 2) {
              (/** @type {?} */ (instance))[initialInputs[i]] = initialInputs[i | 1];
          }
      }
  }
  /**
   * Generates initialInputData for a node and stores it in the template's static storage
   * so subsequent template invocations don't have to recalculate it.
   *
   * initialInputData is an array containing values that need to be set as input properties
   * for directives on this node, but only once on creation. We need this array to support
   * the case where you set an \@Input property of a directive using attribute-like syntax.
   * e.g. if you have a `name` \@Input, you can set it once like this:
   *
   * <my-component name="Bess"></my-component>
   *
   * @param {?} directiveIndex Index to store the initial input data
   * @param {?} inputs The list of inputs from the directive def
   * @param {?} staticData The static data on this node
   * @return {?}
   */
  function generateInitialInputs(directiveIndex, inputs, staticData) {
      var /** @type {?} */ initialInputData = staticData.initialInputs || (staticData.initialInputs = []);
      initialInputData[directiveIndex] = null;
      var /** @type {?} */ attrs = /** @type {?} */ ((staticData.attrs));
      for (var /** @type {?} */ i = 0; i < attrs.length; i += 2) {
          var /** @type {?} */ attrName = attrs[i];
          var /** @type {?} */ minifiedInputName = inputs[attrName];
          if (minifiedInputName !== undefined) {
              var /** @type {?} */ inputsToStore = initialInputData[directiveIndex] || (initialInputData[directiveIndex] = []);
              inputsToStore.push(minifiedInputName, attrs[i | 1]);
          }
      }
      return initialInputData;
  }
  /**
   * @param {?} lifecycle
   * @param {?=} self
   * @param {?=} method
   * @return {?}
   */
  
  /**
   * Iterates over view hook functions and calls them.
   * @return {?}
   */
  function executeViewHooks() {
      if (viewHookStartIndex == null)
          return;
      // Instead of using splice to remove init hooks after their first run (expensive), we
      // shift over the AFTER_CHECKED hooks as we call them and truncate once at the end.
      var /** @type {?} */ checkIndex = /** @type {?} */ (viewHookStartIndex);
      var /** @type {?} */ writeIndex = checkIndex;
      while (checkIndex < data.length) {
          // Call lifecycle hook with its context
          data[checkIndex + 1].call(data[checkIndex + 2]);
          if (data[checkIndex] === 16 /* AFTER_VIEW_CHECKED */) {
              // We know if the writeIndex falls behind that there is an init that needs to
              // be overwritten.
              if (writeIndex < checkIndex) {
                  data[writeIndex] = data[checkIndex];
                  data[writeIndex + 1] = data[checkIndex + 1];
                  data[writeIndex + 2] = data[checkIndex + 2];
              }
              writeIndex += 3;
          }
          checkIndex += 3;
      }
      // Truncate once at the writeIndex
      data.length = writeIndex;
  }
  /**
   * Creates an LContainer.
   *
   * Only `LView`s can go into `LContainer`.
   *
   * @param {?} index The index of the container in the data array
   * @param {?=} template Optional inline template
   * @param {?=} tagName The name of the container element, if applicable
   * @param {?=} attrs The attrs attached to the container, if applicable
   * @param {?=} localName
   * @return {?}
   */
  function containerStart(index, template, tagName, attrs, localName) {
      ngDevMode && assertEqual(currentView.bindingStartIndex, null, 'bindingStartIndex');
      // If the direct parent of the container is a view, its views (including its comment)
      // will need to be added through insertView() when its parent view is being inserted.
      // For now, it is marked "headless" so we know to append its views later.
      var /** @type {?} */ comment = renderer.createComment(ngDevMode ? 'container' : '');
      var /** @type {?} */ renderParent = null;
      var /** @type {?} */ currentParent = isParent ? previousOrParentNode : /** @type {?} */ ((previousOrParentNode.parent));
      ngDevMode && assertNotEqual(currentParent, null, 'currentParent');
      if (appendChild(currentParent, comment, currentView)) {
          // we are adding to an Element which is either:
          // - Not a component (will not be re-projected, just added)
          // - View of the Component
          renderParent = /** @type {?} */ (currentParent);
      }
      var /** @type {?} */ node = createLNode(index, 0 /* Container */, comment, /** @type {?} */ ({
          views: [],
          nextIndex: 0, renderParent: renderParent,
          template: template == null ? null : template,
          next: null,
          parent: currentView
      }));
      if (node.staticData == null) {
          node.staticData = ngStaticData[index] =
              createNodeStatic(tagName || null, attrs || null, [], localName || null);
      }
      // Containers are added to the current view tree instead of their embedded views
      // because views can be removed and re-inserted.
      addToViewTree(node.data);
  }
  /**
   * @return {?}
   */
  function containerEnd() {
      if (isParent) {
          isParent = false;
      }
      else {
          ngDevMode && assertHasParent();
          previousOrParentNode = /** @type {?} */ ((previousOrParentNode.parent));
      }
      ngDevMode && assertNodeType(previousOrParentNode, 0 /* Container */);
      var /** @type {?} */ query = previousOrParentNode.query;
      query && query.addNode(previousOrParentNode);
  }
  /**
   * Sets a container up to receive views.
   *
   * @param {?} index The index of the container in the data array
   * @return {?}
   */
  function containerRefreshStart(index) {
      ngDevMode && assertDataInRange(index);
      previousOrParentNode = /** @type {?} */ (data[index]);
      ngDevMode && assertNodeType(previousOrParentNode, 0 /* Container */);
      isParent = true;
      (/** @type {?} */ (previousOrParentNode)).data.nextIndex = 0;
  }
  /**
   * Marks the end of the LContainer.
   *
   * Marking the end of ViewContainer is the time when to child Views get inserted or removed.
   * @return {?}
   */
  function containerRefreshEnd() {
      if (isParent) {
          isParent = false;
      }
      else {
          ngDevMode && assertNodeType(previousOrParentNode, 2 /* View */);
          ngDevMode && assertHasParent();
          previousOrParentNode = /** @type {?} */ ((previousOrParentNode.parent));
      }
      ngDevMode && assertNodeType(previousOrParentNode, 0 /* Container */);
      var /** @type {?} */ container = /** @type {?} */ (previousOrParentNode);
      ngDevMode && assertNodeType(container, 0 /* Container */);
      var /** @type {?} */ nextIndex = container.data.nextIndex;
      while (nextIndex < container.data.views.length) {
          // remove extra view.
          removeView(container, nextIndex);
      }
  }
  /**
   * Creates an LView.
   *
   * @param {?} viewBlockId The ID of this view
   * @return {?} Whether or not this view is in creation mode
   */
  function viewStart(viewBlockId) {
      var /** @type {?} */ container = /** @type {?} */ ((isParent ? previousOrParentNode : /** @type {?} */ ((previousOrParentNode.parent))));
      ngDevMode && assertNodeType(container, 0 /* Container */);
      var /** @type {?} */ containerState = container.data;
      var /** @type {?} */ views = containerState.views;
      var /** @type {?} */ existingView = !creationMode && containerState.nextIndex < views.length && views[containerState.nextIndex];
      var /** @type {?} */ viewUpdateMode = existingView && viewBlockId === (/** @type {?} */ (existingView)).data.id;
      if (viewUpdateMode) {
          previousOrParentNode = views[containerState.nextIndex++];
          ngDevMode && assertNodeType(previousOrParentNode, 2 /* View */);
          isParent = true;
          enterView((/** @type {?} */ (existingView)).data, /** @type {?} */ (previousOrParentNode));
      }
      else {
          // When we create a new View, we always reset the state of the instructions.
          var /** @type {?} */ newViewState = createViewState(viewBlockId, renderer, initViewStaticData(viewBlockId, container));
          enterView(newViewState, createLNode(null, 2 /* View */, null, newViewState));
          containerState.nextIndex++;
      }
      return !viewUpdateMode;
  }
  /**
   * Initialize the static data for the active view.
   *
   * Each embedded view needs to set the global ngStaticData variable to the static data for
   * that view. Otherwise, the view's static data for a particular node would overwrite
   * the staticdata for a node in the view above it with the same index (since it's in the
   * same template).
   *
   * @param {?} viewIndex The index of the view's static data in containerStatic
   * @param {?} parent The parent container in which to look for the view's static data
   * @return {?} NgStaticData
   */
  function initViewStaticData(viewIndex, parent) {
      ngDevMode && assertNodeType(parent, 0 /* Container */);
      var /** @type {?} */ containerStatic = (/** @type {?} */ (((parent)).staticData)).containerStatic;
      if (viewIndex >= containerStatic.length || containerStatic[viewIndex] == null) {
          containerStatic[viewIndex] = [];
      }
      return containerStatic[viewIndex];
  }
  /**
   * Marks the end of the LView.
   * @return {?}
   */
  function viewEnd() {
      isParent = false;
      var /** @type {?} */ viewNode = previousOrParentNode = /** @type {?} */ (currentView.node);
      var /** @type {?} */ container = /** @type {?} */ (previousOrParentNode.parent);
      ngDevMode && assertNodeType(viewNode, 2 /* View */);
      ngDevMode && assertNodeType(container, 0 /* Container */);
      var /** @type {?} */ containerState = container.data;
      var /** @type {?} */ previousView = containerState.nextIndex <= containerState.views.length ? /** @type {?} */ (containerState.views[containerState.nextIndex - 1]) :
          null;
      var /** @type {?} */ viewIdChanged = previousView == null ? true : previousView.data.id !== viewNode.data.id;
      if (viewIdChanged) {
          insertView(container, viewNode, containerState.nextIndex - 1);
          currentView.creationMode = false;
      }
      leaveView(/** @type {?} */ ((/** @type {?} */ ((currentView)).parent)));
      ngDevMode && assertEqual(isParent, false, 'isParent');
      ngDevMode && assertNodeType(previousOrParentNode, 2 /* View */);
  }
  /**
   * Refreshes the component view.
   *
   * In other words, enters the component's view and processes it to update bindings, queries, etc.
   *
   * @param directiveIndex
   * @param elementIndex
   * @param template
   */
  var componentRefresh = function (directiveIndex, elementIndex, template) {
      ngDevMode && assertDataInRange(elementIndex);
      var /** @type {?} */ element = /** @type {?} */ (((data))[elementIndex]);
      ngDevMode && assertNodeType(element, 3 /* Element */);
      ngDevMode && assertNotEqual(element.data, null, 'isComponent');
      ngDevMode && assertDataInRange(directiveIndex);
      var /** @type {?} */ hostView = /** @type {?} */ ((element.data));
      ngDevMode && assertNotEqual(hostView, null, 'hostView');
      var /** @type {?} */ directive = data[directiveIndex];
      var /** @type {?} */ oldView = enterView(hostView, element);
      try {
          template(directive, creationMode);
      }
      finally {
          hostView.creationMode = false;
          leaveView(oldView);
      }
  };
  /**
   * Instruction to distribute projectable nodes among <ng-content> occurrences in a given template.
   * It takes all the selectors from the entire component's template and decides where
   * each projected node belongs (it re-distributes nodes among "buckets" where each "bucket" is
   * backed by a selector).
   *
   * @param {?=} selectors
   * @return {?}
   */
  
  /**
   * Inserts previously re-distributed projected nodes. This instruction must be preceded by a call
   * to the projectionDef instruction.
   *
   * @param {?} nodeIndex
   * @param {?} localIndex - index under which distribution of projected nodes was memorized
   * @param {?=} selectorIndex - 0 means <ng-content> without any selector
   * @return {?}
   */
  
  /**
   * Adds a ViewState or a ContainerState to the end of the current view tree.
   *
   * This structure will be used to traverse through nested views to remove listeners
   * and call onDestroy callbacks.
   *
   * @template T
   * @param {?} state The ViewState or ContainerState to add to the view tree
   * @return {?} The state passed in
   */
  function addToViewTree(state) {
      currentView.tail ? (currentView.tail.next = state) : (currentView.child = state);
      currentView.tail = state;
      return state;
  }
  /**
   * A special value which designates that a value has not changed.
   */
  var NO_CHANGE = /** @type {?} */ ({});
  /**
   * Create interpolation bindings with variable number of arguments.
   *
   * If any of the arguments change, then the interpolation is concatenated
   * and causes an update.
   *
   * @param {?} values an array of values to diff.
   * @return {?}
   */
  
  /**
   * Create a single value binding without interpolation.
   *
   * @template T
   * @param {?} value Value to diff
   * @return {?}
   */
  function bind(value) {
      var /** @type {?} */ different;
      if (different = creationMode) {
          if (typeof currentView.bindingStartIndex !== 'number') {
              bindingIndex = currentView.bindingStartIndex = data.length;
          }
          data[bindingIndex++] = value;
      }
      else {
          if (different = value !== NO_CHANGE && isDifferent(data[bindingIndex], value)) {
              data[bindingIndex] = value;
          }
          bindingIndex++;
      }
      return different ? value : NO_CHANGE;
  }
  /**
   * Create an interpolation bindings with 1 arguments.
   *
   * @param {?} prefix static value used for concatenation only.
   * @param {?} value value checked for change.
   * @param {?} suffix static value used for concatenation only.
   * @return {?}
   */
  function bind1(prefix, value, suffix) {
      return bind(value) === NO_CHANGE ? NO_CHANGE : prefix + stringify$1(value) + suffix;
  }
  /**
   * Create an interpolation bindings with 2 arguments.
   *
   * @param {?} prefix
   * @param {?} v0 value checked for change
   * @param {?} i0
   * @param {?} v1 value checked for change
   * @param {?} suffix
   * @return {?}
   */
  
  /**
   * Create an interpolation bindings with 3 arguments.
   *
   * @param {?} prefix
   * @param {?} v0
   * @param {?} i0
   * @param {?} v1
   * @param {?} i1
   * @param {?} v2
   * @param {?} suffix
   * @return {?}
   */
  
  /**
   * Create an interpolation binding with 4 arguments.
   *
   * @param {?} prefix
   * @param {?} v0
   * @param {?} i0
   * @param {?} v1
   * @param {?} i1
   * @param {?} v2
   * @param {?} i2
   * @param {?} v3
   * @param {?} suffix
   * @return {?}
   */
  
  /**
   * Create an interpolation binding with 5 arguments.
   *
   * @param {?} prefix
   * @param {?} v0
   * @param {?} i0
   * @param {?} v1
   * @param {?} i1
   * @param {?} v2
   * @param {?} i2
   * @param {?} v3
   * @param {?} i3
   * @param {?} v4
   * @param {?} suffix
   * @return {?}
   */
  
  /**
   * Create an interpolation binding with 6 arguments.
   *
   * @param {?} prefix
   * @param {?} v0
   * @param {?} i0
   * @param {?} v1
   * @param {?} i1
   * @param {?} v2
   * @param {?} i2
   * @param {?} v3
   * @param {?} i3
   * @param {?} v4
   * @param {?} i4
   * @param {?} v5
   * @param {?} suffix
   * @return {?}
   */
  
  /**
   * Create an interpolation binding with 7 arguments.
   *
   * @param {?} prefix
   * @param {?} v0
   * @param {?} i0
   * @param {?} v1
   * @param {?} i1
   * @param {?} v2
   * @param {?} i2
   * @param {?} v3
   * @param {?} i3
   * @param {?} v4
   * @param {?} i4
   * @param {?} v5
   * @param {?} i5
   * @param {?} v6
   * @param {?} suffix
   * @return {?}
   */
  
  /**
   * Create an interpolation binding with 8 arguments.
   *
   * @param {?} prefix
   * @param {?} v0
   * @param {?} i0
   * @param {?} v1
   * @param {?} i1
   * @param {?} v2
   * @param {?} i2
   * @param {?} v3
   * @param {?} i3
   * @param {?} v4
   * @param {?} i4
   * @param {?} v5
   * @param {?} i5
   * @param {?} v6
   * @param {?} i6
   * @param {?} v7
   * @param {?} suffix
   * @return {?}
   */
  
  /**
   * @template T
   * @param {?} index
   * @param {?=} value
   * @return {?}
   */
  
  /**
   * @template T
   * @param {?} predicate
   * @param {?=} descend
   * @param {?=} read
   * @return {?}
   */
  
  /**
   * @return {?}
   */
  function assertPreviousIsParent() {
      assertEqual(isParent, true, 'isParent');
  }
  /**
   * @return {?}
   */
  function assertHasParent() {
      assertNotEqual(previousOrParentNode.parent, null, 'isParent');
  }
  /**
   * @param {?} index
   * @param {?=} arr
   * @return {?}
   */
  function assertDataInRange(index, arr) {
      if (arr == null)
          arr = data;
      assertLessThan(arr ? arr.length : 0, index, 'data.length');
  }
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  /**
   * Options that control how the component should be bootstrapped.
   * @record
   */
  
  /**
   * Bootstraps a component, then creates and returns a `ComponentRef` for that component.
   *
   * @template T
   * @param {?} componentType Component to bootstrap
   * @param {?} opts
   * @return {?}
   */
  
  // TODO: A hack to not pull in the NullInjector from @angular/core.
  
  /**
   * Bootstraps a Component into an existing host element and returns an instance
   * of the component.
   *
   * @template T
   * @param {?} componentType Component to bootstrap
   * @param {?=} opts
   * @return {?}
   */
  function renderComponent(componentType, opts) {
      if (opts === void 0) { opts = {}; }
      var /** @type {?} */ rendererFactory = opts.rendererFactory || domRendererFactory3;
      var /** @type {?} */ componentDef = componentType.ngComponentDef;
      var /** @type {?} */ component;
      var /** @type {?} */ hostNode = locateHostElement(rendererFactory, opts.host || componentDef.tag);
      var /** @type {?} */ oldView = enterView(createViewState(-1, rendererFactory.createRenderer(hostNode, componentDef.rendererType), []), /** @type {?} */ ((null)));
      try {
          // Create element node at index 0 in data array
          hostElement(hostNode, componentDef);
          // Create directive instance with n() and store at index 1 in data array (el is 0)
          component = directive(1, componentDef.n(), componentDef);
      }
      finally {
          leaveView(oldView);
      }
      opts.features && opts.features.forEach(function (feature) { return feature(component, componentDef); });
      detectChanges(component);
      return component;
  }
  /**
   * @template T
   * @param {?} component
   * @return {?}
   */
  function detectChanges(component) {
      ngDevMode && assertNotNull(component, 'component');
      var /** @type {?} */ hostNode = /** @type {?} */ ((/** @type {?} */ (component))[NG_HOST_SYMBOL]);
      if (ngDevMode && !hostNode) {
          createError('Not a directive instance', component);
      }
      ngDevMode && assertNotNull(hostNode.data, 'hostNode.data');
      renderComponentOrTemplate(hostNode, hostNode.view, component);
      isDirty = false;
  }
  var isDirty = false;
  /**
   * @template T
   * @param {?} component
   * @param {?=} scheduler
   * @return {?}
   */
  
  /**
   * @template T
   * @param {?} component
   * @return {?}
   */
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  /**
   * Create a component definition object.
   *
   *
   * # Example
   * ```
   * class MyDirective {
   *   // Generated by Angular Template Compiler
   *   // [Symbol] syntax will not be supported by TypeScript until v2.7
   *   static [COMPONENT_DEF_SYMBOL] = defineComponent({
   *     ...
   *   });
   * }
   * ```
   * @template T
   * @param {?} componentDefinition
   * @return {?}
   */
  function defineComponent(componentDefinition) {
      var /** @type {?} */ def = /** @type {?} */ ({
          type: componentDefinition.type,
          diPublic: null,
          n: componentDefinition.factory,
          tag: (/** @type {?} */ (componentDefinition)).tag || /** @type {?} */ ((null)),
          template: (/** @type {?} */ (componentDefinition)).template || /** @type {?} */ ((null)),
          r: componentDefinition.refresh ||
              function (d, e) { componentRefresh(d, e, componentDefinition.template); },
          h: componentDefinition.hostBindings || noop$1,
          inputs: invertObject(componentDefinition.inputs),
          outputs: invertObject(componentDefinition.outputs),
          methods: invertObject(componentDefinition.methods),
          rendererType: resolveRendererType2(componentDefinition.rendererType) || null,
      });
      var /** @type {?} */ feature = componentDefinition.features;
      feature && feature.forEach(function (fn) { return fn(def); });
      return def;
  }
  /**
   * @template T
   * @param {?} definition
   * @return {?}
   */
  
  /**
   * @template T
   * @param {?} definition
   * @return {?}
   */
  
  var EMPTY$1 = {};
  /**
   * @return {?}
   */
  function noop$1() { }
  /**
   * Swaps the keys and values of an object.
   * @param {?} obj
   * @return {?}
   */
  function invertObject(obj) {
      if (obj == null)
          return EMPTY$1;
      var /** @type {?} */ newObj = {};
      for (var /** @type {?} */ minifiedKey in obj) {
          newObj[obj[minifiedKey]] = minifiedKey;
      }
      return newObj;
  }
  /**
   * Create a directive definition object.
   *
   * # Example
   * ```
   * class MyDirective {
   *   // Generated by Angular Template Compiler
   *   // [Symbol] syntax will not be supported by TypeScript until v2.7
   *   static [DIRECTIVE_DEF_SYMBOL] = defineDirective({
   *     ...
   *   });
   * }
   * ```
   */
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  
  // clang-format on
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   */
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @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
   * @record
   */
  
  /**
   * \@experimental Animation support is experimental.
   */
  
  /**
   * \@experimental Animation support is experimental.
   * @record
   */
  
  /**
   * Metadata representing the entry of animations. Instances of this interface are provided via the
   * animation DSL when the {\@link trigger trigger animation function} is called.
   *
   * \@experimental Animation support is experimental.
   * @record
   */
  
  /**
   * Metadata representing the entry of animations. Instances of this interface are provided via the
   * animation DSL when the {\@link state state animation function} is called.
   *
   * \@experimental Animation support is experimental.
   * @record
   */
  
  /**
   * Metadata representing the entry of animations. Instances of this interface are provided via the
   * animation DSL when the {\@link transition transition animation function} is called.
   *
   * \@experimental Animation support is experimental.
   * @record
   */
  
  /**
   * \@experimental Animation support is experimental.
   * @record
   */
  
  /**
   * \@experimental Animation support is experimental.
   * @record
   */
  
  /**
   * Metadata representing the entry of animations. Instances of this interface are provided via the
   * animation DSL when the {\@link keyframes keyframes animation function} is called.
   *
   * \@experimental Animation support is experimental.
   * @record
   */
  
  /**
   * Metadata representing the entry of animations. Instances of this interface are provided via the
   * animation DSL when the {\@link style style animation function} is called.
   *
   * \@experimental Animation support is experimental.
   * @record
   */
  
  /**
   * Metadata representing the entry of animations. Instances of this interface are provided via the
   * animation DSL when the {\@link animate animate animation function} is called.
   *
   * \@experimental Animation support is experimental.
   * @record
   */
  
  /**
   * Metadata representing the entry of animations. Instances of this interface are provided via the
   * animation DSL when the {\@link animateChild animateChild animation function} is called.
   *
   * \@experimental Animation support is experimental.
   * @record
   */
  
  /**
   * Metadata representing the entry of animations. Instances of this interface are provided via the
   * animation DSL when the {\@link useAnimation useAnimation animation function} is called.
   *
   * \@experimental Animation support is experimental.
   * @record
   */
  
  /**
   * Metadata representing the entry of animations. Instances of this interface are provided via the
   * animation DSL when the {\@link sequence sequence animation function} is called.
   *
   * \@experimental Animation support is experimental.
   * @record
   */
  
  /**
   * Metadata representing the entry of animations. Instances of this interface are provided via the
   * animation DSL when the {\@link group group animation function} is called.
   *
   * \@experimental Animation support is experimental.
   * @record
   */
  
  /**
   * Metadata representing the entry of animations. Instances of this interface are provided via the
   * animation DSL when the {\@link stagger stagger animation function} is called.
   *
   * \@experimental Animation support is experimental.
   * @record
   */
  
  /**
   * `trigger` is an animation-specific function that is designed to be used inside of Angular's
   * animation DSL language. If this information is new, please navigate to the
   * {\@link Component#animations component animations metadata page} to gain a better
   * understanding of how animations in Angular are used.
   *
   * `trigger` Creates an animation trigger which will a list of {\@link state state} and
   * {\@link transition transition} entries that will be evaluated when the expression
   * bound to the trigger changes.
   *
   * Triggers are registered within the component annotation data under the
   * {\@link Component#animations animations section}. An animation trigger can be placed on an element
   * within a template by referencing the name of the trigger followed by the expression value that
   * the
   * trigger is bound to (in the form of `[\@triggerName]="expression"`.
   *
   * Animation trigger bindings strigify values and then match the previous and current values against
   * any linked transitions. If a boolean value is provided into the trigger binding then it will both
   * be represented as `1` or `true` and `0` or `false` for a true and false boolean values
   * respectively.
   *
   * ### Usage
   *
   * `trigger` will create an animation trigger reference based on the provided `name` value. The
   * provided `animation` value is expected to be an array consisting of {\@link state state} and
   * {\@link transition transition} declarations.
   *
   * ```typescript
   * \@Component({
   *   selector: 'my-component',
   *   templateUrl: 'my-component-tpl.html',
   *   animations: [
   *     trigger("myAnimationTrigger", [
   *       state(...),
   *       state(...),
   *       transition(...),
   *       transition(...)
   *     ])
   *   ]
   * })
   * class MyComponent {
   *   myStatusExp = "something";
   * }
   * ```
   *
   * The template associated with this component will make use of the `myAnimationTrigger` animation
   * trigger by binding to an element within its template code.
   *
   * ```html
   * <!-- somewhere inside of my-component-tpl.html -->
   * <div [\@myAnimationTrigger]="myStatusExp">...</div>
   * ```
   *
   * ## Disable Animations
   * A special animation control binding called `\@.disabled` can be placed on an element which will
   * then disable animations for any inner animation triggers situated within the element as well as
   * any animations on the element itself.
   *
   * When true, the `\@.disabled` binding will prevent all animations from rendering. The example
   * below shows how to use this feature:
   *
   * ```ts
   * \@Component({
   *   selector: 'my-component',
   *   template: `
   *     <div [\@.disabled]="isDisabled">
   *       <div [\@childAnimation]="exp"></div>
   *     </div>
   *   `,
   *   animations: [
   *     trigger("childAnimation", [
   *       // ...
   *     ])
   *   ]
   * })
   * class MyComponent {
   *   isDisabled = true;
   *   exp = '...';
   * }
   * ```
   *
   * The `\@childAnimation` trigger will not animate because `\@.disabled` prevents it from happening
   * (when true).
   *
   * Note that `\@.disabled` will only disable all animations (this means any animations running on
   * the same element will also be disabled).
   *
   * ### Disabling Animations Application-wide
   * When an area of the template is set to have animations disabled, **all** inner components will
   * also have their animations disabled as well. This means that all animations for an angular
   * application can be disabled by placing a host binding set on `\@.disabled` on the topmost Angular
   * component.
   *
   * ```ts
   * import {Component, HostBinding} from '\@angular/core';
   *
   * \@Component({
   *   selector: 'app-component',
   *   templateUrl: 'app.component.html',
   * })
   * class AppComponent {
   *   \@HostBinding('\@.disabled')
   *   public animationsDisabled = true;
   * }
   * ```
   *
   * ### What about animations that us `query()` and `animateChild()`?
   * Despite inner animations being disabled, a parent animation can {\@link query query} for inner
   * elements located in disabled areas of the template and still animate them as it sees fit. This is
   * also the case for when a sub animation is queried by a parent and then later animated using {\@link
   * animateChild animateChild}.
   *
   * \@experimental Animation support is experimental.
   * @param {?} name
   * @param {?} definitions
   * @return {?}
   */
  function trigger$1(name, definitions) {
      return { type: 7 /* Trigger */, name: name, definitions: definitions, options: {} };
  }
  /**
   * `animate` is an animation-specific function that is designed to be used inside of Angular's
   * animation DSL language. If this information is new, please navigate to the {\@link
   * Component#animations component animations metadata page} to gain a better understanding of
   * how animations in Angular are used.
   *
   * `animate` specifies an animation step that will apply the provided `styles` data for a given
   * amount of time based on the provided `timing` expression value. Calls to `animate` are expected
   * to be used within {\@link sequence an animation sequence}, {\@link group group}, or {\@link
   * transition transition}.
   *
   * ### Usage
   *
   * The `animate` function accepts two input parameters: `timing` and `styles`:
   *
   * - `timing` is a string based value that can be a combination of a duration with optional delay
   * and easing values. The format for the expression breaks down to `duration delay easing`
   * (therefore a value such as `1s 100ms ease-out` will be parse itself into `duration=1000,
   * delay=100, easing=ease-out`. If a numeric value is provided then that will be used as the
   * `duration` value in millisecond form.
   * - `styles` is the style input data which can either be a call to {\@link style style} or {\@link
   * keyframes keyframes}. If left empty then the styles from the destination state will be collected
   * and used (this is useful when describing an animation step that will complete an animation by
   * {\@link transition#the-final-animate-call animating to the final state}).
   *
   * ```typescript
   * // various functions for specifying timing data
   * animate(500, style(...))
   * animate("1s", style(...))
   * animate("100ms 0.5s", style(...))
   * animate("5s ease", style(...))
   * animate("5s 10ms cubic-bezier(.17,.67,.88,.1)", style(...))
   *
   * // either style() of keyframes() can be used
   * animate(500, style({ background: "red" }))
   * animate(500, keyframes([
   *   style({ background: "blue" })),
   *   style({ background: "red" }))
   * ])
   * ```
   *
   * {\@example core/animation/ts/dsl/animation_example.ts region='Component'}
   *
   * \@experimental Animation support is experimental.
   * @param {?} timings
   * @param {?=} styles
   * @return {?}
   */
  function animate$1(timings, styles) {
      if (styles === void 0) { styles = null; }
      return { type: 4 /* Animate */, styles: styles, timings: timings };
  }
  /**
   * `group` is an animation-specific function that is designed to be used inside of Angular's
   * animation DSL language. If this information is new, please navigate to the {\@link
   * Component#animations component animations metadata page} to gain a better understanding of
   * how animations in Angular are used.
   *
   * `group` specifies a list of animation steps that are all run in parallel. Grouped animations are
   * useful when a series of styles must be animated/closed off at different starting/ending times.
   *
   * The `group` function can either be used within a {\@link sequence sequence} or a {\@link transition
   * transition} and it will only continue to the next instruction once all of the inner animation
   * steps have completed.
   *
   * ### Usage
   *
   * The `steps` data that is passed into the `group` animation function can either consist of {\@link
   * style style} or {\@link animate animate} function calls. Each call to `style()` or `animate()`
   * within a group will be executed instantly (use {\@link keyframes keyframes} or a {\@link
   * animate#usage animate() with a delay value} to offset styles to be applied at a later time).
   *
   * ```typescript
   * group([
   *   animate("1s", { background: "black" }))
   *   animate("2s", { color: "white" }))
   * ])
   * ```
   *
   * {\@example core/animation/ts/dsl/animation_example.ts region='Component'}
   *
   * \@experimental Animation support is experimental.
   * @param {?} steps
   * @param {?=} options
   * @return {?}
   */
  function group$1(steps, options) {
      if (options === void 0) { options = null; }
      return { type: 3 /* Group */, steps: steps, options: options };
  }
  /**
   * `sequence` is an animation-specific function that is designed to be used inside of Angular's
   * animation DSL language. If this information is new, please navigate to the {\@link
   * Component#animations component animations metadata page} to gain a better understanding of
   * how animations in Angular are used.
   *
   * `sequence` Specifies a list of animation steps that are run one by one. (`sequence` is used by
   * default when an array is passed as animation data into {\@link transition transition}.)
   *
   * The `sequence` function can either be used within a {\@link group group} or a {\@link transition
   * transition} and it will only continue to the next instruction once each of the inner animation
   * steps have completed.
   *
   * To perform animation styling in parallel with other animation steps then have a look at the
   * {\@link group group} animation function.
   *
   * ### Usage
   *
   * The `steps` data that is passed into the `sequence` animation function can either consist of
   * {\@link style style} or {\@link animate animate} function calls. A call to `style()` will apply the
   * provided styling data immediately while a call to `animate()` will apply its styling data over a
   * given time depending on its timing data.
   *
   * ```typescript
   * sequence([
   *   style({ opacity: 0 })),
   *   animate("1s", { opacity: 1 }))
   * ])
   * ```
   *
   * {\@example core/animation/ts/dsl/animation_example.ts region='Component'}
   *
   * \@experimental Animation support is experimental.
   * @param {?} steps
   * @param {?=} options
   * @return {?}
   */
  function sequence$1(steps, options) {
      if (options === void 0) { options = null; }
      return { type: 2 /* Sequence */, steps: steps, options: options };
  }
  /**
   * `style` is an animation-specific function that is designed to be used inside of Angular's
   * animation DSL language. If this information is new, please navigate to the {\@link
   * Component#animations component animations metadata page} to gain a better understanding of
   * how animations in Angular are used.
   *
   * `style` declares a key/value object containing CSS properties/styles that can then be used for
   * {\@link state animation states}, within an {\@link sequence animation sequence}, or as styling data
   * for both {\@link animate animate} and {\@link keyframes keyframes}.
   *
   * ### Usage
   *
   * `style` takes in a key/value string map as data and expects one or more CSS property/value pairs
   * to be defined.
   *
   * ```typescript
   * // string values are used for css properties
   * style({ background: "red", color: "blue" })
   *
   * // numerical (pixel) values are also supported
   * style({ width: 100, height: 0 })
   * ```
   *
   * #### Auto-styles (using `*`)
   *
   * When an asterix (`*`) character is used as a value then it will be detected from the element
   * being animated and applied as animation data when the animation starts.
   *
   * This feature proves useful for a state depending on layout and/or environment factors; in such
   * cases the styles are calculated just before the animation starts.
   *
   * ```typescript
   * // the steps below will animate from 0 to the
   * // actual height of the element
   * style({ height: 0 }),
   * animate("1s", style({ height: "*" }))
   * ```
   *
   * {\@example core/animation/ts/dsl/animation_example.ts region='Component'}
   *
   * \@experimental Animation support is experimental.
   * @param {?} tokens
   * @return {?}
   */
  function style$1(tokens) {
      return { type: 6 /* Style */, styles: tokens, offset: null };
  }
  /**
   * `state` is an animation-specific function that is designed to be used inside of Angular's
   * animation DSL language. If this information is new, please navigate to the {\@link
   * Component#animations component animations metadata page} to gain a better understanding of
   * how animations in Angular are used.
   *
   * `state` declares an animation state within the given trigger. When a state is active within a
   * component then its associated styles will persist on the element that the trigger is attached to
   * (even when the animation ends).
   *
   * To animate between states, have a look at the animation {\@link transition transition} DSL
   * function. To register states to an animation trigger please have a look at the {\@link trigger
   * trigger} function.
   *
   * #### The `void` state
   *
   * The `void` state value is a reserved word that angular uses to determine when the element is not
   * apart of the application anymore (e.g. when an `ngIf` evaluates to false then the state of the
   * associated element is void).
   *
   * #### The `*` (default) state
   *
   * The `*` state (when styled) is a fallback state that will be used if the state that is being
   * animated is not declared within the trigger.
   *
   * ### Usage
   *
   * `state` will declare an animation state with its associated styles
   * within the given trigger.
   *
   * - `stateNameExpr` can be one or more state names separated by commas.
   * - `styles` refers to the {\@link style styling data} that will be persisted on the element once
   * the state has been reached.
   *
   * ```typescript
   * // "void" is a reserved name for a state and is used to represent
   * // the state in which an element is detached from from the application.
   * state("void", style({ height: 0 }))
   *
   * // user-defined states
   * state("closed", style({ height: 0 }))
   * state("open, visible", style({ height: "*" }))
   * ```
   *
   * {\@example core/animation/ts/dsl/animation_example.ts region='Component'}
   *
   * \@experimental Animation support is experimental.
   * @param {?} name
   * @param {?} styles
   * @param {?=} options
   * @return {?}
   */
  function state$1(name, styles, options) {
      return { type: 0 /* State */, name: name, styles: styles, options: options };
  }
  /**
   * `keyframes` is an animation-specific function that is designed to be used inside of Angular's
   * animation DSL language. If this information is new, please navigate to the {\@link
   * Component#animations component animations metadata page} to gain a better understanding of
   * how animations in Angular are used.
   *
   * `keyframes` specifies a collection of {\@link style style} entries each optionally characterized
   * by an `offset` value.
   *
   * ### Usage
   *
   * The `keyframes` animation function is designed to be used alongside the {\@link animate animate}
   * animation function. Instead of applying animations from where they are currently to their
   * destination, keyframes can describe how each style entry is applied and at what point within the
   * animation arc (much like CSS Keyframe Animations do).
   *
   * For each `style()` entry an `offset` value can be set. Doing so allows to specifiy at what
   * percentage of the animate time the styles will be applied.
   *
   * ```typescript
   * // the provided offset values describe when each backgroundColor value is applied.
   * animate("5s", keyframes([
   *   style({ backgroundColor: "red", offset: 0 }),
   *   style({ backgroundColor: "blue", offset: 0.2 }),
   *   style({ backgroundColor: "orange", offset: 0.3 }),
   *   style({ backgroundColor: "black", offset: 1 })
   * ]))
   * ```
   *
   * Alternatively, if there are no `offset` values used within the style entries then the offsets
   * will be calculated automatically.
   *
   * ```typescript
   * animate("5s", keyframes([
   *   style({ backgroundColor: "red" }) // offset = 0
   *   style({ backgroundColor: "blue" }) // offset = 0.33
   *   style({ backgroundColor: "orange" }) // offset = 0.66
   *   style({ backgroundColor: "black" }) // offset = 1
   * ]))
   * ```
   *
   * {\@example core/animation/ts/dsl/animation_example.ts region='Component'}
   *
   * \@experimental Animation support is experimental.
   * @param {?} steps
   * @return {?}
   */
  function keyframes$1(steps) {
      return { type: 5 /* Keyframes */, steps: steps };
  }
  /**
   * `transition` is an animation-specific function that is designed to be used inside of Angular's
   * animation DSL language. If this information is new, please navigate to the {\@link
   * Component#animations component animations metadata page} to gain a better understanding of
   * how animations in Angular are used.
   *
   * `transition` declares the {\@link sequence sequence of animation steps} that will be run when the
   * provided `stateChangeExpr` value is satisfied. The `stateChangeExpr` consists of a `state1 =>
   * state2` which consists of two known states (use an asterix (`*`) to refer to a dynamic starting
   * and/or ending state).
   *
   * A function can also be provided as the `stateChangeExpr` argument for a transition and this
   * function will be executed each time a state change occurs. If the value returned within the
   * function is true then the associated animation will be run.
   *
   * Animation transitions are placed within an {\@link trigger animation trigger}. For an transition
   * to animate to a state value and persist its styles then one or more {\@link state animation
   * states} is expected to be defined.
   *
   * ### Usage
   *
   * An animation transition is kicked off the `stateChangeExpr` predicate evaluates to true based on
   * what the previous state is and what the current state has become. In other words, if a transition
   * is defined that matches the old/current state criteria then the associated animation will be
   * triggered.
   *
   * ```typescript
   * // all transition/state changes are defined within an animation trigger
   * trigger("myAnimationTrigger", [
   *   // if a state is defined then its styles will be persisted when the
   *   // animation has fully completed itself
   *   state("on", style({ background: "green" })),
   *   state("off", style({ background: "grey" })),
   *
   *   // a transition animation that will be kicked off when the state value
   *   // bound to "myAnimationTrigger" changes from "on" to "off"
   *   transition("on => off", animate(500)),
   *
   *   // it is also possible to do run the same animation for both directions
   *   transition("on <=> off", animate(500)),
   *
   *   // or to define multiple states pairs separated by commas
   *   transition("on => off, off => void", animate(500)),
   *
   *   // this is a catch-all state change for when an element is inserted into
   *   // the page and the destination state is unknown
   *   transition("void => *", [
   *     style({ opacity: 0 }),
   *     animate(500)
   *   ]),
   *
   *   // this will capture a state change between any states
   *   transition("* => *", animate("1s 0s")),
   *
   *   // you can also go full out and include a function
   *   transition((fromState, toState) => {
   *     // when `true` then it will allow the animation below to be invoked
   *     return fromState == "off" && toState == "on";
   *   }, animate("1s 0s"))
   * ])
   * ```
   *
   * The template associated with this component will make use of the `myAnimationTrigger` animation
   * trigger by binding to an element within its template code.
   *
   * ```html
   * <!-- somewhere inside of my-component-tpl.html -->
   * <div [\@myAnimationTrigger]="myStatusExp">...</div>
   * ```
   *
   * #### The final `animate` call
   *
   * If the final step within the transition steps is a call to `animate()` that **only** uses a
   * timing value with **no style data** then it will be automatically used as the final animation arc
   * for the element to animate itself to the final state. This involves an automatic mix of
   * adding/removing CSS styles so that the element will be in the exact state it should be for the
   * applied state to be presented correctly.
   *
   * ```
   * // start off by hiding the element, but make sure that it animates properly to whatever state
   * // is currently active for "myAnimationTrigger"
   * transition("void => *", [
   *   style({ opacity: 0 }),
   *   animate(500)
   * ])
   * ```
   *
   * ### Using :enter and :leave
   *
   * Given that enter (insertion) and leave (removal) animations are so common, the `transition`
   * function accepts both `:enter` and `:leave` values which are aliases for the `void => *` and `*
   * => void` state changes.
   *
   * ```
   * transition(":enter", [
   *   style({ opacity: 0 }),
   *   animate(500, style({ opacity: 1 }))
   * ]),
   * transition(":leave", [
   *   animate(500, style({ opacity: 0 }))
   * ])
   * ```
   *
   * ### Boolean values
   * if a trigger binding value is a boolean value then it can be matched using a transition
   * expression that compares `true` and `false` or `1` and `0`.
   *
   * ```
   * // in the template
   * <div [\@openClose]="open ? true : false">...</div>
   *
   * // in the component metadata
   * trigger('openClose', [
   *   state('true', style({ height: '*' })),
   *   state('false', style({ height: '0px' })),
   *   transition('false <=> true', animate(500))
   * ])
   * ```
   *
   * ### Using :increment and :decrement
   * In addition to the :enter and :leave transition aliases, the :increment and :decrement aliases
   * can be used to kick off a transition when a numeric value has increased or decreased in value.
   *
   * ```
   * import {group, animate, query, transition, style, trigger} from '\@angular/animations';
   * import {Component} from '\@angular/core';
   *
   * \@Component({
   *   selector: 'banner-carousel-component',
   *   styles: [`
   *     .banner-container {
   *        position:relative;
   *        height:500px;
   *        overflow:hidden;
   *      }
   *     .banner-container > .banner {
   *        position:absolute;
   *        left:0;
   *        top:0;
   *        font-size:200px;
   *        line-height:500px;
   *        font-weight:bold;
   *        text-align:center;
   *        width:100%;
   *      }
   *   `],
   *   template: `
   *     <button (click)="previous()">Previous</button>
   *     <button (click)="next()">Next</button>
   *     <hr>
   *     <div [\@bannerAnimation]="selectedIndex" class="banner-container">
   *       <div class="banner" *ngFor="let banner of banners"> {{ banner }} </div>
   *     </div>
   *   `,
   *   animations: [
   *     trigger('bannerAnimation', [
   *       transition(":increment", group([
   *         query(':enter', [
   *           style({ left: '100%' }),
   *           animate('0.5s ease-out', style('*'))
   *         ]),
   *         query(':leave', [
   *           animate('0.5s ease-out', style({ left: '-100%' }))
   *         ])
   *       ])),
   *       transition(":decrement", group([
   *         query(':enter', [
   *           style({ left: '-100%' }),
   *           animate('0.5s ease-out', style('*'))
   *         ]),
   *         query(':leave', [
   *           animate('0.5s ease-out', style({ left: '100%' }))
   *         ])
   *       ]))
   *     ])
   *   ]
   * })
   * class BannerCarouselComponent {
   *   allBanners: string[] = ['1', '2', '3', '4'];
   *   selectedIndex: number = 0;
   *
   *   get banners() {
   *      return [this.allBanners[this.selectedIndex]];
   *   }
   *
   *   previous() {
   *     this.selectedIndex = Math.max(this.selectedIndex - 1, 0);
   *   }
   *
   *   next() {
   *     this.selectedIndex = Math.min(this.selectedIndex + 1, this.allBanners.length - 1);
   *   }
   * }
   * ```
   *
   * {\@example core/animation/ts/dsl/animation_example.ts region='Component'}
   *
   * \@experimental Animation support is experimental.
   * @param {?} stateChangeExpr
   * @param {?} steps
   * @param {?=} options
   * @return {?}
   */
  function transition$1(stateChangeExpr, steps, options) {
      if (options === void 0) { options = null; }
      return { type: 1 /* Transition */, expr: stateChangeExpr, animation: steps, options: options };
  }
  /**
   * `animation` is an animation-specific function that is designed to be used inside of Angular's
   * animation DSL language.
   *
   * `var myAnimation = animation(...)` is designed to produce a reusable animation that can be later
   * invoked in another animation or sequence. Reusable animations are designed to make use of
   * animation parameters and the produced animation can be used via the `useAnimation` method.
   *
   * ```
   * var fadeAnimation = animation([
   *   style({ opacity: '{{ start }}' }),
   *   animate('{{ time }}',
   *     style({ opacity: '{{ end }}'}))
   * ], { params: { time: '1000ms', start: 0, end: 1 }});
   * ```
   *
   * If parameters are attached to an animation then they act as **default parameter values**. When an
   * animation is invoked via `useAnimation` then parameter values are allowed to be passed in
   * directly. If any of the passed in parameter values are missing then the default values will be
   * used.
   *
   * ```
   * useAnimation(fadeAnimation, {
   *   params: {
   *     time: '2s',
   *     start: 1,
   *     end: 0
   *   }
   * })
   * ```
   *
   * If one or more parameter values are missing before animated then an error will be thrown.
   *
   * \@experimental Animation support is experimental.
   * @param {?} steps
   * @param {?=} options
   * @return {?}
   */
  
  /**
   * `animateChild` is an animation-specific function that is designed to be used inside of Angular's
   * animation DSL language. It works by allowing a queried element to execute its own
   * animation within the animation sequence.
   *
   * Each time an animation is triggered in angular, the parent animation
   * will always get priority and any child animations will be blocked. In order
   * for a child animation to run, the parent animation must query each of the elements
   * containing child animations and then allow the animations to run using `animateChild`.
   *
   * The example HTML code below shows both parent and child elements that have animation
   * triggers that will execute at the same time.
   *
   * ```html
   * <!-- parent-child.component.html -->
   * <button (click)="exp =! exp">Toggle</button>
   * <hr>
   *
   * <div [\@parentAnimation]="exp">
   *   <header>Hello</header>
   *   <div [\@childAnimation]="exp">
   *       one
   *   </div>
   *   <div [\@childAnimation]="exp">
   *       two
   *   </div>
   *   <div [\@childAnimation]="exp">
   *       three
   *   </div>
   * </div>
   * ```
   *
   * Now when the `exp` value changes to true, only the `parentAnimation` animation will animate
   * because it has priority. However, using `query` and `animateChild` each of the inner animations
   * can also fire:
   *
   * ```ts
   * // parent-child.component.ts
   * import {trigger, transition, animate, style, query, animateChild} from '\@angular/animations';
   * \@Component({
   *   selector: 'parent-child-component',
   *   animations: [
   *     trigger('parentAnimation', [
   *       transition('false => true', [
   *         query('header', [
   *           style({ opacity: 0 }),
   *           animate(500, style({ opacity: 1 }))
   *         ]),
   *         query('\@childAnimation', [
   *           animateChild()
   *         ])
   *       ])
   *     ]),
   *     trigger('childAnimation', [
   *       transition('false => true', [
   *         style({ opacity: 0 }),
   *         animate(500, style({ opacity: 1 }))
   *       ])
   *     ])
   *   ]
   * })
   * class ParentChildCmp {
   *   exp: boolean = false;
   * }
   * ```
   *
   * In the animation code above, when the `parentAnimation` transition kicks off it first queries to
   * find the header element and fades it in. It then finds each of the sub elements that contain the
   * `\@childAnimation` trigger and then allows for their animations to fire.
   *
   * This example can be further extended by using stagger:
   *
   * ```ts
   * query('\@childAnimation', stagger(100, [
   *   animateChild()
   * ]))
   * ```
   *
   * Now each of the sub animations start off with respect to the `100ms` staggering step.
   *
   * ## The first frame of child animations
   * When sub animations are executed using `animateChild` the animation engine will always apply the
   * first frame of every sub animation immediately at the start of the animation sequence. This way
   * the parent animation does not need to set any initial styling data on the sub elements before the
   * sub animations kick off.
   *
   * In the example above the first frame of the `childAnimation`'s `false => true` transition
   * consists of a style of `opacity: 0`. This is applied immediately when the `parentAnimation`
   * animation transition sequence starts. Only then when the `\@childAnimation` is queried and called
   * with `animateChild` will it then animate to its destination of `opacity: 1`.
   *
   * Note that this feature designed to be used alongside {\@link query query()} and it will only work
   * with animations that are assigned using the Angular animation DSL (this means that CSS keyframes
   * and transitions are not handled by this API).
   *
   * \@experimental Animation support is experimental.
   * @param {?=} options
   * @return {?}
   */
  
  /**
   * `useAnimation` is an animation-specific function that is designed to be used inside of Angular's
   * animation DSL language. It is used to kick off a reusable animation that is created using {\@link
   * animation animation()}.
   *
   * \@experimental Animation support is experimental.
   * @param {?} animation
   * @param {?=} options
   * @return {?}
   */
  
  /**
   * `query` is an animation-specific function that is designed to be used inside of Angular's
   * animation DSL language.
   *
   * query() is used to find one or more inner elements within the current element that is
   * being animated within the sequence. The provided animation steps are applied
   * to the queried element (by default, an array is provided, then this will be
   * treated as an animation sequence).
   *
   * ### Usage
   *
   * query() is designed to collect mutiple elements and works internally by using
   * `element.querySelectorAll`. An additional options object can be provided which
   * can be used to limit the total amount of items to be collected.
   *
   * ```js
   * query('div', [
   *   animate(...),
   *   animate(...)
   * ], { limit: 1 })
   * ```
   *
   * query(), by default, will throw an error when zero items are found. If a query
   * has the `optional` flag set to true then this error will be ignored.
   *
   * ```js
   * query('.some-element-that-may-not-be-there', [
   *   animate(...),
   *   animate(...)
   * ], { optional: true })
   * ```
   *
   * ### Special Selector Values
   *
   * The selector value within a query can collect elements that contain angular-specific
   * characteristics
   * using special pseudo-selectors tokens.
   *
   * These include:
   *
   *  - Querying for newly inserted/removed elements using `query(":enter")`/`query(":leave")`
   *  - Querying all currently animating elements using `query(":animating")`
   *  - Querying elements that contain an animation trigger using `query("\@triggerName")`
   *  - Querying all elements that contain an animation triggers using `query("\@*")`
   *  - Including the current element into the animation sequence using `query(":self")`
   *
   *
   *  Each of these pseudo-selector tokens can be merged together into a combined query selector
   * string:
   *
   *  ```
   *  query(':self, .record:enter, .record:leave, \@subTrigger', [...])
   *  ```
   *
   * ### Demo
   *
   * ```
   * \@Component({
   *   selector: 'inner',
   *   template: `
   *     <div [\@queryAnimation]="exp">
   *       <h1>Title</h1>
   *       <div class="content">
   *         Blah blah blah
   *       </div>
   *     </div>
   *   `,
   *   animations: [
   *    trigger('queryAnimation', [
   *      transition('* => goAnimate', [
   *        // hide the inner elements
   *        query('h1', style({ opacity: 0 })),
   *        query('.content', style({ opacity: 0 })),
   *
   *        // animate the inner elements in, one by one
   *        query('h1', animate(1000, style({ opacity: 1 })),
   *        query('.content', animate(1000, style({ opacity: 1 })),
   *      ])
   *    ])
   *  ]
   * })
   * class Cmp {
   *   exp = '';
   *
   *   goAnimate() {
   *     this.exp = 'goAnimate';
   *   }
   * }
   * ```
   *
   * \@experimental Animation support is experimental.
   * @param {?} selector
   * @param {?} animation
   * @param {?=} options
   * @return {?}
   */
  
  /**
   * `stagger` is an animation-specific function that is designed to be used inside of Angular's
   * animation DSL language. It is designed to be used inside of an animation {\@link query query()}
   * and works by issuing a timing gap between after each queried item is animated.
   *
   * ### Usage
   *
   * In the example below there is a container element that wraps a list of items stamped out
   * by an ngFor. The container element contains an animation trigger that will later be set
   * to query for each of the inner items.
   *
   * ```html
   * <!-- list.component.html -->
   * <button (click)="toggle()">Show / Hide Items</button>
   * <hr />
   * <div [\@listAnimation]="items.length">
   *   <div *ngFor="let item of items">
   *     {{ item }}
   *   </div>
   * </div>
   * ```
   *
   * The component code for this looks as such:
   *
   * ```ts
   * import {trigger, transition, style, animate, query, stagger} from '\@angular/animations';
   * \@Component({
   *   templateUrl: 'list.component.html',
   *   animations: [
   *     trigger('listAnimation', [
   *        //...
   *     ])
   *   ]
   * })
   * class ListComponent {
   *   items = [];
   *
   *   showItems() {
   *     this.items = [0,1,2,3,4];
   *   }
   *
   *   hideItems() {
   *     this.items = [];
   *   }
   *
   *   toggle() {
   *     this.items.length ? this.hideItems() : this.showItems();
   *   }
   * }
   * ```
   *
   * And now for the animation trigger code:
   *
   * ```ts
   * trigger('listAnimation', [
   *   transition('* => *', [ // each time the binding value changes
   *     query(':leave', [
   *       stagger(100, [
   *         animate('0.5s', style({ opacity: 0 }))
   *       ])
   *     ]),
   *     query(':enter', [
   *       style({ opacity: 0 }),
   *       stagger(100, [
   *         animate('0.5s', style({ opacity: 1 }))
   *       ])
   *     ])
   *   ])
   * ])
   * ```
   *
   * Now each time the items are added/removed then either the opacity
   * fade-in animation will run or each removed item will be faded out.
   * When either of these animations occur then a stagger effect will be
   * applied after each item's animation is started.
   *
   * \@experimental Animation support is experimental.
   * @param {?} timings
   * @param {?} animation
   * @return {?}
   */
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * @deprecated This symbol has moved. Please Import from \@angular/animations instead!
   */
  var AUTO_STYLE = '*';
  /**
   * @deprecated This symbol has moved. Please Import from \@angular/animations instead!
   * @record
   */
  
  /**
   * @deprecated This symbol has moved. Please Import from \@angular/animations instead!
   * @record
   */
  
  /**
   * @deprecated This symbol has moved. Please Import from \@angular/animations instead!
   * @record
   */
  
  /**
   * @deprecated This symbol has moved. Please Import from \@angular/animations instead!
   * @record
   */
  
  /**
   * @deprecated This symbol has moved. Please Import from \@angular/animations instead!
   * @record
   */
  
  /**
   * @deprecated This symbol has moved. Please Import from \@angular/animations instead!
   * @record
   */
  
  /**
   * @deprecated This symbol has moved. Please Import from \@angular/animations instead!
   * @record
   */
  
  /**
   * @deprecated This symbol has moved. Please Import from \@angular/animations instead!
   * @record
   */
  
  /**
   * @deprecated This symbol has moved. Please Import from \@angular/animations instead!
   * @record
   */
  
  /**
   * @deprecated This symbol has moved. Please Import from \@angular/animations instead!
   * @param {?} name
   * @param {?} definitions
   * @return {?}
   */
  function trigger$$1(name, definitions) {
      return trigger$1(name, definitions);
  }
  /**
   * @deprecated This symbol has moved. Please Import from \@angular/animations instead!
   * @param {?} timings
   * @param {?=} styles
   * @return {?}
   */
  function animate$$1(timings, styles) {
      return animate$1(timings, styles);
  }
  /**
   * @deprecated This symbol has moved. Please Import from \@angular/animations instead!
   * @param {?} steps
   * @return {?}
   */
  function group$$1(steps) {
      return group$1(steps);
  }
  /**
   * @deprecated This symbol has moved. Please Import from \@angular/animations instead!
   * @param {?} steps
   * @return {?}
   */
  function sequence$$1(steps) {
      return sequence$1(steps);
  }
  /**
   * @deprecated This symbol has moved. Please Import from \@angular/animations instead!
   * @param {?} tokens
   * @return {?}
   */
  function style$$1(tokens) {
      return style$1(tokens);
  }
  /**
   * @deprecated This symbol has moved. Please Import from \@angular/animations instead!
   * @param {?} name
   * @param {?} styles
   * @return {?}
   */
  function state$$1(name, styles) {
      return state$1(name, styles);
  }
  /**
   * @deprecated This symbol has moved. Please Import from \@angular/animations instead!
   * @param {?} steps
   * @return {?}
   */
  function keyframes$$1(steps) {
      return keyframes$1(steps);
  }
  /**
   * @deprecated This symbol has moved. Please Import from \@angular/animations instead!
   * @param {?} stateChangeExpr
   * @param {?} steps
   * @return {?}
   */
  function transition$$1(stateChangeExpr, steps) {
      return transition$1(stateChangeExpr, steps);
  }
  
  exports.createPlatform = createPlatform;
  exports.assertPlatform = assertPlatform;
  exports.destroyPlatform = destroyPlatform;
  exports.getPlatform = getPlatform;
  exports.PlatformRef = PlatformRef;
  exports.ApplicationRef = ApplicationRef;
  exports.enableProdMode = enableProdMode;
  exports.isDevMode = isDevMode;
  exports.createPlatformFactory = createPlatformFactory;
  exports.NgProbeToken = NgProbeToken;
  exports.APP_ID = APP_ID;
  exports.PACKAGE_ROOT_URL = PACKAGE_ROOT_URL;
  exports.PLATFORM_INITIALIZER = PLATFORM_INITIALIZER;
  exports.PLATFORM_ID = PLATFORM_ID;
  exports.APP_BOOTSTRAP_LISTENER = APP_BOOTSTRAP_LISTENER;
  exports.APP_INITIALIZER = APP_INITIALIZER;
  exports.ApplicationInitStatus = ApplicationInitStatus;
  exports.DebugElement = DebugElement;
  exports.DebugNode = DebugNode;
  exports.asNativeElements = asNativeElements;
  exports.getDebugNode = getDebugNode;
  exports.Testability = Testability;
  exports.TestabilityRegistry = TestabilityRegistry;
  exports.setTestabilityGetter = setTestabilityGetter;
  exports.TRANSLATIONS = TRANSLATIONS;
  exports.TRANSLATIONS_FORMAT = TRANSLATIONS_FORMAT;
  exports.LOCALE_ID = LOCALE_ID;
  exports.MissingTranslationStrategy = MissingTranslationStrategy;
  exports.ApplicationModule = ApplicationModule;
  exports.wtfCreateScope = wtfCreateScope;
  exports.wtfLeave = wtfLeave;
  exports.wtfStartTimeRange = wtfStartTimeRange;
  exports.wtfEndTimeRange = wtfEndTimeRange;
  exports.Type = Type;
  exports.EventEmitter = EventEmitter;
  exports.ErrorHandler = ErrorHandler;
  exports.Sanitizer = Sanitizer;
  exports.SecurityContext = SecurityContext;
  exports.ANALYZE_FOR_ENTRY_COMPONENTS = ANALYZE_FOR_ENTRY_COMPONENTS;
  exports.Attribute = Attribute;
  exports.ContentChild = ContentChild;
  exports.ContentChildren = ContentChildren;
  exports.Query = Query;
  exports.ViewChild = ViewChild;
  exports.ViewChildren = ViewChildren;
  exports.Component = Component;
  exports.Directive = Directive;
  exports.HostBinding = HostBinding;
  exports.HostListener = HostListener;
  exports.Input = Input;
  exports.Output = Output;
  exports.Pipe = Pipe;
  exports.CUSTOM_ELEMENTS_SCHEMA = CUSTOM_ELEMENTS_SCHEMA;
  exports.NO_ERRORS_SCHEMA = NO_ERRORS_SCHEMA;
  exports.NgModule = NgModule;
  exports.ViewEncapsulation = ViewEncapsulation;
  exports.Version = Version;
  exports.VERSION = VERSION;
  exports.forwardRef = forwardRef;
  exports.resolveForwardRef = resolveForwardRef;
  exports.Injector = Injector;
  exports.ReflectiveInjector = ReflectiveInjector;
  exports.ResolvedReflectiveFactory = ResolvedReflectiveFactory;
  exports.ReflectiveKey = ReflectiveKey;
  exports.InjectionToken = InjectionToken;
  exports.Inject = Inject;
  exports.Optional = Optional;
  exports.Injectable = Injectable;
  exports.Self = Self;
  exports.SkipSelf = SkipSelf;
  exports.Host = Host;
  exports.NgZone = NgZone;
  exports.RenderComponentType = RenderComponentType;
  exports.Renderer = Renderer;
  exports.Renderer2 = Renderer2;
  exports.RendererFactory2 = RendererFactory2;
  exports.RendererStyleFlags2 = RendererStyleFlags2;
  exports.RootRenderer = RootRenderer;
  exports.COMPILER_OPTIONS = COMPILER_OPTIONS;
  exports.Compiler = Compiler;
  exports.CompilerFactory = CompilerFactory;
  exports.ModuleWithComponentFactories = ModuleWithComponentFactories;
  exports.ComponentFactory = ComponentFactory;
  exports.ComponentRef = ComponentRef;
  exports.ComponentFactoryResolver = ComponentFactoryResolver;
  exports.ElementRef = ElementRef;
  exports.NgModuleFactory = NgModuleFactory;
  exports.NgModuleRef = NgModuleRef;
  exports.NgModuleFactoryLoader = NgModuleFactoryLoader;
  exports.getModuleFactory = getModuleFactory;
  exports.QueryList = QueryList;
  exports.SystemJsNgModuleLoader = SystemJsNgModuleLoader;
  exports.SystemJsNgModuleLoaderConfig = SystemJsNgModuleLoaderConfig;
  exports.TemplateRef = TemplateRef;
  exports.ViewContainerRef = ViewContainerRef;
  exports.EmbeddedViewRef = EmbeddedViewRef;
  exports.ViewRef = ViewRef;
  exports.ChangeDetectionStrategy = ChangeDetectionStrategy;
  exports.ChangeDetectorRef = ChangeDetectorRef;
  exports.DefaultIterableDiffer = DefaultIterableDiffer;
  exports.IterableDiffers = IterableDiffers;
  exports.KeyValueDiffers = KeyValueDiffers;
  exports.SimpleChange = SimpleChange;
  exports.WrappedValue = WrappedValue;
  exports.platformCore = platformCore;
  exports.ɵALLOW_MULTIPLE_PLATFORMS = ALLOW_MULTIPLE_PLATFORMS;
  exports.ɵAPP_ID_RANDOM_PROVIDER = APP_ID_RANDOM_PROVIDER;
  exports.ɵdevModeEqual = devModeEqual;
  exports.ɵisListLikeIterable = isListLikeIterable;
  exports.ɵChangeDetectorStatus = ChangeDetectorStatus;
  exports.ɵisDefaultChangeDetectionStrategy = isDefaultChangeDetectionStrategy;
  exports.ɵConsole = Console;
  exports.ɵComponentFactory = ComponentFactory;
  exports.ɵCodegenComponentFactoryResolver = CodegenComponentFactoryResolver;
  exports.ɵReflectionCapabilities = ReflectionCapabilities;
  exports.ɵRenderDebugInfo = RenderDebugInfo;
  exports.ɵglobal = _global;
  exports.ɵlooseIdentical = looseIdentical;
  exports.ɵstringify = stringify;
  exports.ɵmakeDecorator = makeDecorator;
  exports.ɵisObservable = isObservable;
  exports.ɵisPromise = isPromise;
  exports.ɵclearOverrides = clearOverrides;
  exports.ɵoverrideComponentView = overrideComponentView;
  exports.ɵoverrideProvider = overrideProvider;
  exports.ɵNOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR = NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR;
  exports.ɵdefineComponent = defineComponent;
  exports.ɵdetectChanges = detectChanges;
  exports.ɵrenderComponent = renderComponent;
  exports.ɵC = containerStart;
  exports.ɵD = directive;
  exports.ɵE = elementStart;
  exports.ɵT = text;
  exports.ɵV = viewStart;
  exports.ɵb = bind;
  exports.ɵb1 = bind1;
  exports.ɵc = containerEnd;
  exports.ɵcR = containerRefreshStart;
  exports.ɵcr = containerRefreshEnd;
  exports.ɵe = elementEnd;
  exports.ɵp = elementProperty;
  exports.ɵs = elementStyle;
  exports.ɵt = textBinding;
  exports.ɵv = viewEnd;
  exports.ɵregisterModuleFactory = registerModuleFactory;
  exports.ɵEMPTY_ARRAY = EMPTY_ARRAY;
  exports.ɵEMPTY_MAP = EMPTY_MAP;
  exports.ɵand = anchorDef;
  exports.ɵccf = createComponentFactory;
  exports.ɵcmf = createNgModuleFactory;
  exports.ɵcrt = createRendererType2;
  exports.ɵdid = directiveDef;
  exports.ɵeld = elementDef;
  exports.ɵelementEventFullName = elementEventFullName;
  exports.ɵgetComponentViewDefinitionFactory = getComponentViewDefinitionFactory;
  exports.ɵinlineInterpolate = inlineInterpolate;
  exports.ɵinterpolate = interpolate;
  exports.ɵmod = moduleDef;
  exports.ɵmpd = moduleProvideDef;
  exports.ɵncd = ngContentDef;
  exports.ɵnov = nodeValue;
  exports.ɵpid = pipeDef;
  exports.ɵprd = providerDef;
  exports.ɵpad = pureArrayDef;
  exports.ɵpod = pureObjectDef;
  exports.ɵppd = purePipeDef;
  exports.ɵqud = queryDef;
  exports.ɵted = textDef;
  exports.ɵunv = unwrapValue;
  exports.ɵvid = viewDef;
  exports.AUTO_STYLE = AUTO_STYLE;
  exports.trigger = trigger$$1;
  exports.animate = animate$$1;
  exports.group = group$$1;
  exports.sequence = sequence$$1;
  exports.style = style$$1;
  exports.state = state$$1;
  exports.keyframes = keyframes$$1;
  exports.transition = transition$$1;
  exports.ɵbf = animate$1;
  exports.ɵbg = group$1;
  exports.ɵbk = keyframes$1;
  exports.ɵbh = sequence$1;
  exports.ɵbj = state$1;
  exports.ɵbi = style$1;
  exports.ɵbl = transition$1;
  exports.ɵbe = trigger$1;
  exports.ɵn = _iterableDiffersFactory;
  exports.ɵo = _keyValueDiffersFactory;
  exports.ɵq = _localeFactory;
  exports.ɵi = _appIdRandomProviderFactory;
  exports.ɵj = defaultIterableDiffers;
  exports.ɵk = defaultKeyValueDiffers;
  exports.ɵl = DefaultIterableDifferFactory;
  exports.ɵm = DefaultKeyValueDifferFactory;
  exports.ɵf = ReflectiveInjector_;
  exports.ɵg = ReflectiveDependency;
  exports.ɵh = resolveReflectiveProviders;
  exports.ɵr = wtfEnabled;
  exports.ɵw = createScope;
  exports.ɵu = detectWTF;
  exports.ɵz = endTimeRange;
  exports.ɵx = leave;
  exports.ɵy = startTimeRange;
  exports.ɵbc = stringify$1;
  exports.ɵa = makeParamDecorator;
  exports.ɵd = makePropDecorator;
  exports.ɵba = _def;
  exports.ɵbb = DebugContext;
  
  Object.defineProperty(exports, '__esModule', { value: true });
  
  })));
  //# sourceMappingURL=core.umd.js.map
  