text: /**
   * @license
   * Copyright Google LLC All Rights Reserved.
   *
   * Use of this source code is governed by an MIT-style license that can be
   * found in the LICENSE file at https://angular.io/license
   */
  (function (global, factory) {
  	typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@angular/cdk/a11y'), require('@angular/cdk/overlay'), require('@angular/common'), require('@angular/core'), require('@angular/cdk/bidi'), require('@angular/cdk/coercion'), require('rxjs/Subject'), require('@angular/platform-browser'), require('@angular/cdk/platform'), require('@angular/cdk/keycodes'), require('@angular/cdk/portal'), require('@angular/cdk/rxjs'), require('rxjs/observable/defer'), require('@angular/animations'), require('rxjs/observable/of'), require('@angular/http'), require('rxjs/Observable'), require('rxjs/observable/forkJoin'), require('rxjs/observable/throw'), require('rxjs/operator/first'), require('rxjs/Subscription'), require('@angular/forms'), require('rxjs/observable/fromEvent'), require('rxjs/observable/merge')) :
  	typeof define === 'function' && define.amd ? define(['exports', '@angular/cdk/a11y', '@angular/cdk/overlay', '@angular/common', '@angular/core', '@angular/cdk/bidi', '@angular/cdk/coercion', 'rxjs/Subject', '@angular/platform-browser', '@angular/cdk/platform', '@angular/cdk/keycodes', '@angular/cdk/portal', '@angular/cdk/rxjs', 'rxjs/observable/defer', '@angular/animations', 'rxjs/observable/of', '@angular/http', 'rxjs/Observable', 'rxjs/observable/forkJoin', 'rxjs/observable/throw', 'rxjs/operator/first', 'rxjs/Subscription', '@angular/forms', 'rxjs/observable/fromEvent', 'rxjs/observable/merge'], factory) :
  	(factory((global.ng = global.ng || {}, global.ng.material = global.ng.material || {}, global.ng.material.datepicker = global.ng.material.datepicker || {}),global.ng.cdk.a11y,global.ng.cdk.overlay,global.ng.common,global.ng.core,global.ng.cdk.bidi,global.ng.cdk.coercion,global.Rx,global.ng.platformBrowser,global.ng.cdk.platform,global.ng.cdk.keycodes,global.ng.cdk.portal,global.ng.cdk.rxjs,global.Rx.Observable,global.ng.animations,global.Rx.Observable,global.ng.http,global.Rx,global.Rx.Observable,global.Rx.Observable,global.Rx.Observable.prototype,global.Rx,global.ng.forms,global.Rx.Observable,global.Rx.Observable));
  }(this, (function (exports,_angular_cdk_a11y,_angular_cdk_overlay,_angular_common,_angular_core,_angular_cdk_bidi,_angular_cdk_coercion,rxjs_Subject,_angular_platformBrowser,_angular_cdk_platform,_angular_cdk_keycodes,_angular_cdk_portal,_angular_cdk_rxjs,rxjs_observable_defer,_angular_animations,rxjs_observable_of,_angular_http,rxjs_Observable,rxjs_observable_forkJoin,rxjs_observable_throw,rxjs_operator_first,rxjs_Subscription,_angular_forms,rxjs_observable_fromEvent,rxjs_observable_merge) { '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 MATERIAL_COMPATIBILITY_MODE = new _angular_core.InjectionToken('md-compatibility-mode');
  /**
   * Selector that matches all elements that may have style collisions with AngularJS Material.
   */
  var MAT_ELEMENTS_SELECTOR = "\n  [mat-button],\n  [mat-fab],\n  [mat-icon-button],\n  [mat-mini-fab],\n  [mat-raised-button],\n  [matCardSubtitle],\n  [matCardTitle],\n  [matCellDef],\n  [matColumnDef],\n  [matDialogActions],\n  [matDialogClose],\n  [matDialogContent],\n  [matDialogTitle],\n  [matHeaderCellDef],\n  [matHeaderRowDef],\n  [matLine],\n  [matRowDef],\n  [matStepLabel],\n  [matStepperNext],\n  [matStepperPrevious],\n  [matTabLabel],\n  [matTabLink],\n  [matTabNav],\n  [matTooltip],\n  [matInput],\n  [matPrefix],\n  [matSuffix],\n  mat-autocomplete,\n  mat-button-toggle,\n  mat-button-toggle,\n  mat-button-toggle-group,\n  mat-card,\n  mat-card-actions,\n  mat-card-content,\n  mat-card-footer,\n  mat-card-header,\n  mat-card-subtitle,\n  mat-card-title,\n  mat-card-title-group,\n  mat-cell,\n  mat-checkbox,\n  mat-chip,\n  mat-dialog-actions,\n  mat-dialog-container,\n  mat-dialog-content,\n  mat-divider,\n  mat-error,\n  mat-grid-list,\n  mat-grid-tile,\n  mat-grid-tile-footer,\n  mat-grid-tile-header,\n  mat-header-cell,\n  mat-header-row,\n  mat-hint,\n  mat-horizontal-stepper,\n  mat-icon,\n  mat-input-container,\n  mat-form-field,\n  mat-list,\n  mat-list-item,\n  mat-menu,\n  mat-nav-list,\n  mat-option,\n  mat-placeholder,\n  mat-progress-bar,\n  mat-pseudo-checkbox,\n  mat-radio-button,\n  mat-radio-group,\n  mat-row,\n  mat-select,\n  mat-sidenav,\n  mat-sidenav-container,\n  mat-slider,\n  mat-spinner,\n  mat-step,\n  mat-tab,\n  mat-table,\n  mat-tab-group,\n  mat-toolbar,\n  mat-vertical-stepper";
  /**
   * Selector that matches all elements that may have style collisions with AngularJS Material.
   */
  var MD_ELEMENTS_SELECTOR = "\n  [md-button],\n  [md-fab],\n  [md-icon-button],\n  [md-mini-fab],\n  [md-raised-button],\n  [mdCardSubtitle],\n  [mdCardTitle],\n  [mdCellDef],\n  [mdColumnDef],\n  [mdDialogActions],\n  [mdDialogClose],\n  [mdDialogContent],\n  [mdDialogTitle],\n  [mdHeaderCellDef],\n  [mdHeaderRowDef],\n  [mdLine],\n  [mdRowDef],\n  [mdStepLabel],\n  [mdStepperNext],\n  [mdStepperPrevious],\n  [mdTabLabel],\n  [mdTabLink],\n  [mdTabNav],\n  [mdTooltip],\n  [mdInput],\n  [mdPrefix],\n  [mdSuffix],\n  md-autocomplete,\n  md-button-toggle,\n  md-button-toggle,\n  md-button-toggle-group,\n  md-card,\n  md-card-actions,\n  md-card-content,\n  md-card-footer,\n  md-card-header,\n  md-card-subtitle,\n  md-card-title,\n  md-card-title-group,\n  md-cell,\n  md-checkbox,\n  md-chip,\n  md-dialog-actions,\n  md-dialog-container,\n  md-dialog-content,\n  md-divider,\n  md-error,\n  md-grid-list,\n  md-grid-tile,\n  md-grid-tile-footer,\n  md-grid-tile-header,\n  md-header-cell,\n  md-header-row,\n  md-hint,\n  md-horizontal-stepper,\n  md-icon,\n  md-input-container,\n  md-form-field,\n  md-list,\n  md-list-item,\n  md-menu,\n  md-nav-list,\n  md-option,\n  md-placeholder,\n  md-progress-bar,\n  md-pseudo-checkbox,\n  md-radio-button,\n  md-radio-group,\n  md-row,\n  md-select,\n  md-sidenav,\n  md-sidenav-container,\n  md-slider,\n  md-spinner,\n  md-step,\n  md-tab,\n  md-table,\n  md-tab-group,\n  md-toolbar,\n  md-vertical-stepper";
  /**
   * Directive that enforces that the `mat-` prefix cannot be used.
   */
  var MatPrefixRejector = (function () {
      function MatPrefixRejector() {
      }
      MatPrefixRejector.decorators = [
          { type: _angular_core.Directive, args: [{ selector: MAT_ELEMENTS_SELECTOR },] },
      ];
      /**
       * @nocollapse
       */
      MatPrefixRejector.ctorParameters = function () { return []; };
      return MatPrefixRejector;
  }());
  /**
   * Directive that enforces that the `md-` prefix cannot be used.
   */
  var MdPrefixRejector = (function () {
      function MdPrefixRejector() {
      }
      MdPrefixRejector.decorators = [
          { type: _angular_core.Directive, args: [{ selector: MD_ELEMENTS_SELECTOR },] },
      ];
      /**
       * @nocollapse
       */
      MdPrefixRejector.ctorParameters = function () { return []; };
      return MdPrefixRejector;
  }());
  /**
   * Module that enforces the default compatibility mode settings. When this module is loaded
   * without NoConflictStyleCompatibilityMode also being imported, it will throw an error if
   * there are any uses of the `mat-` prefix.
   */
  var CompatibilityModule = (function () {
      function CompatibilityModule() {
      }
      CompatibilityModule.decorators = [
          { type: _angular_core.NgModule, args: [{
                      declarations: [MatPrefixRejector, MdPrefixRejector],
                      exports: [MatPrefixRejector, MdPrefixRejector],
                  },] },
      ];
      /**
       * @nocollapse
       */
      CompatibilityModule.ctorParameters = function () { return []; };
      return CompatibilityModule;
  }());
  /**
   * Injection token that configures whether the Material sanity checks are enabled.
   */
  var MATERIAL_SANITY_CHECKS = new _angular_core.InjectionToken('mat-sanity-checks');
  /**
   * Module that captures anything that should be loaded and/or run for *all* Angular Material
   * components. This includes Bidi, compatibility mode, etc.
   *
   * This module should be imported to each top-level component module (e.g., MatTabsModule).
   */
  var MatCommonModule = (function () {
      /**
       * @param {?} sanityChecksEnabled
       */
      function MatCommonModule(sanityChecksEnabled) {
          /**
           * Whether we've done the global sanity checks (e.g. a theme is loaded, there is a doctype).
           */
          this._hasDoneGlobalChecks = false;
          /**
           * Reference to the global `document` object.
           */
          this._document = typeof document === 'object' && document ? document : null;
          if (sanityChecksEnabled && !this._hasDoneGlobalChecks && _angular_core.isDevMode()) {
              this._checkDoctype();
              this._checkTheme();
              this._hasDoneGlobalChecks = true;
          }
      }
      /**
       * @return {?}
       */
      MatCommonModule.prototype._checkDoctype = function () {
          if (this._document && !this._document.doctype) {
              console.warn('Current document does not have a doctype. This may cause ' +
                  'some Angular Material components not to behave as expected.');
          }
      };
      /**
       * @return {?}
       */
      MatCommonModule.prototype._checkTheme = function () {
          if (this._document && typeof getComputedStyle === 'function') {
              var /** @type {?} */ testElement = this._document.createElement('div');
              testElement.classList.add('mat-theme-loaded-marker');
              this._document.body.appendChild(testElement);
              var /** @type {?} */ computedStyle = getComputedStyle(testElement);
              // In some situations, the computed style of the test element can be null. For example in
              // Firefox, the computed style is null if an application is running inside of a hidden iframe.
              // See: https://bugzilla.mozilla.org/show_bug.cgi?id=548397
              if (computedStyle && computedStyle.display !== 'none') {
                  console.warn('Could not find Angular Material core theme. Most Material ' +
                      'components may not work as expected. For more info refer ' +
                      'to the theming guide: https://material.angular.io/guide/theming');
              }
              this._document.body.removeChild(testElement);
          }
      };
      MatCommonModule.decorators = [
          { type: _angular_core.NgModule, args: [{
                      imports: [CompatibilityModule, _angular_cdk_bidi.BidiModule],
                      exports: [CompatibilityModule, _angular_cdk_bidi.BidiModule],
                      providers: [{
                              provide: MATERIAL_SANITY_CHECKS, useValue: true,
                          }],
                  },] },
      ];
      /**
       * @nocollapse
       */
      MatCommonModule.ctorParameters = function () { return [
          { type: undefined, decorators: [{ type: _angular_core.Optional }, { type: _angular_core.Inject, args: [MATERIAL_SANITY_CHECKS,] },] },
      ]; };
      return MatCommonModule;
  }());
  
  /**
   * Mixin to augment a directive with a `disabled` property.
   * @template T
   * @param {?} base
   * @return {?}
   */
  function mixinDisabled(base) {
      return (function (_super) {
          __extends(class_1, _super);
          /**
           * @param {...?} args
           */
          function class_1() {
              var args = [];
              for (var _i = 0; _i < arguments.length; _i++) {
                  args[_i] = arguments[_i];
              }
              var _this = _super.apply(this, args) || this;
              _this._disabled = false;
              return _this;
          }
          Object.defineProperty(class_1.prototype, "disabled", {
              /**
               * @return {?}
               */
              get: function () { return this._disabled; },
              /**
               * @param {?} value
               * @return {?}
               */
              set: function (value) { this._disabled = _angular_cdk_coercion.coerceBooleanProperty(value); },
              enumerable: true,
              configurable: true
          });
          return class_1;
      }(base));
  }
  
  /**
   * Mixin to augment a directive with a `color` property.
   * @template T
   * @param {?} base
   * @param {?=} defaultColor
   * @return {?}
   */
  function mixinColor(base, defaultColor) {
      return (function (_super) {
          __extends(class_1, _super);
          /**
           * @param {...?} args
           */
          function class_1() {
              var args = [];
              for (var _i = 0; _i < arguments.length; _i++) {
                  args[_i] = arguments[_i];
              }
              var _this = _super.apply(this, args) || this;
              // Set the default color that can be specified from the mixin.
              _this.color = defaultColor;
              return _this;
          }
          Object.defineProperty(class_1.prototype, "color", {
              /**
               * @return {?}
               */
              get: function () { return this._color; },
              /**
               * @param {?} value
               * @return {?}
               */
              set: function (value) {
                  var /** @type {?} */ colorPalette = value || defaultColor;
                  if (colorPalette !== this._color) {
                      if (this._color) {
                          this._renderer.removeClass(this._elementRef.nativeElement, "mat-" + this._color);
                      }
                      if (colorPalette) {
                          this._renderer.addClass(this._elementRef.nativeElement, "mat-" + colorPalette);
                      }
                      this._color = colorPalette;
                  }
              },
              enumerable: true,
              configurable: true
          });
          return class_1;
      }(base));
  }
  
  /**
   * Mixin to augment a directive with a `disableRipple` property.
   * @template T
   * @param {?} base
   * @return {?}
   */
  function mixinDisableRipple(base) {
      return (function (_super) {
          __extends(class_1, _super);
          /**
           * @param {...?} args
           */
          function class_1() {
              var args = [];
              for (var _i = 0; _i < arguments.length; _i++) {
                  args[_i] = arguments[_i];
              }
              var _this = _super.apply(this, args) || this;
              _this._disableRipple = false;
              return _this;
          }
          Object.defineProperty(class_1.prototype, "disableRipple", {
              /**
               * Whether the ripple effect is disabled or not.
               * @return {?}
               */
              get: function () { return this._disableRipple; },
              /**
               * @param {?} value
               * @return {?}
               */
              set: function (value) { this._disableRipple = _angular_cdk_coercion.coerceBooleanProperty(value); },
              enumerable: true,
              configurable: true
          });
          return class_1;
      }(base));
  }
  
  /**
   * InjectionToken for datepicker that can be used to override default locale code.
   */
  var MAT_DATE_LOCALE = new _angular_core.InjectionToken('MAT_DATE_LOCALE');
  /**
   * Adapts type `D` to be usable as a date by cdk-based components that work with dates.
   * @abstract
   */
  var DateAdapter = (function () {
      function DateAdapter() {
          this._localeChanges = new rxjs_Subject.Subject();
      }
      Object.defineProperty(DateAdapter.prototype, "localeChanges", {
          /**
           * A stream that emits when the locale changes.
           * @return {?}
           */
          get: function () { return this._localeChanges; },
          enumerable: true,
          configurable: true
      });
      /**
       * Gets the year component of the given date.
       * @abstract
       * @param {?} date The date to extract the year from.
       * @return {?} The year component.
       */
      DateAdapter.prototype.getYear = function (date) { };
      /**
       * Gets the month component of the given date.
       * @abstract
       * @param {?} date The date to extract the month from.
       * @return {?} The month component (0-indexed, 0 = January).
       */
      DateAdapter.prototype.getMonth = function (date) { };
      /**
       * Gets the date of the month component of the given date.
       * @abstract
       * @param {?} date The date to extract the date of the month from.
       * @return {?} The month component (1-indexed, 1 = first of month).
       */
      DateAdapter.prototype.getDate = function (date) { };
      /**
       * Gets the day of the week component of the given date.
       * @abstract
       * @param {?} date The date to extract the day of the week from.
       * @return {?} The month component (0-indexed, 0 = Sunday).
       */
      DateAdapter.prototype.getDayOfWeek = function (date) { };
      /**
       * Gets a list of names for the months.
       * @abstract
       * @param {?} style The naming style (e.g. long = 'January', short = 'Jan', narrow = 'J').
       * @return {?} An ordered list of all month names, starting with January.
       */
      DateAdapter.prototype.getMonthNames = function (style$$1) { };
      /**
       * Gets a list of names for the dates of the month.
       * @abstract
       * @return {?} An ordered list of all date of the month names, starting with '1'.
       */
      DateAdapter.prototype.getDateNames = function () { };
      /**
       * Gets a list of names for the days of the week.
       * @abstract
       * @param {?} style The naming style (e.g. long = 'Sunday', short = 'Sun', narrow = 'S').
       * @return {?} An ordered list of all weekday names, starting with Sunday.
       */
      DateAdapter.prototype.getDayOfWeekNames = function (style$$1) { };
      /**
       * Gets the name for the year of the given date.
       * @abstract
       * @param {?} date The date to get the year name for.
       * @return {?} The name of the given year (e.g. '2017').
       */
      DateAdapter.prototype.getYearName = function (date) { };
      /**
       * Gets the first day of the week.
       * @abstract
       * @return {?} The first day of the week (0-indexed, 0 = Sunday).
       */
      DateAdapter.prototype.getFirstDayOfWeek = function () { };
      /**
       * Gets the number of days in the month of the given date.
       * @abstract
       * @param {?} date The date whose month should be checked.
       * @return {?} The number of days in the month of the given date.
       */
      DateAdapter.prototype.getNumDaysInMonth = function (date) { };
      /**
       * Clones the given date.
       * @abstract
       * @param {?} date The date to clone
       * @return {?} A new date equal to the given date.
       */
      DateAdapter.prototype.clone = function (date) { };
      /**
       * Creates a date with the given year, month, and date. Does not allow over/under-flow of the
       * month and date.
       * @abstract
       * @param {?} year The full year of the date. (e.g. 89 means the year 89, not the year 1989).
       * @param {?} month The month of the date (0-indexed, 0 = January). Must be an integer 0 - 11.
       * @param {?} date The date of month of the date. Must be an integer 1 - length of the given month.
       * @return {?} The new date, or null if invalid.
       */
      DateAdapter.prototype.createDate = function (year, month, date) { };
      /**
       * Gets today's date.
       * @abstract
       * @return {?} Today's date.
       */
      DateAdapter.prototype.today = function () { };
      /**
       * Parses a date from a value.
       * @abstract
       * @param {?} value The value to parse.
       * @param {?} parseFormat The expected format of the value being parsed
       *     (type is implementation-dependent).
       * @return {?} The parsed date.
       */
      DateAdapter.prototype.parse = function (value, parseFormat) { };
      /**
       * Formats a date as a string.
       * @abstract
       * @param {?} date The value to format.
       * @param {?} displayFormat The format to use to display the date as a string.
       * @return {?} The formatted date string.
       */
      DateAdapter.prototype.format = function (date, displayFormat) { };
      /**
       * Adds the given number of years to the date. Years are counted as if flipping 12 pages on the
       * calendar for each year and then finding the closest date in the new month. For example when
       * adding 1 year to Feb 29, 2016, the resulting date will be Feb 28, 2017.
       * @abstract
       * @param {?} date The date to add years to.
       * @param {?} years The number of years to add (may be negative).
       * @return {?} A new date equal to the given one with the specified number of years added.
       */
      DateAdapter.prototype.addCalendarYears = function (date, years) { };
      /**
       * Adds the given number of months to the date. Months are counted as if flipping a page on the
       * calendar for each month and then finding the closest date in the new month. For example when
       * adding 1 month to Jan 31, 2017, the resulting date will be Feb 28, 2017.
       * @abstract
       * @param {?} date The date to add months to.
       * @param {?} months The number of months to add (may be negative).
       * @return {?} A new date equal to the given one with the specified number of months added.
       */
      DateAdapter.prototype.addCalendarMonths = function (date, months) { };
      /**
       * Adds the given number of days to the date. Days are counted as if moving one cell on the
       * calendar for each day.
       * @abstract
       * @param {?} date The date to add days to.
       * @param {?} days The number of days to add (may be negative).
       * @return {?} A new date equal to the given one with the specified number of days added.
       */
      DateAdapter.prototype.addCalendarDays = function (date, days) { };
      /**
       * Gets the RFC 3339 compatible string (https://tools.ietf.org/html/rfc3339) for the given date.
       * @abstract
       * @param {?} date The date to get the ISO date string for.
       * @return {?} The ISO date string date string.
       */
      DateAdapter.prototype.toIso8601 = function (date) { };
      /**
       * Creates a date from an RFC 3339 compatible string (https://tools.ietf.org/html/rfc3339).
       * @abstract
       * @param {?} iso8601String The ISO date string to create a date from
       * @return {?} The date created from the ISO date string.
       */
      DateAdapter.prototype.fromIso8601 = function (iso8601String) { };
      /**
       * Checks whether the given object is considered a date instance by this DateAdapter.
       * @abstract
       * @param {?} obj The object to check
       * @return {?} Whether the object is a date instance.
       */
      DateAdapter.prototype.isDateInstance = function (obj) { };
      /**
       * Checks whether the given date is valid.
       * @abstract
       * @param {?} date The date to check.
       * @return {?} Whether the date is valid.
       */
      DateAdapter.prototype.isValid = function (date) { };
      /**
       * Sets the locale used for all dates.
       * @param {?} locale The new locale.
       * @return {?}
       */
      DateAdapter.prototype.setLocale = function (locale) {
          this.locale = locale;
          this._localeChanges.next();
      };
      /**
       * Compares two dates.
       * @param {?} first The first date to compare.
       * @param {?} second The second date to compare.
       * @return {?} 0 if the dates are equal, a number less than 0 if the first date is earlier,
       *     a number greater than 0 if the first date is later.
       */
      DateAdapter.prototype.compareDate = function (first$$1, second) {
          return this.getYear(first$$1) - this.getYear(second) ||
              this.getMonth(first$$1) - this.getMonth(second) ||
              this.getDate(first$$1) - this.getDate(second);
      };
      /**
       * Checks if two dates are equal.
       * @param {?} first The first date to check.
       * @param {?} second The second date to check.
       *     Null dates are considered equal to other null dates.
       * @return {?}
       */
      DateAdapter.prototype.sameDate = function (first$$1, second) {
          return first$$1 && second ? !this.compareDate(first$$1, second) : first$$1 == second;
      };
      /**
       * Clamp the given date between min and max dates.
       * @param {?} date The date to clamp.
       * @param {?=} min The minimum value to allow. If null or omitted no min is enforced.
       * @param {?=} max The maximum value to allow. If null or omitted no max is enforced.
       * @return {?} `min` if `date` is less than `min`, `max` if date is greater than `max`,
       *     otherwise `date`.
       */
      DateAdapter.prototype.clampDate = function (date, min, max) {
          if (min && this.compareDate(date, min) < 0) {
              return min;
          }
          if (max && this.compareDate(date, max) > 0) {
              return max;
          }
          return date;
      };
      return DateAdapter;
  }());
  
  /**
   * Extends an object with the *enumerable* and *own* properties of one or more source objects,
   * similar to Object.assign.
   *
   * @param {?} dest The object which will have properties copied to it.
   * @param {...?} sources The source objects from which properties will be copied.
   * @return {?}
   */
  function extendObject(dest) {
      var sources = [];
      for (var _i = 1; _i < arguments.length; _i++) {
          sources[_i - 1] = arguments[_i];
      }
      if (dest == null) {
          throw TypeError('Cannot convert undefined or null to object');
      }
      for (var _a = 0, sources_1 = sources; _a < sources_1.length; _a++) {
          var source = sources_1[_a];
          if (source != null) {
              for (var /** @type {?} */ key in source) {
                  if (source.hasOwnProperty(key)) {
                      dest[key] = source[key];
                  }
              }
          }
      }
      return dest;
  }
  
  /**
   * Whether the browser supports the Intl API.
   */
  var SUPPORTS_INTL_API = typeof Intl != 'undefined';
  /**
   * The default month names to use if Intl API is not available.
   */
  var DEFAULT_MONTH_NAMES = {
      'long': [
          'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September',
          'October', 'November', 'December'
      ],
      'short': ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
      'narrow': ['J', 'F', 'M', 'A', 'M', 'J', 'J', 'A', 'S', 'O', 'N', 'D']
  };
  /**
   * The default date names to use if Intl API is not available.
   */
  var DEFAULT_DATE_NAMES = range(31, function (i) { return String(i + 1); });
  /**
   * The default day of the week names to use if Intl API is not available.
   */
  var DEFAULT_DAY_OF_WEEK_NAMES = {
      'long': ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
      'short': ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
      'narrow': ['S', 'M', 'T', 'W', 'T', 'F', 'S']
  };
  /**
   * Matches strings that have the form of a valid RFC 3339 string
   * (https://tools.ietf.org/html/rfc3339). Note that the string may not actually be a valid date
   * because the regex will match strings an with out of bounds month, date, etc.
   */
  var ISO_8601_REGEX = /^\d{4}-\d{2}-\d{2}(?:T\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|(?:(?:\+|-)\d{2}:\d{2}))?)?$/;
  /**
   * Creates an array and fills it with values.
   * @template T
   * @param {?} length
   * @param {?} valueFunction
   * @return {?}
   */
  function range(length, valueFunction) {
      var /** @type {?} */ valuesArray = Array(length);
      for (var /** @type {?} */ i = 0; i < length; i++) {
          valuesArray[i] = valueFunction(i);
      }
      return valuesArray;
  }
  /**
   * Adapts the native JS Date for use with cdk-based components that work with dates.
   */
  var NativeDateAdapter = (function (_super) {
      __extends(NativeDateAdapter, _super);
      /**
       * @param {?} matDateLocale
       */
      function NativeDateAdapter(matDateLocale) {
          var _this = _super.call(this) || this;
          /**
           * Whether to use `timeZone: 'utc'` with `Intl.DateTimeFormat` when formatting dates.
           * Without this `Intl.DateTimeFormat` sometimes chooses the wrong timeZone, which can throw off
           * the result. (e.g. in the en-US locale `new Date(1800, 7, 14).toLocaleDateString()`
           * will produce `'8/13/1800'`.
           */
          _this.useUtcForDisplay = true;
          _super.prototype.setLocale.call(_this, matDateLocale);
          return _this;
      }
      /**
       * @param {?} date
       * @return {?}
       */
      NativeDateAdapter.prototype.getYear = function (date) {
          return date.getFullYear();
      };
      /**
       * @param {?} date
       * @return {?}
       */
      NativeDateAdapter.prototype.getMonth = function (date) {
          return date.getMonth();
      };
      /**
       * @param {?} date
       * @return {?}
       */
      NativeDateAdapter.prototype.getDate = function (date) {
          return date.getDate();
      };
      /**
       * @param {?} date
       * @return {?}
       */
      NativeDateAdapter.prototype.getDayOfWeek = function (date) {
          return date.getDay();
      };
      /**
       * @param {?} style
       * @return {?}
       */
      NativeDateAdapter.prototype.getMonthNames = function (style$$1) {
          var _this = this;
          if (SUPPORTS_INTL_API) {
              var /** @type {?} */ dtf_1 = new Intl.DateTimeFormat(this.locale, { month: style$$1 });
              return range(12, function (i) { return _this._stripDirectionalityCharacters(dtf_1.format(new Date(2017, i, 1))); });
          }
          return DEFAULT_MONTH_NAMES[style$$1];
      };
      /**
       * @return {?}
       */
      NativeDateAdapter.prototype.getDateNames = function () {
          var _this = this;
          if (SUPPORTS_INTL_API) {
              var /** @type {?} */ dtf_2 = new Intl.DateTimeFormat(this.locale, { day: 'numeric' });
              return range(31, function (i) { return _this._stripDirectionalityCharacters(dtf_2.format(new Date(2017, 0, i + 1))); });
          }
          return DEFAULT_DATE_NAMES;
      };
      /**
       * @param {?} style
       * @return {?}
       */
      NativeDateAdapter.prototype.getDayOfWeekNames = function (style$$1) {
          var _this = this;
          if (SUPPORTS_INTL_API) {
              var /** @type {?} */ dtf_3 = new Intl.DateTimeFormat(this.locale, { weekday: style$$1 });
              return range(7, function (i) { return _this._stripDirectionalityCharacters(dtf_3.format(new Date(2017, 0, i + 1))); });
          }
          return DEFAULT_DAY_OF_WEEK_NAMES[style$$1];
      };
      /**
       * @param {?} date
       * @return {?}
       */
      NativeDateAdapter.prototype.getYearName = function (date) {
          if (SUPPORTS_INTL_API) {
              var /** @type {?} */ dtf = new Intl.DateTimeFormat(this.locale, { year: 'numeric' });
              return this._stripDirectionalityCharacters(dtf.format(date));
          }
          return String(this.getYear(date));
      };
      /**
       * @return {?}
       */
      NativeDateAdapter.prototype.getFirstDayOfWeek = function () {
          // We can't tell using native JS Date what the first day of the week is, we default to Sunday.
          return 0;
      };
      /**
       * @param {?} date
       * @return {?}
       */
      NativeDateAdapter.prototype.getNumDaysInMonth = function (date) {
          return this.getDate(this._createDateWithOverflow(this.getYear(date), this.getMonth(date) + 1, 0));
      };
      /**
       * @param {?} date
       * @return {?}
       */
      NativeDateAdapter.prototype.clone = function (date) {
          return this.createDate(this.getYear(date), this.getMonth(date), this.getDate(date));
      };
      /**
       * @param {?} year
       * @param {?} month
       * @param {?} date
       * @return {?}
       */
      NativeDateAdapter.prototype.createDate = function (year, month, date) {
          // Check for invalid month and date (except upper bound on date which we have to check after
          // creating the Date).
          if (month < 0 || month > 11) {
              throw Error("Invalid month index \"" + month + "\". Month index has to be between 0 and 11.");
          }
          if (date < 1) {
              throw Error("Invalid date \"" + date + "\". Date has to be greater than 0.");
          }
          var /** @type {?} */ result = this._createDateWithOverflow(year, month, date);
          // Check that the date wasn't above the upper bound for the month, causing the month to overflow
          if (result.getMonth() != month) {
              throw Error("Invalid date \"" + date + "\" for month with index \"" + month + "\".");
          }
          return result;
      };
      /**
       * @return {?}
       */
      NativeDateAdapter.prototype.today = function () {
          return new Date();
      };
      /**
       * @param {?} value
       * @return {?}
       */
      NativeDateAdapter.prototype.parse = function (value) {
          // We have no way using the native JS Date to set the parse format or locale, so we ignore these
          // parameters.
          if (typeof value == 'number') {
              return new Date(value);
          }
          return value ? new Date(Date.parse(value)) : null;
      };
      /**
       * @param {?} date
       * @param {?} displayFormat
       * @return {?}
       */
      NativeDateAdapter.prototype.format = function (date, displayFormat) {
          if (!this.isValid(date)) {
              throw Error('NativeDateAdapter: Cannot format invalid date.');
          }
          if (SUPPORTS_INTL_API) {
              if (this.useUtcForDisplay) {
                  date = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds(), date.getMilliseconds()));
                  displayFormat = extendObject({}, displayFormat, { timeZone: 'utc' });
              }
              var /** @type {?} */ dtf = new Intl.DateTimeFormat(this.locale, displayFormat);
              return this._stripDirectionalityCharacters(dtf.format(date));
          }
          return this._stripDirectionalityCharacters(date.toDateString());
      };
      /**
       * @param {?} date
       * @param {?} years
       * @return {?}
       */
      NativeDateAdapter.prototype.addCalendarYears = function (date, years) {
          return this.addCalendarMonths(date, years * 12);
      };
      /**
       * @param {?} date
       * @param {?} months
       * @return {?}
       */
      NativeDateAdapter.prototype.addCalendarMonths = function (date, months) {
          var /** @type {?} */ newDate = this._createDateWithOverflow(this.getYear(date), this.getMonth(date) + months, this.getDate(date));
          // It's possible to wind up in the wrong month if the original month has more days than the new
          // month. In this case we want to go to the last day of the desired month.
          // Note: the additional + 12 % 12 ensures we end up with a positive number, since JS % doesn't
          // guarantee this.
          if (this.getMonth(newDate) != ((this.getMonth(date) + months) % 12 + 12) % 12) {
              newDate = this._createDateWithOverflow(this.getYear(newDate), this.getMonth(newDate), 0);
          }
          return newDate;
      };
      /**
       * @param {?} date
       * @param {?} days
       * @return {?}
       */
      NativeDateAdapter.prototype.addCalendarDays = function (date, days) {
          return this._createDateWithOverflow(this.getYear(date), this.getMonth(date), this.getDate(date) + days);
      };
      /**
       * @param {?} date
       * @return {?}
       */
      NativeDateAdapter.prototype.toIso8601 = function (date) {
          return [
              date.getUTCFullYear(),
              this._2digit(date.getUTCMonth() + 1),
              this._2digit(date.getUTCDate())
          ].join('-');
      };
      /**
       * @param {?} iso8601String
       * @return {?}
       */
      NativeDateAdapter.prototype.fromIso8601 = function (iso8601String) {
          // The `Date` constructor accepts formats other than ISO 8601, so we need to make sure the
          // string is the right format first.
          if (ISO_8601_REGEX.test(iso8601String)) {
              var /** @type {?} */ d = new Date(iso8601String);
              if (this.isValid(d)) {
                  return d;
              }
          }
          return null;
      };
      /**
       * @param {?} obj
       * @return {?}
       */
      NativeDateAdapter.prototype.isDateInstance = function (obj) {
          return obj instanceof Date;
      };
      /**
       * @param {?} date
       * @return {?}
       */
      NativeDateAdapter.prototype.isValid = function (date) {
          return !isNaN(date.getTime());
      };
      /**
       * Creates a date but allows the month and date to overflow.
       * @param {?} year
       * @param {?} month
       * @param {?} date
       * @return {?}
       */
      NativeDateAdapter.prototype._createDateWithOverflow = function (year, month, date) {
          var /** @type {?} */ result = new Date(year, month, date);
          // We need to correct for the fact that JS native Date treats years in range [0, 99] as
          // abbreviations for 19xx.
          if (year >= 0 && year < 100) {
              result.setFullYear(this.getYear(result) - 1900);
          }
          return result;
      };
      /**
       * Pads a number to make it two digits.
       * @param {?} n The number to pad.
       * @return {?} The padded number.
       */
      NativeDateAdapter.prototype._2digit = function (n) {
          return ('00' + n).slice(-2);
      };
      /**
       * Strip out unicode LTR and RTL characters. Edge and IE insert these into formatted dates while
       * other browsers do not. We remove them to make output consistent and because they interfere with
       * date parsing.
       * @param {?} str The string to strip direction characters from.
       * @return {?} The stripped string.
       */
      NativeDateAdapter.prototype._stripDirectionalityCharacters = function (str) {
          return str.replace(/[\u200e\u200f]/g, '');
      };
      NativeDateAdapter.decorators = [
          { type: _angular_core.Injectable },
      ];
      /**
       * @nocollapse
       */
      NativeDateAdapter.ctorParameters = function () { return [
          { type: undefined, decorators: [{ type: _angular_core.Optional }, { type: _angular_core.Inject, args: [MAT_DATE_LOCALE,] },] },
      ]; };
      return NativeDateAdapter;
  }(DateAdapter));
  
  var MAT_DATE_FORMATS = new _angular_core.InjectionToken('mat-date-formats');
  
  var GestureConfig = (function (_super) {
      __extends(GestureConfig, _super);
      function GestureConfig() {
          var _this = _super.call(this) || this;
          _this._hammer = typeof window !== 'undefined' ? ((window)).Hammer : null;
          /* List of new event names to add to the gesture support list */
          _this.events = _this._hammer ? [
              'longpress',
              'slide',
              'slidestart',
              'slideend',
              'slideright',
              'slideleft'
          ] : [];
          if (!_this._hammer && _angular_core.isDevMode()) {
              console.warn('Could not find HammerJS. Certain Angular Material ' +
                  'components may not work correctly.');
          }
          return _this;
      }
      /**
       * Builds Hammer instance manually to add custom recognizers that match the Material Design spec.
       *
       * Our gesture names come from the Material Design gestures spec:
       * https://www.google.com/design/spec/patterns/gestures.html#gestures-touch-mechanics
       *
       * More information on default recognizers can be found in Hammer docs:
       * http://hammerjs.github.io/recognizer-pan/
       * http://hammerjs.github.io/recognizer-press/
       *
       * @param {?} element Element to which to assign the new HammerJS gestures.
       * @return {?} Newly-created HammerJS instance.
       */
      GestureConfig.prototype.buildHammer = function (element) {
          var /** @type {?} */ mc = new this._hammer(element);
          // Default Hammer Recognizers.
          var /** @type {?} */ pan = new this._hammer.Pan();
          var /** @type {?} */ swipe = new this._hammer.Swipe();
          var /** @type {?} */ press = new this._hammer.Press();
          // Notice that a HammerJS recognizer can only depend on one other recognizer once.
          // Otherwise the previous `recognizeWith` will be dropped.
          // TODO: Confirm threshold numbers with Material Design UX Team
          var /** @type {?} */ slide = this._createRecognizer(pan, { event: 'slide', threshold: 0 }, swipe);
          var /** @type {?} */ longpress = this._createRecognizer(press, { event: 'longpress', time: 500 });
          // Overwrite the default `pan` event to use the swipe event.
          pan.recognizeWith(swipe);
          // Add customized gestures to Hammer manager
          mc.add([swipe, press, pan, slide, longpress]);
          return (mc);
      };
      /**
       * Creates a new recognizer, without affecting the default recognizers of HammerJS
       * @param {?} base
       * @param {?} options
       * @param {...?} inheritances
       * @return {?}
       */
      GestureConfig.prototype._createRecognizer = function (base, options) {
          var inheritances = [];
          for (var _i = 2; _i < arguments.length; _i++) {
              inheritances[_i - 2] = arguments[_i];
          }
          var /** @type {?} */ recognizer = new ((base.constructor))(options);
          inheritances.push(base);
          inheritances.forEach(function (item) { return recognizer.recognizeWith(item); });
          return recognizer;
      };
      GestureConfig.decorators = [
          { type: _angular_core.Injectable },
      ];
      /**
       * @nocollapse
       */
      GestureConfig.ctorParameters = function () { return []; };
      return GestureConfig;
  }(_angular_platformBrowser.HammerGestureConfig));
  
  var RippleState = {};
  RippleState.FADING_IN = 0;
  RippleState.VISIBLE = 1;
  RippleState.FADING_OUT = 2;
  RippleState.HIDDEN = 3;
  RippleState[RippleState.FADING_IN] = "FADING_IN";
  RippleState[RippleState.VISIBLE] = "VISIBLE";
  RippleState[RippleState.FADING_OUT] = "FADING_OUT";
  RippleState[RippleState.HIDDEN] = "HIDDEN";
  /**
   * Reference to a previously launched ripple element.
   */
  var RippleRef = (function () {
      /**
       * @param {?} _renderer
       * @param {?} element
       * @param {?} config
       */
      function RippleRef(_renderer, element, config) {
          this._renderer = _renderer;
          this.element = element;
          this.config = config;
          /**
           * Current state of the ripple reference.
           */
          this.state = RippleState.HIDDEN;
      }
      /**
       * Fades out the ripple element.
       * @return {?}
       */
      RippleRef.prototype.fadeOut = function () {
          this._renderer.fadeOutRipple(this);
      };
      return RippleRef;
  }());
  
  /**
   * Fade-in duration for the ripples. Can be modified with the speedFactor option.
   */
  var RIPPLE_FADE_IN_DURATION = 450;
  /**
   * Fade-out duration for the ripples in milliseconds. This can't be modified by the speedFactor.
   */
  var RIPPLE_FADE_OUT_DURATION = 400;
  /**
   * Helper service that performs DOM manipulations. Not intended to be used outside this module.
   * The constructor takes a reference to the ripple directive's host element and a map of DOM
   * event handlers to be installed on the element that triggers ripple animations.
   * This will eventually become a custom renderer once Angular support exists.
   * \@docs-private
   */
  var RippleRenderer = (function () {
      /**
       * @param {?} elementRef
       * @param {?} _ngZone
       * @param {?} platform
       */
      function RippleRenderer(elementRef, _ngZone, platform) {
          this._ngZone = _ngZone;
          /**
           * Whether the mouse is currently down or not.
           */
          this._isMousedown = false;
          /**
           * Events to be registered on the trigger element.
           */
          this._triggerEvents = new Map();
          /**
           * Set of currently active ripple references.
           */
          this._activeRipples = new Set();
          /**
           * Ripple config for all ripples created by events.
           */
          this.rippleConfig = {};
          /**
           * Whether mouse ripples should be created or not.
           */
          this.rippleDisabled = false;
          // Only do anything if we're on the browser.
          if (platform.isBrowser) {
              this._containerElement = elementRef.nativeElement;
              // Specify events which need to be registered on the trigger.
              this._triggerEvents.set('mousedown', this.onMousedown.bind(this));
              this._triggerEvents.set('mouseup', this.onMouseup.bind(this));
              this._triggerEvents.set('mouseleave', this.onMouseup.bind(this));
              // By default use the host element as trigger element.
              this.setTriggerElement(this._containerElement);
          }
      }
      /**
       * Fades in a ripple at the given coordinates.
       * @param {?} x Coordinate within the element, along the X axis at which to start the ripple.
       * @param {?} y Coordinate within the element, along the Y axis at which to start the ripple.
       * @param {?=} config Extra ripple options.
       * @return {?}
       */
      RippleRenderer.prototype.fadeInRipple = function (x, y, config) {
          var _this = this;
          if (config === void 0) { config = {}; }
          var /** @type {?} */ containerRect = this._containerElement.getBoundingClientRect();
          if (config.centered) {
              x = containerRect.left + containerRect.width / 2;
              y = containerRect.top + containerRect.height / 2;
          }
          var /** @type {?} */ radius = config.radius || distanceToFurthestCorner(x, y, containerRect);
          var /** @type {?} */ duration = RIPPLE_FADE_IN_DURATION * (1 / (config.speedFactor || 1));
          var /** @type {?} */ offsetX = x - containerRect.left;
          var /** @type {?} */ offsetY = y - containerRect.top;
          var /** @type {?} */ ripple = document.createElement('div');
          ripple.classList.add('mat-ripple-element');
          ripple.style.left = offsetX - radius + "px";
          ripple.style.top = offsetY - radius + "px";
          ripple.style.height = radius * 2 + "px";
          ripple.style.width = radius * 2 + "px";
          // If the color is not set, the default CSS color will be used.
          ripple.style.backgroundColor = config.color || null;
          ripple.style.transitionDuration = duration + "ms";
          this._containerElement.appendChild(ripple);
          // By default the browser does not recalculate the styles of dynamically created
          // ripple elements. This is critical because then the `scale` would not animate properly.
          enforceStyleRecalculation(ripple);
          ripple.style.transform = 'scale(1)';
          // Exposed reference to the ripple that will be returned.
          var /** @type {?} */ rippleRef = new RippleRef(this, ripple, config);
          rippleRef.state = RippleState.FADING_IN;
          // Add the ripple reference to the list of all active ripples.
          this._activeRipples.add(rippleRef);
          // Wait for the ripple element to be completely faded in.
          // Once it's faded in, the ripple can be hidden immediately if the mouse is released.
          this.runTimeoutOutsideZone(function () {
              rippleRef.state = RippleState.VISIBLE;
              if (!config.persistent && !_this._isMousedown) {
                  rippleRef.fadeOut();
              }
          }, duration);
          return rippleRef;
      };
      /**
       * Fades out a ripple reference.
       * @param {?} rippleRef
       * @return {?}
       */
      RippleRenderer.prototype.fadeOutRipple = function (rippleRef) {
          // For ripples that are not active anymore, don't re-un the fade-out animation.
          if (!this._activeRipples.delete(rippleRef)) {
              return;
          }
          var /** @type {?} */ rippleEl = rippleRef.element;
          rippleEl.style.transitionDuration = RIPPLE_FADE_OUT_DURATION + "ms";
          rippleEl.style.opacity = '0';
          rippleRef.state = RippleState.FADING_OUT;
          // Once the ripple faded out, the ripple can be safely removed from the DOM.
          this.runTimeoutOutsideZone(function () {
              rippleRef.state = RippleState.HIDDEN; /** @type {?} */
              ((rippleEl.parentNode)).removeChild(rippleEl);
          }, RIPPLE_FADE_OUT_DURATION);
      };
      /**
       * Fades out all currently active ripples.
       * @return {?}
       */
      RippleRenderer.prototype.fadeOutAll = function () {
          this._activeRipples.forEach(function (ripple) { return ripple.fadeOut(); });
      };
      /**
       * Sets the trigger element and registers the mouse events.
       * @param {?} element
       * @return {?}
       */
      RippleRenderer.prototype.setTriggerElement = function (element) {
          var _this = this;
          // Remove all previously register event listeners from the trigger element.
          if (this._triggerElement) {
              this._triggerEvents.forEach(function (fn, type) {
                  ((_this._triggerElement)).removeEventListener(type, fn);
              });
          }
          if (element) {
              // If the element is not null, register all event listeners on the trigger element.
              this._ngZone.runOutsideAngular(function () {
                  _this._triggerEvents.forEach(function (fn, type) { return element.addEventListener(type, fn); });
              });
          }
          this._triggerElement = element;
      };
      /**
       * Function being called whenever the trigger is being pressed.
       * @param {?} event
       * @return {?}
       */
      RippleRenderer.prototype.onMousedown = function (event) {
          if (!this.rippleDisabled) {
              this._isMousedown = true;
              this.fadeInRipple(event.clientX, event.clientY, this.rippleConfig);
          }
      };
      /**
       * Function being called whenever the trigger is being released.
       * @return {?}
       */
      RippleRenderer.prototype.onMouseup = function () {
          if (!this._isMousedown) {
              return;
          }
          this._isMousedown = false;
          // Fade-out all ripples that are completely visible and not persistent.
          this._activeRipples.forEach(function (ripple) {
              if (!ripple.config.persistent && ripple.state === RippleState.VISIBLE) {
                  ripple.fadeOut();
              }
          });
      };
      /**
       * Runs a timeout outside of the Angular zone to avoid triggering the change detection.
       * @param {?} fn
       * @param {?=} delay
       * @return {?}
       */
      RippleRenderer.prototype.runTimeoutOutsideZone = function (fn, delay) {
          if (delay === void 0) { delay = 0; }
          this._ngZone.runOutsideAngular(function () { return setTimeout(fn, delay); });
      };
      return RippleRenderer;
  }());
  /**
   * @param {?} element
   * @return {?}
   */
  function enforceStyleRecalculation(element) {
      // Enforce a style recalculation by calling `getComputedStyle` and accessing any property.
      // Calling `getPropertyValue` is important to let optimizers know that this is not a noop.
      // See: https://gist.github.com/paulirish/5d52fb081b3570c81e3a
      window.getComputedStyle(element).getPropertyValue('opacity');
  }
  /**
   * Returns the distance from the point (x, y) to the furthest corner of a rectangle.
   * @param {?} x
   * @param {?} y
   * @param {?} rect
   * @return {?}
   */
  function distanceToFurthestCorner(x, y, rect) {
      var /** @type {?} */ distX = Math.max(Math.abs(x - rect.left), Math.abs(x - rect.right));
      var /** @type {?} */ distY = Math.max(Math.abs(y - rect.top), Math.abs(y - rect.bottom));
      return Math.sqrt(distX * distX + distY * distY);
  }
  
  /**
   * Injection token that can be used to specify the global ripple options.
   */
  var MAT_RIPPLE_GLOBAL_OPTIONS = new _angular_core.InjectionToken('mat-ripple-global-options');
  var MatRipple = (function () {
      /**
       * @param {?} elementRef
       * @param {?} ngZone
       * @param {?} platform
       * @param {?} globalOptions
       */
      function MatRipple(elementRef, ngZone, platform, globalOptions) {
          /**
           * If set, the radius in pixels of foreground ripples when fully expanded. If unset, the radius
           * will be the distance from the center of the ripple to the furthest corner of the host element's
           * bounding rectangle.
           */
          this.radius = 0;
          /**
           * If set, the normal duration of ripple animations is divided by this value. For example,
           * setting it to 0.5 will cause the animations to take twice as long.
           * A changed speedFactor will not modify the fade-out duration of the ripples.
           */
          this.speedFactor = 1;
          this._rippleRenderer = new RippleRenderer(elementRef, ngZone, platform);
          this._globalOptions = globalOptions ? globalOptions : {};
          this._updateRippleRenderer();
      }
      /**
       * @param {?} changes
       * @return {?}
       */
      MatRipple.prototype.ngOnChanges = function (changes) {
          if ((changes['trigger'] || changes['_matRippleTrigger']) && this.trigger) {
              this._rippleRenderer.setTriggerElement(this.trigger);
          }
          this._updateRippleRenderer();
      };
      /**
       * @return {?}
       */
      MatRipple.prototype.ngOnDestroy = function () {
          // Set the trigger element to null to cleanup all listeners.
          this._rippleRenderer.setTriggerElement(null);
      };
      /**
       * Launches a manual ripple at the specified position.
       * @param {?} x
       * @param {?} y
       * @param {?=} config
       * @return {?}
       */
      MatRipple.prototype.launch = function (x, y, config) {
          if (config === void 0) { config = this.rippleConfig; }
          return this._rippleRenderer.fadeInRipple(x, y, config);
      };
      /**
       * Fades out all currently showing ripple elements.
       * @return {?}
       */
      MatRipple.prototype.fadeOutAll = function () {
          this._rippleRenderer.fadeOutAll();
      };
      Object.defineProperty(MatRipple.prototype, "rippleConfig", {
          /**
           * Ripple configuration from the directive's input values.
           * @return {?}
           */
          get: function () {
              return {
                  centered: this.centered,
                  speedFactor: this.speedFactor * (this._globalOptions.baseSpeedFactor || 1),
                  radius: this.radius,
                  color: this.color
              };
          },
          enumerable: true,
          configurable: true
      });
      /**
       * Updates the ripple renderer with the latest ripple configuration.
       * @return {?}
       */
      MatRipple.prototype._updateRippleRenderer = function () {
          this._rippleRenderer.rippleDisabled = this._globalOptions.disabled || this.disabled;
          this._rippleRenderer.rippleConfig = this.rippleConfig;
      };
      MatRipple.decorators = [
          { type: _angular_core.Directive, args: [{
                      selector: '[mat-ripple], [matRipple]',
                      exportAs: 'matRipple',
                      host: {
                          'class': 'mat-ripple',
                          '[class.mat-ripple-unbounded]': 'unbounded'
                      }
                  },] },
      ];
      /**
       * @nocollapse
       */
      MatRipple.ctorParameters = function () { return [
          { type: _angular_core.ElementRef, },
          { type: _angular_core.NgZone, },
          { type: _angular_cdk_platform.Platform, },
          { type: undefined, decorators: [{ type: _angular_core.Optional }, { type: _angular_core.Inject, args: [MAT_RIPPLE_GLOBAL_OPTIONS,] },] },
      ]; };
      MatRipple.propDecorators = {
          'trigger': [{ type: _angular_core.Input, args: ['matRippleTrigger',] },],
          'centered': [{ type: _angular_core.Input, args: ['matRippleCentered',] },],
          'disabled': [{ type: _angular_core.Input, args: ['matRippleDisabled',] },],
          'radius': [{ type: _angular_core.Input, args: ['matRippleRadius',] },],
          'speedFactor': [{ type: _angular_core.Input, args: ['matRippleSpeedFactor',] },],
          'color': [{ type: _angular_core.Input, args: ['matRippleColor',] },],
          'unbounded': [{ type: _angular_core.Input, args: ['matRippleUnbounded',] },],
      };
      return MatRipple;
  }());
  
  var MatRippleModule = (function () {
      function MatRippleModule() {
      }
      MatRippleModule.decorators = [
          { type: _angular_core.NgModule, args: [{
                      imports: [MatCommonModule, _angular_cdk_platform.PlatformModule],
                      exports: [MatRipple, MatCommonModule],
                      declarations: [MatRipple],
                  },] },
      ];
      /**
       * @nocollapse
       */
      MatRippleModule.ctorParameters = function () { return []; };
      return MatRippleModule;
  }());
  
  /**
   * \@docs-private
   */
  var MatOptgroupBase = (function () {
      function MatOptgroupBase() {
      }
      return MatOptgroupBase;
  }());
  var _MatOptgroupMixinBase = mixinDisabled(MatOptgroupBase);
  // Counter for unique group ids.
  var _uniqueOptgroupIdCounter = 0;
  /**
   * Component that is used to group instances of `mat-option`.
   */
  var MatOptgroup = (function (_super) {
      __extends(MatOptgroup, _super);
      function MatOptgroup() {
          var _this = _super !== null && _super.apply(this, arguments) || this;
          /**
           * Unique id for the underlying label.
           */
          _this._labelId = "mat-optgroup-label-" + _uniqueOptgroupIdCounter++;
          return _this;
      }
      MatOptgroup.decorators = [
          { type: _angular_core.Component, args: [{selector: 'mat-optgroup',
                      exportAs: 'matOptgroup',
                      template: "<label class=\"mat-optgroup-label\" [id]=\"_labelId\">{{ label }}</label><ng-content select=\"mat-option\"></ng-content>",
                      encapsulation: _angular_core.ViewEncapsulation.None,
                      preserveWhitespaces: false,
                      changeDetection: _angular_core.ChangeDetectionStrategy.OnPush,
                      inputs: ['disabled'],
                      host: {
                          'class': 'mat-optgroup',
                          'role': 'group',
                          '[class.mat-optgroup-disabled]': 'disabled',
                          '[attr.aria-disabled]': 'disabled.toString()',
                          '[attr.aria-labelledby]': '_labelId',
                      }
                  },] },
      ];
      /**
       * @nocollapse
       */
      MatOptgroup.ctorParameters = function () { return []; };
      MatOptgroup.propDecorators = {
          'label': [{ type: _angular_core.Input },],
      };
      return MatOptgroup;
  }(_MatOptgroupMixinBase));
  
  /**
   * Option IDs need to be unique across components, so this counter exists outside of
   * the component definition.
   */
  var _uniqueIdCounter = 0;
  /**
   * Event object emitted by MatOption when selected or deselected.
   */
  var MatOptionSelectionChange = (function () {
      /**
       * @param {?} source
       * @param {?=} isUserInput
       */
      function MatOptionSelectionChange(source, isUserInput) {
          if (isUserInput === void 0) { isUserInput = false; }
          this.source = source;
          this.isUserInput = isUserInput;
      }
      return MatOptionSelectionChange;
  }());
  /**
   * Single option inside of a `<mat-select>` element.
   */
  var MatOption = (function () {
      /**
       * @param {?} _element
       * @param {?} _changeDetectorRef
       * @param {?} group
       */
      function MatOption(_element, _changeDetectorRef, group) {
          this._element = _element;
          this._changeDetectorRef = _changeDetectorRef;
          this.group = group;
          this._selected = false;
          this._active = false;
          this._multiple = false;
          this._disableRipple = false;
          /**
           * Whether the option is disabled.
           */
          this._disabled = false;
          this._id = "mat-option-" + _uniqueIdCounter++;
          /**
           * Event emitted when the option is selected or deselected.
           */
          this.onSelectionChange = new _angular_core.EventEmitter();
      }
      Object.defineProperty(MatOption.prototype, "multiple", {
          /**
           * Whether the wrapping component is in multiple selection mode.
           * @return {?}
           */
          get: function () { return this._multiple; },
          /**
           * @param {?} value
           * @return {?}
           */
          set: function (value) {
              if (value !== this._multiple) {
                  this._multiple = value;
                  this._changeDetectorRef.markForCheck();
              }
          },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(MatOption.prototype, "id", {
          /**
           * The unique ID of the option.
           * @return {?}
           */
          get: function () { return this._id; },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(MatOption.prototype, "selected", {
          /**
           * Whether or not the option is currently selected.
           * @return {?}
           */
          get: function () { return this._selected; },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(MatOption.prototype, "disabled", {
          /**
           * Whether the option is disabled.
           * @return {?}
           */
          get: function () { return (this.group && this.group.disabled) || this._disabled; },
          /**
           * @param {?} value
           * @return {?}
           */
          set: function (value) { this._disabled = _angular_cdk_coercion.coerceBooleanProperty(value); },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(MatOption.prototype, "disableRipple", {
          /**
           * Whether ripples for the option are disabled.
           * @return {?}
           */
          get: function () { return this._disableRipple; },
          /**
           * @param {?} value
           * @return {?}
           */
          set: function (value) {
              this._disableRipple = value;
              this._changeDetectorRef.markForCheck();
          },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(MatOption.prototype, "active", {
          /**
           * Whether or not the option is currently active and ready to be selected.
           * An active option displays styles as if it is focused, but the
           * focus is actually retained somewhere else. This comes in handy
           * for components like autocomplete where focus must remain on the input.
           * @return {?}
           */
          get: function () {
              return this._active;
          },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(MatOption.prototype, "viewValue", {
          /**
           * The displayed value of the option. It is necessary to show the selected option in the
           * select's trigger.
           * @return {?}
           */
          get: function () {
              // TODO(kara): Add input property alternative for node envs.
              return (this._getHostElement().textContent || '').trim();
          },
          enumerable: true,
          configurable: true
      });
      /**
       * Selects the option.
       * @return {?}
       */
      MatOption.prototype.select = function () {
          this._selected = true;
          this._changeDetectorRef.markForCheck();
          this._emitSelectionChangeEvent();
      };
      /**
       * Deselects the option.
       * @return {?}
       */
      MatOption.prototype.deselect = function () {
          this._selected = false;
          this._changeDetectorRef.markForCheck();
          this._emitSelectionChangeEvent();
      };
      /**
       * Sets focus onto this option.
       * @return {?}
       */
      MatOption.prototype.focus = function () {
          var /** @type {?} */ element = this._getHostElement();
          if (typeof element.focus === 'function') {
              element.focus();
          }
      };
      /**
       * This method sets display styles on the option to make it appear
       * active. This is used by the ActiveDescendantKeyManager so key
       * events will display the proper options as active on arrow key events.
       * @return {?}
       */
      MatOption.prototype.setActiveStyles = function () {
          if (!this._active) {
              this._active = true;
              this._changeDetectorRef.markForCheck();
          }
      };
      /**
       * This method removes display styles on the option that made it appear
       * active. This is used by the ActiveDescendantKeyManager so key
       * events will display the proper options as active on arrow key events.
       * @return {?}
       */
      MatOption.prototype.setInactiveStyles = function () {
          if (this._active) {
              this._active = false;
              this._changeDetectorRef.markForCheck();
          }
      };
      /**
       * Gets the label to be used when determining whether the option should be focused.
       * @return {?}
       */
      MatOption.prototype.getLabel = function () {
          return this.viewValue;
      };
      /**
       * Ensures the option is selected when activated from the keyboard.
       * @param {?} event
       * @return {?}
       */
      MatOption.prototype._handleKeydown = function (event) {
          if (event.keyCode === _angular_cdk_keycodes.ENTER || event.keyCode === _angular_cdk_keycodes.SPACE) {
              this._selectViaInteraction();
              // Prevent the page from scrolling down and form submits.
              event.preventDefault();
          }
      };
      /**
       * Selects the option while indicating the selection came from the user. Used to
       * determine if the select's view -> model callback should be invoked.
       * @return {?}
       */
      MatOption.prototype._selectViaInteraction = function () {
          if (!this.disabled) {
              this._selected = this.multiple ? !this._selected : true;
              this._changeDetectorRef.markForCheck();
              this._emitSelectionChangeEvent(true);
          }
      };
      /**
       * Returns the correct tabindex for the option depending on disabled state.
       * @return {?}
       */
      MatOption.prototype._getTabIndex = function () {
          return this.disabled ? '-1' : '0';
      };
      /**
       * Gets the host DOM element.
       * @return {?}
       */
      MatOption.prototype._getHostElement = function () {
          return this._element.nativeElement;
      };
      /**
       * Emits the selection change event.
       * @param {?=} isUserInput
       * @return {?}
       */
      MatOption.prototype._emitSelectionChangeEvent = function (isUserInput) {
          if (isUserInput === void 0) { isUserInput = false; }
          this.onSelectionChange.emit(new MatOptionSelectionChange(this, isUserInput));
      };
      /**
       * Counts the amount of option group labels that precede the specified option.
       * @param {?} optionIndex Index of the option at which to start counting.
       * @param {?} options Flat list of all of the options.
       * @param {?} optionGroups Flat list of all of the option groups.
       * @return {?}
       */
      MatOption.countGroupLabelsBeforeOption = function (optionIndex, options, optionGroups) {
          if (optionGroups.length) {
              var /** @type {?} */ optionsArray = options.toArray();
              var /** @type {?} */ groups = optionGroups.toArray();
              var /** @type {?} */ groupCounter = 0;
              for (var /** @type {?} */ i = 0; i < optionIndex + 1; i++) {
                  if (optionsArray[i].group && optionsArray[i].group === groups[groupCounter]) {
                      groupCounter++;
                  }
              }
              return groupCounter;
          }
          return 0;
      };
      MatOption.decorators = [
          { type: _angular_core.Component, args: [{selector: 'mat-option',
                      exportAs: 'matOption',
                      host: {
                          'role': 'option',
                          '[attr.tabindex]': '_getTabIndex()',
                          '[class.mat-selected]': 'selected',
                          '[class.mat-option-multiple]': 'multiple',
                          '[class.mat-active]': 'active',
                          '[id]': 'id',
                          '[attr.aria-selected]': 'selected.toString()',
                          '[attr.aria-disabled]': 'disabled.toString()',
                          '[class.mat-option-disabled]': 'disabled',
                          '(click)': '_selectViaInteraction()',
                          '(keydown)': '_handleKeydown($event)',
                          'class': 'mat-option',
                      },
                      template: "<span *ngIf=\"multiple\"><mat-pseudo-checkbox class=\"mat-option-pseudo-checkbox\" [state]=\"selected ? 'checked' : ''\" [disabled]=\"disabled\"></mat-pseudo-checkbox></span><span class=\"mat-option-text\"><ng-content></ng-content></span><div class=\"mat-option-ripple\" mat-ripple [matRippleTrigger]=\"_getHostElement()\" [matRippleDisabled]=\"disabled || disableRipple\"></div>",
                      encapsulation: _angular_core.ViewEncapsulation.None,
                      preserveWhitespaces: false,
                      changeDetection: _angular_core.ChangeDetectionStrategy.OnPush,
                  },] },
      ];
      /**
       * @nocollapse
       */
      MatOption.ctorParameters = function () { return [
          { type: _angular_core.ElementRef, },
          { type: _angular_core.ChangeDetectorRef, },
          { type: MatOptgroup, decorators: [{ type: _angular_core.Optional },] },
      ]; };
      MatOption.propDecorators = {
          'value': [{ type: _angular_core.Input },],
          'disabled': [{ type: _angular_core.Input },],
          'onSelectionChange': [{ type: _angular_core.Output },],
      };
      return MatOption;
  }());
  
  /**
   * InjectionToken that can be used to specify the global placeholder options.
   */
  var MAT_PLACEHOLDER_GLOBAL_OPTIONS = new _angular_core.InjectionToken('mat-placeholder-global-options');
  
  /**
   * Default color palette for round buttons (mat-fab and mat-mini-fab)
   */
  var DEFAULT_ROUND_BUTTON_COLOR = 'accent';
  /**
   * Directive whose purpose is to add the mat- CSS styling to this selector.
   * \@docs-private
   */
  var MatButtonCssMatStyler = (function () {
      function MatButtonCssMatStyler() {
      }
      MatButtonCssMatStyler.decorators = [
          { type: _angular_core.Directive, args: [{
                      selector: 'button[mat-button], a[mat-button]',
                      host: { 'class': 'mat-button' }
                  },] },
      ];
      /**
       * @nocollapse
       */
      MatButtonCssMatStyler.ctorParameters = function () { return []; };
      return MatButtonCssMatStyler;
  }());
  /**
   * Directive whose purpose is to add the mat- CSS styling to this selector.
   * \@docs-private
   */
  var MatRaisedButtonCssMatStyler = (function () {
      function MatRaisedButtonCssMatStyler() {
      }
      MatRaisedButtonCssMatStyler.decorators = [
          { type: _angular_core.Directive, args: [{
                      selector: 'button[mat-raised-button], a[mat-raised-button]',
                      host: { 'class': 'mat-raised-button' }
                  },] },
      ];
      /**
       * @nocollapse
       */
      MatRaisedButtonCssMatStyler.ctorParameters = function () { return []; };
      return MatRaisedButtonCssMatStyler;
  }());
  /**
   * Directive whose purpose is to add the mat- CSS styling to this selector.
   * \@docs-private
   */
  var MatIconButtonCssMatStyler = (function () {
      function MatIconButtonCssMatStyler() {
      }
      MatIconButtonCssMatStyler.decorators = [
          { type: _angular_core.Directive, args: [{
                      selector: 'button[mat-icon-button], a[mat-icon-button]',
                      host: { 'class': 'mat-icon-button' }
                  },] },
      ];
      /**
       * @nocollapse
       */
      MatIconButtonCssMatStyler.ctorParameters = function () { return []; };
      return MatIconButtonCssMatStyler;
  }());
  /**
   * Directive whose purpose is to add the mat- CSS styling to this selector.
   * \@docs-private
   */
  var MatFab = (function () {
      /**
       * @param {?} button
       * @param {?} anchor
       */
      function MatFab(button, anchor) {
          // Set the default color palette for the mat-fab components.
          (button || anchor).color = DEFAULT_ROUND_BUTTON_COLOR;
      }
      MatFab.decorators = [
          { type: _angular_core.Directive, args: [{
                      selector: 'button[mat-fab], a[mat-fab]',
                      host: { 'class': 'mat-fab' }
                  },] },
      ];
      /**
       * @nocollapse
       */
      MatFab.ctorParameters = function () { return [
          { type: MatButton, decorators: [{ type: _angular_core.Self }, { type: _angular_core.Optional }, { type: _angular_core.Inject, args: [_angular_core.forwardRef(function () { return MatButton; }),] },] },
          { type: MatAnchor, decorators: [{ type: _angular_core.Self }, { type: _angular_core.Optional }, { type: _angular_core.Inject, args: [_angular_core.forwardRef(function () { return MatAnchor; }),] },] },
      ]; };
      return MatFab;
  }());
  /**
   * Directive that targets mini-fab buttons and anchors. It's used to apply the `mat-` class
   * to all mini-fab buttons and also is responsible for setting the default color palette.
   * \@docs-private
   */
  var MatMiniFab = (function () {
      /**
       * @param {?} button
       * @param {?} anchor
       */
      function MatMiniFab(button, anchor) {
          // Set the default color palette for the mat-mini-fab components.
          (button || anchor).color = DEFAULT_ROUND_BUTTON_COLOR;
      }
      MatMiniFab.decorators = [
          { type: _angular_core.Directive, args: [{
                      selector: 'button[mat-mini-fab], a[mat-mini-fab]',
                      host: { 'class': 'mat-mini-fab' }
                  },] },
      ];
      /**
       * @nocollapse
       */
      MatMiniFab.ctorParameters = function () { return [
          { type: MatButton, decorators: [{ type: _angular_core.Self }, { type: _angular_core.Optional }, { type: _angular_core.Inject, args: [_angular_core.forwardRef(function () { return MatButton; }),] },] },
          { type: MatAnchor, decorators: [{ type: _angular_core.Self }, { type: _angular_core.Optional }, { type: _angular_core.Inject, args: [_angular_core.forwardRef(function () { return MatAnchor; }),] },] },
      ]; };
      return MatMiniFab;
  }());
  /**
   * \@docs-private
   */
  var MatButtonBase = (function () {
      /**
       * @param {?} _renderer
       * @param {?} _elementRef
       */
      function MatButtonBase(_renderer, _elementRef) {
          this._renderer = _renderer;
          this._elementRef = _elementRef;
      }
      return MatButtonBase;
  }());
  var _MatButtonMixinBase = mixinColor(mixinDisabled(mixinDisableRipple(MatButtonBase)));
  /**
   * Material design button.
   */
  var MatButton = (function (_super) {
      __extends(MatButton, _super);
      /**
       * @param {?} renderer
       * @param {?} elementRef
       * @param {?} _platform
       * @param {?} _focusMonitor
       */
      function MatButton(renderer, elementRef, _platform, _focusMonitor) {
          var _this = _super.call(this, renderer, elementRef) || this;
          _this._platform = _platform;
          _this._focusMonitor = _focusMonitor;
          /**
           * Whether the button is round.
           */
          _this._isRoundButton = _this._hasAttributeWithPrefix('fab', 'mini-fab');
          /**
           * Whether the button is icon button.
           */
          _this._isIconButton = _this._hasAttributeWithPrefix('icon-button');
          _this._focusMonitor.monitor(_this._elementRef.nativeElement, _this._renderer, true);
          return _this;
      }
      /**
       * @return {?}
       */
      MatButton.prototype.ngOnDestroy = function () {
          this._focusMonitor.stopMonitoring(this._elementRef.nativeElement);
      };
      /**
       * Focuses the button.
       * @return {?}
       */
      MatButton.prototype.focus = function () {
          this._getHostElement().focus();
      };
      /**
       * @return {?}
       */
      MatButton.prototype._getHostElement = function () {
          return this._elementRef.nativeElement;
      };
      /**
       * @return {?}
       */
      MatButton.prototype._isRippleDisabled = function () {
          return this.disableRipple || this.disabled;
      };
      /**
       * Gets whether the button has one of the given attributes with a 'mat-' prefix.
       * @param {...?} unprefixedAttributeNames
       * @return {?}
       */
      MatButton.prototype._hasAttributeWithPrefix = function () {
          var _this = this;
          var unprefixedAttributeNames = [];
          for (var _i = 0; _i < arguments.length; _i++) {
              unprefixedAttributeNames[_i] = arguments[_i];
          }
          // If not on the browser, say that there are none of the attributes present.
          // Since these only affect how the ripple displays (and ripples only happen on the client),
          // detecting these attributes isn't necessary when not on the browser.
          if (!this._platform.isBrowser) {
              return false;
          }
          return unprefixedAttributeNames.some(function (suffix) {
              return _this._getHostElement().hasAttribute('mat-' + suffix);
          });
      };
      MatButton.decorators = [
          { type: _angular_core.Component, args: [{selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button],\n             button[mat-fab], button[mat-mini-fab]",
                      exportAs: 'matButton',
                      host: {
                          '[disabled]': 'disabled || null',
                      },
                      template: "<span class=\"mat-button-wrapper\"><ng-content></ng-content></span><div matRipple class=\"mat-button-ripple\" [class.mat-button-ripple-round]=\"_isRoundButton || _isIconButton\" [matRippleDisabled]=\"_isRippleDisabled()\" [matRippleCentered]=\"_isIconButton\" [matRippleTrigger]=\"_getHostElement()\"></div><div class=\"mat-button-focus-overlay\"></div>",
                      styles: [".mat-button,.mat-fab,.mat-icon-button,.mat-mini-fab,.mat-raised-button{box-sizing:border-box;position:relative;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;cursor:pointer;outline:0;border:none;-webkit-tap-highlight-color:transparent;display:inline-block;white-space:nowrap;text-decoration:none;vertical-align:baseline;text-align:center;margin:0;min-width:88px;line-height:36px;padding:0 16px;border-radius:2px}[disabled].mat-button,[disabled].mat-fab,[disabled].mat-icon-button,[disabled].mat-mini-fab,[disabled].mat-raised-button{cursor:default}.cdk-keyboard-focused.mat-button .mat-button-focus-overlay,.cdk-keyboard-focused.mat-fab .mat-button-focus-overlay,.cdk-keyboard-focused.mat-icon-button .mat-button-focus-overlay,.cdk-keyboard-focused.mat-mini-fab .mat-button-focus-overlay,.cdk-keyboard-focused.mat-raised-button .mat-button-focus-overlay{opacity:1}.mat-button::-moz-focus-inner,.mat-fab::-moz-focus-inner,.mat-icon-button::-moz-focus-inner,.mat-mini-fab::-moz-focus-inner,.mat-raised-button::-moz-focus-inner{border:0}.mat-fab,.mat-mini-fab,.mat-raised-button{transform:translate3d(0,0,0);transition:background .4s cubic-bezier(.25,.8,.25,1),box-shadow 280ms cubic-bezier(.4,0,.2,1)}.mat-fab:not([class*=mat-elevation-z]),.mat-mini-fab:not([class*=mat-elevation-z]),.mat-raised-button:not([class*=mat-elevation-z]){box-shadow:0 3px 1px -2px rgba(0,0,0,.2),0 2px 2px 0 rgba(0,0,0,.14),0 1px 5px 0 rgba(0,0,0,.12)}.mat-fab:not([disabled]):active:not([class*=mat-elevation-z]),.mat-mini-fab:not([disabled]):active:not([class*=mat-elevation-z]),.mat-raised-button:not([disabled]):active:not([class*=mat-elevation-z]){box-shadow:0 5px 5px -3px rgba(0,0,0,.2),0 8px 10px 1px rgba(0,0,0,.14),0 3px 14px 2px rgba(0,0,0,.12)}[disabled].mat-fab,[disabled].mat-mini-fab,[disabled].mat-raised-button{box-shadow:none}.mat-button .mat-button-focus-overlay,.mat-icon-button .mat-button-focus-overlay{transition:none;opacity:0}.mat-button:hover .mat-button-focus-overlay{opacity:1}.mat-fab{min-width:0;border-radius:50%;width:56px;height:56px;padding:0;flex-shrink:0}.mat-fab:not([class*=mat-elevation-z]){box-shadow:0 3px 5px -1px rgba(0,0,0,.2),0 6px 10px 0 rgba(0,0,0,.14),0 1px 18px 0 rgba(0,0,0,.12)}.mat-fab:not([disabled]):active:not([class*=mat-elevation-z]){box-shadow:0 7px 8px -4px rgba(0,0,0,.2),0 12px 17px 2px rgba(0,0,0,.14),0 5px 22px 4px rgba(0,0,0,.12)}.mat-fab .mat-button-wrapper{padding:16px 0;display:inline-block;line-height:24px}.mat-mini-fab{min-width:0;border-radius:50%;width:40px;height:40px;padding:0;flex-shrink:0}.mat-mini-fab:not([class*=mat-elevation-z]){box-shadow:0 3px 5px -1px rgba(0,0,0,.2),0 6px 10px 0 rgba(0,0,0,.14),0 1px 18px 0 rgba(0,0,0,.12)}.mat-mini-fab:not([disabled]):active:not([class*=mat-elevation-z]){box-shadow:0 7px 8px -4px rgba(0,0,0,.2),0 12px 17px 2px rgba(0,0,0,.14),0 5px 22px 4px rgba(0,0,0,.12)}.mat-mini-fab .mat-button-wrapper{padding:8px 0;display:inline-block;line-height:24px}.mat-icon-button{padding:0;min-width:0;width:40px;height:40px;flex-shrink:0;line-height:40px;border-radius:50%}.mat-icon-button .mat-icon,.mat-icon-button i{line-height:24px}.mat-button,.mat-icon-button,.mat-raised-button{color:currentColor}.mat-button .mat-button-wrapper>*,.mat-icon-button .mat-button-wrapper>*,.mat-raised-button .mat-button-wrapper>*{vertical-align:middle}.mat-button-focus-overlay,.mat-button-ripple{top:0;left:0;right:0;bottom:0;position:absolute;pointer-events:none}.mat-button-focus-overlay{background-color:rgba(0,0,0,.12);border-radius:inherit;opacity:0;transition:opacity .2s cubic-bezier(.35,0,.25,1),background-color .2s cubic-bezier(.35,0,.25,1)}@media screen and (-ms-high-contrast:active){.mat-button-focus-overlay{background-color:rgba(255,255,255,.5)}}.mat-button-ripple-round{border-radius:50%;z-index:1}@media screen and (-ms-high-contrast:active){.mat-button,.mat-fab,.mat-icon-button,.mat-mini-fab,.mat-raised-button{outline:solid 1px}}"],
                      inputs: ['disabled', 'disableRipple', 'color'],
                      encapsulation: _angular_core.ViewEncapsulation.None,
                      preserveWhitespaces: false,
                      changeDetection: _angular_core.ChangeDetectionStrategy.OnPush,
                  },] },
      ];
      /**
       * @nocollapse
       */
      MatButton.ctorParameters = function () { return [
          { type: _angular_core.Renderer2, },
          { type: _angular_core.ElementRef, },
          { type: _angular_cdk_platform.Platform, },
          { type: _angular_cdk_a11y.FocusMonitor, },
      ]; };
      return MatButton;
  }(_MatButtonMixinBase));
  /**
   * Raised Material design button.
   */
  var MatAnchor = (function (_super) {
      __extends(MatAnchor, _super);
      /**
       * @param {?} platform
       * @param {?} focusMonitor
       * @param {?} elementRef
       * @param {?} renderer
       */
      function MatAnchor(platform, focusMonitor, elementRef, renderer) {
          return _super.call(this, renderer, elementRef, platform, focusMonitor) || this;
      }
      /**
       * @param {?} event
       * @return {?}
       */
      MatAnchor.prototype._haltDisabledEvents = function (event) {
          // A disabled button shouldn't apply any actions
          if (this.disabled) {
              event.preventDefault();
              event.stopImmediatePropagation();
          }
      };
      MatAnchor.decorators = [
          { type: _angular_core.Component, args: [{selector: "a[mat-button], a[mat-raised-button], a[mat-icon-button], a[mat-fab], a[mat-mini-fab]",
                      exportAs: 'matButton, matAnchor',
                      host: {
                          '[attr.tabindex]': 'disabled ? -1 : 0',
                          '[attr.disabled]': 'disabled || null',
                          '[attr.aria-disabled]': 'disabled.toString()',
                          '(click)': '_haltDisabledEvents($event)',
                      },
                      inputs: ['disabled', 'disableRipple', 'color'],
                      template: "<span class=\"mat-button-wrapper\"><ng-content></ng-content></span><div matRipple class=\"mat-button-ripple\" [class.mat-button-ripple-round]=\"_isRoundButton || _isIconButton\" [matRippleDisabled]=\"_isRippleDisabled()\" [matRippleCentered]=\"_isIconButton\" [matRippleTrigger]=\"_getHostElement()\"></div><div class=\"mat-button-focus-overlay\"></div>",
                      styles: [".mat-button,.mat-fab,.mat-icon-button,.mat-mini-fab,.mat-raised-button{box-sizing:border-box;position:relative;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;cursor:pointer;outline:0;border:none;-webkit-tap-highlight-color:transparent;display:inline-block;white-space:nowrap;text-decoration:none;vertical-align:baseline;text-align:center;margin:0;min-width:88px;line-height:36px;padding:0 16px;border-radius:2px}[disabled].mat-button,[disabled].mat-fab,[disabled].mat-icon-button,[disabled].mat-mini-fab,[disabled].mat-raised-button{cursor:default}.cdk-keyboard-focused.mat-button .mat-button-focus-overlay,.cdk-keyboard-focused.mat-fab .mat-button-focus-overlay,.cdk-keyboard-focused.mat-icon-button .mat-button-focus-overlay,.cdk-keyboard-focused.mat-mini-fab .mat-button-focus-overlay,.cdk-keyboard-focused.mat-raised-button .mat-button-focus-overlay{opacity:1}.mat-button::-moz-focus-inner,.mat-fab::-moz-focus-inner,.mat-icon-button::-moz-focus-inner,.mat-mini-fab::-moz-focus-inner,.mat-raised-button::-moz-focus-inner{border:0}.mat-fab,.mat-mini-fab,.mat-raised-button{transform:translate3d(0,0,0);transition:background .4s cubic-bezier(.25,.8,.25,1),box-shadow 280ms cubic-bezier(.4,0,.2,1)}.mat-fab:not([class*=mat-elevation-z]),.mat-mini-fab:not([class*=mat-elevation-z]),.mat-raised-button:not([class*=mat-elevation-z]){box-shadow:0 3px 1px -2px rgba(0,0,0,.2),0 2px 2px 0 rgba(0,0,0,.14),0 1px 5px 0 rgba(0,0,0,.12)}.mat-fab:not([disabled]):active:not([class*=mat-elevation-z]),.mat-mini-fab:not([disabled]):active:not([class*=mat-elevation-z]),.mat-raised-button:not([disabled]):active:not([class*=mat-elevation-z]){box-shadow:0 5px 5px -3px rgba(0,0,0,.2),0 8px 10px 1px rgba(0,0,0,.14),0 3px 14px 2px rgba(0,0,0,.12)}[disabled].mat-fab,[disabled].mat-mini-fab,[disabled].mat-raised-button{box-shadow:none}.mat-button .mat-button-focus-overlay,.mat-icon-button .mat-button-focus-overlay{transition:none;opacity:0}.mat-button:hover .mat-button-focus-overlay{opacity:1}.mat-fab{min-width:0;border-radius:50%;width:56px;height:56px;padding:0;flex-shrink:0}.mat-fab:not([class*=mat-elevation-z]){box-shadow:0 3px 5px -1px rgba(0,0,0,.2),0 6px 10px 0 rgba(0,0,0,.14),0 1px 18px 0 rgba(0,0,0,.12)}.mat-fab:not([disabled]):active:not([class*=mat-elevation-z]){box-shadow:0 7px 8px -4px rgba(0,0,0,.2),0 12px 17px 2px rgba(0,0,0,.14),0 5px 22px 4px rgba(0,0,0,.12)}.mat-fab .mat-button-wrapper{padding:16px 0;display:inline-block;line-height:24px}.mat-mini-fab{min-width:0;border-radius:50%;width:40px;height:40px;padding:0;flex-shrink:0}.mat-mini-fab:not([class*=mat-elevation-z]){box-shadow:0 3px 5px -1px rgba(0,0,0,.2),0 6px 10px 0 rgba(0,0,0,.14),0 1px 18px 0 rgba(0,0,0,.12)}.mat-mini-fab:not([disabled]):active:not([class*=mat-elevation-z]){box-shadow:0 7px 8px -4px rgba(0,0,0,.2),0 12px 17px 2px rgba(0,0,0,.14),0 5px 22px 4px rgba(0,0,0,.12)}.mat-mini-fab .mat-button-wrapper{padding:8px 0;display:inline-block;line-height:24px}.mat-icon-button{padding:0;min-width:0;width:40px;height:40px;flex-shrink:0;line-height:40px;border-radius:50%}.mat-icon-button .mat-icon,.mat-icon-button i{line-height:24px}.mat-button,.mat-icon-button,.mat-raised-button{color:currentColor}.mat-button .mat-button-wrapper>*,.mat-icon-button .mat-button-wrapper>*,.mat-raised-button .mat-button-wrapper>*{vertical-align:middle}.mat-button-focus-overlay,.mat-button-ripple{top:0;left:0;right:0;bottom:0;position:absolute;pointer-events:none}.mat-button-focus-overlay{background-color:rgba(0,0,0,.12);border-radius:inherit;opacity:0;transition:opacity .2s cubic-bezier(.35,0,.25,1),background-color .2s cubic-bezier(.35,0,.25,1)}@media screen and (-ms-high-contrast:active){.mat-button-focus-overlay{background-color:rgba(255,255,255,.5)}}.mat-button-ripple-round{border-radius:50%;z-index:1}@media screen and (-ms-high-contrast:active){.mat-button,.mat-fab,.mat-icon-button,.mat-mini-fab,.mat-raised-button{outline:solid 1px}}"],
                      encapsulation: _angular_core.ViewEncapsulation.None,
                      preserveWhitespaces: false,
                      changeDetection: _angular_core.ChangeDetectionStrategy.OnPush,
                  },] },
      ];
      /**
       * @nocollapse
       */
      MatAnchor.ctorParameters = function () { return [
          { type: _angular_cdk_platform.Platform, },
          { type: _angular_cdk_a11y.FocusMonitor, },
          { type: _angular_core.ElementRef, },
          { type: _angular_core.Renderer2, },
      ]; };
      return MatAnchor;
  }(MatButton));
  
  var MatButtonModule = (function () {
      function MatButtonModule() {
      }
      MatButtonModule.decorators = [
          { type: _angular_core.NgModule, args: [{
                      imports: [
                          _angular_common.CommonModule,
                          MatRippleModule,
                          MatCommonModule,
                          _angular_cdk_a11y.A11yModule,
                      ],
                      exports: [
                          MatButton,
                          MatAnchor,
                          MatMiniFab,
                          MatFab,
                          MatCommonModule,
                          MatButtonCssMatStyler,
                          MatRaisedButtonCssMatStyler,
                          MatIconButtonCssMatStyler,
                      ],
                      declarations: [
                          MatButton,
                          MatAnchor,
                          MatMiniFab,
                          MatFab,
                          MatButtonCssMatStyler,
                          MatRaisedButtonCssMatStyler,
                          MatIconButtonCssMatStyler,
                      ],
                  },] },
      ];
      /**
       * @nocollapse
       */
      MatButtonModule.ctorParameters = function () { return []; };
      return MatButtonModule;
  }());
  
  /**
   * Configuration for opening a modal dialog with the MatDialog service.
   */
  var MatDialogConfig = (function () {
      function MatDialogConfig() {
          /**
           * The ARIA role of the dialog element.
           */
          this.role = 'dialog';
          /**
           * Custom class for the overlay pane.
           */
          this.panelClass = '';
          /**
           * Whether the dialog has a backdrop.
           */
          this.hasBackdrop = true;
          /**
           * Custom class for the backdrop,
           */
          this.backdropClass = '';
          /**
           * Whether the user can use escape or clicking outside to close a modal.
           */
          this.disableClose = false;
          /**
           * Width of the dialog.
           */
          this.width = '';
          /**
           * Height of the dialog.
           */
          this.height = '';
          /**
           * Data being injected into the child component.
           */
          this.data = null;
          /**
           * Layout direction for the dialog's content.
           */
          this.direction = 'ltr';
          /**
           * ID of the element that describes the dialog.
           */
          this.ariaDescribedBy = null;
          // TODO(jelbourn): add configuration for lifecycle hooks, ARIA labelling.
      }
      return MatDialogConfig;
  }());
  
  /**
   * Throws an exception for the case when a ComponentPortal is
   * attached to a DomPortalHost without an origin.
   * \@docs-private
   * @return {?}
   */
  function throwMatDialogContentAlreadyAttachedError() {
      throw Error('Attempting to attach dialog content after content is already attached');
  }
  /**
   * Internal component that wraps user-provided dialog content.
   * Animation is based on https://material.io/guidelines/motion/choreography.html.
   * \@docs-private
   */
  var MatDialogContainer = (function (_super) {
      __extends(MatDialogContainer, _super);
      /**
       * @param {?} _elementRef
       * @param {?} _focusTrapFactory
       * @param {?} _changeDetectorRef
       * @param {?} _document
       */
      function MatDialogContainer(_elementRef, _focusTrapFactory, _changeDetectorRef, _document) {
          var _this = _super.call(this) || this;
          _this._elementRef = _elementRef;
          _this._focusTrapFactory = _focusTrapFactory;
          _this._changeDetectorRef = _changeDetectorRef;
          _this._document = _document;
          /**
           * Element that was focused before the dialog was opened. Save this to restore upon close.
           */
          _this._elementFocusedBeforeDialogWasOpened = null;
          /**
           * State of the dialog animation.
           */
          _this._state = 'enter';
          /**
           * Emits when an animation state changes.
           */
          _this._animationStateChanged = new _angular_core.EventEmitter();
          /**
           * ID of the element that should be considered as the dialog's label.
           */
          _this._ariaLabelledBy = null;
          /**
           * Whether the container is currently mid-animation.
           */
          _this._isAnimating = false;
          return _this;
      }
      /**
       * Attach a ComponentPortal as content to this dialog container.
       * @template T
       * @param {?} portal Portal to be attached as the dialog content.
       * @return {?}
       */
      MatDialogContainer.prototype.attachComponentPortal = function (portal) {
          if (this._portalHost.hasAttached()) {
              throwMatDialogContentAlreadyAttachedError();
          }
          this._savePreviouslyFocusedElement();
          return this._portalHost.attachComponentPortal(portal);
      };
      /**
       * Attach a TemplatePortal as content to this dialog container.
       * @template C
       * @param {?} portal Portal to be attached as the dialog content.
       * @return {?}
       */
      MatDialogContainer.prototype.attachTemplatePortal = function (portal) {
          if (this._portalHost.hasAttached()) {
              throwMatDialogContentAlreadyAttachedError();
          }
          this._savePreviouslyFocusedElement();
          return this._portalHost.attachTemplatePortal(portal);
      };
      /**
       * Moves the focus inside the focus trap.
       * @return {?}
       */
      MatDialogContainer.prototype._trapFocus = function () {
          var _this = this;
          if (!this._focusTrap) {
              this._focusTrap = this._focusTrapFactory.create(this._elementRef.nativeElement);
          }
          // If were to attempt to focus immediately, then the content of the dialog would not yet be
          // ready in instances where change detection has to run first. To deal with this, we simply
          // wait for the microtask queue to be empty.
          this._focusTrap.focusInitialElementWhenReady().then(function (hasMovedFocus) {
              // If we didn't find any focusable elements inside the dialog, focus the
              // container so the user can't tab into other elements behind it.
              if (!hasMovedFocus) {
                  _this._elementRef.nativeElement.focus();
              }
          });
      };
      /**
       * Restores focus to the element that was focused before the dialog opened.
       * @return {?}
       */
      MatDialogContainer.prototype._restoreFocus = function () {
          var /** @type {?} */ toFocus = this._elementFocusedBeforeDialogWasOpened;
          // We need the extra check, because IE can set the `activeElement` to null in some cases.
          if (toFocus && typeof toFocus.focus === 'function') {
              toFocus.focus();
          }
          if (this._focusTrap) {
              this._focusTrap.destroy();
          }
      };
      /**
       * Saves a reference to the element that was focused before the dialog was opened.
       * @return {?}
       */
      MatDialogContainer.prototype._savePreviouslyFocusedElement = function () {
          if (this._document) {
              this._elementFocusedBeforeDialogWasOpened = (this._document.activeElement);
          }
      };
      /**
       * Callback, invoked whenever an animation on the host completes.
       * @param {?} event
       * @return {?}
       */
      MatDialogContainer.prototype._onAnimationDone = function (event) {
          if (event.toState === 'enter') {
              this._trapFocus();
          }
          else if (event.toState === 'exit') {
              this._restoreFocus();
          }
          this._animationStateChanged.emit(event);
          this._isAnimating = false;
      };
      /**
       * Callback, invoked when an animation on the host starts.
       * @param {?} event
       * @return {?}
       */
      MatDialogContainer.prototype._onAnimationStart = function (event) {
          this._isAnimating = true;
          this._animationStateChanged.emit(event);
      };
      /**
       * Starts the dialog exit animation.
       * @return {?}
       */
      MatDialogContainer.prototype._startExitAnimation = function () {
          this._state = 'exit';
          // Mark the container for check so it can react if the
          // view container is using OnPush change detection.
          this._changeDetectorRef.markForCheck();
      };
      MatDialogContainer.decorators = [
          { type: _angular_core.Component, args: [{selector: 'mat-dialog-container',
                      template: "<ng-template cdkPortalHost></ng-template>",
                      styles: [".mat-dialog-container{box-shadow:0 11px 15px -7px rgba(0,0,0,.2),0 24px 38px 3px rgba(0,0,0,.14),0 9px 46px 8px rgba(0,0,0,.12);display:block;padding:24px;border-radius:2px;box-sizing:border-box;overflow:auto;max-width:80vw;outline:0;width:100%;height:100%}@media screen and (-ms-high-contrast:active){.mat-dialog-container{outline:solid 1px}}.mat-dialog-content{display:block;margin:0 -24px;padding:0 24px;max-height:65vh;overflow:auto;-webkit-overflow-scrolling:touch;-webkit-backface-visibility:hidden;backface-visibility:hidden}.mat-dialog-title{margin:0 0 20px;display:block}.mat-dialog-actions{padding:12px 0;display:flex;flex-wrap:wrap}.mat-dialog-actions:last-child{margin-bottom:-24px}.mat-dialog-actions[align=end]{justify-content:flex-end}.mat-dialog-actions[align=center]{justify-content:center}.mat-dialog-actions .mat-button+.mat-button,.mat-dialog-actions .mat-button+.mat-raised-button,.mat-dialog-actions .mat-raised-button+.mat-button,.mat-dialog-actions .mat-raised-button+.mat-raised-button{margin-left:8px}[dir=rtl] .mat-dialog-actions .mat-button+.mat-button,[dir=rtl] .mat-dialog-actions .mat-button+.mat-raised-button,[dir=rtl] .mat-dialog-actions .mat-raised-button+.mat-button,[dir=rtl] .mat-dialog-actions .mat-raised-button+.mat-raised-button{margin-left:0;margin-right:8px}"],
                      encapsulation: _angular_core.ViewEncapsulation.None,
                      preserveWhitespaces: false,
                      // Using OnPush for dialogs caused some G3 sync issues. Disabled until we can track them down.
                      // tslint:disable-next-line:validate-decorators
                      changeDetection: _angular_core.ChangeDetectionStrategy.Default,
                      animations: [
                          _angular_animations.trigger('slideDialog', [
                              // Note: The `enter` animation doesn't transition to something like `translate3d(0, 0, 0)
                              // scale(1)`, because for some reason specifying the transform explicitly, causes IE both
                              // to blur the dialog content and decimate the animation performance. Leaving it as `none`
                              // solves both issues.
                              _angular_animations.state('enter', _angular_animations.style({ transform: 'none', opacity: 1 })),
                              _angular_animations.state('void', _angular_animations.style({ transform: 'translate3d(0, 25%, 0) scale(0.9)', opacity: 0 })),
                              _angular_animations.state('exit', _angular_animations.style({ transform: 'translate3d(0, 25%, 0)', opacity: 0 })),
                              _angular_animations.transition('* => *', _angular_animations.animate('400ms cubic-bezier(0.25, 0.8, 0.25, 1)')),
                          ])
                      ],
                      host: {
                          'class': 'mat-dialog-container',
                          'tabindex': '-1',
                          '[attr.role]': '_config?.role',
                          '[attr.aria-labelledby]': '_ariaLabelledBy',
                          '[attr.aria-describedby]': '_config?.ariaDescribedBy || null',
                          '[@slideDialog]': '_state',
                          '(@slideDialog.start)': '_onAnimationStart($event)',
                          '(@slideDialog.done)': '_onAnimationDone($event)',
                      },
                  },] },
      ];
      /**
       * @nocollapse
       */
      MatDialogContainer.ctorParameters = function () { return [
          { type: _angular_core.ElementRef, },
          { type: _angular_cdk_a11y.FocusTrapFactory, },
          { type: _angular_core.ChangeDetectorRef, },
          { type: undefined, decorators: [{ type: _angular_core.Optional }, { type: _angular_core.Inject, args: [_angular_platformBrowser.DOCUMENT,] },] },
      ]; };
      MatDialogContainer.propDecorators = {
          '_portalHost': [{ type: _angular_core.ViewChild, args: [_angular_cdk_portal.PortalHostDirective,] },],
      };
      return MatDialogContainer;
  }(_angular_cdk_portal.BasePortalHost));
  
  // TODO(jelbourn): resizing
  // Counter for unique dialog ids.
  var uniqueId = 0;
  /**
   * Reference to a dialog opened via the MatDialog service.
   */
  var MatDialogRef = (function () {
      /**
       * @param {?} _overlayRef
       * @param {?} _containerInstance
       * @param {?=} id
       */
      function MatDialogRef(_overlayRef, _containerInstance, id) {
          if (id === void 0) { id = "mat-dialog-" + uniqueId++; }
          var _this = this;
          this._overlayRef = _overlayRef;
          this._containerInstance = _containerInstance;
          this.id = id;
          /**
           * Whether the user is allowed to close the dialog.
           */
          this.disableClose = this._containerInstance._config.disableClose;
          /**
           * Subject for notifying the user that the dialog has finished opening.
           */
          this._afterOpen = new rxjs_Subject.Subject();
          /**
           * Subject for notifying the user that the dialog has finished closing.
           */
          this._afterClosed = new rxjs_Subject.Subject();
          /**
           * Subject for notifying the user that the dialog has started closing.
           */
          this._beforeClose = new rxjs_Subject.Subject();
          // Emit when opening animation completes
          _angular_cdk_rxjs.RxChain.from(_containerInstance._animationStateChanged)
              .call(_angular_cdk_rxjs.filter, function (event) { return event.phaseName === 'done' && event.toState === 'enter'; })
              .call(_angular_cdk_rxjs.first)
              .subscribe(function () {
              _this._afterOpen.next();
              _this._afterOpen.complete();
          });
          // Dispose overlay when closing animation is complete
          _angular_cdk_rxjs.RxChain.from(_containerInstance._animationStateChanged)
              .call(_angular_cdk_rxjs.filter, function (event) { return event.phaseName === 'done' && event.toState === 'exit'; })
              .call(_angular_cdk_rxjs.first)
              .subscribe(function () {
              _this._overlayRef.dispose();
              _this._afterClosed.next(_this._result);
              _this._afterClosed.complete();
              _this.componentInstance = null;
          });
      }
      /**
       * Close the dialog.
       * @param {?=} dialogResult Optional result to return to the dialog opener.
       * @return {?}
       */
      MatDialogRef.prototype.close = function (dialogResult) {
          var _this = this;
          this._result = dialogResult;
          // Transition the backdrop in parallel to the dialog.
          _angular_cdk_rxjs.RxChain.from(this._containerInstance._animationStateChanged)
              .call(_angular_cdk_rxjs.filter, function (event) { return event.phaseName === 'start'; })
              .call(_angular_cdk_rxjs.first)
              .subscribe(function () {
              _this._beforeClose.next(dialogResult);
              _this._beforeClose.complete();
              _this._overlayRef.detachBackdrop();
          });
          this._containerInstance._startExitAnimation();
      };
      /**
       * Gets an observable that is notified when the dialog is finished opening.
       * @return {?}
       */
      MatDialogRef.prototype.afterOpen = function () {
          return this._afterOpen.asObservable();
      };
      /**
       * Gets an observable that is notified when the dialog is finished closing.
       * @return {?}
       */
      MatDialogRef.prototype.afterClosed = function () {
          return this._afterClosed.asObservable();
      };
      /**
       * Gets an observable that is notified when the dialog has started closing.
       * @return {?}
       */
      MatDialogRef.prototype.beforeClose = function () {
          return this._beforeClose.asObservable();
      };
      /**
       * Gets an observable that emits when the overlay's backdrop has been clicked.
       * @return {?}
       */
      MatDialogRef.prototype.backdropClick = function () {
          return this._overlayRef.backdropClick();
      };
      /**
       * Updates the dialog's position.
       * @param {?=} position New dialog position.
       * @return {?}
       */
      MatDialogRef.prototype.updatePosition = function (position) {
          var /** @type {?} */ strategy = this._getPositionStrategy();
          if (position && (position.left || position.right)) {
              position.left ? strategy.left(position.left) : strategy.right(position.right);
          }
          else {
              strategy.centerHorizontally();
          }
          if (position && (position.top || position.bottom)) {
              position.top ? strategy.top(position.top) : strategy.bottom(position.bottom);
          }
          else {
              strategy.centerVertically();
          }
          this._overlayRef.updatePosition();
          return this;
      };
      /**
       * Updates the dialog's width and height.
       * @param {?=} width New width of the dialog.
       * @param {?=} height New height of the dialog.
       * @return {?}
       */
      MatDialogRef.prototype.updateSize = function (width, height) {
          if (width === void 0) { width = 'auto'; }
          if (height === void 0) { height = 'auto'; }
          this._getPositionStrategy().width(width).height(height);
          this._overlayRef.updatePosition();
          return this;
      };
      /**
       * Returns whether the dialog is animating.
       * @return {?}
       */
      MatDialogRef.prototype._isAnimating = function () {
          return this._containerInstance._isAnimating;
      };
      /**
       * Fetches the position strategy object from the overlay ref.
       * @return {?}
       */
      MatDialogRef.prototype._getPositionStrategy = function () {
          return (this._overlayRef.getConfig().positionStrategy);
      };
      return MatDialogRef;
  }());
  
  var MAT_DIALOG_DATA = new _angular_core.InjectionToken('MatDialogData');
  /**
   * Injection token that determines the scroll handling while the dialog is open.
   */
  var MAT_DIALOG_SCROLL_STRATEGY = new _angular_core.InjectionToken('mat-dialog-scroll-strategy');
  /**
   * \@docs-private
   * @param {?} overlay
   * @return {?}
   */
  function MAT_DIALOG_SCROLL_STRATEGY_PROVIDER_FACTORY(overlay) {
      return function () { return overlay.scrollStrategies.block(); };
  }
  /**
   * \@docs-private
   */
  var MAT_DIALOG_SCROLL_STRATEGY_PROVIDER = {
      provide: MAT_DIALOG_SCROLL_STRATEGY,
      deps: [_angular_cdk_overlay.Overlay],
      useFactory: MAT_DIALOG_SCROLL_STRATEGY_PROVIDER_FACTORY,
  };
  /**
   * Service to open Material Design modal dialogs.
   */
  var MatDialog = (function () {
      /**
       * @param {?} _overlay
       * @param {?} _injector
       * @param {?} location
       * @param {?} _scrollStrategy
       * @param {?} _parentDialog
       */
      function MatDialog(_overlay, _injector, location, _scrollStrategy, _parentDialog) {
          var _this = this;
          this._overlay = _overlay;
          this._injector = _injector;
          this._scrollStrategy = _scrollStrategy;
          this._parentDialog = _parentDialog;
          this._openDialogsAtThisLevel = [];
          this._afterAllClosedAtThisLevel = new rxjs_Subject.Subject();
          this._afterOpenAtThisLevel = new rxjs_Subject.Subject();
          this._boundKeydown = this._handleKeydown.bind(this);
          /**
           * Stream that emits when all open dialog have finished closing.
           * Will emit on subscribe if there are no open dialogs to begin with.
           */
          this.afterAllClosed = rxjs_observable_defer.defer(function () { return _this.openDialogs.length ?
              _this._afterAllClosed :
              _angular_cdk_rxjs.startWith.call(_this._afterAllClosed, undefined); });
          // Close all of the dialogs when the user goes forwards/backwards in history or when the
          // location hash changes. Note that this usually doesn't include clicking on links (unless
          // the user is using the `HashLocationStrategy`).
          if (!_parentDialog && location) {
              location.subscribe(function () { return _this.closeAll(); });
          }
      }
      Object.defineProperty(MatDialog.prototype, "openDialogs", {
          /**
           * Keeps track of the currently-open dialogs.
           * @return {?}
           */
          get: function () {
              return this._parentDialog ? this._parentDialog.openDialogs : this._openDialogsAtThisLevel;
          },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(MatDialog.prototype, "afterOpen", {
          /**
           * Stream that emits when a dialog has been opened.
           * @return {?}
           */
          get: function () {
              return this._parentDialog ? this._parentDialog.afterOpen : this._afterOpenAtThisLevel;
          },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(MatDialog.prototype, "_afterAllClosed", {
          /**
           * @return {?}
           */
          get: function () {
              var /** @type {?} */ parent = this._parentDialog;
              return parent ? parent._afterAllClosed : this._afterAllClosedAtThisLevel;
          },
          enumerable: true,
          configurable: true
      });
      /**
       * Opens a modal dialog containing the given component.
       * @template T
       * @param {?} componentOrTemplateRef Type of the component to load into the dialog,
       *     or a TemplateRef to instantiate as the dialog content.
       * @param {?=} config Extra configuration options.
       * @return {?} Reference to the newly-opened dialog.
       */
      MatDialog.prototype.open = function (componentOrTemplateRef, config) {
          var _this = this;
          var /** @type {?} */ inProgressDialog = this.openDialogs.find(function (dialog) { return dialog._isAnimating(); });
          // If there's a dialog that is in the process of being opened, return it instead.
          if (inProgressDialog) {
              return inProgressDialog;
          }
          config = _applyConfigDefaults(config);
          if (config.id && this.getDialogById(config.id)) {
              throw Error("Dialog with id \"" + config.id + "\" exists already. The dialog id must be unique.");
          }
          var /** @type {?} */ overlayRef = this._createOverlay(config);
          var /** @type {?} */ dialogContainer = this._attachDialogContainer(overlayRef, config);
          var /** @type {?} */ dialogRef = this._attachDialogContent(componentOrTemplateRef, dialogContainer, overlayRef, config);
          if (!this.openDialogs.length) {
              document.addEventListener('keydown', this._boundKeydown);
          }
          this.openDialogs.push(dialogRef);
          dialogRef.afterClosed().subscribe(function () { return _this._removeOpenDialog(dialogRef); });
          this.afterOpen.next(dialogRef);
          return dialogRef;
      };
      /**
       * Closes all of the currently-open dialogs.
       * @return {?}
       */
      MatDialog.prototype.closeAll = function () {
          var /** @type {?} */ i = this.openDialogs.length;
          while (i--) {
              // The `_openDialogs` property isn't updated after close until the rxjs subscription
              // runs on the next microtask, in addition to modifying the array as we're going
              // through it. We loop through all of them and call close without assuming that
              // they'll be removed from the list instantaneously.
              this.openDialogs[i].close();
          }
      };
      /**
       * Finds an open dialog by its id.
       * @param {?} id ID to use when looking up the dialog.
       * @return {?}
       */
      MatDialog.prototype.getDialogById = function (id) {
          return this.openDialogs.find(function (dialog) { return dialog.id === id; });
      };
      /**
       * Creates the overlay into which the dialog will be loaded.
       * @param {?} config The dialog configuration.
       * @return {?} A promise resolving to the OverlayRef for the created overlay.
       */
      MatDialog.prototype._createOverlay = function (config) {
          var /** @type {?} */ overlayConfig = this._getOverlayConfig(config);
          return this._overlay.create(overlayConfig);
      };
      /**
       * Creates an overlay config from a dialog config.
       * @param {?} dialogConfig The dialog configuration.
       * @return {?} The overlay configuration.
       */
      MatDialog.prototype._getOverlayConfig = function (dialogConfig) {
          var /** @type {?} */ state$$1 = new _angular_cdk_overlay.OverlayConfig({
              positionStrategy: this._overlay.position().global(),
              scrollStrategy: this._scrollStrategy(),
              panelClass: dialogConfig.panelClass,
              hasBackdrop: dialogConfig.hasBackdrop,
              direction: dialogConfig.direction
          });
          if (dialogConfig.backdropClass) {
              state$$1.backdropClass = dialogConfig.backdropClass;
          }
          return state$$1;
      };
      /**
       * Attaches an MatDialogContainer to a dialog's already-created overlay.
       * @param {?} overlay Reference to the dialog's underlying overlay.
       * @param {?} config The dialog configuration.
       * @return {?} A promise resolving to a ComponentRef for the attached container.
       */
      MatDialog.prototype._attachDialogContainer = function (overlay, config) {
          var /** @type {?} */ containerPortal = new _angular_cdk_portal.ComponentPortal(MatDialogContainer, config.viewContainerRef);
          var /** @type {?} */ containerRef = overlay.attach(containerPortal);
          containerRef.instance._config = config;
          return containerRef.instance;
      };
      /**
       * Attaches the user-provided component to the already-created MatDialogContainer.
       * @template T
       * @param {?} componentOrTemplateRef The type of component being loaded into the dialog,
       *     or a TemplateRef to instantiate as the content.
       * @param {?} dialogContainer Reference to the wrapping MatDialogContainer.
       * @param {?} overlayRef Reference to the overlay in which the dialog resides.
       * @param {?} config The dialog configuration.
       * @return {?} A promise resolving to the MatDialogRef that should be returned to the user.
       */
      MatDialog.prototype._attachDialogContent = function (componentOrTemplateRef, dialogContainer, overlayRef, config) {
          // Create a reference to the dialog we're creating in order to give the user a handle
          // to modify and close it.
          var /** @type {?} */ dialogRef = new MatDialogRef(overlayRef, dialogContainer, config.id);
          // When the dialog backdrop is clicked, we want to close it.
          if (config.hasBackdrop) {
              overlayRef.backdropClick().subscribe(function () {
                  if (!dialogRef.disableClose) {
                      dialogRef.close();
                  }
              });
          }
          if (componentOrTemplateRef instanceof _angular_core.TemplateRef) {
              dialogContainer.attachTemplatePortal(new _angular_cdk_portal.TemplatePortal(componentOrTemplateRef, /** @type {?} */ ((null)), /** @type {?} */ ({ $implicit: config.data, dialogRef: dialogRef })));
          }
          else {
              var /** @type {?} */ injector = this._createInjector(config, dialogRef, dialogContainer);
              var /** @type {?} */ contentRef = dialogContainer.attachComponentPortal(new _angular_cdk_portal.ComponentPortal(componentOrTemplateRef, undefined, injector));
              dialogRef.componentInstance = contentRef.instance;
          }
          dialogRef
              .updateSize(config.width, config.height)
              .updatePosition(config.position);
          return dialogRef;
      };
      /**
       * Creates a custom injector to be used inside the dialog. This allows a component loaded inside
       * of a dialog to close itself and, optionally, to return a value.
       * @template T
       * @param {?} config Config object that is used to construct the dialog.
       * @param {?} dialogRef Reference to the dialog.
       * @param {?} dialogContainer
       * @return {?} The custom injector that can be used inside the dialog.
       */
      MatDialog.prototype._createInjector = function (config, dialogRef, dialogContainer) {
          var /** @type {?} */ userInjector = config && config.viewContainerRef && config.viewContainerRef.injector;
          var /** @type {?} */ injectionTokens = new WeakMap();
          injectionTokens.set(MatDialogRef, dialogRef);
          injectionTokens.set(MatDialogContainer, dialogContainer);
          injectionTokens.set(MAT_DIALOG_DATA, config.data);
          injectionTokens.set(_angular_cdk_bidi.Directionality, {
              value: config.direction,
              change: rxjs_observable_of.of()
          });
          return new _angular_cdk_portal.PortalInjector(userInjector || this._injector, injectionTokens);
      };
      /**
       * Removes a dialog from the array of open dialogs.
       * @param {?} dialogRef Dialog to be removed.
       * @return {?}
       */
      MatDialog.prototype._removeOpenDialog = function (dialogRef) {
          var /** @type {?} */ index = this.openDialogs.indexOf(dialogRef);
          if (index > -1) {
              this.openDialogs.splice(index, 1);
              // no open dialogs are left, call next on afterAllClosed Subject
              if (!this.openDialogs.length) {
                  this._afterAllClosed.next();
                  document.removeEventListener('keydown', this._boundKeydown);
              }
          }
      };
      /**
       * Handles global key presses while there are open dialogs. Closes the
       * top dialog when the user presses escape.
       * @param {?} event
       * @return {?}
       */
      MatDialog.prototype._handleKeydown = function (event) {
          var /** @type {?} */ topDialog = this.openDialogs[this.openDialogs.length - 1];
          var /** @type {?} */ canClose = topDialog ? !topDialog.disableClose : false;
          if (event.keyCode === _angular_cdk_keycodes.ESCAPE && canClose) {
              topDialog.close();
          }
      };
      MatDialog.decorators = [
          { type: _angular_core.Injectable },
      ];
      /**
       * @nocollapse
       */
      MatDialog.ctorParameters = function () { return [
          { type: _angular_cdk_overlay.Overlay, },
          { type: _angular_core.Injector, },
          { type: _angular_common.Location, decorators: [{ type: _angular_core.Optional },] },
          { type: undefined, decorators: [{ type: _angular_core.Inject, args: [MAT_DIALOG_SCROLL_STRATEGY,] },] },
          { type: MatDialog, decorators: [{ type: _angular_core.Optional }, { type: _angular_core.SkipSelf },] },
      ]; };
      return MatDialog;
  }());
  /**
   * Applies default options to the dialog config.
   * @param {?=} config Config to be modified.
   * @return {?} The new configuration object.
   */
  function _applyConfigDefaults(config) {
      return extendObject(new MatDialogConfig(), config);
  }
  
  /**
   * Counter used to generate unique IDs for dialog elements.
   */
  var dialogElementUid = 0;
  /**
   * Button that will close the current dialog.
   */
  var MatDialogClose = (function () {
      /**
       * @param {?} dialogRef
       */
      function MatDialogClose(dialogRef) {
          this.dialogRef = dialogRef;
          /**
           * Screenreader label for the button.
           */
          this.ariaLabel = 'Close dialog';
      }
      /**
       * @param {?} changes
       * @return {?}
       */
      MatDialogClose.prototype.ngOnChanges = function (changes) {
          var /** @type {?} */ proxiedChange = changes._matDialogClose || changes._matDialogCloseResult;
          if (proxiedChange) {
              this.dialogResult = proxiedChange.currentValue;
          }
      };
      MatDialogClose.decorators = [
          { type: _angular_core.Directive, args: [{
                      selector: "button[mat-dialog-close], button[matDialogClose]",
                      exportAs: 'matDialogClose',
                      host: {
                          '(click)': 'dialogRef.close(dialogResult)',
                          '[attr.aria-label]': 'ariaLabel',
                          'type': 'button',
                      }
                  },] },
      ];
      /**
       * @nocollapse
       */
      MatDialogClose.ctorParameters = function () { return [
          { type: MatDialogRef, },
      ]; };
      MatDialogClose.propDecorators = {
          'ariaLabel': [{ type: _angular_core.Input, args: ['aria-label',] },],
          'dialogResult': [{ type: _angular_core.Input, args: ['mat-dialog-close',] },],
          '_matDialogClose': [{ type: _angular_core.Input, args: ['matDialogClose',] },],
      };
      return MatDialogClose;
  }());
  /**
   * Title of a dialog element. Stays fixed to the top of the dialog when scrolling.
   */
  var MatDialogTitle = (function () {
      /**
       * @param {?} _container
       */
      function MatDialogTitle(_container) {
          this._container = _container;
          this.id = "mat-dialog-title-" + dialogElementUid++;
      }
      /**
       * @return {?}
       */
      MatDialogTitle.prototype.ngOnInit = function () {
          var _this = this;
          if (this._container && !this._container._ariaLabelledBy) {
              Promise.resolve().then(function () { return _this._container._ariaLabelledBy = _this.id; });
          }
      };
      MatDialogTitle.decorators = [
          { type: _angular_core.Directive, args: [{
                      selector: '[mat-dialog-title], [matDialogTitle]',
                      exportAs: 'matDialogTitle',
                      host: {
                          'class': 'mat-dialog-title',
                          '[id]': 'id',
                      },
                  },] },
      ];
      /**
       * @nocollapse
       */
      MatDialogTitle.ctorParameters = function () { return [
          { type: MatDialogContainer, decorators: [{ type: _angular_core.Optional },] },
      ]; };
      MatDialogTitle.propDecorators = {
          'id': [{ type: _angular_core.Input },],
      };
      return MatDialogTitle;
  }());
  /**
   * Scrollable content container of a dialog.
   */
  var MatDialogContent = (function () {
      function MatDialogContent() {
      }
      MatDialogContent.decorators = [
          { type: _angular_core.Directive, args: [{
                      selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]",
                      host: { 'class': 'mat-dialog-content' }
                  },] },
      ];
      /**
       * @nocollapse
       */
      MatDialogContent.ctorParameters = function () { return []; };
      return MatDialogContent;
  }());
  /**
   * Container for the bottom action buttons in a dialog.
   * Stays fixed to the bottom when scrolling.
   */
  var MatDialogActions = (function () {
      function MatDialogActions() {
      }
      MatDialogActions.decorators = [
          { type: _angular_core.Directive, args: [{
                      selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]",
                      host: { 'class': 'mat-dialog-actions' }
                  },] },
      ];
      /**
       * @nocollapse
       */
      MatDialogActions.ctorParameters = function () { return []; };
      return MatDialogActions;
  }());
  
  var MatDialogModule = (function () {
      function MatDialogModule() {
      }
      MatDialogModule.decorators = [
          { type: _angular_core.NgModule, args: [{
                      imports: [
                          _angular_common.CommonModule,
                          _angular_cdk_overlay.OverlayModule,
                          _angular_cdk_portal.PortalModule,
                          _angular_cdk_a11y.A11yModule,
                          MatCommonModule,
                      ],
                      exports: [
                          MatDialogContainer,
                          MatDialogClose,
                          MatDialogTitle,
                          MatDialogContent,
                          MatDialogActions,
                          MatCommonModule,
                      ],
                      declarations: [
                          MatDialogContainer,
                          MatDialogClose,
                          MatDialogTitle,
                          MatDialogActions,
                          MatDialogContent,
                      ],
                      providers: [
                          MatDialog,
                          MAT_DIALOG_SCROLL_STRATEGY_PROVIDER,
                      ],
                      entryComponents: [MatDialogContainer],
                  },] },
      ];
      /**
       * @nocollapse
       */
      MatDialogModule.ctorParameters = function () { return []; };
      return MatDialogModule;
  }());
  
  /**
   * Returns an exception to be thrown in the case when attempting to
   * load an icon with a name that cannot be found.
   * \@docs-private
   * @param {?} iconName
   * @return {?}
   */
  function getMatIconNameNotFoundError(iconName) {
      return Error("Unable to find icon with the name \"" + iconName + "\"");
  }
  /**
   * Returns an exception to be thrown when the consumer attempts to use
   * `<mat-icon>` without including \@angular/http.
   * \@docs-private
   * @return {?}
   */
  function getMatIconNoHttpProviderError() {
      return Error('Could not find Http provider for use with Angular Material icons. ' +
          'Please include the HttpModule from @angular/http in your app imports.');
  }
  /**
   * Returns an exception to be thrown when a URL couldn't be sanitized.
   * \@docs-private
   * @param {?} url URL that was attempted to be sanitized.
   * @return {?}
   */
  function getMatIconFailedToSanitizeError(url) {
      return Error("The URL provided to MatIconRegistry was not trusted as a resource URL " +
          ("via Angular's DomSanitizer. Attempted URL was \"" + url + "\"."));
  }
  /**
   * Configuration for an icon, including the URL and possibly the cached SVG element.
   * \@docs-private
   */
  var SvgIconConfig = (function () {
      /**
       * @param {?} url
       */
      function SvgIconConfig(url) {
          this.url = url;
          this.svgElement = null;
      }
      return SvgIconConfig;
  }());
  /**
   * Service to register and display icons used by the <mat-icon> component.
   * - Registers icon URLs by namespace and name.
   * - Registers icon set URLs by namespace.
   * - Registers aliases for CSS classes, for use with icon fonts.
   * - Loads icons from URLs and extracts individual icons from icon sets.
   */
  var MatIconRegistry = (function () {
      /**
       * @param {?} _http
       * @param {?} _sanitizer
       */
      function MatIconRegistry(_http, _sanitizer) {
          this._http = _http;
          this._sanitizer = _sanitizer;
          /**
           * URLs and cached SVG elements for individual icons. Keys are of the format "[namespace]:[icon]".
           */
          this._svgIconConfigs = new Map();
          /**
           * SvgIconConfig objects and cached SVG elements for icon sets, keyed by namespace.
           * Multiple icon sets can be registered under the same namespace.
           */
          this._iconSetConfigs = new Map();
          /**
           * Cache for icons loaded by direct URLs.
           */
          this._cachedIconsByUrl = new Map();
          /**
           * In-progress icon fetches. Used to coalesce multiple requests to the same URL.
           */
          this._inProgressUrlFetches = new Map();
          /**
           * Map from font identifiers to their CSS class names. Used for icon fonts.
           */
          this._fontCssClassesByAlias = new Map();
          /**
           * The CSS class to apply when an <mat-icon> component has no icon name, url, or font specified.
           * The default 'material-icons' value assumes that the material icon font has been loaded as
           * described at http://google.github.io/material-design-icons/#icon-font-for-the-web
           */
          this._defaultFontSetClass = 'material-icons';
      }
      /**
       * Registers an icon by URL in the default namespace.
       * @param {?} iconName Name under which the icon should be registered.
       * @param {?} url
       * @return {?}
       */
      MatIconRegistry.prototype.addSvgIcon = function (iconName, url) {
          return this.addSvgIconInNamespace('', iconName, url);
      };
      /**
       * Registers an icon by URL in the specified namespace.
       * @param {?} namespace Namespace in which the icon should be registered.
       * @param {?} iconName Name under which the icon should be registered.
       * @param {?} url
       * @return {?}
       */
      MatIconRegistry.prototype.addSvgIconInNamespace = function (namespace, iconName, url) {
          var /** @type {?} */ key = iconKey(namespace, iconName);
          this._svgIconConfigs.set(key, new SvgIconConfig(url));
          return this;
      };
      /**
       * Registers an icon set by URL in the default namespace.
       * @param {?} url
       * @return {?}
       */
      MatIconRegistry.prototype.addSvgIconSet = function (url) {
          return this.addSvgIconSetInNamespace('', url);
      };
      /**
       * Registers an icon set by URL in the specified namespace.
       * @param {?} namespace Namespace in which to register the icon set.
       * @param {?} url
       * @return {?}
       */
      MatIconRegistry.prototype.addSvgIconSetInNamespace = function (namespace, url) {
          var /** @type {?} */ config = new SvgIconConfig(url);
          var /** @type {?} */ configNamespace = this._iconSetConfigs.get(namespace);
          if (configNamespace) {
              configNamespace.push(config);
          }
          else {
              this._iconSetConfigs.set(namespace, [config]);
          }
          return this;
      };
      /**
       * Defines an alias for a CSS class name to be used for icon fonts. Creating an matIcon
       * component with the alias as the fontSet input will cause the class name to be applied
       * to the <mat-icon> element.
       *
       * @param {?} alias Alias for the font.
       * @param {?=} className Class name override to be used instead of the alias.
       * @return {?}
       */
      MatIconRegistry.prototype.registerFontClassAlias = function (alias, className) {
          if (className === void 0) { className = alias; }
          this._fontCssClassesByAlias.set(alias, className);
          return this;
      };
      /**
       * Returns the CSS class name associated with the alias by a previous call to
       * registerFontClassAlias. If no CSS class has been associated, returns the alias unmodified.
       * @param {?} alias
       * @return {?}
       */
      MatIconRegistry.prototype.classNameForFontAlias = function (alias) {
          return this._fontCssClassesByAlias.get(alias) || alias;
      };
      /**
       * Sets the CSS class name to be used for icon fonts when an <mat-icon> component does not
       * have a fontSet input value, and is not loading an icon by name or URL.
       *
       * @param {?} className
       * @return {?}
       */
      MatIconRegistry.prototype.setDefaultFontSetClass = function (className) {
          this._defaultFontSetClass = className;
          return this;
      };
      /**
       * Returns the CSS class name to be used for icon fonts when an <mat-icon> component does not
       * have a fontSet input value, and is not loading an icon by name or URL.
       * @return {?}
       */
      MatIconRegistry.prototype.getDefaultFontSetClass = function () {
          return this._defaultFontSetClass;
      };
      /**
       * Returns an Observable that produces the icon (as an <svg> DOM element) from the given URL.
       * The response from the URL may be cached so this will not always cause an HTTP request, but
       * the produced element will always be a new copy of the originally fetched icon. (That is,
       * it will not contain any modifications made to elements previously returned).
       *
       * @param {?} safeUrl URL from which to fetch the SVG icon.
       * @return {?}
       */
      MatIconRegistry.prototype.getSvgIconFromUrl = function (safeUrl) {
          var _this = this;
          var /** @type {?} */ url = this._sanitizer.sanitize(_angular_core.SecurityContext.RESOURCE_URL, safeUrl);
          if (!url) {
              throw getMatIconFailedToSanitizeError(safeUrl);
          }
          var /** @type {?} */ cachedIcon = this._cachedIconsByUrl.get(url);
          if (cachedIcon) {
              return rxjs_observable_of.of(cloneSvg(cachedIcon));
          }
          return _angular_cdk_rxjs.RxChain.from(this._loadSvgIconFromConfig(new SvgIconConfig(url)))
              .call(_angular_cdk_rxjs.doOperator, function (svg) { return _this._cachedIconsByUrl.set(/** @type {?} */ ((url)), svg); })
              .call(_angular_cdk_rxjs.map, function (svg) { return cloneSvg(svg); })
              .result();
      };
      /**
       * Returns an Observable that produces the icon (as an <svg> DOM element) with the given name
       * and namespace. The icon must have been previously registered with addIcon or addIconSet;
       * if not, the Observable will throw an error.
       *
       * @param {?} name Name of the icon to be retrieved.
       * @param {?=} namespace Namespace in which to look for the icon.
       * @return {?}
       */
      MatIconRegistry.prototype.getNamedSvgIcon = function (name, namespace) {
          if (namespace === void 0) { namespace = ''; }
          // Return (copy of) cached icon if possible.
          var /** @type {?} */ key = iconKey(namespace, name);
          var /** @type {?} */ config = this._svgIconConfigs.get(key);
          if (config) {
              return this._getSvgFromConfig(config);
          }
          // See if we have any icon sets registered for the namespace.
          var /** @type {?} */ iconSetConfigs = this._iconSetConfigs.get(namespace);
          if (iconSetConfigs) {
              return this._getSvgFromIconSetConfigs(name, iconSetConfigs);
          }
          return rxjs_observable_throw._throw(getMatIconNameNotFoundError(key));
      };
      /**
       * Returns the cached icon for a SvgIconConfig if available, or fetches it from its URL if not.
       * @param {?} config
       * @return {?}
       */
      MatIconRegistry.prototype._getSvgFromConfig = function (config) {
          if (config.svgElement) {
              // We already have the SVG element for this icon, return a copy.
              return rxjs_observable_of.of(cloneSvg(config.svgElement));
          }
          else {
              // Fetch the icon from the config's URL, cache it, and return a copy.
              return _angular_cdk_rxjs.RxChain.from(this._loadSvgIconFromConfig(config))
                  .call(_angular_cdk_rxjs.doOperator, function (svg) { return config.svgElement = svg; })
                  .call(_angular_cdk_rxjs.map, function (svg) { return cloneSvg(svg); })
                  .result();
          }
      };
      /**
       * Attempts to find an icon with the specified name in any of the SVG icon sets.
       * First searches the available cached icons for a nested element with a matching name, and
       * if found copies the element to a new <svg> element. If not found, fetches all icon sets
       * that have not been cached, and searches again after all fetches are completed.
       * The returned Observable produces the SVG element if possible, and throws
       * an error if no icon with the specified name can be found.
       * @param {?} name
       * @param {?} iconSetConfigs
       * @return {?}
       */
      MatIconRegistry.prototype._getSvgFromIconSetConfigs = function (name, iconSetConfigs) {
          var _this = this;
          // For all the icon set SVG elements we've fetched, see if any contain an icon with the
          // requested name.
          var /** @type {?} */ namedIcon = this._extractIconWithNameFromAnySet(name, iconSetConfigs);
          if (namedIcon) {
              // We could cache namedIcon in _svgIconConfigs, but since we have to make a copy every
              // time anyway, there's probably not much advantage compared to just always extracting
              // it from the icon set.
              return rxjs_observable_of.of(namedIcon);
          }
          // Not found in any cached icon sets. If there are icon sets with URLs that we haven't
          // fetched, fetch them now and look for iconName in the results.
          var /** @type {?} */ iconSetFetchRequests = iconSetConfigs
              .filter(function (iconSetConfig) { return !iconSetConfig.svgElement; })
              .map(function (iconSetConfig) {
              return _angular_cdk_rxjs.RxChain.from(_this._loadSvgIconSetFromConfig(iconSetConfig))
                  .call(_angular_cdk_rxjs.catchOperator, function (err) {
                  var /** @type {?} */ url = _this._sanitizer.sanitize(_angular_core.SecurityContext.RESOURCE_URL, iconSetConfig.url);
                  // Swallow errors fetching individual URLs so the combined Observable won't
                  // necessarily fail.
                  console.log("Loading icon set URL: " + url + " failed: " + err);
                  return rxjs_observable_of.of(null);
              })
                  .call(_angular_cdk_rxjs.doOperator, function (svg) {
                  // Cache the SVG element.
                  if (svg) {
                      iconSetConfig.svgElement = svg;
                  }
              })
                  .result();
          });
          // Fetch all the icon set URLs. When the requests complete, every IconSet should have a
          // cached SVG element (unless the request failed), and we can check again for the icon.
          return _angular_cdk_rxjs.map.call(rxjs_observable_forkJoin.forkJoin.call(rxjs_Observable.Observable, iconSetFetchRequests), function () {
              var /** @type {?} */ foundIcon = _this._extractIconWithNameFromAnySet(name, iconSetConfigs);
              if (!foundIcon) {
                  throw getMatIconNameNotFoundError(name);
              }
              return foundIcon;
          });
      };
      /**
       * Searches the cached SVG elements for the given icon sets for a nested icon element whose "id"
       * tag matches the specified name. If found, copies the nested element to a new SVG element and
       * returns it. Returns null if no matching element is found.
       * @param {?} iconName
       * @param {?} iconSetConfigs
       * @return {?}
       */
      MatIconRegistry.prototype._extractIconWithNameFromAnySet = function (iconName, iconSetConfigs) {
          // Iterate backwards, so icon sets added later have precedence.
          for (var /** @type {?} */ i = iconSetConfigs.length - 1; i >= 0; i--) {
              var /** @type {?} */ config = iconSetConfigs[i];
              if (config.svgElement) {
                  var /** @type {?} */ foundIcon = this._extractSvgIconFromSet(config.svgElement, iconName);
                  if (foundIcon) {
                      return foundIcon;
                  }
              }
          }
          return null;
      };
      /**
       * Loads the content of the icon URL specified in the SvgIconConfig and creates an SVG element
       * from it.
       * @param {?} config
       * @return {?}
       */
      MatIconRegistry.prototype._loadSvgIconFromConfig = function (config) {
          var _this = this;
          return _angular_cdk_rxjs.map.call(this._fetchUrl(config.url), function (svgText) { return _this._createSvgElementForSingleIcon(svgText); });
      };
      /**
       * Loads the content of the icon set URL specified in the SvgIconConfig and creates an SVG element
       * from it.
       * @param {?} config
       * @return {?}
       */
      MatIconRegistry.prototype._loadSvgIconSetFromConfig = function (config) {
          var _this = this;
          // TODO: Document that icons should only be loaded from trusted sources.
          return _angular_cdk_rxjs.map.call(this._fetchUrl(config.url), function (svgText) { return _this._svgElementFromString(svgText); });
      };
      /**
       * Creates a DOM element from the given SVG string, and adds default attributes.
       * @param {?} responseText
       * @return {?}
       */
      MatIconRegistry.prototype._createSvgElementForSingleIcon = function (responseText) {
          var /** @type {?} */ svg = this._svgElementFromString(responseText);
          this._setSvgAttributes(svg);
          return svg;
      };
      /**
       * Searches the cached element of the given SvgIconConfig for a nested icon element whose "id"
       * tag matches the specified name. If found, copies the nested element to a new SVG element and
       * returns it. Returns null if no matching element is found.
       * @param {?} iconSet
       * @param {?} iconName
       * @return {?}
       */
      MatIconRegistry.prototype._extractSvgIconFromSet = function (iconSet, iconName) {
          var /** @type {?} */ iconNode = iconSet.querySelector('#' + iconName);
          if (!iconNode) {
              return null;
          }
          // If the icon node is itself an <svg> node, clone and return it directly. If not, set it as
          // the content of a new <svg> node.
          if (iconNode.tagName.toLowerCase() === 'svg') {
              return this._setSvgAttributes(/** @type {?} */ (iconNode.cloneNode(true)));
          }
          // If the node is a <symbol>, it won't be rendered so we have to convert it into <svg>. Note
          // that the same could be achieved by referring to it via <use href="#id">, however the <use>
          // tag is problematic on Firefox, because it needs to include the current page path.
          if (iconNode.nodeName.toLowerCase() === 'symbol') {
              return this._setSvgAttributes(this._toSvgElement(iconNode));
          }
          // createElement('SVG') doesn't work as expected; the DOM ends up with
          // the correct nodes, but the SVG content doesn't render. Instead we
          // have to create an empty SVG node using innerHTML and append its content.
          // Elements created using DOMParser.parseFromString have the same problem.
          // http://stackoverflow.com/questions/23003278/svg-innerhtml-in-firefox-can-not-display
          var /** @type {?} */ svg = this._svgElementFromString('<svg></svg>');
          // Clone the node so we don't remove it from the parent icon set element.
          svg.appendChild(iconNode.cloneNode(true));
          return this._setSvgAttributes(svg);
      };
      /**
       * Creates a DOM element from the given SVG string.
       * @param {?} str
       * @return {?}
       */
      MatIconRegistry.prototype._svgElementFromString = function (str) {
          // TODO: Is there a better way than innerHTML? Renderer doesn't appear to have a method for
          // creating an element from an HTML string.
          var /** @type {?} */ div = document.createElement('DIV');
          div.innerHTML = str;
          var /** @type {?} */ svg = (div.querySelector('svg'));
          if (!svg) {
              throw Error('<svg> tag not found');
          }
          return svg;
      };
      /**
       * Converts an element into an SVG node by cloning all of its children.
       * @param {?} element
       * @return {?}
       */
      MatIconRegistry.prototype._toSvgElement = function (element) {
          var /** @type {?} */ svg = this._svgElementFromString('<svg></svg>');
          for (var /** @type {?} */ i = 0; i < element.childNodes.length; i++) {
              if (element.childNodes[i].nodeType === Node.ELEMENT_NODE) {
                  svg.appendChild(element.childNodes[i].cloneNode(true));
              }
          }
          return svg;
      };
      /**
       * Sets the default attributes for an SVG element to be used as an icon.
       * @param {?} svg
       * @return {?}
       */
      MatIconRegistry.prototype._setSvgAttributes = function (svg) {
          if (!svg.getAttribute('xmlns')) {
              svg.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
          }
          svg.setAttribute('fit', '');
          svg.setAttribute('height', '100%');
          svg.setAttribute('width', '100%');
          svg.setAttribute('preserveAspectRatio', 'xMidYMid meet');
          svg.setAttribute('focusable', 'false'); // Disable IE11 default behavior to make SVGs focusable.
          return svg;
      };
      /**
       * Returns an Observable which produces the string contents of the given URL. Results may be
       * cached, so future calls with the same URL may not cause another HTTP request.
       * @param {?} safeUrl
       * @return {?}
       */
      MatIconRegistry.prototype._fetchUrl = function (safeUrl) {
          var _this = this;
          if (!this._http) {
              throw getMatIconNoHttpProviderError();
          }
          var /** @type {?} */ url = this._sanitizer.sanitize(_angular_core.SecurityContext.RESOURCE_URL, safeUrl);
          if (!url) {
              throw getMatIconFailedToSanitizeError(safeUrl);
          }
          // Store in-progress fetches to avoid sending a duplicate request for a URL when there is
          // already a request in progress for that URL. It's necessary to call share() on the
          // Observable returned by http.get() so that multiple subscribers don't cause multiple XHRs.
          var /** @type {?} */ inProgressFetch = this._inProgressUrlFetches.get(url);
          if (inProgressFetch) {
              return inProgressFetch;
          }
          // TODO(jelbourn): for some reason, the `finally` operator "loses" the generic type on the
          // Observable. Figure out why and fix it.
          var /** @type {?} */ req = _angular_cdk_rxjs.RxChain.from(this._http.get(url))
              .call(_angular_cdk_rxjs.map, function (response) { return response.text(); })
              .call(_angular_cdk_rxjs.finallyOperator, function () { return _this._inProgressUrlFetches.delete(url); })
              .call(_angular_cdk_rxjs.share)
              .result();
          this._inProgressUrlFetches.set(url, req);
          return req;
      };
      MatIconRegistry.decorators = [
          { type: _angular_core.Injectable },
      ];
      /**
       * @nocollapse
       */
      MatIconRegistry.ctorParameters = function () { return [
          { type: _angular_http.Http, decorators: [{ type: _angular_core.Optional },] },
          { type: _angular_platformBrowser.DomSanitizer, },
      ]; };
      return MatIconRegistry;
  }());
  /**
   * \@docs-private
   * @param {?} parentRegistry
   * @param {?} http
   * @param {?} sanitizer
   * @return {?}
   */
  function ICON_REGISTRY_PROVIDER_FACTORY(parentRegistry, http, sanitizer) {
      return parentRegistry || new MatIconRegistry(http, sanitizer);
  }
  /**
   * \@docs-private
   */
  var ICON_REGISTRY_PROVIDER = {
      // If there is already an MatIconRegistry available, use that. Otherwise, provide a new one.
      provide: MatIconRegistry,
      deps: [[new _angular_core.Optional(), new _angular_core.SkipSelf(), MatIconRegistry], [new _angular_core.Optional(), _angular_http.Http], _angular_platformBrowser.DomSanitizer],
      useFactory: ICON_REGISTRY_PROVIDER_FACTORY
  };
  /**
   * Clones an SVGElement while preserving type information.
   * @param {?} svg
   * @return {?}
   */
  function cloneSvg(svg) {
      return (svg.cloneNode(true));
  }
  /**
   * Returns the cache key to use for an icon namespace and name.
   * @param {?} namespace
   * @param {?} name
   * @return {?}
   */
  function iconKey(namespace, name) {
      return namespace + ':' + name;
  }
  
  /**
   * \@docs-private
   */
  var MatIconBase = (function () {
      /**
       * @param {?} _renderer
       * @param {?} _elementRef
       */
      function MatIconBase(_renderer, _elementRef) {
          this._renderer = _renderer;
          this._elementRef = _elementRef;
      }
      return MatIconBase;
  }());
  var _MatIconMixinBase = mixinColor(MatIconBase);
  /**
   * Component to display an icon. It can be used in the following ways:
   *
   * - Specify the svgIcon input to load an SVG icon from a URL previously registered with the
   *   addSvgIcon, addSvgIconInNamespace, addSvgIconSet, or addSvgIconSetInNamespace methods of
   *   MatIconRegistry. If the svgIcon value contains a colon it is assumed to be in the format
   *   "[namespace]:[name]", if not the value will be the name of an icon in the default namespace.
   *   Examples:
   *     <mat-icon svgIcon="left-arrow"></mat-icon>
   *     <mat-icon svgIcon="animals:cat"></mat-icon>
   *
   * - Use a font ligature as an icon by putting the ligature text in the content of the <mat-icon>
   *   component. By default the Material icons font is used as described at
   *   http://google.github.io/material-design-icons/#icon-font-for-the-web. You can specify an
   *   alternate font by setting the fontSet input to either the CSS class to apply to use the
   *   desired font, or to an alias previously registered with MatIconRegistry.registerFontClassAlias.
   *   Examples:
   *     <mat-icon>home</mat-icon>
   *     <mat-icon fontSet="myfont">sun</mat-icon>
   *
   * - Specify a font glyph to be included via CSS rules by setting the fontSet input to specify the
   *   font, and the fontIcon input to specify the icon. Typically the fontIcon will specify a
   *   CSS class which causes the glyph to be displayed via a :before selector, as in
   *   https://fortawesome.github.io/Font-Awesome/examples/
   *   Example:
   *     <mat-icon fontSet="fa" fontIcon="alarm"></mat-icon>
   */
  var MatIcon = (function (_super) {
      __extends(MatIcon, _super);
      /**
       * @param {?} renderer
       * @param {?} elementRef
       * @param {?} _iconRegistry
       * @param {?} ariaHidden
       */
      function MatIcon(renderer, elementRef, _iconRegistry, ariaHidden) {
          var _this = _super.call(this, renderer, elementRef) || this;
          _this._iconRegistry = _iconRegistry;
          // If the user has not explicitly set aria-hidden, mark the icon as hidden, as this is
          // the right thing to do for the majority of icon use-cases.
          if (!ariaHidden) {
              renderer.setAttribute(elementRef.nativeElement, 'aria-hidden', 'true');
          }
          return _this;
      }
      /**
       * Splits an svgIcon binding value into its icon set and icon name components.
       * Returns a 2-element array of [(icon set), (icon name)].
       * The separator for the two fields is ':'. If there is no separator, an empty
       * string is returned for the icon set and the entire value is returned for
       * the icon name. If the argument is falsy, returns an array of two empty strings.
       * Throws an error if the name contains two or more ':' separators.
       * Examples:
       *   'social:cake' -> ['social', 'cake']
       *   'penguin' -> ['', 'penguin']
       *   null -> ['', '']
       *   'a:b:c' -> (throws Error)
       * @param {?} iconName
       * @return {?}
       */
      MatIcon.prototype._splitIconName = function (iconName) {
          if (!iconName) {
              return ['', ''];
          }
          var /** @type {?} */ parts = iconName.split(':');
          switch (parts.length) {
              case 1: return ['', parts[0]]; // Use default namespace.
              case 2: return (parts);
              default: throw Error("Invalid icon name: \"" + iconName + "\"");
          }
      };
      /**
       * @param {?} changes
       * @return {?}
       */
      MatIcon.prototype.ngOnChanges = function (changes) {
          var _this = this;
          // Only update the inline SVG icon if the inputs changed, to avoid unnecessary DOM operations.
          if (changes.svgIcon) {
              if (this.svgIcon) {
                  var _a = this._splitIconName(this.svgIcon), namespace = _a[0], iconName = _a[1];
                  _angular_cdk_rxjs.first.call(this._iconRegistry.getNamedSvgIcon(iconName, namespace)).subscribe(function (svg) { return _this._setSvgElement(svg); }, function (err) { return console.log("Error retrieving icon: " + err.message); });
              }
              else {
                  this._clearSvgElement();
              }
          }
          if (this._usingFontIcon()) {
              this._updateFontIconClasses();
          }
      };
      /**
       * @return {?}
       */
      MatIcon.prototype.ngOnInit = function () {
          // Update font classes because ngOnChanges won't be called if none of the inputs are present,
          // e.g. <mat-icon>arrow</mat-icon> In this case we need to add a CSS class for the default font.
          if (this._usingFontIcon()) {
              this._updateFontIconClasses();
          }
      };
      /**
       * @return {?}
       */
      MatIcon.prototype._usingFontIcon = function () {
          return !this.svgIcon;
      };
      /**
       * @param {?} svg
       * @return {?}
       */
      MatIcon.prototype._setSvgElement = function (svg) {
          this._clearSvgElement();
          this._renderer.appendChild(this._elementRef.nativeElement, svg);
      };
      /**
       * @return {?}
       */
      MatIcon.prototype._clearSvgElement = function () {
          var /** @type {?} */ layoutElement = this._elementRef.nativeElement;
          var /** @type {?} */ childCount = layoutElement.childNodes.length;
          // Remove existing child nodes and add the new SVG element. Note that we can't
          // use innerHTML, because IE will throw if the element has a data binding.
          for (var /** @type {?} */ i = 0; i < childCount; i++) {
              this._renderer.removeChild(layoutElement, layoutElement.childNodes[i]);
          }
      };
      /**
       * @return {?}
       */
      MatIcon.prototype._updateFontIconClasses = function () {
          if (!this._usingFontIcon()) {
              return;
          }
          var /** @type {?} */ elem = this._elementRef.nativeElement;
          var /** @type {?} */ fontSetClass = this.fontSet ?
              this._iconRegistry.classNameForFontAlias(this.fontSet) :
              this._iconRegistry.getDefaultFontSetClass();
          if (fontSetClass != this._previousFontSetClass) {
              if (this._previousFontSetClass) {
                  this._renderer.removeClass(elem, this._previousFontSetClass);
              }
              if (fontSetClass) {
                  this._renderer.addClass(elem, fontSetClass);
              }
              this._previousFontSetClass = fontSetClass;
          }
          if (this.fontIcon != this._previousFontIconClass) {
              if (this._previousFontIconClass) {
                  this._renderer.removeClass(elem, this._previousFontIconClass);
              }
              if (this.fontIcon) {
                  this._renderer.addClass(elem, this.fontIcon);
              }
              this._previousFontIconClass = this.fontIcon;
          }
      };
      MatIcon.decorators = [
          { type: _angular_core.Component, args: [{template: '<ng-content></ng-content>',
                      selector: 'mat-icon',
                      exportAs: 'matIcon',
                      styles: [".mat-icon{background-repeat:no-repeat;display:inline-block;fill:currentColor;height:24px;width:24px}"],
                      inputs: ['color'],
                      host: {
                          'role': 'img',
                          'class': 'mat-icon',
                      },
                      encapsulation: _angular_core.ViewEncapsulation.None,
                      preserveWhitespaces: false,
                      changeDetection: _angular_core.ChangeDetectionStrategy.OnPush,
                  },] },
      ];
      /**
       * @nocollapse
       */
      MatIcon.ctorParameters = function () { return [
          { type: _angular_core.Renderer2, },
          { type: _angular_core.ElementRef, },
          { type: MatIconRegistry, },
          { type: undefined, decorators: [{ type: _angular_core.Attribute, args: ['aria-hidden',] },] },
      ]; };
      MatIcon.propDecorators = {
          'svgIcon': [{ type: _angular_core.Input },],
          'fontSet': [{ type: _angular_core.Input },],
          'fontIcon': [{ type: _angular_core.Input },],
      };
      return MatIcon;
  }(_MatIconMixinBase));
  
  var MatIconModule = (function () {
      function MatIconModule() {
      }
      MatIconModule.decorators = [
          { type: _angular_core.NgModule, args: [{
                      imports: [MatCommonModule],
                      exports: [MatIcon, MatCommonModule],
                      declarations: [MatIcon],
                      providers: [ICON_REGISTRY_PROVIDER],
                  },] },
      ];
      /**
       * @nocollapse
       */
      MatIconModule.ctorParameters = function () { return []; };
      return MatIconModule;
  }());
  
  var nextUniqueId = 0;
  /**
   * Single error message to be shown underneath the form field.
   */
  var MatError = (function () {
      function MatError() {
          this.id = "mat-error-" + nextUniqueId++;
      }
      MatError.decorators = [
          { type: _angular_core.Directive, args: [{
                      selector: 'mat-error',
                      host: {
                          'class': 'mat-error',
                          'role': 'alert',
                          '[attr.id]': 'id',
                      }
                  },] },
      ];
      /**
       * @nocollapse
       */
      MatError.ctorParameters = function () { return []; };
      MatError.propDecorators = {
          'id': [{ type: _angular_core.Input },],
      };
      return MatError;
  }());
  
  /**
   * An interface which allows a control to work inside of a `MatFormField`.
   * @abstract
   */
  var MatFormFieldControl = (function () {
      function MatFormFieldControl() {
      }
      /**
       * Sets the list of element IDs that currently describe this control.
       * @abstract
       * @param {?} ids
       * @return {?}
       */
      MatFormFieldControl.prototype.setDescribedByIds = function (ids) { };
      /**
       * Handles a click on the control's container.
       * @abstract
       * @param {?} event
       * @return {?}
       */
      MatFormFieldControl.prototype.onContainerClick = function (event) { };
      return MatFormFieldControl;
  }());
  
  /**
   * \@docs-private
   * @return {?}
   */
  function getMatFormFieldPlaceholderConflictError() {
      return Error('Placeholder attribute and child element were both specified.');
  }
  /**
   * \@docs-private
   * @param {?} align
   * @return {?}
   */
  function getMatFormFieldDuplicatedHintError(align) {
      return Error("A hint was already declared for 'align=\"" + align + "\"'.");
  }
  /**
   * \@docs-private
   * @return {?}
   */
  function getMatFormFieldMissingControlError() {
      return Error('mat-form-field must contain a MatFormFieldControl. ' +
          'Did you forget to add matInput to the native input or textarea element?');
  }
  
  var nextUniqueId$2 = 0;
  /**
   * Hint text to be shown underneath the form field control.
   */
  var MatHint = (function () {
      function MatHint() {
          /**
           * Whether to align the hint label at the start or end of the line.
           */
          this.align = 'start';
          /**
           * Unique ID for the hint. Used for the aria-describedby on the form field control.
           */
          this.id = "mat-hint-" + nextUniqueId$2++;
      }
      MatHint.decorators = [
          { type: _angular_core.Directive, args: [{
                      selector: 'mat-hint',
                      host: {
                          'class': 'mat-hint',
                          '[class.mat-right]': 'align == "end"',
                          '[attr.id]': 'id',
                          // Remove align attribute to prevent it from interfering with layout.
                          '[attr.align]': 'null',
                      }
                  },] },
      ];
      /**
       * @nocollapse
       */
      MatHint.ctorParameters = function () { return []; };
      MatHint.propDecorators = {
          'align': [{ type: _angular_core.Input },],
          'id': [{ type: _angular_core.Input },],
      };
      return MatHint;
  }());
  
  /**
   * The floating placeholder for an `MatFormField`.
   */
  var MatPlaceholder = (function () {
      function MatPlaceholder() {
      }
      MatPlaceholder.decorators = [
          { type: _angular_core.Directive, args: [{
                      selector: 'mat-placeholder'
                  },] },
      ];
      /**
       * @nocollapse
       */
      MatPlaceholder.ctorParameters = function () { return []; };
      return MatPlaceholder;
  }());
  
  /**
   * Prefix to be placed the the front of the form field.
   */
  var MatPrefix = (function () {
      function MatPrefix() {
      }
      MatPrefix.decorators = [
          { type: _angular_core.Directive, args: [{
                      selector: '[matPrefix]',
                  },] },
      ];
      /**
       * @nocollapse
       */
      MatPrefix.ctorParameters = function () { return []; };
      return MatPrefix;
  }());
  
  /**
   * Suffix to be placed at the end of the form field.
   */
  var MatSuffix = (function () {
      function MatSuffix() {
      }
      MatSuffix.decorators = [
          { type: _angular_core.Directive, args: [{
                      selector: '[matSuffix]',
                  },] },
      ];
      /**
       * @nocollapse
       */
      MatSuffix.ctorParameters = function () { return []; };
      return MatSuffix;
  }());
  
  var nextUniqueId$1 = 0;
  /**
   * Container for form controls that applies Material Design styling and behavior.
   */
  var MatFormField = (function () {
      /**
       * @param {?} _elementRef
       * @param {?} _renderer
       * @param {?} _changeDetectorRef
       * @param {?} placeholderOptions
       */
      function MatFormField(_elementRef, _renderer, _changeDetectorRef, placeholderOptions) {
          this._elementRef = _elementRef;
          this._renderer = _renderer;
          this._changeDetectorRef = _changeDetectorRef;
          /**
           * Color of the form field underline, based on the theme.
           */
          this.color = 'primary';
          /**
           * Override for the logic that disables the placeholder animation in certain cases.
           */
          this._showAlwaysAnimate = false;
          /**
           * State of the mat-hint and mat-error animations.
           */
          this._subscriptAnimationState = '';
          this._hintLabel = '';
          // Unique id for the hint label.
          this._hintLabelId = "mat-hint-" + nextUniqueId$1++;
          this._placeholderOptions = placeholderOptions ? placeholderOptions : {};
          this.floatPlaceholder = this._placeholderOptions.float || 'auto';
      }
      Object.defineProperty(MatFormField.prototype, "dividerColor", {
          /**
           * @deprecated Use `color` instead.
           * @return {?}
           */
          get: function () { return this.color; },
          /**
           * @param {?} value
           * @return {?}
           */
          set: function (value) { this.color = value; },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(MatFormField.prototype, "hideRequiredMarker", {
          /**
           * Whether the required marker should be hidden.
           * @return {?}
           */
          get: function () { return this._hideRequiredMarker; },
          /**
           * @param {?} value
           * @return {?}
           */
          set: function (value) {
              this._hideRequiredMarker = _angular_cdk_coercion.coerceBooleanProperty(value);
          },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(MatFormField.prototype, "_shouldAlwaysFloat", {
          /**
           * Whether the floating label should always float or not.
           * @return {?}
           */
          get: function () {
              return this._floatPlaceholder === 'always' && !this._showAlwaysAnimate;
          },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(MatFormField.prototype, "_canPlaceholderFloat", {
          /**
           * Whether the placeholder can float or not.
           * @return {?}
           */
          get: function () { return this._floatPlaceholder !== 'never'; },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(MatFormField.prototype, "hintLabel", {
          /**
           * Text for the form field hint.
           * @return {?}
           */
          get: function () { return this._hintLabel; },
          /**
           * @param {?} value
           * @return {?}
           */
          set: function (value) {
              this._hintLabel = value;
              this._processHints();
          },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(MatFormField.prototype, "floatPlaceholder", {
          /**
           * Whether the placeholder should always float, never float or float as the user types.
           * @return {?}
           */
          get: function () { return this._floatPlaceholder; },
          /**
           * @param {?} value
           * @return {?}
           */
          set: function (value) {
              if (value !== this._floatPlaceholder) {
                  this._floatPlaceholder = value || this._placeholderOptions.float || 'auto';
                  this._changeDetectorRef.markForCheck();
              }
          },
          enumerable: true,
          configurable: true
      });
      /**
       * @return {?}
       */
      MatFormField.prototype.ngAfterContentInit = function () {
          var _this = this;
          this._validateControlChild();
          if (this._control.controlType) {
              this._renderer.addClass(this._elementRef.nativeElement, "mat-form-field-type-" + this._control.controlType);
          }
          // Subscribe to changes in the child control state in order to update the form field UI.
          _angular_cdk_rxjs.startWith.call(this._control.stateChanges, null).subscribe(function () {
              _this._validatePlaceholders();
              _this._syncDescribedByIds();
              _this._changeDetectorRef.markForCheck();
          });
          var /** @type {?} */ ngControl = this._control.ngControl;
          if (ngControl && ngControl.valueChanges) {
              ngControl.valueChanges.subscribe(function () {
                  _this._changeDetectorRef.markForCheck();
              });
          }
          // Re-validate when the number of hints changes.
          _angular_cdk_rxjs.startWith.call(this._hintChildren.changes, null).subscribe(function () {
              _this._processHints();
              _this._changeDetectorRef.markForCheck();
          });
          // Update the aria-described by when the number of errors changes.
          _angular_cdk_rxjs.startWith.call(this._errorChildren.changes, null).subscribe(function () {
              _this._syncDescribedByIds();
              _this._changeDetectorRef.markForCheck();
          });
      };
      /**
       * @return {?}
       */
      MatFormField.prototype.ngAfterContentChecked = function () {
          this._validateControlChild();
      };
      /**
       * @return {?}
       */
      MatFormField.prototype.ngAfterViewInit = function () {
          // Avoid animations on load.
          this._subscriptAnimationState = 'enter';
          this._changeDetectorRef.detectChanges();
      };
      /**
       * Determines whether a class from the NgControl should be forwarded to the host element.
       * @param {?} prop
       * @return {?}
       */
      MatFormField.prototype._shouldForward = function (prop) {
          var /** @type {?} */ ngControl = this._control ? this._control.ngControl : null;
          return ngControl && ((ngControl))[prop];
      };
      /**
       * Whether the form field has a placeholder.
       * @return {?}
       */
      MatFormField.prototype._hasPlaceholder = function () {
          return !!(this._control.placeholder || this._placeholderChild);
      };
      /**
       * Determines whether to display hints or errors.
       * @return {?}
       */
      MatFormField.prototype._getDisplayedMessages = function () {
          return (this._errorChildren && this._errorChildren.length > 0 &&
              this._control.errorState) ? 'error' : 'hint';
      };
      /**
       * Animates the placeholder up and locks it in position.
       * @return {?}
       */
      MatFormField.prototype._animateAndLockPlaceholder = function () {
          var _this = this;
          if (this._placeholder && this._canPlaceholderFloat) {
              this._showAlwaysAnimate = true;
              this._floatPlaceholder = 'always';
              _angular_cdk_rxjs.first.call(rxjs_observable_fromEvent.fromEvent(this._placeholder.nativeElement, 'transitionend')).subscribe(function () {
                  _this._showAlwaysAnimate = false;
              });
              this._changeDetectorRef.markForCheck();
          }
      };
      /**
       * Ensure that there is only one placeholder (either `placeholder` attribute on the child control
       * or child element with the `mat-placeholder` directive).
       * @return {?}
       */
      MatFormField.prototype._validatePlaceholders = function () {
          if (this._control.placeholder && this._placeholderChild) {
              throw getMatFormFieldPlaceholderConflictError();
          }
      };
      /**
       * Does any extra processing that is required when handling the hints.
       * @return {?}
       */
      MatFormField.prototype._processHints = function () {
          this._validateHints();
          this._syncDescribedByIds();
      };
      /**
       * Ensure that there is a maximum of one of each `<mat-hint>` alignment specified, with the
       * attribute being considered as `align="start"`.
       * @return {?}
       */
      MatFormField.prototype._validateHints = function () {
          var _this = this;
          if (this._hintChildren) {
              var /** @type {?} */ startHint_1;
              var /** @type {?} */ endHint_1;
              this._hintChildren.forEach(function (hint) {
                  if (hint.align == 'start') {
                      if (startHint_1 || _this.hintLabel) {
                          throw getMatFormFieldDuplicatedHintError('start');
                      }
                      startHint_1 = hint;
                  }
                  else if (hint.align == 'end') {
                      if (endHint_1) {
                          throw getMatFormFieldDuplicatedHintError('end');
                      }
                      endHint_1 = hint;
                  }
              });
          }
      };
      /**
       * Sets the list of element IDs that describe the child control. This allows the control to update
       * its `aria-describedby` attribute accordingly.
       * @return {?}
       */
      MatFormField.prototype._syncDescribedByIds = function () {
          if (this._control) {
              var /** @type {?} */ ids = [];
              if (this._getDisplayedMessages() === 'hint') {
                  var /** @type {?} */ startHint = this._hintChildren ?
                      this._hintChildren.find(function (hint) { return hint.align === 'start'; }) : null;
                  var /** @type {?} */ endHint = this._hintChildren ?
                      this._hintChildren.find(function (hint) { return hint.align === 'end'; }) : null;
                  if (startHint) {
                      ids.push(startHint.id);
                  }
                  else if (this._hintLabel) {
                      ids.push(this._hintLabelId);
                  }
                  if (endHint) {
                      ids.push(endHint.id);
                  }
              }
              else if (this._errorChildren) {
                  ids = this._errorChildren.map(function (error) { return error.id; });
              }
              this._control.setDescribedByIds(ids);
          }
      };
      /**
       * Throws an error if the form field's control is missing.
       * @return {?}
       */
      MatFormField.prototype._validateControlChild = function () {
          if (!this._control) {
              throw getMatFormFieldMissingControlError();
          }
      };
      MatFormField.decorators = [
          { type: _angular_core.Component, args: [{// TODO(mmalerba): the input-container selectors and classes are deprecated and will be removed.
                      selector: 'mat-input-container, mat-form-field',
                      exportAs: 'matFormField',
                      template: "<div class=\"mat-input-wrapper mat-form-field-wrapper\"><div class=\"mat-input-flex mat-form-field-flex\" #connectionContainer (click)=\"_control.onContainerClick && _control.onContainerClick($event)\"><div class=\"mat-input-prefix mat-form-field-prefix\" *ngIf=\"_prefixChildren.length\"><ng-content select=\"[matPrefix]\"></ng-content></div><div class=\"mat-input-infix mat-form-field-infix\"><ng-content></ng-content><span class=\"mat-input-placeholder-wrapper mat-form-field-placeholder-wrapper\"><label class=\"mat-input-placeholder mat-form-field-placeholder\" [attr.for]=\"_control.id\" [attr.aria-owns]=\"_control.id\" [class.mat-empty]=\"_control.empty && !_shouldAlwaysFloat\" [class.mat-form-field-empty]=\"_control.empty && !_shouldAlwaysFloat\" [class.mat-accent]=\"color == 'accent'\" [class.mat-warn]=\"color == 'warn'\" #placeholder *ngIf=\"_hasPlaceholder()\"><ng-content select=\"mat-placeholder\"></ng-content>{{_control.placeholder}} <span class=\"mat-placeholder-required mat-form-field-required-marker\" aria-hidden=\"true\" *ngIf=\"!hideRequiredMarker && _control.required\">*</span></label></span></div><div class=\"mat-input-suffix mat-form-field-suffix\" *ngIf=\"_suffixChildren.length\"><ng-content select=\"[matSuffix]\"></ng-content></div></div><div class=\"mat-input-underline mat-form-field-underline\" #underline [class.mat-disabled]=\"_control.disabled\"><span class=\"mat-input-ripple mat-form-field-ripple\" [class.mat-accent]=\"color == 'accent'\" [class.mat-warn]=\"color == 'warn'\"></span></div><div class=\"mat-input-subscript-wrapper mat-form-field-subscript-wrapper\" [ngSwitch]=\"_getDisplayedMessages()\"><div *ngSwitchCase=\"'error'\" [@transitionMessages]=\"_subscriptAnimationState\"><ng-content select=\"mat-error\"></ng-content></div><div class=\"mat-input-hint-wrapper mat-form-field-hint-wrapper\" *ngSwitchCase=\"'hint'\" [@transitionMessages]=\"_subscriptAnimationState\"><div *ngIf=\"hintLabel\" [id]=\"_hintLabelId\" class=\"mat-hint\">{{hintLabel}}</div><ng-content select=\"mat-hint:not([align='end'])\"></ng-content><div class=\"mat-input-hint-spacer mat-form-field-hint-spacer\"></div><ng-content select=\"mat-hint[align='end']\"></ng-content></div></div></div>",
                      // MatInput is a directive and can't have styles, so we need to include its styles here.
                      // The MatInput styles are fairly minimal so it shouldn't be a big deal for people who
                      // aren't using MatInput.
                      styles: [".mat-form-field{display:inline-block;position:relative;text-align:left}[dir=rtl] .mat-form-field{text-align:right}.mat-form-field-wrapper{position:relative}.mat-form-field-flex{display:inline-flex;align-items:baseline;width:100%}.mat-form-field-prefix,.mat-form-field-suffix{white-space:nowrap;flex:none}.mat-form-field-prefix .mat-icon,.mat-form-field-suffix .mat-icon{width:1em}.mat-form-field-prefix .mat-icon-button,.mat-form-field-suffix .mat-icon-button{font:inherit;vertical-align:baseline}.mat-form-field-prefix .mat-icon-button .mat-icon,.mat-form-field-suffix .mat-icon-button .mat-icon{font-size:inherit}.mat-form-field-infix{display:block;position:relative;flex:auto;min-width:0}.mat-form-field-placeholder-wrapper{position:absolute;left:0;box-sizing:content-box;width:100%;height:100%;overflow:hidden;pointer-events:none}.mat-form-field-placeholder{position:absolute;left:0;font:inherit;pointer-events:none;width:100%;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;transform:perspective(100px);-ms-transform:none;transform-origin:0 0;transition:transform .4s cubic-bezier(.25,.8,.25,1),color .4s cubic-bezier(.25,.8,.25,1),width .4s cubic-bezier(.25,.8,.25,1);display:none}[dir=rtl] .mat-form-field-placeholder{transform-origin:100% 0;left:auto;right:0}.mat-form-field-can-float.mat-form-field-should-float .mat-form-field-placeholder,.mat-form-field-empty.mat-form-field-placeholder{display:block}.mat-form-field-autofill-control:-webkit-autofill+.mat-form-field-placeholder-wrapper .mat-form-field-placeholder{display:none}.mat-form-field-can-float .mat-form-field-autofill-control:-webkit-autofill+.mat-form-field-placeholder-wrapper .mat-form-field-placeholder{display:block;transition:none}.mat-form-field-placeholder:not(.mat-form-field-empty){transition:none}.mat-form-field-underline{position:absolute;height:1px;width:100%}.mat-form-field-underline.mat-disabled{background-position:0;background-color:transparent}.mat-form-field-underline .mat-form-field-ripple{position:absolute;height:1px;top:0;left:0;width:100%;transform-origin:50%;transform:scaleX(.5);visibility:hidden;transition:background-color .3s cubic-bezier(.55,0,.55,.2)}.mat-focused .mat-form-field-underline .mat-form-field-ripple{height:2px}.mat-focused .mat-form-field-underline .mat-form-field-ripple,.mat-form-field-invalid .mat-form-field-underline .mat-form-field-ripple{visibility:visible;transform:scaleX(1);transition:transform 150ms linear,background-color .3s cubic-bezier(.55,0,.55,.2)}.mat-form-field-subscript-wrapper{position:absolute;width:100%;overflow:hidden}.mat-form-field-placeholder-wrapper .mat-icon,.mat-form-field-subscript-wrapper .mat-icon{width:1em;height:1em;font-size:inherit;vertical-align:baseline}.mat-form-field-hint-wrapper{display:flex}.mat-form-field-hint-spacer{flex:1 0 1em}.mat-error{display:block} .mat-input-element{font:inherit;background:0 0;color:currentColor;border:none;outline:0;padding:0;margin:0;width:100%;max-width:100%;vertical-align:bottom}.mat-input-element:-moz-ui-invalid{box-shadow:none}.mat-input-element::placeholder{color:transparent!important}.mat-input-element::-moz-placeholder{color:transparent!important}.mat-input-element::-webkit-input-placeholder{color:transparent!important}.mat-input-element:-ms-input-placeholder{color:transparent!important}textarea.mat-input-element{resize:vertical;overflow:auto}"],
                      animations: [
                          // TODO(mmalerba): Use angular animations for placeholder animation as well.
                          _angular_animations.trigger('transitionMessages', [
                              _angular_animations.state('enter', _angular_animations.style({ opacity: 1, transform: 'translateY(0%)' })),
                              _angular_animations.transition('void => enter', [
                                  _angular_animations.style({ opacity: 0, transform: 'translateY(-100%)' }),
                                  _angular_animations.animate('300ms cubic-bezier(0.55, 0, 0.55, 0.2)'),
                              ]),
                          ]),
                      ],
                      host: {
                          'class': 'mat-input-container mat-form-field',
                          '[class.mat-input-invalid]': '_control.errorState',
                          '[class.mat-form-field-invalid]': '_control.errorState',
                          '[class.mat-form-field-can-float]': '_canPlaceholderFloat',
                          '[class.mat-form-field-should-float]': '_control.shouldPlaceholderFloat || _shouldAlwaysFloat',
                          '[class.mat-focused]': '_control.focused',
                          '[class.mat-primary]': 'color == "primary"',
                          '[class.mat-accent]': 'color == "accent"',
                          '[class.mat-warn]': 'color == "warn"',
                          '[class.ng-untouched]': '_shouldForward("untouched")',
                          '[class.ng-touched]': '_shouldForward("touched")',
                          '[class.ng-pristine]': '_shouldForward("pristine")',
                          '[class.ng-dirty]': '_shouldForward("dirty")',
                          '[class.ng-valid]': '_shouldForward("valid")',
                          '[class.ng-invalid]': '_shouldForward("invalid")',
                          '[class.ng-pending]': '_shouldForward("pending")',
                      },
                      encapsulation: _angular_core.ViewEncapsulation.None,
                      preserveWhitespaces: false,
                      changeDetection: _angular_core.ChangeDetectionStrategy.OnPush,
                  },] },
      ];
      /**
       * @nocollapse
       */
      MatFormField.ctorParameters = function () { return [
          { type: _angular_core.ElementRef, },
          { type: _angular_core.Renderer2, },
          { type: _angular_core.ChangeDetectorRef, },
          { type: undefined, decorators: [{ type: _angular_core.Optional }, { type: _angular_core.Inject, args: [MAT_PLACEHOLDER_GLOBAL_OPTIONS,] },] },
      ]; };
      MatFormField.propDecorators = {
          'color': [{ type: _angular_core.Input },],
          'dividerColor': [{ type: _angular_core.Input },],
          'hideRequiredMarker': [{ type: _angular_core.Input },],
          'hintLabel': [{ type: _angular_core.Input },],
          'floatPlaceholder': [{ type: _angular_core.Input },],
          'underlineRef': [{ type: _angular_core.ViewChild, args: ['underline',] },],
          '_connectionContainerRef': [{ type: _angular_core.ViewChild, args: ['connectionContainer',] },],
          '_placeholder': [{ type: _angular_core.ViewChild, args: ['placeholder',] },],
          '_control': [{ type: _angular_core.ContentChild, args: [MatFormFieldControl,] },],
          '_placeholderChild': [{ type: _angular_core.ContentChild, args: [MatPlaceholder,] },],
          '_errorChildren': [{ type: _angular_core.ContentChildren, args: [MatError,] },],
          '_hintChildren': [{ type: _angular_core.ContentChildren, args: [MatHint,] },],
          '_prefixChildren': [{ type: _angular_core.ContentChildren, args: [MatPrefix,] },],
          '_suffixChildren': [{ type: _angular_core.ContentChildren, args: [MatSuffix,] },],
      };
      return MatFormField;
  }());
  
  /**
   * Function that attempts to coerce a value to a date using a DateAdapter. Date instances, null,
   * and undefined will be passed through. Empty strings will be coerced to null. Valid ISO 8601
   * strings (https://www.ietf.org/rfc/rfc3339.txt) will be coerced to dates. All other values will
   * result in an error being thrown.
   * @throws Throws when the value cannot be coerced.
   * @template D
   * @param {?} adapter The date adapter to use for coercion
   * @param {?} value The value to coerce.
   * @return {?} A date object coerced from the value.
   */
  function coerceDateProperty(adapter, value) {
      if (typeof value === 'string') {
          if (value == '') {
              value = null;
          }
          else {
              value = adapter.fromIso8601(value) || value;
          }
      }
      if (value == null || adapter.isDateInstance(value)) {
          return value;
      }
      throw Error("Datepicker: Value must be either a date object recognized by the DateAdapter or " +
          ("an ISO 8601 string. Instead got: " + value));
  }
  
  /**
   * \@docs-private
   * @param {?} provider
   * @return {?}
   */
  function createMissingDateImplError(provider) {
      return Error("MatDatepicker: No provider found for " + provider + ". You must import one of the following " +
          "modules at your application root: MatNativeDateModule, or provide a custom implementation.");
  }
  
  /**
   * Datepicker data that requires internationalization.
   */
  var MatDatepickerIntl = (function () {
      function MatDatepickerIntl() {
          /**
           * Stream that emits whenever the labels here are changed. Use this to notify
           * components if the labels have changed after initialization.
           */
          this.changes = new rxjs_Subject.Subject();
          /**
           * A label for the calendar popup (used by screen readers).
           */
          this.calendarLabel = 'Calendar';
          /**
           * A label for the button used to open the calendar popup (used by screen readers).
           */
          this.openCalendarLabel = 'Open calendar';
          /**
           * A label for the previous month button (used by screen readers).
           */
          this.prevMonthLabel = 'Previous month';
          /**
           * A label for the next month button (used by screen readers).
           */
          this.nextMonthLabel = 'Next month';
          /**
           * A label for the previous year button (used by screen readers).
           */
          this.prevYearLabel = 'Previous year';
          /**
           * A label for the next year button (used by screen readers).
           */
          this.nextYearLabel = 'Next year';
          /**
           * A label for the 'switch to month view' button (used by screen readers).
           */
          this.switchToMonthViewLabel = 'Change to month view';
          /**
           * A label for the 'switch to year view' button (used by screen readers).
           */
          this.switchToYearViewLabel = 'Change to year view';
      }
      MatDatepickerIntl.decorators = [
          { type: _angular_core.Injectable },
      ];
      /**
       * @nocollapse
       */
      MatDatepickerIntl.ctorParameters = function () { return []; };
      return MatDatepickerIntl;
  }());
  
  /**
   * An internal class that represents the data corresponding to a single calendar cell.
   * \@docs-private
   */
  var MatCalendarCell = (function () {
      /**
       * @param {?} value
       * @param {?} displayValue
       * @param {?} ariaLabel
       * @param {?} enabled
       */
      function MatCalendarCell(value, displayValue, ariaLabel, enabled) {
          this.value = value;
          this.displayValue = displayValue;
          this.ariaLabel = ariaLabel;
          this.enabled = enabled;
      }
      return MatCalendarCell;
  }());
  /**
   * An internal component used to display calendar data in a table.
   * \@docs-private
   */
  var MatCalendarBody = (function () {
      function MatCalendarBody() {
          /**
           * The number of columns in the table.
           */
          this.numCols = 7;
          /**
           * Whether to allow selection of disabled cells.
           */
          this.allowDisabledSelection = false;
          /**
           * The cell number of the active cell in the table.
           */
          this.activeCell = 0;
          /**
           * The aspect ratio (width / height) to use for the cells in the table. This aspect ratio will be
           * maintained even as the table resizes.
           */
          this.cellAspectRatio = 1;
          /**
           * Emits when a new value is selected.
           */
          this.selectedValueChange = new _angular_core.EventEmitter();
      }
      /**
       * @param {?} cell
       * @return {?}
       */
      MatCalendarBody.prototype._cellClicked = function (cell) {
          if (!this.allowDisabledSelection && !cell.enabled) {
              return;
          }
          this.selectedValueChange.emit(cell.value);
      };
      Object.defineProperty(MatCalendarBody.prototype, "_firstRowOffset", {
          /**
           * The number of blank cells to put at the beginning for the first row.
           * @return {?}
           */
          get: function () {
              return this.rows && this.rows.length && this.rows[0].length ?
                  this.numCols - this.rows[0].length : 0;
          },
          enumerable: true,
          configurable: true
      });
      /**
       * @param {?} rowIndex
       * @param {?} colIndex
       * @return {?}
       */
      MatCalendarBody.prototype._isActiveCell = function (rowIndex, colIndex) {
          var /** @type {?} */ cellNumber = rowIndex * this.numCols + colIndex;
          // Account for the fact that the first row may not have as many cells.
          if (rowIndex) {
              cellNumber -= this._firstRowOffset;
          }
          return cellNumber == this.activeCell;
      };
      MatCalendarBody.decorators = [
          { type: _angular_core.Component, args: [{selector: '[mat-calendar-body]',
                      template: "<tr *ngIf=\"_firstRowOffset < labelMinRequiredCells\" aria-hidden=\"true\"><td class=\"mat-calendar-body-label\" [attr.colspan]=\"numCols\" [style.paddingTop.%]=\"50 * cellAspectRatio / numCols\" [style.paddingBottom.%]=\"50 * cellAspectRatio / numCols\">{{label}}</td></tr><tr *ngFor=\"let row of rows; let rowIndex = index\" role=\"row\"><td *ngIf=\"rowIndex === 0 && _firstRowOffset\" aria-hidden=\"true\" class=\"mat-calendar-body-label\" [attr.colspan]=\"_firstRowOffset\" [style.paddingTop.%]=\"50 * cellAspectRatio / numCols\" [style.paddingBottom.%]=\"50 * cellAspectRatio / numCols\">{{_firstRowOffset >= labelMinRequiredCells ? label : ''}}</td><td *ngFor=\"let item of row; let colIndex = index\" role=\"gridcell\" class=\"mat-calendar-body-cell\" [tabindex]=\"_isActiveCell(rowIndex, colIndex) ? 0 : -1\" [class.mat-calendar-body-disabled]=\"!item.enabled\" [class.mat-calendar-body-active]=\"_isActiveCell(rowIndex, colIndex)\" [attr.aria-label]=\"item.ariaLabel\" [attr.aria-disabled]=\"!item.enabled || null\" (click)=\"_cellClicked(item)\" [style.width.%]=\"100 / numCols\" [style.paddingTop.%]=\"50 * cellAspectRatio / numCols\" [style.paddingBottom.%]=\"50 * cellAspectRatio / numCols\"><div class=\"mat-calendar-body-cell-content\" [class.mat-calendar-body-selected]=\"selectedValue === item.value\" [class.mat-calendar-body-today]=\"todayValue === item.value\">{{item.displayValue}}</div></td></tr>",
                      styles: [".mat-calendar-body{min-width:224px}.mat-calendar-body-label{height:0;line-height:0;text-align:left;padding-left:4.71429%;padding-right:4.71429%}.mat-calendar-body-cell{position:relative;height:0;line-height:0;text-align:center;outline:0;cursor:pointer}.mat-calendar-body-disabled{cursor:default}.mat-calendar-body-cell-content{position:absolute;top:5%;left:5%;display:flex;align-items:center;justify-content:center;box-sizing:border-box;width:90%;height:90%;line-height:1;border-width:1px;border-style:solid;border-radius:999px}[dir=rtl] .mat-calendar-body-label{text-align:right}"],
                      host: {
                          'class': 'mat-calendar-body',
                      },
                      encapsulation: _angular_core.ViewEncapsulation.None,
                      preserveWhitespaces: false,
                      changeDetection: _angular_core.ChangeDetectionStrategy.OnPush,
                  },] },
      ];
      /**
       * @nocollapse
       */
      MatCalendarBody.ctorParameters = function () { return []; };
      MatCalendarBody.propDecorators = {
          'label': [{ type: _angular_core.Input },],
          'rows': [{ type: _angular_core.Input },],
          'todayValue': [{ type: _angular_core.Input },],
          'selectedValue': [{ type: _angular_core.Input },],
          'labelMinRequiredCells': [{ type: _angular_core.Input },],
          'numCols': [{ type: _angular_core.Input },],
          'allowDisabledSelection': [{ type: _angular_core.Input },],
          'activeCell': [{ type: _angular_core.Input },],
          'cellAspectRatio': [{ type: _angular_core.Input },],
          'selectedValueChange': [{ type: _angular_core.Output },],
      };
      return MatCalendarBody;
  }());
  
  var DAYS_PER_WEEK = 7;
  /**
   * An internal component used to display a single month in the datepicker.
   * \@docs-private
   */
  var MatMonthView = (function () {
      /**
       * @param {?} _dateAdapter
       * @param {?} _dateFormats
       * @param {?} _changeDetectorRef
       */
      function MatMonthView(_dateAdapter, _dateFormats, _changeDetectorRef) {
          this._dateAdapter = _dateAdapter;
          this._dateFormats = _dateFormats;
          this._changeDetectorRef = _changeDetectorRef;
          /**
           * Emits when a new date is selected.
           */
          this.selectedChange = new _angular_core.EventEmitter();
          /**
           * Emits when any date is selected.
           */
          this._userSelection = new _angular_core.EventEmitter();
          if (!this._dateAdapter) {
              throw createMissingDateImplError('DateAdapter');
          }
          if (!this._dateFormats) {
              throw createMissingDateImplError('MAT_DATE_FORMATS');
          }
          var firstDayOfWeek = this._dateAdapter.getFirstDayOfWeek();
          var narrowWeekdays = this._dateAdapter.getDayOfWeekNames('narrow');
          var longWeekdays = this._dateAdapter.getDayOfWeekNames('long');
          // Rotate the labels for days of the week based on the configured first day of the week.
          var weekdays = longWeekdays.map(function (long, i) {
              return { long: long, narrow: narrowWeekdays[i] };
          });
          this._weekdays = weekdays.slice(firstDayOfWeek).concat(weekdays.slice(0, firstDayOfWeek));
          this._activeDate = this._dateAdapter.today();
      }
      Object.defineProperty(MatMonthView.prototype, "activeDate", {
          /**
           * The date to display in this month view (everything other than the month and year is ignored).
           * @return {?}
           */
          get: function () { return this._activeDate; },
          /**
           * @param {?} value
           * @return {?}
           */
          set: function (value) {
              var /** @type {?} */ oldActiveDate = this._activeDate;
              this._activeDate = coerceDateProperty(this._dateAdapter, value) || this._dateAdapter.today();
              if (!this._hasSameMonthAndYear(oldActiveDate, this._activeDate)) {
                  this._init();
              }
          },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(MatMonthView.prototype, "selected", {
          /**
           * The currently selected date.
           * @return {?}
           */
          get: function () { return this._selected; },
          /**
           * @param {?} value
           * @return {?}
           */
          set: function (value) {
              this._selected = coerceDateProperty(this._dateAdapter, value);
              this._selectedDate = this._getDateInCurrentMonth(this._selected);
          },
          enumerable: true,
          configurable: true
      });
      /**
       * @return {?}
       */
      MatMonthView.prototype.ngAfterContentInit = function () {
          this._init();
      };
      /**
       * Handles when a new date is selected.
       * @param {?} date
       * @return {?}
       */
      MatMonthView.prototype._dateSelected = function (date) {
          if (this._selectedDate != date) {
              var /** @type {?} */ selectedYear = this._dateAdapter.getYear(this.activeDate);
              var /** @type {?} */ selectedMonth = this._dateAdapter.getMonth(this.activeDate);
              var /** @type {?} */ selectedDate = this._dateAdapter.createDate(selectedYear, selectedMonth, date);
              this.selectedChange.emit(selectedDate);
          }
          this._userSelection.emit();
      };
      /**
       * Initializes this month view.
       * @return {?}
       */
      MatMonthView.prototype._init = function () {
          this._selectedDate = this._getDateInCurrentMonth(this.selected);
          this._todayDate = this._getDateInCurrentMonth(this._dateAdapter.today());
          this._monthLabel =
              this._dateAdapter.getMonthNames('short')[this._dateAdapter.getMonth(this.activeDate)]
                  .toLocaleUpperCase();
          var /** @type {?} */ firstOfMonth = this._dateAdapter.createDate(this._dateAdapter.getYear(this.activeDate), this._dateAdapter.getMonth(this.activeDate), 1);
          this._firstWeekOffset =
              (DAYS_PER_WEEK + this._dateAdapter.getDayOfWeek(firstOfMonth) -
                  this._dateAdapter.getFirstDayOfWeek()) % DAYS_PER_WEEK;
          this._createWeekCells();
          this._changeDetectorRef.markForCheck();
      };
      /**
       * Creates MatCalendarCells for the dates in this month.
       * @return {?}
       */
      MatMonthView.prototype._createWeekCells = function () {
          var /** @type {?} */ daysInMonth = this._dateAdapter.getNumDaysInMonth(this.activeDate);
          var /** @type {?} */ dateNames = this._dateAdapter.getDateNames();
          this._weeks = [[]];
          for (var /** @type {?} */ i = 0, /** @type {?} */ cell = this._firstWeekOffset; i < daysInMonth; i++, cell++) {
              if (cell == DAYS_PER_WEEK) {
                  this._weeks.push([]);
                  cell = 0;
              }
              var /** @type {?} */ date = this._dateAdapter.createDate(this._dateAdapter.getYear(this.activeDate), this._dateAdapter.getMonth(this.activeDate), i + 1);
              var /** @type {?} */ enabled = !this.dateFilter ||
                  this.dateFilter(date);
              var /** @type {?} */ ariaLabel = this._dateAdapter.format(date, this._dateFormats.display.dateA11yLabel);
              this._weeks[this._weeks.length - 1]
                  .push(new MatCalendarCell(i + 1, dateNames[i], ariaLabel, enabled));
          }
      };
      /**
       * Gets the date in this month that the given Date falls on.
       * Returns null if the given Date is in another month.
       * @param {?} date
       * @return {?}
       */
      MatMonthView.prototype._getDateInCurrentMonth = function (date) {
          return date && this._hasSameMonthAndYear(date, this.activeDate) ?
              this._dateAdapter.getDate(date) : null;
      };
      /**
       * Checks whether the 2 dates are non-null and fall within the same month of the same year.
       * @param {?} d1
       * @param {?} d2
       * @return {?}
       */
      MatMonthView.prototype._hasSameMonthAndYear = function (d1, d2) {
          return !!(d1 && d2 && this._dateAdapter.getMonth(d1) == this._dateAdapter.getMonth(d2) &&
              this._dateAdapter.getYear(d1) == this._dateAdapter.getYear(d2));
      };
      MatMonthView.decorators = [
          { type: _angular_core.Component, args: [{selector: 'mat-month-view',
                      template: "<table class=\"mat-calendar-table\"><thead class=\"mat-calendar-table-header\"><tr><th *ngFor=\"let day of _weekdays\" [attr.aria-label]=\"day.long\">{{day.narrow}}</th></tr><tr><th class=\"mat-calendar-table-header-divider\" colspan=\"7\" aria-hidden=\"true\"></th></tr></thead><tbody mat-calendar-body role=\"grid\" [label]=\"_monthLabel\" [rows]=\"_weeks\" [todayValue]=\"_todayDate\" [selectedValue]=\"_selectedDate\" [labelMinRequiredCells]=\"3\" [activeCell]=\"_dateAdapter.getDate(activeDate) - 1\" (selectedValueChange)=\"_dateSelected($event)\"></tbody></table>",
                      encapsulation: _angular_core.ViewEncapsulation.None,
                      preserveWhitespaces: false,
                      changeDetection: _angular_core.ChangeDetectionStrategy.OnPush,
                  },] },
      ];
      /**
       * @nocollapse
       */
      MatMonthView.ctorParameters = function () { return [
          { type: DateAdapter, decorators: [{ type: _angular_core.Optional },] },
          { type: undefined, decorators: [{ type: _angular_core.Optional }, { type: _angular_core.Inject, args: [MAT_DATE_FORMATS,] },] },
          { type: _angular_core.ChangeDetectorRef, },
      ]; };
      MatMonthView.propDecorators = {
          'activeDate': [{ type: _angular_core.Input },],
          'selected': [{ type: _angular_core.Input },],
          'dateFilter': [{ type: _angular_core.Input },],
          'selectedChange': [{ type: _angular_core.Output },],
          '_userSelection': [{ type: _angular_core.Output },],
      };
      return MatMonthView;
  }());
  
  /**
   * An internal component used to display a single year in the datepicker.
   * \@docs-private
   */
  var MatYearView = (function () {
      /**
       * @param {?} _dateAdapter
       * @param {?} _dateFormats
       * @param {?} _changeDetectorRef
       */
      function MatYearView(_dateAdapter, _dateFormats, _changeDetectorRef) {
          this._dateAdapter = _dateAdapter;
          this._dateFormats = _dateFormats;
          this._changeDetectorRef = _changeDetectorRef;
          /**
           * Emits when a new month is selected.
           */
          this.selectedChange = new _angular_core.EventEmitter();
          if (!this._dateAdapter) {
              throw createMissingDateImplError('DateAdapter');
          }
          if (!this._dateFormats) {
              throw createMissingDateImplError('MAT_DATE_FORMATS');
          }
          this._activeDate = this._dateAdapter.today();
      }
      Object.defineProperty(MatYearView.prototype, "activeDate", {
          /**
           * The date to display in this year view (everything other than the year is ignored).
           * @return {?}
           */
          get: function () { return this._activeDate; },
          /**
           * @param {?} value
           * @return {?}
           */
          set: function (value) {
              var /** @type {?} */ oldActiveDate = this._activeDate;
              this._activeDate = coerceDateProperty(this._dateAdapter, value) || this._dateAdapter.today();
              if (this._dateAdapter.getYear(oldActiveDate) != this._dateAdapter.getYear(this._activeDate)) {
                  this._init();
              }
          },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(MatYearView.prototype, "selected", {
          /**
           * The currently selected date.
           * @return {?}
           */
          get: function () { return this._selected; },
          /**
           * @param {?} value
           * @return {?}
           */
          set: function (value) {
              this._selected = coerceDateProperty(this._dateAdapter, value);
              this._selectedMonth = this._getMonthInCurrentYear(this._selected);
          },
          enumerable: true,
          configurable: true
      });
      /**
       * @return {?}
       */
      MatYearView.prototype.ngAfterContentInit = function () {
          this._init();
      };
      /**
       * Handles when a new month is selected.
       * @param {?} month
       * @return {?}
       */
      MatYearView.prototype._monthSelected = function (month) {
          var /** @type {?} */ daysInMonth = this._dateAdapter.getNumDaysInMonth(this._dateAdapter.createDate(this._dateAdapter.getYear(this.activeDate), month, 1));
          this.selectedChange.emit(this._dateAdapter.createDate(this._dateAdapter.getYear(this.activeDate), month, Math.min(this._dateAdapter.getDate(this.activeDate), daysInMonth)));
      };
      /**
       * Initializes this month view.
       * @return {?}
       */
      MatYearView.prototype._init = function () {
          var _this = this;
          this._selectedMonth = this._getMonthInCurrentYear(this.selected);
          this._todayMonth = this._getMonthInCurrentYear(this._dateAdapter.today());
          this._yearLabel = this._dateAdapter.getYearName(this.activeDate);
          var /** @type {?} */ monthNames = this._dateAdapter.getMonthNames('short');
          // First row of months only contains 5 elements so we can fit the year label on the same row.
          this._months = [[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11]].map(function (row) { return row.map(function (month) { return _this._createCellForMonth(month, monthNames[month]); }); });
          this._changeDetectorRef.markForCheck();
      };
      /**
       * Gets the month in this year that the given Date falls on.
       * Returns null if the given Date is in another year.
       * @param {?} date
       * @return {?}
       */
      MatYearView.prototype._getMonthInCurrentYear = function (date) {
          return date && this._dateAdapter.getYear(date) == this._dateAdapter.getYear(this.activeDate) ?
              this._dateAdapter.getMonth(date) : null;
      };
      /**
       * Creates an MatCalendarCell for the given month.
       * @param {?} month
       * @param {?} monthName
       * @return {?}
       */
      MatYearView.prototype._createCellForMonth = function (month, monthName) {
          var /** @type {?} */ ariaLabel = this._dateAdapter.format(this._dateAdapter.createDate(this._dateAdapter.getYear(this.activeDate), month, 1), this._dateFormats.display.monthYearA11yLabel);
          return new MatCalendarCell(month, monthName.toLocaleUpperCase(), ariaLabel, this._isMonthEnabled(month));
      };
      /**
       * Whether the given month is enabled.
       * @param {?} month
       * @return {?}
       */
      MatYearView.prototype._isMonthEnabled = function (month) {
          if (!this.dateFilter) {
              return true;
          }
          var /** @type {?} */ firstOfMonth = this._dateAdapter.createDate(this._dateAdapter.getYear(this.activeDate), month, 1);
          // If any date in the month is enabled count the month as enabled.
          for (var /** @type {?} */ date = firstOfMonth; this._dateAdapter.getMonth(date) == month; date = this._dateAdapter.addCalendarDays(date, 1)) {
              if (this.dateFilter(date)) {
                  return true;
              }
          }
          return false;
      };
      MatYearView.decorators = [
          { type: _angular_core.Component, args: [{selector: 'mat-year-view',
                      template: "<table class=\"mat-calendar-table\"><thead class=\"mat-calendar-table-header\"><tr><th class=\"mat-calendar-table-header-divider\" colspan=\"4\"></th></tr></thead><tbody mat-calendar-body role=\"grid\" allowDisabledSelection=\"true\" [label]=\"_yearLabel\" [rows]=\"_months\" [todayValue]=\"_todayMonth\" [selectedValue]=\"_selectedMonth\" [labelMinRequiredCells]=\"2\" [numCols]=\"4\" [cellAspectRatio]=\"4 / 7\" [activeCell]=\"_dateAdapter.getMonth(activeDate)\" (selectedValueChange)=\"_monthSelected($event)\"></tbody></table>",
                      encapsulation: _angular_core.ViewEncapsulation.None,
                      preserveWhitespaces: false,
                      changeDetection: _angular_core.ChangeDetectionStrategy.OnPush,
                  },] },
      ];
      /**
       * @nocollapse
       */
      MatYearView.ctorParameters = function () { return [
          { type: DateAdapter, decorators: [{ type: _angular_core.Optional },] },
          { type: undefined, decorators: [{ type: _angular_core.Optional }, { type: _angular_core.Inject, args: [MAT_DATE_FORMATS,] },] },
          { type: _angular_core.ChangeDetectorRef, },
      ]; };
      MatYearView.propDecorators = {
          'activeDate': [{ type: _angular_core.Input },],
          'selected': [{ type: _angular_core.Input },],
          'dateFilter': [{ type: _angular_core.Input },],
          'selectedChange': [{ type: _angular_core.Output },],
      };
      return MatYearView;
  }());
  
  /**
   * A calendar that is used as part of the datepicker.
   * \@docs-private
   */
  var MatCalendar = (function () {
      /**
       * @param {?} _elementRef
       * @param {?} _intl
       * @param {?} _ngZone
       * @param {?} _dateAdapter
       * @param {?} _dateFormats
       * @param {?} changeDetectorRef
       */
      function MatCalendar(_elementRef, _intl, _ngZone, _dateAdapter, _dateFormats, changeDetectorRef) {
          var _this = this;
          this._elementRef = _elementRef;
          this._intl = _intl;
          this._ngZone = _ngZone;
          this._dateAdapter = _dateAdapter;
          this._dateFormats = _dateFormats;
          /**
           * Whether the calendar should be started in month or year view.
           */
          this.startView = 'month';
          /**
           * Emits when the currently selected date changes.
           */
          this.selectedChange = new _angular_core.EventEmitter();
          /**
           * Emits when any date is selected.
           */
          this._userSelection = new _angular_core.EventEmitter();
          /**
           * Date filter for the month and year views.
           */
          this._dateFilterForViews = function (date) {
              return !!date &&
                  (!_this.dateFilter || _this.dateFilter(date)) &&
                  (!_this.minDate || _this._dateAdapter.compareDate(date, _this.minDate) >= 0) &&
                  (!_this.maxDate || _this._dateAdapter.compareDate(date, _this.maxDate) <= 0);
          };
          if (!this._dateAdapter) {
              throw createMissingDateImplError('DateAdapter');
          }
          if (!this._dateFormats) {
              throw createMissingDateImplError('MAT_DATE_FORMATS');
          }
          this._intlChanges = _intl.changes.subscribe(function () { return changeDetectorRef.markForCheck(); });
      }
      Object.defineProperty(MatCalendar.prototype, "startAt", {
          /**
           * A date representing the period (month or year) to start the calendar in.
           * @return {?}
           */
          get: function () { return this._startAt; },
          /**
           * @param {?} value
           * @return {?}
           */
          set: function (value) { this._startAt = coerceDateProperty(this._dateAdapter, value); },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(MatCalendar.prototype, "selected", {
          /**
           * The currently selected date.
           * @return {?}
           */
          get: function () { return this._selected; },
          /**
           * @param {?} value
           * @return {?}
           */
          set: function (value) { this._selected = coerceDateProperty(this._dateAdapter, value); },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(MatCalendar.prototype, "minDate", {
          /**
           * The minimum selectable date.
           * @return {?}
           */
          get: function () { return this._minDate; },
          /**
           * @param {?} value
           * @return {?}
           */
          set: function (value) { this._minDate = coerceDateProperty(this._dateAdapter, value); },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(MatCalendar.prototype, "maxDate", {
          /**
           * The maximum selectable date.
           * @return {?}
           */
          get: function () { return this._maxDate; },
          /**
           * @param {?} value
           * @return {?}
           */
          set: function (value) { this._maxDate = coerceDateProperty(this._dateAdapter, value); },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(MatCalendar.prototype, "_activeDate", {
          /**
           * The current active date. This determines which time period is shown and which date is
           * highlighted when using keyboard navigation.
           * @return {?}
           */
          get: function () { return this._clampedActiveDate; },
          /**
           * @param {?} value
           * @return {?}
           */
          set: function (value) {
              this._clampedActiveDate = this._dateAdapter.clampDate(value, this.minDate, this.maxDate);
          },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(MatCalendar.prototype, "_periodButtonText", {
          /**
           * The label for the current calendar view.
           * @return {?}
           */
          get: function () {
              return this._monthView ?
                  this._dateAdapter.format(this._activeDate, this._dateFormats.display.monthYearLabel)
                      .toLocaleUpperCase() :
                  this._dateAdapter.getYearName(this._activeDate);
          },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(MatCalendar.prototype, "_periodButtonLabel", {
          /**
           * @return {?}
           */
          get: function () {
              return this._monthView ? this._intl.switchToYearViewLabel : this._intl.switchToMonthViewLabel;
          },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(MatCalendar.prototype, "_prevButtonLabel", {
          /**
           * The label for the the previous button.
           * @return {?}
           */
          get: function () {
              return this._monthView ? this._intl.prevMonthLabel : this._intl.prevYearLabel;
          },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(MatCalendar.prototype, "_nextButtonLabel", {
          /**
           * The label for the the next button.
           * @return {?}
           */
          get: function () {
              return this._monthView ? this._intl.nextMonthLabel : this._intl.nextYearLabel;
          },
          enumerable: true,
          configurable: true
      });
      /**
       * @return {?}
       */
      MatCalendar.prototype.ngAfterContentInit = function () {
          this._activeDate = this.startAt || this._dateAdapter.today();
          this._focusActiveCell();
          this._monthView = this.startView != 'year';
      };
      /**
       * @return {?}
       */
      MatCalendar.prototype.ngOnDestroy = function () {
          this._intlChanges.unsubscribe();
      };
      /**
       * @param {?} changes
       * @return {?}
       */
      MatCalendar.prototype.ngOnChanges = function (changes) {
          var /** @type {?} */ change = changes.minDate || changes.maxDate || changes.dateFilter;
          if (change && !change.firstChange) {
              var /** @type {?} */ view = this.monthView || this.yearView;
              if (view) {
                  view._init();
              }
          }
      };
      /**
       * Handles date selection in the month view.
       * @param {?} date
       * @return {?}
       */
      MatCalendar.prototype._dateSelected = function (date) {
          if (!this._dateAdapter.sameDate(date, this.selected)) {
              this.selectedChange.emit(date);
          }
      };
      /**
       * @return {?}
       */
      MatCalendar.prototype._userSelected = function () {
          this._userSelection.emit();
      };
      /**
       * Handles month selection in the year view.
       * @param {?} month
       * @return {?}
       */
      MatCalendar.prototype._monthSelected = function (month) {
          this._activeDate = month;
          this._monthView = true;
      };
      /**
       * Handles user clicks on the period label.
       * @return {?}
       */
      MatCalendar.prototype._currentPeriodClicked = function () {
          this._monthView = !this._monthView;
      };
      /**
       * Handles user clicks on the previous button.
       * @return {?}
       */
      MatCalendar.prototype._previousClicked = function () {
          this._activeDate = this._monthView ?
              this._dateAdapter.addCalendarMonths(this._activeDate, -1) :
              this._dateAdapter.addCalendarYears(this._activeDate, -1);
      };
      /**
       * Handles user clicks on the next button.
       * @return {?}
       */
      MatCalendar.prototype._nextClicked = function () {
          this._activeDate = this._monthView ?
              this._dateAdapter.addCalendarMonths(this._activeDate, 1) :
              this._dateAdapter.addCalendarYears(this._activeDate, 1);
      };
      /**
       * Whether the previous period button is enabled.
       * @return {?}
       */
      MatCalendar.prototype._previousEnabled = function () {
          if (!this.minDate) {
              return true;
          }
          return !this.minDate || !this._isSameView(this._activeDate, this.minDate);
      };
      /**
       * Whether the next period button is enabled.
       * @return {?}
       */
      MatCalendar.prototype._nextEnabled = function () {
          return !this.maxDate || !this._isSameView(this._activeDate, this.maxDate);
      };
      /**
       * Handles keydown events on the calendar body.
       * @param {?} event
       * @return {?}
       */
      MatCalendar.prototype._handleCalendarBodyKeydown = function (event) {
          // TODO(mmalerba): We currently allow keyboard navigation to disabled dates, but just prevent
          // disabled ones from being selected. This may not be ideal, we should look into whether
          // navigation should skip over disabled dates, and if so, how to implement that efficiently.
          if (this._monthView) {
              this._handleCalendarBodyKeydownInMonthView(event);
          }
          else {
              this._handleCalendarBodyKeydownInYearView(event);
          }
      };
      /**
       * Focuses the active cell after the microtask queue is empty.
       * @return {?}
       */
      MatCalendar.prototype._focusActiveCell = function () {
          var _this = this;
          this._ngZone.runOutsideAngular(function () {
              rxjs_operator_first.first.call(_this._ngZone.onStable.asObservable()).subscribe(function () {
                  _this._elementRef.nativeElement.querySelector('.mat-calendar-body-active').focus();
              });
          });
      };
      /**
       * Whether the two dates represent the same view in the current view mode (month or year).
       * @param {?} date1
       * @param {?} date2
       * @return {?}
       */
      MatCalendar.prototype._isSameView = function (date1, date2) {
          return this._monthView ?
              this._dateAdapter.getYear(date1) == this._dateAdapter.getYear(date2) &&
                  this._dateAdapter.getMonth(date1) == this._dateAdapter.getMonth(date2) :
              this._dateAdapter.getYear(date1) == this._dateAdapter.getYear(date2);
      };
      /**
       * Handles keydown events on the calendar body when calendar is in month view.
       * @param {?} event
       * @return {?}
       */
      MatCalendar.prototype._handleCalendarBodyKeydownInMonthView = function (event) {
          switch (event.keyCode) {
              case _angular_cdk_keycodes.LEFT_ARROW:
                  this._activeDate = this._dateAdapter.addCalendarDays(this._activeDate, -1);
                  break;
              case _angular_cdk_keycodes.RIGHT_ARROW:
                  this._activeDate = this._dateAdapter.addCalendarDays(this._activeDate, 1);
                  break;
              case _angular_cdk_keycodes.UP_ARROW:
                  this._activeDate = this._dateAdapter.addCalendarDays(this._activeDate, -7);
                  break;
              case _angular_cdk_keycodes.DOWN_ARROW:
                  this._activeDate = this._dateAdapter.addCalendarDays(this._activeDate, 7);
                  break;
              case _angular_cdk_keycodes.HOME:
                  this._activeDate = this._dateAdapter.addCalendarDays(this._activeDate, 1 - this._dateAdapter.getDate(this._activeDate));
                  break;
              case _angular_cdk_keycodes.END:
                  this._activeDate = this._dateAdapter.addCalendarDays(this._activeDate, (this._dateAdapter.getNumDaysInMonth(this._activeDate) -
                      this._dateAdapter.getDate(this._activeDate)));
                  break;
              case _angular_cdk_keycodes.PAGE_UP:
                  this._activeDate = event.altKey ?
                      this._dateAdapter.addCalendarYears(this._activeDate, -1) :
                      this._dateAdapter.addCalendarMonths(this._activeDate, -1);
                  break;
              case _angular_cdk_keycodes.PAGE_DOWN:
                  this._activeDate = event.altKey ?
                      this._dateAdapter.addCalendarYears(this._activeDate, 1) :
                      this._dateAdapter.addCalendarMonths(this._activeDate, 1);
                  break;
              case _angular_cdk_keycodes.ENTER:
                  if (this._dateFilterForViews(this._activeDate)) {
                      this._dateSelected(this._activeDate);
                      // Prevent unexpected default actions such as form submission.
                      event.preventDefault();
                  }
                  return;
              default:
                  // Don't prevent default or focus active cell on keys that we don't explicitly handle.
                  return;
          }
          this._focusActiveCell();
          // Prevent unexpected default actions such as form submission.
          event.preventDefault();
      };
      /**
       * Handles keydown events on the calendar body when calendar is in year view.
       * @param {?} event
       * @return {?}
       */
      MatCalendar.prototype._handleCalendarBodyKeydownInYearView = function (event) {
          switch (event.keyCode) {
              case _angular_cdk_keycodes.LEFT_ARROW:
                  this._activeDate = this._dateAdapter.addCalendarMonths(this._activeDate, -1);
                  break;
              case _angular_cdk_keycodes.RIGHT_ARROW:
                  this._activeDate = this._dateAdapter.addCalendarMonths(this._activeDate, 1);
                  break;
              case _angular_cdk_keycodes.UP_ARROW:
                  this._activeDate = this._prevMonthInSameCol(this._activeDate);
                  break;
              case _angular_cdk_keycodes.DOWN_ARROW:
                  this._activeDate = this._nextMonthInSameCol(this._activeDate);
                  break;
              case _angular_cdk_keycodes.HOME:
                  this._activeDate = this._dateAdapter.addCalendarMonths(this._activeDate, -this._dateAdapter.getMonth(this._activeDate));
                  break;
              case _angular_cdk_keycodes.END:
                  this._activeDate = this._dateAdapter.addCalendarMonths(this._activeDate, 11 - this._dateAdapter.getMonth(this._activeDate));
                  break;
              case _angular_cdk_keycodes.PAGE_UP:
                  this._activeDate =
                      this._dateAdapter.addCalendarYears(this._activeDate, event.altKey ? -10 : -1);
                  break;
              case _angular_cdk_keycodes.PAGE_DOWN:
                  this._activeDate =
                      this._dateAdapter.addCalendarYears(this._activeDate, event.altKey ? 10 : 1);
                  break;
              case _angular_cdk_keycodes.ENTER:
                  this._monthSelected(this._activeDate);
                  break;
              default:
                  // Don't prevent default or focus active cell on keys that we don't explicitly handle.
                  return;
          }
          this._focusActiveCell();
          // Prevent unexpected default actions such as form submission.
          event.preventDefault();
      };
      /**
       * Determine the date for the month that comes before the given month in the same column in the
       * calendar table.
       * @param {?} date
       * @return {?}
       */
      MatCalendar.prototype._prevMonthInSameCol = function (date) {
          // Determine how many months to jump forward given that there are 2 empty slots at the beginning
          // of each year.
          var /** @type {?} */ increment = this._dateAdapter.getMonth(date) <= 4 ? -5 :
              (this._dateAdapter.getMonth(date) >= 7 ? -7 : -12);
          return this._dateAdapter.addCalendarMonths(date, increment);
      };
      /**
       * Determine the date for the month that comes after the given month in the same column in the
       * calendar table.
       * @param {?} date
       * @return {?}
       */
      MatCalendar.prototype._nextMonthInSameCol = function (date) {
          // Determine how many months to jump forward given that there are 2 empty slots at the beginning
          // of each year.
          var /** @type {?} */ increment = this._dateAdapter.getMonth(date) <= 4 ? 7 :
              (this._dateAdapter.getMonth(date) >= 7 ? 5 : 12);
          return this._dateAdapter.addCalendarMonths(date, increment);
      };
      MatCalendar.decorators = [
          { type: _angular_core.Component, args: [{selector: 'mat-calendar',
                      template: "<div class=\"mat-calendar-header\"><div class=\"mat-calendar-controls\"><button mat-button class=\"mat-calendar-period-button\" (click)=\"_currentPeriodClicked()\" [attr.aria-label]=\"_periodButtonLabel\">{{_periodButtonText}}<div class=\"mat-calendar-arrow\" [class.mat-calendar-invert]=\"!_monthView\"></div></button><div class=\"mat-calendar-spacer\"></div><button mat-icon-button class=\"mat-calendar-previous-button\" [disabled]=\"!_previousEnabled()\" (click)=\"_previousClicked()\" [attr.aria-label]=\"_prevButtonLabel\"></button> <button mat-icon-button class=\"mat-calendar-next-button\" [disabled]=\"!_nextEnabled()\" (click)=\"_nextClicked()\" [attr.aria-label]=\"_nextButtonLabel\"></button></div></div><div class=\"mat-calendar-content\" (keydown)=\"_handleCalendarBodyKeydown($event)\" [ngSwitch]=\"_monthView\" cdkMonitorSubtreeFocus><mat-month-view *ngSwitchCase=\"true\" [activeDate]=\"_activeDate\" [selected]=\"selected\" [dateFilter]=\"_dateFilterForViews\" (selectedChange)=\"_dateSelected($event)\" (_userSelection)=\"_userSelected()\"></mat-month-view><mat-year-view *ngSwitchDefault [activeDate]=\"_activeDate\" [selected]=\"selected\" [dateFilter]=\"_dateFilterForViews\" (selectedChange)=\"_monthSelected($event)\"></mat-year-view></div>",
                      styles: [".mat-calendar{display:block}.mat-calendar-header{padding:8px 8px 0 8px}.mat-calendar-content{padding:0 8px 8px 8px;outline:0}.mat-calendar-controls{display:flex;margin:5% calc(33% / 7 - 16px)}.mat-calendar-spacer{flex:1 1 auto}.mat-calendar-period-button{min-width:0}.mat-calendar-arrow{display:inline-block;width:0;height:0;border-left:5px solid transparent;border-right:5px solid transparent;border-top-width:5px;border-top-style:solid;margin:0 0 0 5px;vertical-align:middle}.mat-calendar-arrow.mat-calendar-invert{transform:rotate(180deg)}[dir=rtl] .mat-calendar-arrow{margin:0 5px 0 0}.mat-calendar-next-button,.mat-calendar-previous-button{position:relative}.mat-calendar-next-button::after,.mat-calendar-previous-button::after{top:0;left:0;right:0;bottom:0;position:absolute;content:'';margin:15.5px;border:0 solid currentColor;border-top-width:2px}[dir=rtl] .mat-calendar-next-button,[dir=rtl] .mat-calendar-previous-button{transform:rotate(180deg)}.mat-calendar-previous-button::after{border-left-width:2px;transform:translateX(2px) rotate(-45deg)}.mat-calendar-next-button::after{border-right-width:2px;transform:translateX(-2px) rotate(45deg)}.mat-calendar-table{border-spacing:0;border-collapse:collapse;width:100%}.mat-calendar-table-header th{text-align:center;padding:0 0 8px 0}.mat-calendar-table-header-divider{position:relative;height:1px}.mat-calendar-table-header-divider::after{content:'';position:absolute;top:0;left:-8px;right:-8px;height:1px}"],
                      host: {
                          'class': 'mat-calendar',
                      },
                      encapsulation: _angular_core.ViewEncapsulation.None,
                      preserveWhitespaces: false,
                      changeDetection: _angular_core.ChangeDetectionStrategy.OnPush,
                  },] },
      ];
      /**
       * @nocollapse
       */
      MatCalendar.ctorParameters = function () { return [
          { type: _angular_core.ElementRef, },
          { type: MatDatepickerIntl, },
          { type: _angular_core.NgZone, },
          { type: DateAdapter, decorators: [{ type: _angular_core.Optional },] },
          { type: undefined, decorators: [{ type: _angular_core.Optional }, { type: _angular_core.Inject, args: [MAT_DATE_FORMATS,] },] },
          { type: _angular_core.ChangeDetectorRef, },
      ]; };
      MatCalendar.propDecorators = {
          'startAt': [{ type: _angular_core.Input },],
          'startView': [{ type: _angular_core.Input },],
          'selected': [{ type: _angular_core.Input },],
          'minDate': [{ type: _angular_core.Input },],
          'maxDate': [{ type: _angular_core.Input },],
          'dateFilter': [{ type: _angular_core.Input },],
          'selectedChange': [{ type: _angular_core.Output },],
          '_userSelection': [{ type: _angular_core.Output },],
          'monthView': [{ type: _angular_core.ViewChild, args: [MatMonthView,] },],
          'yearView': [{ type: _angular_core.ViewChild, args: [MatYearView,] },],
      };
      return MatCalendar;
  }());
  
  /**
   * Used to generate a unique ID for each datepicker instance.
   */
  var datepickerUid = 0;
  /**
   * Injection token that determines the scroll handling while the calendar is open.
   */
  var MAT_DATEPICKER_SCROLL_STRATEGY = new _angular_core.InjectionToken('mat-datepicker-scroll-strategy');
  /**
   * \@docs-private
   * @param {?} overlay
   * @return {?}
   */
  function MAT_DATEPICKER_SCROLL_STRATEGY_PROVIDER_FACTORY(overlay) {
      return function () { return overlay.scrollStrategies.reposition(); };
  }
  /**
   * \@docs-private
   */
  var MAT_DATEPICKER_SCROLL_STRATEGY_PROVIDER = {
      provide: MAT_DATEPICKER_SCROLL_STRATEGY,
      deps: [_angular_cdk_overlay.Overlay],
      useFactory: MAT_DATEPICKER_SCROLL_STRATEGY_PROVIDER_FACTORY,
  };
  /**
   * Component used as the content for the datepicker dialog and popup. We use this instead of using
   * MatCalendar directly as the content so we can control the initial focus. This also gives us a
   * place to put additional features of the popup that are not part of the calendar itself in the
   * future. (e.g. confirmation buttons).
   * \@docs-private
   */
  var MatDatepickerContent = (function () {
      function MatDatepickerContent() {
      }
      /**
       * @return {?}
       */
      MatDatepickerContent.prototype.ngAfterContentInit = function () {
          this._calendar._focusActiveCell();
      };
      /**
       * Handles keydown event on datepicker content.
       * @param {?} event The event.
       * @return {?}
       */
      MatDatepickerContent.prototype._handleKeydown = function (event) {
          if (event.keyCode === _angular_cdk_keycodes.ESCAPE) {
              this.datepicker.close();
              event.preventDefault();
              event.stopPropagation();
          }
      };
      MatDatepickerContent.decorators = [
          { type: _angular_core.Component, args: [{selector: 'mat-datepicker-content',
                      template: "<mat-calendar cdkTrapFocus [id]=\"datepicker.id\" [startAt]=\"datepicker.startAt\" [startView]=\"datepicker.startView\" [minDate]=\"datepicker._minDate\" [maxDate]=\"datepicker._maxDate\" [dateFilter]=\"datepicker._dateFilter\" [selected]=\"datepicker._selected\" (selectedChange)=\"datepicker._select($event)\" (_userSelection)=\"datepicker.close()\"></mat-calendar>",
                      styles: [".mat-datepicker-content{box-shadow:0 5px 5px -3px rgba(0,0,0,.2),0 8px 10px 1px rgba(0,0,0,.14),0 3px 14px 2px rgba(0,0,0,.12);display:block}.mat-calendar{width:296px;height:354px}.mat-datepicker-content-touch{box-shadow:0 0 0 0 rgba(0,0,0,.2),0 0 0 0 rgba(0,0,0,.14),0 0 0 0 rgba(0,0,0,.12);display:block;max-height:80vh;overflow:auto;margin:-24px}.mat-datepicker-content-touch .mat-calendar{min-width:250px;min-height:312px;max-width:750px;max-height:788px}@media all and (orientation:landscape){.mat-datepicker-content-touch .mat-calendar{width:64vh;height:80vh}}@media all and (orientation:portrait){.mat-datepicker-content-touch .mat-calendar{width:80vw;height:100vw}}"],
                      host: {
                          'class': 'mat-datepicker-content',
                          '[class.mat-datepicker-content-touch]': 'datepicker.touchUi',
                          '(keydown)': '_handleKeydown($event)',
                      },
                      encapsulation: _angular_core.ViewEncapsulation.None,
                      preserveWhitespaces: false,
                      changeDetection: _angular_core.ChangeDetectionStrategy.OnPush,
                  },] },
      ];
      /**
       * @nocollapse
       */
      MatDatepickerContent.ctorParameters = function () { return []; };
      MatDatepickerContent.propDecorators = {
          '_calendar': [{ type: _angular_core.ViewChild, args: [MatCalendar,] },],
      };
      return MatDatepickerContent;
  }());
  /**
   * Component responsible for managing the datepicker popup/dialog.
   */
  var MatDatepicker = (function () {
      /**
       * @param {?} _dialog
       * @param {?} _overlay
       * @param {?} _ngZone
       * @param {?} _viewContainerRef
       * @param {?} _scrollStrategy
       * @param {?} _dateAdapter
       * @param {?} _dir
       * @param {?} _document
       */
      function MatDatepicker(_dialog, _overlay, _ngZone, _viewContainerRef, _scrollStrategy, _dateAdapter, _dir, _document) {
          this._dialog = _dialog;
          this._overlay = _overlay;
          this._ngZone = _ngZone;
          this._viewContainerRef = _viewContainerRef;
          this._scrollStrategy = _scrollStrategy;
          this._dateAdapter = _dateAdapter;
          this._dir = _dir;
          this._document = _document;
          /**
           * The view that the calendar should start in.
           */
          this.startView = 'month';
          /**
           * Whether the calendar UI is in touch mode. In touch mode the calendar opens in a dialog rather
           * than a popup and elements have more padding to allow for bigger touch targets.
           */
          this.touchUi = false;
          /**
           * Emits new selected date when selected date changes.
           * @deprecated Switch to the `dateChange` and `dateInput` binding on the input element.
           */
          this.selectedChanged = new _angular_core.EventEmitter();
          /**
           * Whether the calendar is open.
           */
          this.opened = false;
          /**
           * The id for the datepicker calendar.
           */
          this.id = "mat-datepicker-" + datepickerUid++;
          this._validSelected = null;
          /**
           * The element that was focused before the datepicker was opened.
           */
          this._focusedElementBeforeOpen = null;
          this._inputSubscription = rxjs_Subscription.Subscription.EMPTY;
          /**
           * Emits when the datepicker is disabled.
           */
          this._disabledChange = new rxjs_Subject.Subject();
          if (!this._dateAdapter) {
              throw createMissingDateImplError('DateAdapter');
          }
      }
      Object.defineProperty(MatDatepicker.prototype, "startAt", {
          /**
           * The date to open the calendar to initially.
           * @return {?}
           */
          get: function () {
              // If an explicit startAt is set we start there, otherwise we start at whatever the currently
              // selected value is.
              return this._startAt || (this._datepickerInput ? this._datepickerInput.value : null);
          },
          /**
           * @param {?} date
           * @return {?}
           */
          set: function (date) { this._startAt = coerceDateProperty(this._dateAdapter, date); },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(MatDatepicker.prototype, "disabled", {
          /**
           * Whether the datepicker pop-up should be disabled.
           * @return {?}
           */
          get: function () {
              return this._disabled === undefined && this._datepickerInput ?
                  this._datepickerInput.disabled : !!this._disabled;
          },
          /**
           * @param {?} value
           * @return {?}
           */
          set: function (value) {
              var /** @type {?} */ newValue = _angular_cdk_coercion.coerceBooleanProperty(value);
              if (newValue !== this._disabled) {
                  this._disabled = newValue;
                  this._disabledChange.next(newValue);
              }
          },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(MatDatepicker.prototype, "_selected", {
          /**
           * The currently selected date.
           * @return {?}
           */
          get: function () { return this._validSelected; },
          /**
           * @param {?} value
           * @return {?}
           */
          set: function (value) { this._validSelected = value; },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(MatDatepicker.prototype, "_minDate", {
          /**
           * The minimum selectable date.
           * @return {?}
           */
          get: function () {
              return this._datepickerInput && this._datepickerInput.min;
          },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(MatDatepicker.prototype, "_maxDate", {
          /**
           * The maximum selectable date.
           * @return {?}
           */
          get: function () {
              return this._datepickerInput && this._datepickerInput.max;
          },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(MatDatepicker.prototype, "_dateFilter", {
          /**
           * @return {?}
           */
          get: function () {
              return this._datepickerInput && this._datepickerInput._dateFilter;
          },
          enumerable: true,
          configurable: true
      });
      /**
       * @return {?}
       */
      MatDatepicker.prototype.ngOnDestroy = function () {
          this.close();
          this._inputSubscription.unsubscribe();
          this._disabledChange.complete();
          if (this._popupRef) {
              this._popupRef.dispose();
          }
      };
      /**
       * Selects the given date
       * @param {?} date
       * @return {?}
       */
      MatDatepicker.prototype._select = function (date) {
          var /** @type {?} */ oldValue = this._selected;
          this._selected = date;
          if (!this._dateAdapter.sameDate(oldValue, this._selected)) {
              this.selectedChanged.emit(date);
          }
      };
      /**
       * Register an input with this datepicker.
       * @param {?} input The datepicker input to register with this datepicker.
       * @return {?}
       */
      MatDatepicker.prototype._registerInput = function (input) {
          var _this = this;
          if (this._datepickerInput) {
              throw Error('An MatDatepicker can only be associated with a single input.');
          }
          this._datepickerInput = input;
          this._inputSubscription =
              this._datepickerInput._valueChange.subscribe(function (value) { return _this._selected = value; });
      };
      /**
       * Open the calendar.
       * @return {?}
       */
      MatDatepicker.prototype.open = function () {
          if (this.opened || this.disabled) {
              return;
          }
          if (!this._datepickerInput) {
              throw Error('Attempted to open an MatDatepicker with no associated input.');
          }
          if (this._document) {
              this._focusedElementBeforeOpen = this._document.activeElement;
          }
          this.touchUi ? this._openAsDialog() : this._openAsPopup();
          this.opened = true;
      };
      /**
       * Close the calendar.
       * @return {?}
       */
      MatDatepicker.prototype.close = function () {
          if (!this.opened) {
              return;
          }
          if (this._popupRef && this._popupRef.hasAttached()) {
              this._popupRef.detach();
          }
          if (this._dialogRef) {
              this._dialogRef.close();
              this._dialogRef = null;
          }
          if (this._calendarPortal && this._calendarPortal.isAttached) {
              this._calendarPortal.detach();
          }
          if (this._focusedElementBeforeOpen &&
              typeof this._focusedElementBeforeOpen.focus === 'function') {
              this._focusedElementBeforeOpen.focus();
              this._focusedElementBeforeOpen = null;
          }
          this.opened = false;
      };
      /**
       * Open the calendar as a dialog.
       * @return {?}
       */
      MatDatepicker.prototype._openAsDialog = function () {
          var _this = this;
          this._dialogRef = this._dialog.open(MatDatepickerContent, {
              direction: this._dir ? this._dir.value : 'ltr',
              viewContainerRef: this._viewContainerRef,
              panelClass: 'mat-datepicker-dialog',
          });
          this._dialogRef.afterClosed().subscribe(function () { return _this.close(); });
          this._dialogRef.componentInstance.datepicker = this;
      };
      /**
       * Open the calendar as a popup.
       * @return {?}
       */
      MatDatepicker.prototype._openAsPopup = function () {
          var _this = this;
          if (!this._calendarPortal) {
              this._calendarPortal = new _angular_cdk_portal.ComponentPortal(MatDatepickerContent, this._viewContainerRef);
          }
          if (!this._popupRef) {
              this._createPopup();
          }
          if (!this._popupRef.hasAttached()) {
              var /** @type {?} */ componentRef = this._popupRef.attach(this._calendarPortal);
              componentRef.instance.datepicker = this;
              // Update the position once the calendar has rendered.
              _angular_cdk_rxjs.first.call(this._ngZone.onStable.asObservable()).subscribe(function () {
                  _this._popupRef.updatePosition();
              });
          }
          this._popupRef.backdropClick().subscribe(function () { return _this.close(); });
      };
      /**
       * Create the popup.
       * @return {?}
       */
      MatDatepicker.prototype._createPopup = function () {
          var /** @type {?} */ overlayConfig = new _angular_cdk_overlay.OverlayConfig({
              positionStrategy: this._createPopupPositionStrategy(),
              hasBackdrop: true,
              backdropClass: 'mat-overlay-transparent-backdrop',
              direction: this._dir ? this._dir.value : 'ltr',
              scrollStrategy: this._scrollStrategy(),
              panelClass: 'mat-datepicker-popup',
          });
          this._popupRef = this._overlay.create(overlayConfig);
      };
      /**
       * Create the popup PositionStrategy.
       * @return {?}
       */
      MatDatepicker.prototype._createPopupPositionStrategy = function () {
          return this._overlay.position()
              .connectedTo(this._datepickerInput.getPopupConnectionElementRef(), { originX: 'start', originY: 'bottom' }, { overlayX: 'start', overlayY: 'top' })
              .withFallbackPosition({ originX: 'start', originY: 'top' }, { overlayX: 'start', overlayY: 'bottom' })
              .withFallbackPosition({ originX: 'end', originY: 'bottom' }, { overlayX: 'end', overlayY: 'top' })
              .withFallbackPosition({ originX: 'end', originY: 'top' }, { overlayX: 'end', overlayY: 'bottom' });
      };
      MatDatepicker.decorators = [
          { type: _angular_core.Component, args: [{selector: 'mat-datepicker',
                      template: '',
                      exportAs: 'matDatepicker',
                      changeDetection: _angular_core.ChangeDetectionStrategy.OnPush,
                      encapsulation: _angular_core.ViewEncapsulation.None,
                      preserveWhitespaces: false,
                  },] },
      ];
      /**
       * @nocollapse
       */
      MatDatepicker.ctorParameters = function () { return [
          { type: MatDialog, },
          { type: _angular_cdk_overlay.Overlay, },
          { type: _angular_core.NgZone, },
          { type: _angular_core.ViewContainerRef, },
          { type: undefined, decorators: [{ type: _angular_core.Inject, args: [MAT_DATEPICKER_SCROLL_STRATEGY,] },] },
          { type: DateAdapter, decorators: [{ type: _angular_core.Optional },] },
          { type: _angular_cdk_bidi.Directionality, decorators: [{ type: _angular_core.Optional },] },
          { type: undefined, decorators: [{ type: _angular_core.Optional }, { type: _angular_core.Inject, args: [_angular_platformBrowser.DOCUMENT,] },] },
      ]; };
      MatDatepicker.propDecorators = {
          'startAt': [{ type: _angular_core.Input },],
          'startView': [{ type: _angular_core.Input },],
          'touchUi': [{ type: _angular_core.Input },],
          'disabled': [{ type: _angular_core.Input },],
          'selectedChanged': [{ type: _angular_core.Output },],
      };
      return MatDatepicker;
  }());
  
  var MAT_DATEPICKER_VALUE_ACCESSOR = {
      provide: _angular_forms.NG_VALUE_ACCESSOR,
      useExisting: _angular_core.forwardRef(function () { return MatDatepickerInput; }),
      multi: true
  };
  var MAT_DATEPICKER_VALIDATORS = {
      provide: _angular_forms.NG_VALIDATORS,
      useExisting: _angular_core.forwardRef(function () { return MatDatepickerInput; }),
      multi: true
  };
  /**
   * An event used for datepicker input and change events. We don't always have access to a native
   * input or change event because the event may have been triggered by the user clicking on the
   * calendar popup. For consistency, we always use MatDatepickerInputEvent instead.
   */
  var MatDatepickerInputEvent = (function () {
      /**
       * @param {?} target
       * @param {?} targetElement
       */
      function MatDatepickerInputEvent(target, targetElement) {
          this.target = target;
          this.targetElement = targetElement;
          this.value = this.target.value;
      }
      return MatDatepickerInputEvent;
  }());
  /**
   * Directive used to connect an input to a MatDatepicker.
   */
  var MatDatepickerInput = (function () {
      /**
       * @param {?} _elementRef
       * @param {?} _renderer
       * @param {?} _dateAdapter
       * @param {?} _dateFormats
       * @param {?} _formField
       */
      function MatDatepickerInput(_elementRef, _renderer, _dateAdapter, _dateFormats, _formField) {
          var _this = this;
          this._elementRef = _elementRef;
          this._renderer = _renderer;
          this._dateAdapter = _dateAdapter;
          this._dateFormats = _dateFormats;
          this._formField = _formField;
          /**
           * Emits when a `change` event is fired on this `<input>`.
           */
          this.dateChange = new _angular_core.EventEmitter();
          /**
           * Emits when an `input` event is fired on this `<input>`.
           */
          this.dateInput = new _angular_core.EventEmitter();
          /**
           * Emits when the value changes (either due to user input or programmatic change).
           */
          this._valueChange = new _angular_core.EventEmitter();
          /**
           * Emits when the disabled state has changed
           */
          this._disabledChange = new _angular_core.EventEmitter();
          this._onTouched = function () { };
          this._cvaOnChange = function () { };
          this._validatorOnChange = function () { };
          this._datepickerSubscription = rxjs_Subscription.Subscription.EMPTY;
          this._localeSubscription = rxjs_Subscription.Subscription.EMPTY;
          /**
           * The form control validator for whether the input parses.
           */
          this._parseValidator = function () {
              return _this._lastValueValid ?
                  null : { 'matDatepickerParse': { 'text': _this._elementRef.nativeElement.value } };
          };
          /**
           * The form control validator for the min date.
           */
          this._minValidator = function (control) {
              var controlValue = coerceDateProperty(_this._dateAdapter, control.value);
              return (!_this.min || !controlValue ||
                  _this._dateAdapter.compareDate(_this.min, controlValue) <= 0) ?
                  null : { 'matDatepickerMin': { 'min': _this.min, 'actual': controlValue } };
          };
          /**
           * The form control validator for the max date.
           */
          this._maxValidator = function (control) {
              var controlValue = coerceDateProperty(_this._dateAdapter, control.value);
              return (!_this.max || !controlValue ||
                  _this._dateAdapter.compareDate(_this.max, controlValue) >= 0) ?
                  null : { 'matDatepickerMax': { 'max': _this.max, 'actual': controlValue } };
          };
          /**
           * The form control validator for the date filter.
           */
          this._filterValidator = function (control) {
              var controlValue = coerceDateProperty(_this._dateAdapter, control.value);
              return !_this._dateFilter || !controlValue || _this._dateFilter(controlValue) ?
                  null : { 'matDatepickerFilter': true };
          };
          /**
           * The combined form control validator for this input.
           */
          this._validator = _angular_forms.Validators.compose([this._parseValidator, this._minValidator, this._maxValidator, this._filterValidator]);
          /**
           * Whether the last value set on the input was valid.
           */
          this._lastValueValid = false;
          if (!this._dateAdapter) {
              throw createMissingDateImplError('DateAdapter');
          }
          if (!this._dateFormats) {
              throw createMissingDateImplError('MAT_DATE_FORMATS');
          }
          // Update the displayed date when the locale changes.
          this._localeSubscription = _dateAdapter.localeChanges.subscribe(function () {
              _this.value = _this.value;
          });
      }
      Object.defineProperty(MatDatepickerInput.prototype, "matDatepicker", {
          /**
           * The datepicker that this input is associated with.
           * @param {?} value
           * @return {?}
           */
          set: function (value) {
              this.registerDatepicker(value);
          },
          enumerable: true,
          configurable: true
      });
      /**
       * @param {?} value
       * @return {?}
       */
      MatDatepickerInput.prototype.registerDatepicker = function (value) {
          if (value) {
              this._datepicker = value;
              this._datepicker._registerInput(this);
          }
      };
      Object.defineProperty(MatDatepickerInput.prototype, "matDatepickerFilter", {
          /**
           * @param {?} filter
           * @return {?}
           */
          set: function (filter$$1) {
              this._dateFilter = filter$$1;
              this._validatorOnChange();
          },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(MatDatepickerInput.prototype, "value", {
          /**
           * The value of the input.
           * @return {?}
           */
          get: function () {
              return this._value;
          },
          /**
           * @param {?} value
           * @return {?}
           */
          set: function (value) {
              value = coerceDateProperty(this._dateAdapter, value);
              this._lastValueValid = !value || this._dateAdapter.isValid(value);
              value = this._getValidDateOrNull(value);
              var /** @type {?} */ oldDate = this.value;
              this._value = value;
              this._renderer.setProperty(this._elementRef.nativeElement, 'value', value ? this._dateAdapter.format(value, this._dateFormats.display.dateInput) : '');
              if (!this._dateAdapter.sameDate(oldDate, value)) {
                  this._valueChange.emit(value);
              }
          },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(MatDatepickerInput.prototype, "min", {
          /**
           * The minimum valid date.
           * @return {?}
           */
          get: function () { return this._min; },
          /**
           * @param {?} value
           * @return {?}
           */
          set: function (value) {
              this._min = coerceDateProperty(this._dateAdapter, value);
              this._validatorOnChange();
          },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(MatDatepickerInput.prototype, "max", {
          /**
           * The maximum valid date.
           * @return {?}
           */
          get: function () { return this._max; },
          /**
           * @param {?} value
           * @return {?}
           */
          set: function (value) {
              this._max = coerceDateProperty(this._dateAdapter, value);
              this._validatorOnChange();
          },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(MatDatepickerInput.prototype, "disabled", {
          /**
           * Whether the datepicker-input is disabled.
           * @return {?}
           */
          get: function () { return !!this._disabled; },
          /**
           * @param {?} value
           * @return {?}
           */
          set: function (value) {
              var /** @type {?} */ newValue = _angular_cdk_coercion.coerceBooleanProperty(value);
              if (this._disabled !== newValue) {
                  this._disabled = newValue;
                  this._disabledChange.emit(newValue);
              }
          },
          enumerable: true,
          configurable: true
      });
      /**
       * @return {?}
       */
      MatDatepickerInput.prototype.ngAfterContentInit = function () {
          var _this = this;
          if (this._datepicker) {
              this._datepickerSubscription =
                  this._datepicker.selectedChanged.subscribe(function (selected) {
                      _this.value = selected;
                      _this._cvaOnChange(selected);
                      _this._onTouched();
                      _this.dateInput.emit(new MatDatepickerInputEvent(_this, _this._elementRef.nativeElement));
                      _this.dateChange.emit(new MatDatepickerInputEvent(_this, _this._elementRef.nativeElement));
                  });
          }
      };
      /**
       * @return {?}
       */
      MatDatepickerInput.prototype.ngOnDestroy = function () {
          this._datepickerSubscription.unsubscribe();
          this._localeSubscription.unsubscribe();
          this._valueChange.complete();
          this._disabledChange.complete();
      };
      /**
       * @param {?} fn
       * @return {?}
       */
      MatDatepickerInput.prototype.registerOnValidatorChange = function (fn) {
          this._validatorOnChange = fn;
      };
      /**
       * @param {?} c
       * @return {?}
       */
      MatDatepickerInput.prototype.validate = function (c) {
          return this._validator ? this._validator(c) : null;
      };
      /**
       * Gets the element that the datepicker popup should be connected to.
       * @return {?} The element to connect the popup to.
       */
      MatDatepickerInput.prototype.getPopupConnectionElementRef = function () {
          return this._formField ? this._formField.underlineRef : this._elementRef;
      };
      /**
       * @param {?} value
       * @return {?}
       */
      MatDatepickerInput.prototype.writeValue = function (value) {
          this.value = value;
      };
      /**
       * @param {?} fn
       * @return {?}
       */
      MatDatepickerInput.prototype.registerOnChange = function (fn) {
          this._cvaOnChange = fn;
      };
      /**
       * @param {?} fn
       * @return {?}
       */
      MatDatepickerInput.prototype.registerOnTouched = function (fn) {
          this._onTouched = fn;
      };
      /**
       * @param {?} disabled
       * @return {?}
       */
      MatDatepickerInput.prototype.setDisabledState = function (disabled) {
          this.disabled = disabled;
      };
      /**
       * @param {?} event
       * @return {?}
       */
      MatDatepickerInput.prototype._onKeydown = function (event) {
          if (event.altKey && event.keyCode === _angular_cdk_keycodes.DOWN_ARROW) {
              this._datepicker.open();
              event.preventDefault();
          }
      };
      /**
       * @param {?} value
       * @return {?}
       */
      MatDatepickerInput.prototype._onInput = function (value) {
          var /** @type {?} */ date = this._dateAdapter.parse(value, this._dateFormats.parse.dateInput);
          this._lastValueValid = !date || this._dateAdapter.isValid(date);
          date = this._getValidDateOrNull(date);
          this._value = date;
          this._cvaOnChange(date);
          this._valueChange.emit(date);
          this.dateInput.emit(new MatDatepickerInputEvent(this, this._elementRef.nativeElement));
      };
      /**
       * @return {?}
       */
      MatDatepickerInput.prototype._onChange = function () {
          this.dateChange.emit(new MatDatepickerInputEvent(this, this._elementRef.nativeElement));
      };
      /**
       * @param {?} obj The object to check.
       * @return {?} The given object if it is both a date instance and valid, otherwise null.
       */
      MatDatepickerInput.prototype._getValidDateOrNull = function (obj) {
          return (this._dateAdapter.isDateInstance(obj) && this._dateAdapter.isValid(obj)) ? obj : null;
      };
      MatDatepickerInput.decorators = [
          { type: _angular_core.Directive, args: [{
                      selector: 'input[matDatepicker]',
                      providers: [MAT_DATEPICKER_VALUE_ACCESSOR, MAT_DATEPICKER_VALIDATORS],
                      host: {
                          '[attr.aria-haspopup]': 'true',
                          '[attr.aria-owns]': '(_datepicker?.opened && _datepicker.id) || null',
                          '[attr.min]': 'min ? _dateAdapter.toIso8601(min) : null',
                          '[attr.max]': 'max ? _dateAdapter.toIso8601(max) : null',
                          '[disabled]': 'disabled',
                          '(input)': '_onInput($event.target.value)',
                          '(change)': '_onChange()',
                          '(blur)': '_onTouched()',
                          '(keydown)': '_onKeydown($event)',
                      },
                      exportAs: 'matDatepickerInput',
                  },] },
      ];
      /**
       * @nocollapse
       */
      MatDatepickerInput.ctorParameters = function () { return [
          { type: _angular_core.ElementRef, },
          { type: _angular_core.Renderer2, },
          { type: DateAdapter, decorators: [{ type: _angular_core.Optional },] },
          { type: undefined, decorators: [{ type: _angular_core.Optional }, { type: _angular_core.Inject, args: [MAT_DATE_FORMATS,] },] },
          { type: MatFormField, decorators: [{ type: _angular_core.Optional },] },
      ]; };
      MatDatepickerInput.propDecorators = {
          'matDatepicker': [{ type: _angular_core.Input },],
          'matDatepickerFilter': [{ type: _angular_core.Input },],
          'value': [{ type: _angular_core.Input },],
          'min': [{ type: _angular_core.Input },],
          'max': [{ type: _angular_core.Input },],
          'disabled': [{ type: _angular_core.Input },],
          'dateChange': [{ type: _angular_core.Output },],
          'dateInput': [{ type: _angular_core.Output },],
      };
      return MatDatepickerInput;
  }());
  
  var MatDatepickerToggle = (function () {
      /**
       * @param {?} _intl
       * @param {?} _changeDetectorRef
       */
      function MatDatepickerToggle(_intl, _changeDetectorRef) {
          this._intl = _intl;
          this._changeDetectorRef = _changeDetectorRef;
          this._stateChanges = rxjs_Subscription.Subscription.EMPTY;
      }
      Object.defineProperty(MatDatepickerToggle.prototype, "disabled", {
          /**
           * Whether the toggle button is disabled.
           * @return {?}
           */
          get: function () {
              return this._disabled === undefined ? this.datepicker.disabled : !!this._disabled;
          },
          /**
           * @param {?} value
           * @return {?}
           */
          set: function (value) {
              this._disabled = _angular_cdk_coercion.coerceBooleanProperty(value);
          },
          enumerable: true,
          configurable: true
      });
      /**
       * @param {?} changes
       * @return {?}
       */
      MatDatepickerToggle.prototype.ngOnChanges = function (changes) {
          if (changes.datepicker) {
              this._watchStateChanges();
          }
      };
      /**
       * @return {?}
       */
      MatDatepickerToggle.prototype.ngOnDestroy = function () {
          this._stateChanges.unsubscribe();
      };
      /**
       * @return {?}
       */
      MatDatepickerToggle.prototype.ngAfterContentInit = function () {
          this._watchStateChanges();
      };
      /**
       * @param {?} event
       * @return {?}
       */
      MatDatepickerToggle.prototype._open = function (event) {
          if (this.datepicker && !this.disabled) {
              this.datepicker.open();
              event.stopPropagation();
          }
      };
      /**
       * @return {?}
       */
      MatDatepickerToggle.prototype._watchStateChanges = function () {
          var _this = this;
          var /** @type {?} */ datepickerDisabled = this.datepicker ? this.datepicker._disabledChange : rxjs_observable_of.of();
          var /** @type {?} */ inputDisabled = this.datepicker && this.datepicker._datepickerInput ?
              this.datepicker._datepickerInput._disabledChange : rxjs_observable_of.of();
          this._stateChanges.unsubscribe();
          this._stateChanges = rxjs_observable_merge.merge(this._intl.changes, datepickerDisabled, inputDisabled)
              .subscribe(function () { return _this._changeDetectorRef.markForCheck(); });
      };
      MatDatepickerToggle.decorators = [
          { type: _angular_core.Component, args: [{selector: 'mat-datepicker-toggle',
                      template: "<button mat-icon-button type=\"button\" [attr.aria-label]=\"_intl.openCalendarLabel\" [disabled]=\"disabled\" (click)=\"_open($event)\"><mat-icon><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" width=\"100%\" height=\"100%\" fill=\"currentColor\" style=\"vertical-align: top\" focusable=\"false\"><path d=\"M0 0h24v24H0z\" fill=\"none\"/><path d=\"M19 3h-1V1h-2v2H8V1H6v2H5c-1.11 0-1.99.9-1.99 2L3 19c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16H5V8h14v11zM7 10h5v5H7z\"/></svg></mat-icon></button>",
                      host: {
                          'class': 'mat-datepicker-toggle',
                      },
                      encapsulation: _angular_core.ViewEncapsulation.None,
                      preserveWhitespaces: false,
                      changeDetection: _angular_core.ChangeDetectionStrategy.OnPush,
                  },] },
      ];
      /**
       * @nocollapse
       */
      MatDatepickerToggle.ctorParameters = function () { return [
          { type: MatDatepickerIntl, },
          { type: _angular_core.ChangeDetectorRef, },
      ]; };
      MatDatepickerToggle.propDecorators = {
          'datepicker': [{ type: _angular_core.Input, args: ['for',] },],
          'disabled': [{ type: _angular_core.Input },],
      };
      return MatDatepickerToggle;
  }());
  
  var MatDatepickerModule = (function () {
      function MatDatepickerModule() {
      }
      MatDatepickerModule.decorators = [
          { type: _angular_core.NgModule, args: [{
                      imports: [
                          _angular_common.CommonModule,
                          MatButtonModule,
                          MatDialogModule,
                          MatIconModule,
                          _angular_cdk_overlay.OverlayModule,
                          _angular_cdk_a11y.A11yModule,
                      ],
                      exports: [
                          MatCalendar,
                          MatCalendarBody,
                          MatDatepicker,
                          MatDatepickerContent,
                          MatDatepickerInput,
                          MatDatepickerToggle,
                          MatMonthView,
                          MatYearView,
                      ],
                      declarations: [
                          MatCalendar,
                          MatCalendarBody,
                          MatDatepicker,
                          MatDatepickerContent,
                          MatDatepickerInput,
                          MatDatepickerToggle,
                          MatMonthView,
                          MatYearView,
                      ],
                      providers: [
                          MatDatepickerIntl,
                          MAT_DATEPICKER_SCROLL_STRATEGY_PROVIDER,
                      ],
                      entryComponents: [
                          MatDatepickerContent,
                      ]
                  },] },
      ];
      /**
       * @nocollapse
       */
      MatDatepickerModule.ctorParameters = function () { return []; };
      return MatDatepickerModule;
  }());
  
  exports.MatDatepickerModule = MatDatepickerModule;
  exports.MatCalendar = MatCalendar;
  exports.MatCalendarCell = MatCalendarCell;
  exports.MatCalendarBody = MatCalendarBody;
  exports.coerceDateProperty = coerceDateProperty;
  exports.MAT_DATEPICKER_SCROLL_STRATEGY = MAT_DATEPICKER_SCROLL_STRATEGY;
  exports.MAT_DATEPICKER_SCROLL_STRATEGY_PROVIDER_FACTORY = MAT_DATEPICKER_SCROLL_STRATEGY_PROVIDER_FACTORY;
  exports.MAT_DATEPICKER_SCROLL_STRATEGY_PROVIDER = MAT_DATEPICKER_SCROLL_STRATEGY_PROVIDER;
  exports.MatDatepickerContent = MatDatepickerContent;
  exports.MatDatepicker = MatDatepicker;
  exports.MAT_DATEPICKER_VALUE_ACCESSOR = MAT_DATEPICKER_VALUE_ACCESSOR;
  exports.MAT_DATEPICKER_VALIDATORS = MAT_DATEPICKER_VALIDATORS;
  exports.MatDatepickerInputEvent = MatDatepickerInputEvent;
  exports.MatDatepickerInput = MatDatepickerInput;
  exports.MatDatepickerIntl = MatDatepickerIntl;
  exports.MatDatepickerToggle = MatDatepickerToggle;
  exports.MatMonthView = MatMonthView;
  exports.MatYearView = MatYearView;
  
  Object.defineProperty(exports, '__esModule', { value: true });
  
  })));
  //# sourceMappingURL=material-datepicker.umd.js.map
  