text: /**
   * @license
   * Copyright Google Inc. All Rights Reserved.
   *
   * Use of this source code is governed by an MIT-style license that can be
   * found in the LICENSE file at https://angular.io/license
   */
  import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Directive, ElementRef, EventEmitter, Inject, Injectable, InjectionToken, Input, LOCALE_ID, NgModule, NgZone, Optional, Output, SkipSelf, ViewEncapsulation, isDevMode } from '@angular/core';
  import { DOCUMENT, HammerGestureConfig } from '@angular/platform-browser';
  import { BidiModule } from '@angular/cdk/bidi';
  import { coerceBooleanProperty } from '@angular/cdk/coercion';
  import { Subject } from 'rxjs/Subject';
  import { CommonModule } from '@angular/common';
  import { ScrollDispatchModule, VIEWPORT_RULER_PROVIDER, ViewportRuler } from '@angular/cdk/scrolling';
  import { Platform, PlatformModule } from '@angular/cdk/platform';
  import { ENTER, SPACE } from '@angular/cdk/keycodes';
  
  /**
   * \@docs-private
   */
  class AnimationCurves {
  }
  AnimationCurves.STANDARD_CURVE = 'cubic-bezier(0.4,0.0,0.2,1)';
  AnimationCurves.DECELERATION_CURVE = 'cubic-bezier(0.0,0.0,0.2,1)';
  AnimationCurves.ACCELERATION_CURVE = 'cubic-bezier(0.4,0.0,1,1)';
  AnimationCurves.SHARP_CURVE = 'cubic-bezier(0.4,0.0,0.6,1)';
  /**
   * \@docs-private
   */
  class AnimationDurations {
  }
  AnimationDurations.COMPLEX = '375ms';
  AnimationDurations.ENTERING = '225ms';
  AnimationDurations.EXITING = '195ms';
  
  const MATERIAL_COMPATIBILITY_MODE = new InjectionToken('md-compatibility-mode');
  /**
   * Returns an exception to be thrown if the consumer has used
  an invalid Material prefix on a component.
  \@docs-private
   * @param {?} prefix
   * @param {?} nodeName
   * @return {?}
   */
  function getMdCompatibilityInvalidPrefixError(prefix, nodeName) {
      return Error(`The "${prefix}-" prefix cannot be used in ng-material v1 compatibility mode. ` +
          `It was used on an "${nodeName.toLowerCase()}" element.`);
  }
  /**
   * Selector that matches all elements that may have style collisions with AngularJS Material.
   */
  const MAT_ELEMENTS_SELECTOR = `
    [mat-button],
    [mat-fab],
    [mat-icon-button],
    [mat-mini-fab],
    [mat-raised-button],
    [matCardSubtitle],
    [matCardTitle],
    [matCellDef],
    [matColumnDef],
    [matDialogActions],
    [matDialogClose],
    [matDialogContent],
    [matDialogTitle],
    [matHeaderCellDef],
    [matHeaderRowDef],
    [matLine],
    [matRowDef],
    [matStepLabel],
    [matStepperNext],
    [matStepperPrevious],
    [matTabLabel],
    [matTabLink],
    [matTabNav],
    [matTooltip],
    [matInput],
    [matPrefix],
    [matSuffix],
    mat-autocomplete,
    mat-button-toggle,
    mat-button-toggle,
    mat-button-toggle-group,
    mat-card,
    mat-card-actions,
    mat-card-content,
    mat-card-footer,
    mat-card-header,
    mat-card-subtitle,
    mat-card-title,
    mat-card-title-group,
    mat-cell,
    mat-checkbox,
    mat-chip,
    mat-dialog-actions,
    mat-dialog-container,
    mat-dialog-content,
    mat-divider,
    mat-error,
    mat-grid-list,
    mat-grid-tile,
    mat-grid-tile-footer,
    mat-grid-tile-header,
    mat-header-cell,
    mat-header-row,
    mat-hint,
    mat-horizontal-stepper,
    mat-icon,
    mat-input-container,
    mat-form-field,
    mat-list,
    mat-list-item,
    mat-menu,
    mat-nav-list,
    mat-option,
    mat-placeholder,
    mat-progress-bar,
    mat-pseudo-checkbox,
    mat-radio-button,
    mat-radio-group,
    mat-row,
    mat-select,
    mat-sidenav,
    mat-sidenav-container,
    mat-slider,
    mat-spinner,
    mat-step,
    mat-tab,
    mat-table,
    mat-tab-group,
    mat-toolbar,
    mat-vertical-stepper`;
  /**
   * Selector that matches all elements that may have style collisions with AngularJS Material.
   */
  const MD_ELEMENTS_SELECTOR = `
    [md-button],
    [md-fab],
    [md-icon-button],
    [md-mini-fab],
    [md-raised-button],
    [mdCardSubtitle],
    [mdCardTitle],
    [mdCellDef],
    [mdColumnDef],
    [mdDialogActions],
    [mdDialogClose],
    [mdDialogContent],
    [mdDialogTitle],
    [mdHeaderCellDef],
    [mdHeaderRowDef],
    [mdLine],
    [mdRowDef],
    [mdStepLabel],
    [mdStepperNext],
    [mdStepperPrevious],
    [mdTabLabel],
    [mdTabLink],
    [mdTabNav],
    [mdTooltip],
    [mdInput],
    [mdPrefix],
    [mdSuffix],
    md-autocomplete,
    md-button-toggle,
    md-button-toggle,
    md-button-toggle-group,
    md-card,
    md-card-actions,
    md-card-content,
    md-card-footer,
    md-card-header,
    md-card-subtitle,
    md-card-title,
    md-card-title-group,
    md-cell,
    md-checkbox,
    md-chip,
    md-dialog-actions,
    md-dialog-container,
    md-dialog-content,
    md-divider,
    md-error,
    md-grid-list,
    md-grid-tile,
    md-grid-tile-footer,
    md-grid-tile-header,
    md-header-cell,
    md-header-row,
    md-hint,
    md-horizontal-stepper,
    md-icon,
    md-input-container,
    md-form-field,
    md-list,
    md-list-item,
    md-menu,
    md-nav-list,
    md-option,
    md-placeholder,
    md-progress-bar,
    md-pseudo-checkbox,
    md-radio-button,
    md-radio-group,
    md-row,
    md-select,
    md-sidenav,
    md-sidenav-container,
    md-slider,
    md-spinner,
    md-step,
    md-tab,
    md-table,
    md-tab-group,
    md-toolbar,
    md-vertical-stepper`;
  /**
   * Directive that enforces that the `mat-` prefix cannot be used.
   */
  class MatPrefixRejector {
      /**
       * @param {?} isCompatibilityMode
       * @param {?} elementRef
       */
      constructor(isCompatibilityMode, elementRef) {
          if (!isCompatibilityMode) {
              throw getMdCompatibilityInvalidPrefixError('mat', elementRef.nativeElement.nodeName);
          }
      }
  }
  MatPrefixRejector.decorators = [
      { type: Directive, args: [{ selector: MAT_ELEMENTS_SELECTOR },] },
  ];
  /**
   * @nocollapse
   */
  MatPrefixRejector.ctorParameters = () => [
      { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [MATERIAL_COMPATIBILITY_MODE,] },] },
      { type: ElementRef, },
  ];
  /**
   * Directive that enforces that the `md-` prefix cannot be used.
   */
  class MdPrefixRejector {
      /**
       * @param {?} isCompatibilityMode
       * @param {?} elementRef
       */
      constructor(isCompatibilityMode, elementRef) {
          if (isCompatibilityMode) {
              throw getMdCompatibilityInvalidPrefixError('md', elementRef.nativeElement.nodeName);
          }
      }
  }
  MdPrefixRejector.decorators = [
      { type: Directive, args: [{ selector: MD_ELEMENTS_SELECTOR },] },
  ];
  /**
   * @nocollapse
   */
  MdPrefixRejector.ctorParameters = () => [
      { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [MATERIAL_COMPATIBILITY_MODE,] },] },
      { type: ElementRef, },
  ];
  /**
   * 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.
   */
  class CompatibilityModule {
  }
  CompatibilityModule.decorators = [
      { type: NgModule, args: [{
                  declarations: [MatPrefixRejector, MdPrefixRejector],
                  exports: [MatPrefixRejector, MdPrefixRejector],
              },] },
  ];
  /**
   * @nocollapse
   */
  CompatibilityModule.ctorParameters = () => [];
  /**
   * Module that enforces "no-conflict" compatibility mode settings. When this module is loaded,
  it will throw an error if there are any uses of the `md-` prefix.
   */
  class NoConflictStyleCompatibilityMode {
  }
  NoConflictStyleCompatibilityMode.decorators = [
      { type: NgModule, args: [{
                  providers: [{
                          provide: MATERIAL_COMPATIBILITY_MODE, useValue: true,
                      }],
              },] },
  ];
  /**
   * @nocollapse
   */
  NoConflictStyleCompatibilityMode.ctorParameters = () => [];
  
  /**
   * Injection token that configures whether the Material sanity checks are enabled.
   */
  const MATERIAL_SANITY_CHECKS = new InjectionToken('md-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., MdTabsModule).
   */
  class MdCommonModule {
      /**
       * @param {?} _document
       * @param {?} _sanityChecksEnabled
       */
      constructor(_document, _sanityChecksEnabled) {
          this._document = _document;
          /**
           * Whether we've done the global sanity checks (e.g. a theme is loaded, there is a doctype).
           */
          this._hasDoneGlobalChecks = false;
          if (_sanityChecksEnabled && !this._hasDoneGlobalChecks && _document && isDevMode()) {
              this._checkDoctype();
              this._checkTheme();
              this._hasDoneGlobalChecks = true;
          }
      }
      /**
       * @return {?}
       */
      _checkDoctype() {
          if (!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 {?}
       */
      _checkTheme() {
          if (typeof getComputedStyle === 'function') {
              const /** @type {?} */ testElement = this._document.createElement('div');
              testElement.classList.add('mat-theme-loaded-marker');
              this._document.body.appendChild(testElement);
              if (getComputedStyle(testElement).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);
          }
      }
  }
  MdCommonModule.decorators = [
      { type: NgModule, args: [{
                  imports: [CompatibilityModule, BidiModule],
                  exports: [CompatibilityModule, BidiModule],
                  providers: [{
                          provide: MATERIAL_SANITY_CHECKS, useValue: true,
                      }],
              },] },
  ];
  /**
   * @nocollapse
   */
  MdCommonModule.ctorParameters = () => [
      { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [DOCUMENT,] },] },
      { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [MATERIAL_SANITY_CHECKS,] },] },
  ];
  
  /**
   * Mixin to augment a directive with a `disabled` property.
   * @template T
   * @param {?} base
   * @return {?}
   */
  function mixinDisabled(base) {
      return class extends base {
          /**
           * @param {...?} args
           */
          constructor(...args) {
              super(...args);
              this._disabled = false;
          }
          /**
           * @return {?}
           */
          get disabled() { return this._disabled; }
          /**
           * @param {?} value
           * @return {?}
           */
          set disabled(value) { this._disabled = coerceBooleanProperty(value); }
      };
  }
  
  /**
   * Mixin to augment a directive with a `color` property.
   * @template T
   * @param {?} base
   * @param {?=} defaultColor
   * @return {?}
   */
  function mixinColor(base, defaultColor) {
      return class extends base {
          /**
           * @return {?}
           */
          get color() { return this._color; }
          /**
           * @param {?} value
           * @return {?}
           */
          set color(value) {
              const /** @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;
              }
          }
          /**
           * @param {...?} args
           */
          constructor(...args) {
              super(...args);
              // Set the default color that can be specified from the mixin.
              this.color = defaultColor;
          }
      };
  }
  
  /**
   * Mixin to augment a directive with a `disableRipple` property.
   * @template T
   * @param {?} base
   * @return {?}
   */
  function mixinDisableRipple(base) {
      return class extends base {
          /**
           * @param {...?} args
           */
          constructor(...args) {
              super(...args);
              this._disableRipple = false;
          }
          /**
           * Whether the ripple effect is disabled or not.
           * @return {?}
           */
          get disableRipple() { return this._disableRipple; }
          /**
           * @param {?} value
           * @return {?}
           */
          set disableRipple(value) { this._disableRipple = coerceBooleanProperty(value); }
      };
  }
  
  /**
   * Mixin to augment a directive with a `tabIndex` property.
   * @template T
   * @param {?} base
   * @param {?=} defaultTabIndex
   * @return {?}
   */
  function mixinTabIndex(base, defaultTabIndex = 0) {
      return class extends base {
          /**
           * @param {...?} args
           */
          constructor(...args) {
              super(...args);
              this._tabIndex = defaultTabIndex;
          }
          /**
           * @return {?}
           */
          get tabIndex() { return this.disabled ? -1 : this._tabIndex; }
          /**
           * @param {?} value
           * @return {?}
           */
          set tabIndex(value) {
              // If the specified tabIndex value is null or undefined, fall back to the default value.
              this._tabIndex = value != null ? value : defaultTabIndex;
          }
      };
  }
  
  /**
   * Class to coordinate unique selection based on name.
  Intended to be consumed as an Angular service.
  This service is needed because native radio change events are only fired on the item currently
  being selected, and we still need to uncheck the previous selection.
  
  This service does not *store* any IDs and names because they may change at any time, so it is
  less error-prone if they are simply passed through when the events occur.
   */
  class UniqueSelectionDispatcher {
      constructor() {
          this._listeners = [];
      }
      /**
       * Notify other items that selection for the given name has been set.
      \@param id ID of the item.
      \@param name Name of the item.
       * @param {?} id
       * @param {?} name
       * @return {?}
       */
      notify(id, name) {
          for (let /** @type {?} */ listener of this._listeners) {
              listener(id, name);
          }
      }
      /**
       * Listen for future changes to item selection.
      \@return Function used to deregister listener
       * @param {?} listener
       * @return {?}
       */
      listen(listener) {
          this._listeners.push(listener);
          return () => {
              this._listeners = this._listeners.filter((registered) => {
                  return listener !== registered;
              });
          };
      }
  }
  UniqueSelectionDispatcher.decorators = [
      { type: Injectable },
  ];
  /**
   * @nocollapse
   */
  UniqueSelectionDispatcher.ctorParameters = () => [];
  /**
   * \@docs-private
   * @param {?} parentDispatcher
   * @return {?}
   */
  function UNIQUE_SELECTION_DISPATCHER_PROVIDER_FACTORY(parentDispatcher) {
      return parentDispatcher || new UniqueSelectionDispatcher();
  }
  /**
   * \@docs-private
   */
  const UNIQUE_SELECTION_DISPATCHER_PROVIDER = {
      // If there is already a dispatcher available, use that. Otherwise, provide a new one.
      provide: UniqueSelectionDispatcher,
      deps: [[new Optional(), new SkipSelf(), UniqueSelectionDispatcher]],
      useFactory: UNIQUE_SELECTION_DISPATCHER_PROVIDER_FACTORY
  };
  
  /**
   * InjectionToken for datepicker that can be used to override default locale code.
   */
  const MAT_DATE_LOCALE = new InjectionToken('MAT_DATE_LOCALE');
  /**
   * Provider for MAT_DATE_LOCALE injection token.
   */
  const MAT_DATE_LOCALE_PROVIDER = { provide: MAT_DATE_LOCALE, useExisting: LOCALE_ID };
  /**
   * Adapts type `D` to be usable as a date by cdk-based components that work with dates.
   * @abstract
   */
  class DateAdapter {
      constructor() {
          this._localeChanges = new Subject();
      }
      /**
       * A stream that emits when the locale changes.
       * @return {?}
       */
      get localeChanges() { return this._localeChanges; }
      /**
       * Gets the year component of the given date.
      \@param date The date to extract the year from.
      \@returns The year component.
       * @abstract
       * @param {?} date
       * @return {?}
       */
      getYear(date) { }
      /**
       * Gets the month component of the given date.
      \@param date The date to extract the month from.
      \@returns The month component (0-indexed, 0 = January).
       * @abstract
       * @param {?} date
       * @return {?}
       */
      getMonth(date) { }
      /**
       * Gets the date of the month component of the given date.
      \@param date The date to extract the date of the month from.
      \@returns The month component (1-indexed, 1 = first of month).
       * @abstract
       * @param {?} date
       * @return {?}
       */
      getDate(date) { }
      /**
       * Gets the day of the week component of the given date.
      \@param date The date to extract the day of the week from.
      \@returns The month component (0-indexed, 0 = Sunday).
       * @abstract
       * @param {?} date
       * @return {?}
       */
      getDayOfWeek(date) { }
      /**
       * Gets a list of names for the months.
      \@param style The naming style (e.g. long = 'January', short = 'Jan', narrow = 'J').
      \@returns An ordered list of all month names, starting with January.
       * @abstract
       * @param {?} style
       * @return {?}
       */
      getMonthNames(style) { }
      /**
       * Gets a list of names for the dates of the month.
      \@returns An ordered list of all date of the month names, starting with '1'.
       * @abstract
       * @return {?}
       */
      getDateNames() { }
      /**
       * Gets a list of names for the days of the week.
      \@param style The naming style (e.g. long = 'Sunday', short = 'Sun', narrow = 'S').
      \@returns An ordered list of all weekday names, starting with Sunday.
       * @abstract
       * @param {?} style
       * @return {?}
       */
      getDayOfWeekNames(style) { }
      /**
       * Gets the name for the year of the given date.
      \@param date The date to get the year name for.
      \@returns The name of the given year (e.g. '2017').
       * @abstract
       * @param {?} date
       * @return {?}
       */
      getYearName(date) { }
      /**
       * Gets the first day of the week.
      \@returns The first day of the week (0-indexed, 0 = Sunday).
       * @abstract
       * @return {?}
       */
      getFirstDayOfWeek() { }
      /**
       * Gets the number of days in the month of the given date.
      \@param date The date whose month should be checked.
      \@returns The number of days in the month of the given date.
       * @abstract
       * @param {?} date
       * @return {?}
       */
      getNumDaysInMonth(date) { }
      /**
       * Clones the given date.
      \@param date The date to clone
      \@returns A new date equal to the given date.
       * @abstract
       * @param {?} date
       * @return {?}
       */
      clone(date) { }
      /**
       * Creates a date with the given year, month, and date. Does not allow over/under-flow of the
      month and date.
      \@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.
      \@returns The new date, or null if invalid.
       * @abstract
       * @param {?} year
       * @param {?} month
       * @param {?} date
       * @return {?}
       */
      createDate(year, month, date) { }
      /**
       * Gets today's date.
      \@returns Today's date.
       * @abstract
       * @return {?}
       */
      today() { }
      /**
       * Parses a date from a value.
      \@param value The value to parse.
      \@param parseFormat The expected format of the value being parsed
          (type is implementation-dependent).
      \@returns The parsed date.
       * @abstract
       * @param {?} value
       * @param {?} parseFormat
       * @return {?}
       */
      parse(value, parseFormat) { }
      /**
       * Formats a date as a string.
      \@param date The value to format.
      \@param displayFormat The format to use to display the date as a string.
      \@returns The formatted date string.
       * @abstract
       * @param {?} date
       * @param {?} displayFormat
       * @return {?}
       */
      format(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.
      \@param date The date to add years to.
      \@param years The number of years to add (may be negative).
      \@returns A new date equal to the given one with the specified number of years added.
       * @abstract
       * @param {?} date
       * @param {?} years
       * @return {?}
       */
      addCalendarYears(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.
      \@param date The date to add months to.
      \@param months The number of months to add (may be negative).
      \@returns A new date equal to the given one with the specified number of months added.
       * @abstract
       * @param {?} date
       * @param {?} months
       * @return {?}
       */
      addCalendarMonths(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.
      \@param date The date to add days to.
      \@param days The number of days to add (may be negative).
      \@returns A new date equal to the given one with the specified number of days added.
       * @abstract
       * @param {?} date
       * @param {?} days
       * @return {?}
       */
      addCalendarDays(date, days) { }
      /**
       * Gets the RFC 3339 compatible string (https://tools.ietf.org/html/rfc3339) for the given date.
      \@param date The date to get the ISO date string for.
      \@returns The ISO date string date string.
       * @abstract
       * @param {?} date
       * @return {?}
       */
      toIso8601(date) { }
      /**
       * Creates a date from an RFC 3339 compatible string (https://tools.ietf.org/html/rfc3339).
      \@param iso8601String The ISO date string to create a date from
      \@returns The date created from the ISO date string.
       * @abstract
       * @param {?} iso8601String
       * @return {?}
       */
      fromIso8601(iso8601String) { }
      /**
       * Checks whether the given object is considered a date instance by this DateAdapter.
      \@param obj The object to check
      \@returns Whether the object is a date instance.
       * @abstract
       * @param {?} obj
       * @return {?}
       */
      isDateInstance(obj) { }
      /**
       * Checks whether the given date is valid.
      \@param date The date to check.
      \@returns Whether the date is valid.
       * @abstract
       * @param {?} date
       * @return {?}
       */
      isValid(date) { }
      /**
       * Sets the locale used for all dates.
      \@param locale The new locale.
       * @param {?} locale
       * @return {?}
       */
      setLocale(locale) {
          this.locale = locale;
          this._localeChanges.next();
      }
      /**
       * Compares two dates.
      \@param first The first date to compare.
      \@param second The second date to compare.
      \@returns 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.
       * @param {?} first
       * @param {?} second
       * @return {?}
       */
      compareDate(first, second) {
          return this.getYear(first) - this.getYear(second) ||
              this.getMonth(first) - this.getMonth(second) ||
              this.getDate(first) - this.getDate(second);
      }
      /**
       * Checks if two dates are equal.
      \@param first The first date to check.
      \@param second The second date to check.
      \@returns {boolean} Whether the two dates are equal.
          Null dates are considered equal to other null dates.
       * @param {?} first
       * @param {?} second
       * @return {?}
       */
      sameDate(first, second) {
          return first && second ? !this.compareDate(first, second) : first == 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.
      \@returns `min` if `date` is less than `min`, `max` if date is greater than `max`,
          otherwise `date`.
       * @param {?} date
       * @param {?=} min
       * @param {?=} max
       * @return {?}
       */
      clampDate(date, min, max) {
          if (min && this.compareDate(date, min) < 0) {
              return min;
          }
          if (max && this.compareDate(date, max) > 0) {
              return max;
          }
          return date;
      }
  }
  
  /**
   * 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.
   * @param {?} dest
   * @param {...?} sources
   * @return {?}
   */
  function extendObject(dest, ...sources) {
      if (dest == null) {
          throw TypeError('Cannot convert undefined or null to object');
      }
      for (let /** @type {?} */ source of sources) {
          if (source != null) {
              for (let /** @type {?} */ key in source) {
                  if (source.hasOwnProperty(key)) {
                      dest[key] = source[key];
                  }
              }
          }
      }
      return dest;
  }
  
  /**
   * Whether the browser supports the Intl API.
   */
  const SUPPORTS_INTL_API = typeof Intl != 'undefined';
  /**
   * The default month names to use if Intl API is not available.
   */
  const 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.
   */
  const DEFAULT_DATE_NAMES = range(31, i => String(i + 1));
  /**
   * The default day of the week names to use if Intl API is not available.
   */
  const 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.
   */
  const 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) {
      const /** @type {?} */ valuesArray = Array(length);
      for (let /** @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.
   */
  class NativeDateAdapter extends DateAdapter {
      /**
       * @param {?} matDateLocale
       */
      constructor(matDateLocale) {
          super();
          /**
           * 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.setLocale(matDateLocale);
      }
      /**
       * @param {?} date
       * @return {?}
       */
      getYear(date) {
          return date.getFullYear();
      }
      /**
       * @param {?} date
       * @return {?}
       */
      getMonth(date) {
          return date.getMonth();
      }
      /**
       * @param {?} date
       * @return {?}
       */
      getDate(date) {
          return date.getDate();
      }
      /**
       * @param {?} date
       * @return {?}
       */
      getDayOfWeek(date) {
          return date.getDay();
      }
      /**
       * @param {?} style
       * @return {?}
       */
      getMonthNames(style) {
          if (SUPPORTS_INTL_API) {
              let /** @type {?} */ dtf = new Intl.DateTimeFormat(this.locale, { month: style });
              return range(12, i => this._stripDirectionalityCharacters(dtf.format(new Date(2017, i, 1))));
          }
          return DEFAULT_MONTH_NAMES[style];
      }
      /**
       * @return {?}
       */
      getDateNames() {
          if (SUPPORTS_INTL_API) {
              let /** @type {?} */ dtf = new Intl.DateTimeFormat(this.locale, { day: 'numeric' });
              return range(31, i => this._stripDirectionalityCharacters(dtf.format(new Date(2017, 0, i + 1))));
          }
          return DEFAULT_DATE_NAMES;
      }
      /**
       * @param {?} style
       * @return {?}
       */
      getDayOfWeekNames(style) {
          if (SUPPORTS_INTL_API) {
              let /** @type {?} */ dtf = new Intl.DateTimeFormat(this.locale, { weekday: style });
              return range(7, i => this._stripDirectionalityCharacters(dtf.format(new Date(2017, 0, i + 1))));
          }
          return DEFAULT_DAY_OF_WEEK_NAMES[style];
      }
      /**
       * @param {?} date
       * @return {?}
       */
      getYearName(date) {
          if (SUPPORTS_INTL_API) {
              let /** @type {?} */ dtf = new Intl.DateTimeFormat(this.locale, { year: 'numeric' });
              return this._stripDirectionalityCharacters(dtf.format(date));
          }
          return String(this.getYear(date));
      }
      /**
       * @return {?}
       */
      getFirstDayOfWeek() {
          // 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 {?}
       */
      getNumDaysInMonth(date) {
          return this.getDate(this._createDateWithOverflow(this.getYear(date), this.getMonth(date) + 1, 0));
      }
      /**
       * @param {?} date
       * @return {?}
       */
      clone(date) {
          return this.createDate(this.getYear(date), this.getMonth(date), this.getDate(date));
      }
      /**
       * @param {?} year
       * @param {?} month
       * @param {?} date
       * @return {?}
       */
      createDate(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.`);
          }
          let /** @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 {?}
       */
      today() {
          return new Date();
      }
      /**
       * @param {?} value
       * @return {?}
       */
      parse(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 {?}
       */
      format(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' });
              }
              let /** @type {?} */ dtf = new Intl.DateTimeFormat(this.locale, displayFormat);
              return this._stripDirectionalityCharacters(dtf.format(date));
          }
          return this._stripDirectionalityCharacters(date.toDateString());
      }
      /**
       * @param {?} date
       * @param {?} years
       * @return {?}
       */
      addCalendarYears(date, years) {
          return this.addCalendarMonths(date, years * 12);
      }
      /**
       * @param {?} date
       * @param {?} months
       * @return {?}
       */
      addCalendarMonths(date, months) {
          let /** @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 {?}
       */
      addCalendarDays(date, days) {
          return this._createDateWithOverflow(this.getYear(date), this.getMonth(date), this.getDate(date) + days);
      }
      /**
       * @param {?} date
       * @return {?}
       */
      toIso8601(date) {
          return [
              date.getUTCFullYear(),
              this._2digit(date.getUTCMonth() + 1),
              this._2digit(date.getUTCDate())
          ].join('-');
      }
      /**
       * @param {?} iso8601String
       * @return {?}
       */
      fromIso8601(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)) {
              let /** @type {?} */ d = new Date(iso8601String);
              if (this.isValid(d)) {
                  return d;
              }
          }
          return null;
      }
      /**
       * @param {?} obj
       * @return {?}
       */
      isDateInstance(obj) {
          return obj instanceof Date;
      }
      /**
       * @param {?} date
       * @return {?}
       */
      isValid(date) {
          return !isNaN(date.getTime());
      }
      /**
       * Creates a date but allows the month and date to overflow.
       * @param {?} year
       * @param {?} month
       * @param {?} date
       * @return {?}
       */
      _createDateWithOverflow(year, month, date) {
          let /** @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.
      \@returns The padded number.
       * @param {?} n
       * @return {?}
       */
      _2digit(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.
      \@returns The stripped string.
       * @param {?} str
       * @return {?}
       */
      _stripDirectionalityCharacters(str) {
          return str.replace(/[\u200e\u200f]/g, '');
      }
  }
  NativeDateAdapter.decorators = [
      { type: Injectable },
  ];
  /**
   * @nocollapse
   */
  NativeDateAdapter.ctorParameters = () => [
      { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [MAT_DATE_LOCALE,] },] },
  ];
  
  const MD_DATE_FORMATS = new InjectionToken('md-date-formats');
  
  const MD_NATIVE_DATE_FORMATS = {
      parse: {
          dateInput: null,
      },
      display: {
          dateInput: { year: 'numeric', month: 'numeric', day: 'numeric' },
          monthYearLabel: { year: 'numeric', month: 'short' },
          dateA11yLabel: { year: 'numeric', month: 'long', day: 'numeric' },
          monthYearA11yLabel: { year: 'numeric', month: 'long' },
      }
  };
  
  class NativeDateModule {
  }
  NativeDateModule.decorators = [
      { type: NgModule, args: [{
                  providers: [
                      { provide: DateAdapter, useClass: NativeDateAdapter },
                      MAT_DATE_LOCALE_PROVIDER
                  ],
              },] },
  ];
  /**
   * @nocollapse
   */
  NativeDateModule.ctorParameters = () => [];
  class MdNativeDateModule {
  }
  MdNativeDateModule.decorators = [
      { type: NgModule, args: [{
                  imports: [NativeDateModule],
                  providers: [{ provide: MD_DATE_FORMATS, useValue: MD_NATIVE_DATE_FORMATS }],
              },] },
  ];
  /**
   * @nocollapse
   */
  MdNativeDateModule.ctorParameters = () => [];
  
  /**
   * Injection token that can be used to specify the global error options.
   */
  const MD_ERROR_GLOBAL_OPTIONS = new InjectionToken('md-error-global-options');
  /**
   * Returns whether control is invalid and is either touched or is a part of a submitted form.
   * @param {?} control
   * @param {?} form
   * @return {?}
   */
  function defaultErrorStateMatcher(control, form) {
      const /** @type {?} */ isSubmitted = form && form.submitted;
      return !!(control.invalid && (control.touched || isSubmitted));
  }
  /**
   * Returns whether control is invalid and is either dirty or is a part of a submitted form.
   * @param {?} control
   * @param {?} form
   * @return {?}
   */
  function showOnDirtyErrorStateMatcher(control, form) {
      const /** @type {?} */ isSubmitted = form && form.submitted;
      return !!(control.invalid && (control.dirty || isSubmitted));
  }
  
  class GestureConfig extends HammerGestureConfig {
      constructor() {
          super();
          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 && isDevMode()) {
              console.warn('Could not find HammerJS. Certain Angular Material ' +
                  'components may not work correctly.');
          }
      }
      /**
       * 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.
      \@returns Newly-created HammerJS instance.
       * @param {?} element
       * @return {?}
       */
      buildHammer(element) {
          const /** @type {?} */ mc = new this._hammer(element);
          // Default Hammer Recognizers.
          let /** @type {?} */ pan = new this._hammer.Pan();
          let /** @type {?} */ swipe = new this._hammer.Swipe();
          let /** @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
          let /** @type {?} */ slide = this._createRecognizer(pan, { event: 'slide', threshold: 0 }, swipe);
          let /** @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 {?}
       */
      _createRecognizer(base, options, ...inheritances) {
          let /** @type {?} */ recognizer = new ((base.constructor))(options);
          inheritances.push(base);
          inheritances.forEach(item => recognizer.recognizeWith(item));
          return recognizer;
      }
  }
  GestureConfig.decorators = [
      { type: Injectable },
  ];
  /**
   * @nocollapse
   */
  GestureConfig.ctorParameters = () => [];
  
  /**
   * Shared directive to count lines inside a text area, such as a list item.
  Line elements can be extracted with a \@ContentChildren(MdLine) query, then
  counted by checking the query list's length.
   */
  class MdLine {
  }
  MdLine.decorators = [
      { type: Directive, args: [{
                  selector: '[md-line], [mat-line], [mdLine], [matLine]',
                  host: { 'class': 'mat-line' }
              },] },
  ];
  /**
   * @nocollapse
   */
  MdLine.ctorParameters = () => [];
  /**
   * Helper that takes a query list of lines and sets the correct class on the host.
  \@docs-private
   */
  class MdLineSetter {
      /**
       * @param {?} _lines
       * @param {?} _renderer
       * @param {?} _element
       */
      constructor(_lines, _renderer, _element) {
          this._lines = _lines;
          this._renderer = _renderer;
          this._element = _element;
          this._setLineClass(this._lines.length);
          this._lines.changes.subscribe(() => {
              this._setLineClass(this._lines.length);
          });
      }
      /**
       * @param {?} count
       * @return {?}
       */
      _setLineClass(count) {
          this._resetClasses();
          if (count === 2 || count === 3) {
              this._setClass(`mat-${count}-line`, true);
          }
          else if (count > 3) {
              this._setClass(`mat-multi-line`, true);
          }
      }
      /**
       * @return {?}
       */
      _resetClasses() {
          this._setClass('mat-2-line', false);
          this._setClass('mat-3-line', false);
          this._setClass('mat-multi-line', false);
      }
      /**
       * @param {?} className
       * @param {?} isAdd
       * @return {?}
       */
      _setClass(className, isAdd) {
          if (isAdd) {
              this._renderer.addClass(this._element.nativeElement, className);
          }
          else {
              this._renderer.removeClass(this._element.nativeElement, className);
          }
      }
  }
  class MdLineModule {
  }
  MdLineModule.decorators = [
      { type: NgModule, args: [{
                  imports: [MdCommonModule],
                  exports: [MdLine, MdCommonModule],
                  declarations: [MdLine],
              },] },
  ];
  /**
   * @nocollapse
   */
  MdLineModule.ctorParameters = () => [];
  
  let 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.
   */
  class RippleRef {
      /**
       * @param {?} _renderer
       * @param {?} element
       * @param {?} config
       */
      constructor(_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 {?}
       */
      fadeOut() {
          this._renderer.fadeOutRipple(this);
      }
  }
  
  /**
   * Fade-in duration for the ripples. Can be modified with the speedFactor option.
   */
  const RIPPLE_FADE_IN_DURATION = 450;
  /**
   * Fade-out duration for the ripples in milliseconds. This can't be modified by the speedFactor.
   */
  const 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
   */
  class RippleRenderer {
      /**
       * @param {?} elementRef
       * @param {?} _ngZone
       * @param {?} _ruler
       * @param {?} platform
       */
      constructor(elementRef, _ngZone, _ruler, platform) {
          this._ngZone = _ngZone;
          this._ruler = _ruler;
          /**
           * 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.onMouseLeave.bind(this));
              // By default use the host element as trigger element.
              this.setTriggerElement(this._containerElement);
          }
      }
      /**
       * Fades in a ripple at the given coordinates.
       * @param {?} pageX
       * @param {?} pageY
       * @param {?=} config
       * @return {?}
       */
      fadeInRipple(pageX, pageY, config = {}) {
          let /** @type {?} */ containerRect = this._containerElement.getBoundingClientRect();
          if (config.centered) {
              pageX = containerRect.left + containerRect.width / 2;
              pageY = containerRect.top + containerRect.height / 2;
          }
          else {
              // Subtract scroll values from the coordinates because calculations below
              // are always relative to the viewport rectangle.
              let /** @type {?} */ scrollPosition = this._ruler.getViewportScrollPosition();
              pageX -= scrollPosition.left;
              pageY -= scrollPosition.top;
          }
          let /** @type {?} */ radius = config.radius || distanceToFurthestCorner(pageX, pageY, containerRect);
          let /** @type {?} */ duration = RIPPLE_FADE_IN_DURATION * (1 / (config.speedFactor || 1));
          let /** @type {?} */ offsetX = pageX - containerRect.left;
          let /** @type {?} */ offsetY = pageY - containerRect.top;
          let /** @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.
          let /** @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(() => {
              rippleRef.state = RippleState.VISIBLE;
              if (!config.persistent && !this._isMousedown) {
                  rippleRef.fadeOut();
              }
          }, duration);
          return rippleRef;
      }
      /**
       * Fades out a ripple reference.
       * @param {?} rippleRef
       * @return {?}
       */
      fadeOutRipple(rippleRef) {
          // For ripples that are not active anymore, don't re-un the fade-out animation.
          if (!this._activeRipples.delete(rippleRef)) {
              return;
          }
          let /** @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(() => {
              rippleRef.state = RippleState.HIDDEN; /** @type {?} */
              ((rippleEl.parentNode)).removeChild(rippleEl);
          }, RIPPLE_FADE_OUT_DURATION);
      }
      /**
       * Fades out all currently active ripples.
       * @return {?}
       */
      fadeOutAll() {
          this._activeRipples.forEach(ripple => ripple.fadeOut());
      }
      /**
       * Sets the trigger element and registers the mouse events.
       * @param {?} element
       * @return {?}
       */
      setTriggerElement(element) {
          // Remove all previously register event listeners from the trigger element.
          if (this._triggerElement) {
              this._triggerEvents.forEach((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(() => {
                  this._triggerEvents.forEach((fn, type) => element.addEventListener(type, fn));
              });
          }
          this._triggerElement = element;
      }
      /**
       * Listener being called on mousedown event.
       * @param {?} event
       * @return {?}
       */
      onMousedown(event) {
          if (!this.rippleDisabled) {
              this._isMousedown = true;
              this.fadeInRipple(event.pageX, event.pageY, this.rippleConfig);
          }
      }
      /**
       * Listener being called on mouseup event.
       * @return {?}
       */
      onMouseup() {
          this._isMousedown = false;
          // Fade-out all ripples that are completely visible and not persistent.
          this._activeRipples.forEach(ripple => {
              if (!ripple.config.persistent && ripple.state === RippleState.VISIBLE) {
                  ripple.fadeOut();
              }
          });
      }
      /**
       * Listener being called on mouseleave event.
       * @return {?}
       */
      onMouseLeave() {
          if (this._isMousedown) {
              this.onMouseup();
          }
      }
      /**
       * Runs a timeout outside of the Angular zone to avoid triggering the change detection.
       * @param {?} fn
       * @param {?=} delay
       * @return {?}
       */
      runTimeoutOutsideZone(fn, delay = 0) {
          this._ngZone.runOutsideAngular(() => setTimeout(fn, delay));
      }
  }
  /**
   * @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) {
      const /** @type {?} */ distX = Math.max(Math.abs(x - rect.left), Math.abs(x - rect.right));
      const /** @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.
   */
  const MD_RIPPLE_GLOBAL_OPTIONS = new InjectionToken('md-ripple-global-options');
  class MdRipple {
      /**
       * @param {?} elementRef
       * @param {?} ngZone
       * @param {?} ruler
       * @param {?} platform
       * @param {?} globalOptions
       */
      constructor(elementRef, ngZone, ruler, 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, ruler, platform);
          this._globalOptions = globalOptions ? globalOptions : {};
          this._updateRippleRenderer();
      }
      /**
       * @return {?}
       */
      get _matRippleTrigger() { return this.trigger; }
      /**
       * @param {?} v
       * @return {?}
       */
      set _matRippleTrigger(v) { this.trigger = v; }
      /**
       * @return {?}
       */
      get _matRippleCentered() { return this.centered; }
      /**
       * @param {?} v
       * @return {?}
       */
      set _matRippleCentered(v) { this.centered = v; }
      /**
       * @return {?}
       */
      get _matRippleDisabled() { return this.disabled; }
      /**
       * @param {?} v
       * @return {?}
       */
      set _matRippleDisabled(v) { this.disabled = v; }
      /**
       * @return {?}
       */
      get _matRippleRadius() { return this.radius; }
      /**
       * @param {?} v
       * @return {?}
       */
      set _matRippleRadius(v) { this.radius = v; }
      /**
       * @return {?}
       */
      get _matRippleSpeedFactor() { return this.speedFactor; }
      /**
       * @param {?} v
       * @return {?}
       */
      set _matRippleSpeedFactor(v) { this.speedFactor = v; }
      /**
       * @return {?}
       */
      get _matRippleColor() { return this.color; }
      /**
       * @param {?} v
       * @return {?}
       */
      set _matRippleColor(v) { this.color = v; }
      /**
       * @return {?}
       */
      get _matRippleUnbounded() { return this.unbounded; }
      /**
       * @param {?} v
       * @return {?}
       */
      set _matRippleUnbounded(v) { this.unbounded = v; }
      /**
       * @param {?} changes
       * @return {?}
       */
      ngOnChanges(changes) {
          if ((changes['trigger'] || changes['_matRippleTrigger']) && this.trigger) {
              this._rippleRenderer.setTriggerElement(this.trigger);
          }
          this._updateRippleRenderer();
      }
      /**
       * @return {?}
       */
      ngOnDestroy() {
          // Set the trigger element to null to cleanup all listeners.
          this._rippleRenderer.setTriggerElement(null);
      }
      /**
       * Launches a manual ripple at the specified position.
       * @param {?} pageX
       * @param {?} pageY
       * @param {?=} config
       * @return {?}
       */
      launch(pageX, pageY, config = this.rippleConfig) {
          return this._rippleRenderer.fadeInRipple(pageX, pageY, config);
      }
      /**
       * Fades out all currently showing ripple elements.
       * @return {?}
       */
      fadeOutAll() {
          this._rippleRenderer.fadeOutAll();
      }
      /**
       * Ripple configuration from the directive's input values.
       * @return {?}
       */
      get rippleConfig() {
          return {
              centered: this.centered,
              speedFactor: this.speedFactor * (this._globalOptions.baseSpeedFactor || 1),
              radius: this.radius,
              color: this.color
          };
      }
      /**
       * Updates the ripple renderer with the latest ripple configuration.
       * @return {?}
       */
      _updateRippleRenderer() {
          this._rippleRenderer.rippleDisabled = this._globalOptions.disabled || this.disabled;
          this._rippleRenderer.rippleConfig = this.rippleConfig;
      }
  }
  MdRipple.decorators = [
      { type: Directive, args: [{
                  selector: '[md-ripple], [mat-ripple], [mdRipple], [matRipple]',
                  exportAs: 'mdRipple, matRipple',
                  host: {
                      'class': 'mat-ripple',
                      '[class.mat-ripple-unbounded]': 'unbounded'
                  }
              },] },
  ];
  /**
   * @nocollapse
   */
  MdRipple.ctorParameters = () => [
      { type: ElementRef, },
      { type: NgZone, },
      { type: ViewportRuler, },
      { type: Platform, },
      { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [MD_RIPPLE_GLOBAL_OPTIONS,] },] },
  ];
  MdRipple.propDecorators = {
      'trigger': [{ type: Input, args: ['mdRippleTrigger',] },],
      'centered': [{ type: Input, args: ['mdRippleCentered',] },],
      'disabled': [{ type: Input, args: ['mdRippleDisabled',] },],
      'radius': [{ type: Input, args: ['mdRippleRadius',] },],
      'speedFactor': [{ type: Input, args: ['mdRippleSpeedFactor',] },],
      'color': [{ type: Input, args: ['mdRippleColor',] },],
      'unbounded': [{ type: Input, args: ['mdRippleUnbounded',] },],
      '_matRippleTrigger': [{ type: Input, args: ['matRippleTrigger',] },],
      '_matRippleCentered': [{ type: Input, args: ['matRippleCentered',] },],
      '_matRippleDisabled': [{ type: Input, args: ['matRippleDisabled',] },],
      '_matRippleRadius': [{ type: Input, args: ['matRippleRadius',] },],
      '_matRippleSpeedFactor': [{ type: Input, args: ['matRippleSpeedFactor',] },],
      '_matRippleColor': [{ type: Input, args: ['matRippleColor',] },],
      '_matRippleUnbounded': [{ type: Input, args: ['matRippleUnbounded',] },],
  };
  
  class MdRippleModule {
  }
  MdRippleModule.decorators = [
      { type: NgModule, args: [{
                  imports: [MdCommonModule, PlatformModule, ScrollDispatchModule],
                  exports: [MdRipple, MdCommonModule],
                  declarations: [MdRipple],
                  providers: [VIEWPORT_RULER_PROVIDER],
              },] },
  ];
  /**
   * @nocollapse
   */
  MdRippleModule.ctorParameters = () => [];
  
  /**
   * Component that shows a simplified checkbox without including any kind of "real" checkbox.
  Meant to be used when the checkbox is purely decorative and a large number of them will be
  included, such as for the options in a multi-select. Uses no SVGs or complex animations.
  Note that theming is meant to be handled by the parent element, e.g.
  `mat-primary .mat-pseudo-checkbox`.
  
  Note that this component will be completely invisible to screen-reader users. This is *not*
  interchangeable with <md-checkbox> and should *not* be used if the user would directly interact
  with the checkbox. The pseudo-checkbox should only be used as an implementation detail of
  more complex components that appropriately handle selected / checked state.
  \@docs-private
   */
  class MdPseudoCheckbox {
      constructor() {
          /**
           * Display state of the checkbox.
           */
          this.state = 'unchecked';
          /**
           * Whether the checkbox is disabled.
           */
          this.disabled = false;
      }
  }
  MdPseudoCheckbox.decorators = [
      { type: Component, args: [{encapsulation: ViewEncapsulation.None,
                  preserveWhitespaces: false,
                  changeDetection: ChangeDetectionStrategy.OnPush,
                  selector: 'md-pseudo-checkbox, mat-pseudo-checkbox',
                  styles: [".mat-pseudo-checkbox{width:20px;height:20px;border:2px solid;border-radius:2px;cursor:pointer;display:inline-block;vertical-align:middle;box-sizing:border-box;position:relative;flex-shrink:0;transition:border-color 90ms cubic-bezier(0,0,.2,.1),background-color 90ms cubic-bezier(0,0,.2,.1)}.mat-pseudo-checkbox::after{position:absolute;opacity:0;content:'';border-bottom:2px solid currentColor;transition:opacity 90ms cubic-bezier(0,0,.2,.1)}.mat-pseudo-checkbox.mat-pseudo-checkbox-checked,.mat-pseudo-checkbox.mat-pseudo-checkbox-indeterminate{border:none}.mat-pseudo-checkbox-disabled{cursor:default}.mat-pseudo-checkbox-indeterminate::after{top:9px;left:2px;width:16px;opacity:1}.mat-pseudo-checkbox-checked::after{top:5px;left:3px;width:12px;height:5px;border-left:2px solid currentColor;transform:rotate(-45deg);opacity:1}"],
                  template: '',
                  host: {
                      'class': 'mat-pseudo-checkbox',
                      '[class.mat-pseudo-checkbox-indeterminate]': 'state === "indeterminate"',
                      '[class.mat-pseudo-checkbox-checked]': 'state === "checked"',
                      '[class.mat-pseudo-checkbox-disabled]': 'disabled',
                  },
              },] },
  ];
  /**
   * @nocollapse
   */
  MdPseudoCheckbox.ctorParameters = () => [];
  MdPseudoCheckbox.propDecorators = {
      'state': [{ type: Input },],
      'disabled': [{ type: Input },],
  };
  
  class MdPseudoCheckboxModule {
  }
  MdPseudoCheckboxModule.decorators = [
      { type: NgModule, args: [{
                  exports: [MdPseudoCheckbox],
                  declarations: [MdPseudoCheckbox]
              },] },
  ];
  /**
   * @nocollapse
   */
  MdPseudoCheckboxModule.ctorParameters = () => [];
  
  /**
   * \@docs-private
   */
  class MdOptgroupBase {
  }
  const _MdOptgroupMixinBase = mixinDisabled(MdOptgroupBase);
  // Counter for unique group ids.
  let _uniqueOptgroupIdCounter = 0;
  /**
   * Component that is used to group instances of `md-option`.
   */
  class MdOptgroup extends _MdOptgroupMixinBase {
      constructor() {
          super(...arguments);
          /**
           * Unique id for the underlying label.
           */
          this._labelId = `mat-optgroup-label-${_uniqueOptgroupIdCounter++}`;
      }
  }
  MdOptgroup.decorators = [
      { type: Component, args: [{selector: 'md-optgroup, mat-optgroup',
                  template: "<label class=\"mat-optgroup-label\" [id]=\"_labelId\">{{ label }}</label><ng-content select=\"md-option, mat-option\"></ng-content>",
                  encapsulation: ViewEncapsulation.None,
                  preserveWhitespaces: false,
                  changeDetection: 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
   */
  MdOptgroup.ctorParameters = () => [];
  MdOptgroup.propDecorators = {
      'label': [{ type: Input },],
  };
  
  /**
   * Option IDs need to be unique across components, so this counter exists outside of
  the component definition.
   */
  let _uniqueIdCounter = 0;
  /**
   * Event object emitted by MdOption when selected or deselected.
   */
  class MdOptionSelectionChange {
      /**
       * @param {?} source
       * @param {?=} isUserInput
       */
      constructor(source, isUserInput = false) {
          this.source = source;
          this.isUserInput = isUserInput;
      }
  }
  /**
   * Single option inside of a `<md-select>` element.
   */
  class MdOption {
      /**
       * @param {?} _element
       * @param {?} _changeDetectorRef
       * @param {?} group
       */
      constructor(_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 = `md-option-${_uniqueIdCounter++}`;
          /**
           * Event emitted when the option is selected or deselected.
           */
          this.onSelectionChange = new EventEmitter();
      }
      /**
       * Whether the wrapping component is in multiple selection mode.
       * @return {?}
       */
      get multiple() { return this._multiple; }
      /**
       * @param {?} value
       * @return {?}
       */
      set multiple(value) {
          if (value !== this._multiple) {
              this._multiple = value;
              this._changeDetectorRef.markForCheck();
          }
      }
      /**
       * The unique ID of the option.
       * @return {?}
       */
      get id() { return this._id; }
      /**
       * Whether or not the option is currently selected.
       * @return {?}
       */
      get selected() { return this._selected; }
      /**
       * Whether the option is disabled.
       * @return {?}
       */
      get disabled() { return (this.group && this.group.disabled) || this._disabled; }
      /**
       * @param {?} value
       * @return {?}
       */
      set disabled(value) { this._disabled = coerceBooleanProperty(value); }
      /**
       * Whether ripples for the option are disabled.
       * @return {?}
       */
      get disableRipple() { return this._disableRipple; }
      /**
       * @param {?} value
       * @return {?}
       */
      set disableRipple(value) {
          this._disableRipple = value;
          this._changeDetectorRef.markForCheck();
      }
      /**
       * 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 active() {
          return this._active;
      }
      /**
       * The displayed value of the option. It is necessary to show the selected option in the
      select's trigger.
       * @return {?}
       */
      get viewValue() {
          // TODO(kara): Add input property alternative for node envs.
          return (this._getHostElement().textContent || '').trim();
      }
      /**
       * Selects the option.
       * @return {?}
       */
      select() {
          this._selected = true;
          this._changeDetectorRef.markForCheck();
          this._emitSelectionChangeEvent();
      }
      /**
       * Deselects the option.
       * @return {?}
       */
      deselect() {
          this._selected = false;
          this._changeDetectorRef.markForCheck();
          this._emitSelectionChangeEvent();
      }
      /**
       * Sets focus onto this option.
       * @return {?}
       */
      focus() {
          const /** @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 {?}
       */
      setActiveStyles() {
          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 {?}
       */
      setInactiveStyles() {
          if (this._active) {
              this._active = false;
              this._changeDetectorRef.markForCheck();
          }
      }
      /**
       * Gets the label to be used when determining whether the option should be focused.
       * @return {?}
       */
      getLabel() {
          return this.viewValue;
      }
      /**
       * Ensures the option is selected when activated from the keyboard.
       * @param {?} event
       * @return {?}
       */
      _handleKeydown(event) {
          if (event.keyCode === ENTER || event.keyCode === 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 {?}
       */
      _selectViaInteraction() {
          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 {?}
       */
      _getTabIndex() {
          return this.disabled ? '-1' : '0';
      }
      /**
       * Gets the host DOM element.
       * @return {?}
       */
      _getHostElement() {
          return this._element.nativeElement;
      }
      /**
       * Emits the selection change event.
       * @param {?=} isUserInput
       * @return {?}
       */
      _emitSelectionChangeEvent(isUserInput = false) {
          this.onSelectionChange.emit(new MdOptionSelectionChange(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.
       * @param {?} optionIndex
       * @param {?} options
       * @param {?} optionGroups
       * @return {?}
       */
      static countGroupLabelsBeforeOption(optionIndex, options, optionGroups) {
          if (optionGroups.length) {
              let /** @type {?} */ optionsArray = options.toArray();
              let /** @type {?} */ groups = optionGroups.toArray();
              let /** @type {?} */ groupCounter = 0;
              for (let /** @type {?} */ i = 0; i < optionIndex + 1; i++) {
                  if (optionsArray[i].group && optionsArray[i].group === groups[groupCounter]) {
                      groupCounter++;
                  }
              }
              return groupCounter;
          }
          return 0;
      }
  }
  MdOption.decorators = [
      { type: Component, args: [{selector: 'md-option, mat-option',
                  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: ViewEncapsulation.None,
                  preserveWhitespaces: false,
                  changeDetection: ChangeDetectionStrategy.OnPush,
                  viewProviders: [{ provide: MATERIAL_COMPATIBILITY_MODE, useValue: true }],
              },] },
  ];
  /**
   * @nocollapse
   */
  MdOption.ctorParameters = () => [
      { type: ElementRef, },
      { type: ChangeDetectorRef, },
      { type: MdOptgroup, decorators: [{ type: Optional },] },
  ];
  MdOption.propDecorators = {
      'value': [{ type: Input },],
      'disabled': [{ type: Input },],
      'onSelectionChange': [{ type: Output },],
  };
  
  class MdOptionModule {
  }
  MdOptionModule.decorators = [
      { type: NgModule, args: [{
                  imports: [MdRippleModule, CommonModule, MdPseudoCheckboxModule],
                  exports: [MdOption, MdOptgroup],
                  declarations: [MdOption, MdOptgroup]
              },] },
  ];
  /**
   * @nocollapse
   */
  MdOptionModule.ctorParameters = () => [];
  
  /**
   * InjectionToken that can be used to specify the global placeholder options.
   */
  const MD_PLACEHOLDER_GLOBAL_OPTIONS = new InjectionToken('md-placeholder-global-options');
  
  /**
   * Applies a CSS transform to an element, including browser-prefixed properties.
  \@param element
  \@param transformValue
   * @param {?} element
   * @param {?} transformValue
   * @return {?}
   */
  function applyCssTransform(element, transformValue) {
      // It's important to trim the result, because the browser will ignore the set operation
      // if the string contains only whitespace.
      let /** @type {?} */ value = transformValue.trim();
      element.style.transform = value;
      element.style.webkitTransform = value;
  }
  
  /**
   * When constructing a Date, the month is zero-based. This can be confusing, since people are
  used to seeing them one-based. So we create these aliases to make writing the tests easier.
   */
  const JAN = 0;
  const FEB = 1;
  const MAR = 2;
  const APR = 3;
  const MAY = 4;
  const JUN = 5;
  const JUL = 6;
  const AUG = 7;
  const SEP = 8;
  const OCT = 9;
  const NOV = 10;
  const DEC = 11;
  
  /**
   * Generated bundle index. Do not edit.
   */
  
  export { AnimationCurves, AnimationDurations, MdCommonModule, MATERIAL_SANITY_CHECKS, mixinDisabled, mixinColor, mixinDisableRipple, mixinTabIndex, MATERIAL_COMPATIBILITY_MODE, getMdCompatibilityInvalidPrefixError, MAT_ELEMENTS_SELECTOR, MD_ELEMENTS_SELECTOR, MatPrefixRejector, MdPrefixRejector, CompatibilityModule, NoConflictStyleCompatibilityMode, UniqueSelectionDispatcher, UNIQUE_SELECTION_DISPATCHER_PROVIDER_FACTORY, UNIQUE_SELECTION_DISPATCHER_PROVIDER, NativeDateModule, MdNativeDateModule, MAT_DATE_LOCALE, MAT_DATE_LOCALE_PROVIDER, DateAdapter, MD_DATE_FORMATS, NativeDateAdapter, MD_NATIVE_DATE_FORMATS, MD_ERROR_GLOBAL_OPTIONS, defaultErrorStateMatcher, showOnDirtyErrorStateMatcher, GestureConfig, MdLine, MdLineSetter, MdLineModule, MdOptionModule, MdOptionSelectionChange, MdOption, MdOptgroupBase, _MdOptgroupMixinBase, MdOptgroup, MD_PLACEHOLDER_GLOBAL_OPTIONS, MdRipple, MD_RIPPLE_GLOBAL_OPTIONS, RippleRef, RippleState, RIPPLE_FADE_IN_DURATION, RIPPLE_FADE_OUT_DURATION, MdRippleModule, MdPseudoCheckboxModule, MdPseudoCheckbox, applyCssTransform, extendObject, MD_DATE_FORMATS as MAT_DATE_FORMATS, MD_RIPPLE_GLOBAL_OPTIONS as MAT_RIPPLE_GLOBAL_OPTIONS, MD_NATIVE_DATE_FORMATS as MAT_NATIVE_DATE_FORMATS, MD_PLACEHOLDER_GLOBAL_OPTIONS as MAT_PLACEHOLDER_GLOBAL_OPTIONS, MD_ERROR_GLOBAL_OPTIONS as MAT_ERROR_GLOBAL_OPTIONS, MdCommonModule as MatCommonModule, MdLine as MatLine, MdLineModule as MatLineModule, MdLineSetter as MatLineSetter, MdOptgroup as MatOptgroup, MdOptgroupBase as MatOptgroupBase, MdOption as MatOption, MdOptionModule as MatOptionModule, MdOptionSelectionChange as MatOptionSelectionChange, MdNativeDateModule as MatNativeDateModule, MdPseudoCheckbox as MatPseudoCheckbox, MdPseudoCheckboxModule as MatPseudoCheckboxModule, MdRipple as MatRipple, MdRippleModule as MatRippleModule, JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC, RippleRenderer as ɵa0 };
  //# sourceMappingURL=core.js.map
  